diff --git a/packages/cli/src/lib/bundler/backend.ts b/packages/cli/src/lib/bundler/backend.ts index f5f233854f..e3cc8af8d1 100644 --- a/packages/cli/src/lib/bundler/backend.ts +++ b/packages/cli/src/lib/bundler/backend.ts @@ -25,7 +25,7 @@ export async function serveBackend( }, ) { const paths = resolveBundlingPaths(options); - const config = createBackendConfig(paths, { + const config = await createBackendConfig(paths, { ...options, isDev: true, }); diff --git a/packages/cli/src/lib/bundler/config.ts b/packages/cli/src/lib/bundler/config.ts index 61f4448dd9..118cb1b40c 100644 --- a/packages/cli/src/lib/bundler/config.ts +++ b/packages/cli/src/lib/bundler/config.ts @@ -15,6 +15,7 @@ */ import fs from 'fs-extra'; +import { resolve as resolvePath } from 'path'; import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin'; import HtmlWebpackPlugin from 'html-webpack-plugin'; import ModuleScopePlugin from 'react-dev-utils/ModuleScopePlugin'; @@ -171,14 +172,23 @@ export async function createConfig( }; } -export function createBackendConfig( +export async function createBackendConfig( paths: BundlingPaths, options: BackendBundlingOptions, -): webpack.Configuration { +): Promise { const { checksEnabled, isDev } = options; const { loaders } = transforms(options); + // Find all local monorepo packages and their node_modules, and mark them as external. + const LernaProject = require('@lerna/project'); + const project = new LernaProject(cliPaths.targetDir); + const packages = await project.getPackages(); + const localPackageNames = packages.map((p: any) => p.name); + const moduleDirs = packages.map((p: any) => + resolvePath(p.location, 'node_modules'), + ); + return { mode: isDev ? 'development' : 'production', profile: false, @@ -193,11 +203,8 @@ export function createBackendConfig( externals: [ nodeExternals({ modulesDir: paths.rootNodeModules, - allowlist: ['webpack/hot/poll?100', /\@backstage\/.*/], - }), - nodeExternals({ - modulesDir: paths.targetNodeModules, - allowlist: ['webpack/hot/poll?100', /\@backstage\/.*/], + additionalModuleDirs: moduleDirs, + allowlist: ['webpack/hot/poll?100', ...localPackageNames], }), ], target: 'node' as const, @@ -219,7 +226,7 @@ export function createBackendConfig( resolve: { extensions: ['.ts', '.tsx', '.mjs', '.js', '.jsx'], mainFields: ['browser', 'module', 'main'], - modules: [paths.targetNodeModules, paths.rootNodeModules], + modules: [paths.rootNodeModules, ...moduleDirs], plugins: [ new ModuleScopePlugin( [paths.targetSrc, paths.targetDev], diff --git a/packages/cli/src/lib/bundler/paths.ts b/packages/cli/src/lib/bundler/paths.ts index 70e82d8d48..390e41a345 100644 --- a/packages/cli/src/lib/bundler/paths.ts +++ b/packages/cli/src/lib/bundler/paths.ts @@ -63,7 +63,6 @@ export function resolveBundlingPaths(options: BundlingPathsOptions) { targetDev: paths.resolveTarget('dev'), targetEntry: resolveTargetModule(entry), targetTsConfig: paths.resolveTargetRoot('tsconfig.json'), - targetNodeModules: paths.resolveTarget('node_modules'), targetPackageJson: paths.resolveTarget('package.json'), rootNodeModules: paths.resolveTargetRoot('node_modules'), root: paths.targetRoot,