cli: enable transformation of workspace packages outside the workspace root

This commit is contained in:
Patrik Oldsberg
2020-11-20 10:25:24 +01:00
parent 8803fec70d
commit 8cc862ebfc
2 changed files with 42 additions and 13 deletions
+28 -6
View File
@@ -70,13 +70,27 @@ async function readBuildInfo() {
};
}
async function loadLernaPackages(): Promise<
{ name: string; location: string }[]
> {
const LernaProject = require('@lerna/project');
const project = new LernaProject(cliPaths.targetDir);
return project.getPackages();
}
export async function createConfig(
paths: BundlingPaths,
options: BundlingOptions,
): Promise<webpack.Configuration> {
const { checksEnabled, isDev, frontendConfig } = options;
const { plugins, loaders } = transforms(options);
const packages = await loadLernaPackages();
const { plugins, loaders } = transforms({
...options,
externalTransforms: packages.map(({ name }) =>
cliPaths.resolveTargetRoot('node_modules', name),
),
});
const baseUrl = frontendConfig.getString('app.baseUrl');
const validBaseUrl = new URL(baseUrl);
@@ -159,6 +173,10 @@ export async function createConfig(
alias: {
'react-dom': '@hot-loader/react-dom',
},
// Enables proper resolution of packages when linking in external packages.
// Without this the packages would depend on dependencies in the node_modules
// of the external packages themselves, leading to module duplication
symlinks: false,
},
module: {
rules: loaders,
@@ -181,17 +199,20 @@ export async function createBackendConfig(
): Promise<webpack.Configuration> {
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 packages = await await loadLernaPackages();
const localPackageNames = packages.map((p: any) => p.name);
const moduleDirs = packages.map((p: any) =>
resolvePath(p.location, 'node_modules'),
);
const { loaders } = transforms({
...options,
externalTransforms: packages.map(({ name }) =>
cliPaths.resolveTargetRoot('node_modules', name),
),
});
return {
mode: isDev ? 'development' : 'production',
profile: false,
@@ -240,6 +261,7 @@ export async function createBackendConfig(
alias: {
'react-dom': '@hot-loader/react-dom',
},
symlinks: false, // See frontend config, added here for the same reason
},
module: {
rules: loaders,
+14 -7
View File
@@ -16,7 +16,6 @@
import webpack, { Module, Plugin } from 'webpack';
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
import { BundlingOptions, BackendBundlingOptions } from './types';
import { svgrTemplate } from '../svgrTemplate';
type Transforms = {
@@ -24,17 +23,25 @@ type Transforms = {
plugins: Plugin[];
};
export const transforms = (
options: BundlingOptions | BackendBundlingOptions,
): Transforms => {
const { isDev } = options;
type TransformOptions = {
isDev: boolean;
// External paths that should be transformed
externalTransforms: string[];
};
export const transforms = (options: TransformOptions): Transforms => {
const { isDev, externalTransforms } = options;
const extraTransforms = isDev ? ['react-hot-loader'] : [];
const transformExcludeCondition = {
and: [/node_modules/, { not: externalTransforms }],
};
const loaders = [
{
test: /\.(tsx?)$/,
exclude: /node_modules/,
exclude: transformExcludeCondition,
loader: require.resolve('@sucrase/webpack-loader'),
options: {
transforms: ['typescript', 'jsx', ...extraTransforms],
@@ -43,7 +50,7 @@ export const transforms = (
},
{
test: /\.(jsx?|mjs)$/,
exclude: /node_modules/,
exclude: transformExcludeCondition,
loader: require.resolve('@sucrase/webpack-loader'),
options: {
transforms: ['jsx', ...extraTransforms],