diff --git a/api/src/extensions.ts b/api/src/extensions.ts index 8784d9c47a..045c6195ca 100644 --- a/api/src/extensions.ts +++ b/api/src/extensions.ts @@ -2,13 +2,13 @@ import express, { Router } from 'express'; import path from 'path'; import { AppExtensionType, Extension, ExtensionType } from '@directus/shared/types'; import { + ensureExtensionsDirs, generateExtensionsEntry, getLocalExtensions, getPackageExtensions, - pluralize, resolvePackage, } from '@directus/shared/utils'; -import { APP_EXTENSION_TYPES, EXTENSION_TYPES, SHARED_DEPS } from '@directus/shared/constants'; +import { APP_EXTENSION_TYPES, SHARED_DEPS } from '@directus/shared/constants'; import getDatabase from './database'; import emitter from './emitter'; import env from './env'; @@ -31,11 +31,17 @@ let extensions: Extension[] = []; let extensionBundles: Partial> = {}; export async function initializeExtensions(): Promise { - await ensureDirsExist(); + await ensureExtensionsDirs(env.EXTENSIONS_PATH); extensions = await getExtensions(); - extensionBundles = await generateExtensionBundles(); - logger.info(`Loaded extensions: ${listExtensions().join(', ')}`); + if (!('DIRECTUS_DEV' in process.env)) { + extensionBundles = await generateExtensionBundles(); + } + + const loadedExtensions = listExtensions(); + if (loadedExtensions.length > 0) { + logger.info(`Loaded extensions: ${loadedExtensions.join(', ')}`); + } } export function listExtensions(type?: ExtensionType): string[] { @@ -81,7 +87,7 @@ async function generateExtensionBundles() { const bundle = await rollup({ input: 'entry', - external: SHARED_DEPS, + external: Object.values(sharedDepsMapping), plugins: [virtual({ entry }), alias({ entries: internalImports })], }); const { output } = await bundle.generate({ format: 'es' }); @@ -94,17 +100,6 @@ async function generateExtensionBundles() { return bundles; } -async function ensureDirsExist() { - for (const extensionType of EXTENSION_TYPES) { - const dirPath = path.resolve(env.EXTENSIONS_PATH, pluralize(extensionType)); - try { - await fse.ensureDir(dirPath); - } catch (err) { - logger.warn(err); - } - } -} - async function getSharedDepsMapping(deps: string[]) { const appDir = await fse.readdir(path.join(resolvePackage('@directus/app'), 'dist')); @@ -115,7 +110,7 @@ async function getSharedDepsMapping(deps: string[]) { if (depName) { depsMapping[dep] = `${env.PUBLIC_URL}/admin/${depName}`; } else { - logger.warn(`Couldn't find extension internal dependency "${dep}"`); + logger.warn(`Couldn't find shared extension dependency "${dep}"`); } } diff --git a/app/vite.config.js b/app/vite.config.js index 9bc7a2f2bb..a673cbbc3e 100644 --- a/app/vite.config.js +++ b/app/vite.config.js @@ -2,7 +2,12 @@ import { defineConfig } from 'vite'; import vue from '@vitejs/plugin-vue'; import yaml from '@rollup/plugin-yaml'; import path from 'path'; -import { getPackageExtensions, getLocalExtensions, generateExtensionsEntry } from '@directus/shared/utils'; +import { + ensureExtensionsDirs, + getPackageExtensions, + getLocalExtensions, + generateExtensionsEntry, +} from '@directus/shared/utils'; import { SHARED_DEPS, APP_EXTENSION_TYPES } from '@directus/shared/constants'; // https://vitejs.dev/config/ @@ -38,7 +43,7 @@ function directusExtensions() { const virtualIds = APP_EXTENSION_TYPES.map((type) => `${prefix}${type}`); let extensionEntrys = {}; - loadExtensions(); + if (process.env.NODE_ENV !== 'production') loadExtensions(); return [ { @@ -84,8 +89,12 @@ function directusExtensions() { ]; async function loadExtensions() { - const packageExtensions = await getPackageExtensions(path.join('..', 'api')); - const localExtensions = await getLocalExtensions(path.join('..', 'api', 'extensions')); + const apiPath = path.join('..', 'api'); + const extensionsPath = path.join(apiPath, 'extensions'); + + await ensureExtensionsDirs(extensionsPath); + const packageExtensions = await getPackageExtensions(apiPath); + const localExtensions = await getLocalExtensions(extensionsPath); const extensions = [...packageExtensions, ...localExtensions]; diff --git a/packages/shared/src/utils/ensure-extensions-dirs.ts b/packages/shared/src/utils/ensure-extensions-dirs.ts new file mode 100644 index 0000000000..57698612c1 --- /dev/null +++ b/packages/shared/src/utils/ensure-extensions-dirs.ts @@ -0,0 +1,11 @@ +import path from 'path'; +import fse from 'fs-extra'; +import { pluralize } from './pluralize'; +import { EXTENSION_TYPES } from '../constants'; + +export async function ensureExtensionsDirs(extensionsPath: string): Promise { + for (const extensionType of EXTENSION_TYPES) { + const dirPath = path.resolve(extensionsPath, pluralize(extensionType)); + await fse.ensureDir(dirPath); + } +} diff --git a/packages/shared/src/utils/generate-extensions-entry.ts b/packages/shared/src/utils/generate-extensions-entry.ts new file mode 100644 index 0000000000..daa5b0a975 --- /dev/null +++ b/packages/shared/src/utils/generate-extensions-entry.ts @@ -0,0 +1,10 @@ +import path from 'path'; +import { AppExtensionType, Extension } from '../types'; + +export function generateExtensionsEntry(type: AppExtensionType, extensions: Extension[]): string { + const filteredExtensions = extensions.filter((extension) => extension.type === type); + + return `${filteredExtensions + .map((extension, i) => `import e${i} from '${path.resolve(extension.path, extension.entrypoint || '')}';\n`) + .join('')}export default [${filteredExtensions.map((_, i) => `e${i}`).join(',')}];`; +} diff --git a/packages/shared/src/utils/load-extensions.ts b/packages/shared/src/utils/get-extensions.ts similarity index 85% rename from packages/shared/src/utils/load-extensions.ts rename to packages/shared/src/utils/get-extensions.ts index 768018395f..8c8dccce73 100644 --- a/packages/shared/src/utils/load-extensions.ts +++ b/packages/shared/src/utils/get-extensions.ts @@ -1,6 +1,6 @@ import path from 'path'; import fse from 'fs-extra'; -import { AppExtensionType, Extension } from '../types'; +import { Extension } from '../types'; import { resolvePackage } from './resolve-package'; import { listFolders } from './list-folders'; import { EXTENSION_NAME_REGEX, EXTENSION_TYPES } from '../constants'; @@ -85,11 +85,3 @@ export async function getLocalExtensions(root: string): Promise { return extensions; } - -export function generateExtensionsEntry(type: AppExtensionType, extensions: Extension[]): string { - const filteredExtensions = extensions.filter((extension) => extension.type === type); - - return `${filteredExtensions - .map((extension, i) => `import e${i} from '${path.resolve(extension.path, extension.entrypoint || '')}';\n`) - .join('')}export default [${filteredExtensions.map((_, i) => `e${i}`).join(',')}];`; -} diff --git a/packages/shared/src/utils/index.ts b/packages/shared/src/utils/index.ts index 95d4e45f30..7ceefd68bb 100644 --- a/packages/shared/src/utils/index.ts +++ b/packages/shared/src/utils/index.ts @@ -1,4 +1,6 @@ +export * from './ensure-extensions-dirs'; +export * from './generate-extensions-entry'; +export * from './get-extensions'; export * from './list-folders'; -export * from './load-extensions'; export * from './pluralize'; export * from './resolve-package';