fix(react): fix external npm packages for rollup (#16713)

This commit is contained in:
Emily Xiong 2023-05-03 04:41:20 -04:00 committed by GitHub
parent db862cf691
commit 68c262d933
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 87 additions and 20 deletions

View File

@ -66,7 +66,10 @@
"external": { "external": {
"type": "array", "type": "array",
"description": "A list of external modules that will not be bundled (`react`, `react-dom`, etc.).", "description": "A list of external modules that will not be bundled (`react`, `react-dom`, etc.).",
"items": { "type": "string" } "oneOf": [
{ "type": "string", "enum": ["all", "none"] },
{ "type": "array", "items": { "type": "string" } }
]
}, },
"watch": { "watch": {
"type": "boolean", "type": "boolean",

View File

@ -38,7 +38,7 @@ export async function addRollupBuildTarget(
const { targets } = readProjectConfiguration(host, options.name); const { targets } = readProjectConfiguration(host, options.name);
const { libsDir } = getWorkspaceLayout(host); const { libsDir } = getWorkspaceLayout(host);
const external: string[] = []; const external: string[] = ['react', 'react-dom'];
if (options.style === '@emotion/styled') { if (options.style === '@emotion/styled') {
external.push('@emotion/react/jsx-runtime'); external.push('@emotion/react/jsx-runtime');

View File

@ -505,7 +505,7 @@ describe('lib', () => {
executor: '@nx/rollup:rollup', executor: '@nx/rollup:rollup',
outputs: ['{options.outputPath}'], outputs: ['{options.outputPath}'],
options: { options: {
external: ['react/jsx-runtime'], external: ['react', 'react-dom', 'react/jsx-runtime'],
entryFile: 'libs/my-lib/src/index.ts', entryFile: 'libs/my-lib/src/index.ts',
outputPath: 'dist/libs/my-lib', outputPath: 'dist/libs/my-lib',
project: 'libs/my-lib/package.json', project: 'libs/my-lib/package.json',
@ -544,7 +544,7 @@ describe('lib', () => {
expect(config.targets.build).toMatchObject({ expect(config.targets.build).toMatchObject({
options: { options: {
external: ['react/jsx-runtime'], external: ['react', 'react-dom', 'react/jsx-runtime'],
}, },
}); });
expect(babelrc.plugins).toEqual([ expect(babelrc.plugins).toEqual([
@ -566,7 +566,7 @@ describe('lib', () => {
expect(config.targets.build).toMatchObject({ expect(config.targets.build).toMatchObject({
options: { options: {
external: ['@emotion/react/jsx-runtime'], external: ['react', 'react-dom', '@emotion/react/jsx-runtime'],
}, },
}); });
expect(babelrc.plugins).toEqual(['@emotion/babel-plugin']); expect(babelrc.plugins).toEqual(['@emotion/babel-plugin']);
@ -588,7 +588,7 @@ describe('lib', () => {
expect(config.targets.build).toMatchObject({ expect(config.targets.build).toMatchObject({
options: { options: {
external: ['react/jsx-runtime'], external: ['react', 'react-dom', 'react/jsx-runtime'],
}, },
}); });
expect(babelrc.plugins).toEqual(['styled-jsx/babel']); expect(babelrc.plugins).toEqual(['styled-jsx/babel']);
@ -606,7 +606,7 @@ describe('lib', () => {
expect(config.targets.build).toMatchObject({ expect(config.targets.build).toMatchObject({
options: { options: {
external: ['react/jsx-runtime'], external: ['react', 'react-dom', 'react/jsx-runtime'],
}, },
}); });
}); });

View File

@ -150,9 +150,13 @@ describe('rollupExecutor', () => {
}); });
}); });
it(`should treat npm dependencies as external`, () => { it(`should treat npm dependencies as external if external is all`, () => {
const options = createRollupOptions( const options = createRollupOptions(
normalizeRollupExecutorOptions(testOptions, '/root', '/root/src'), normalizeRollupExecutorOptions(
{ ...testOptions, external: 'all' },
'/root',
'/root/src'
),
[], [],
context, context,
{ name: 'example' }, { name: 'example' },
@ -166,5 +170,47 @@ describe('rollupExecutor', () => {
expect(external('lodash/fp', '', false)).toBe(true); expect(external('lodash/fp', '', false)).toBe(true);
expect(external('rxjs', '', false)).toBe(false); expect(external('rxjs', '', false)).toBe(false);
}); });
it(`should not treat npm dependencies as external if external is none`, () => {
const options = createRollupOptions(
normalizeRollupExecutorOptions(
{ ...testOptions, external: 'none' },
'/root',
'/root/src'
),
[],
context,
{ name: 'example' },
'/root/src',
['lodash']
);
const external = options[0].external as rollup.IsExternal;
expect(external('lodash', '', false)).toBe(false);
expect(external('lodash/fp', '', false)).toBe(false);
expect(external('rxjs', '', false)).toBe(false);
});
it(`should set external based on options`, () => {
const options = createRollupOptions(
normalizeRollupExecutorOptions(
{ ...testOptions, external: ['rxjs'] },
'/root',
'/root/src'
),
[],
context,
{ name: 'example' },
'/root/src',
['lodash']
);
const external = options[0].external as rollup.IsExternal;
expect(external('lodash', '', false)).toBe(false);
expect(external('lodash/fp', '', false)).toBe(false);
expect(external('rxjs', '', false)).toBe(true);
});
}); });
}); });

View File

@ -271,10 +271,18 @@ export function createRollupOptions(
analyze(), analyze(),
]; ];
const externalPackages = dependencies let externalPackages = [
.map((d) => d.name) ...Object.keys(packageJson.dependencies || {}),
.concat(options.external || []) ...Object.keys(packageJson.peerDependencies || {}),
.concat(Object.keys(packageJson.dependencies || {})); ]; // If external is set to none, include all dependencies and peerDependencies in externalPackages
if (options.external === 'all') {
externalPackages = externalPackages
.concat(dependencies.map((d) => d.name))
.concat(npmDeps);
} else if (Array.isArray(options.external) && options.external.length > 0) {
externalPackages = externalPackages.concat(options.external);
}
externalPackages = [...new Set(externalPackages)];
const rollupConfig = { const rollupConfig = {
input: options.outputFileName input: options.outputFileName
@ -289,10 +297,11 @@ export function createRollupOptions(
entryFileNames: `[name].${format === 'esm' ? 'js' : 'cjs'}`, entryFileNames: `[name].${format === 'esm' ? 'js' : 'cjs'}`,
chunkFileNames: `[name].${format === 'esm' ? 'js' : 'cjs'}`, chunkFileNames: `[name].${format === 'esm' ? 'js' : 'cjs'}`,
}, },
external: (id) => external: (id: string) => {
externalPackages.some( return externalPackages.some(
(name) => id === name || id.startsWith(`${name}/`) (name) => id === name || id.startsWith(`${name}/`)
) || npmDeps.some((name) => id === name || id.startsWith(`${name}/`)), // Could be a deep import ); // Could be a deep import
},
plugins, plugins,
}; };

View File

@ -19,7 +19,7 @@ export interface RollupExecutorOptions {
main: string; main: string;
outputFileName?: string; outputFileName?: string;
extractCss?: boolean | string; extractCss?: boolean | string;
external?: string[]; external?: string[] | 'all' | 'none';
rollupConfig?: string | string[]; rollupConfig?: string | string[];
watch?: boolean; watch?: boolean;
assets?: any[]; assets?: any[];

View File

@ -66,9 +66,18 @@
"external": { "external": {
"type": "array", "type": "array",
"description": "A list of external modules that will not be bundled (`react`, `react-dom`, etc.).", "description": "A list of external modules that will not be bundled (`react`, `react-dom`, etc.).",
"items": { "oneOf": [
"type": "string" {
} "type": "string",
"enum": ["all", "none"]
},
{
"type": "array",
"items": {
"type": "string"
}
}
]
}, },
"watch": { "watch": {
"type": "boolean", "type": "boolean",