Skip to content

Commit

Permalink
feat(bundling): rollup should support ESM config files
Browse files Browse the repository at this point in the history
  • Loading branch information
Coly010 committed Feb 27, 2024
1 parent 53e62c2 commit de4ec26
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 21 deletions.
44 changes: 43 additions & 1 deletion e2e/rollup/src/rollup.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
import { join } from 'path';

describe('Rollup Plugin', () => {
beforeAll(() => newProject());
beforeAll(() => newProject({ packages: ['@nx/rollup', '@nx/js'] }));
afterAll(() => cleanupProject());

it('should be able to setup project to build node programs with rollup and different compilers', async () => {
Expand Down Expand Up @@ -119,4 +119,46 @@ describe('Rollup Plugin', () => {
runCLI(`generate @nx/js:lib ${jsLib} --bundler rollup`);
expect(() => runCLI(`build ${jsLib}`)).not.toThrow();
});

it('should be able to build libs generated with @nx/js:lib --bundler rollup with a custom rollup.config.{cjs|mjs}', () => {
const jsLib = uniq('jslib');
runCLI(`generate @nx/js:lib ${jsLib} --bundler rollup`);
updateFile(
`libs/${jsLib}/rollup.config.cjs`,
`module.exports = {
output: {
format: "cjs",
dir: "dist/test",
name: "Mylib",
entryFileNames: "[name].cjs.js",
chunkFileNames: "[name].cjs.js"
}
}`
);
updateJson(join('libs', jsLib, 'project.json'), (config) => {
config.targets.build.options.rollupConfig = `libs/${jsLib}/rollup.config.cjs`;
return config;
});
expect(() => runCLI(`build ${jsLib}`)).not.toThrow();
checkFilesExist(`dist/test/index.cjs.js`);

updateFile(
`libs/${jsLib}/rollup.config.mjs`,
`export default {
output: {
format: "es",
dir: "dist/test",
name: "Mylib",
entryFileNames: "[name].mjs.js",
chunkFileNames: "[name].mjs.js"
}
}`
);
updateJson(join('libs', jsLib, 'project.json'), (config) => {
config.targets.build.options.rollupConfig = `libs/${jsLib}/rollup.config.mjs`;
return config;
});
expect(() => runCLI(`build ${jsLib}`)).not.toThrow();
checkFilesExist(`dist/test/index.mjs.js`);
});
});
32 changes: 19 additions & 13 deletions packages/rollup/src/executors/rollup/rollup.impl.spec.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import { ExecutorContext } from '@nx/devkit';
import * as fs from 'fs';
import * as rollup from 'rollup';
import { RollupExecutorOptions } from './schema';
import { createRollupOptions } from './rollup.impl';
import { normalizeRollupExecutorOptions } from './lib/normalize';

jest.mock('rollup-plugin-copy', () => jest.fn());

jest.mock('fs', () => ({
...jest.requireActual('fs'),
readdirSync: () => [],
}));
describe('rollupExecutor', () => {
let context: ExecutorContext;
let testOptions: RollupExecutorOptions;
Expand Down Expand Up @@ -35,8 +39,8 @@ describe('rollupExecutor', () => {
});

describe('createRollupOptions', () => {
it('should create rollup options for valid config', () => {
const result: any = createRollupOptions(
it('should create rollup options for valid config', async () => {
const result: any = await createRollupOptions(
normalizeRollupExecutorOptions(
testOptions,
{ root: '/root' } as any,
Expand Down Expand Up @@ -73,7 +77,7 @@ describe('rollupExecutor', () => {
() => (o) => ({ ...o, prop: 'my-val' }),
{ virtual: true }
);
const result: any = createRollupOptions(
const result: any = await createRollupOptions(
normalizeRollupExecutorOptions(
{ ...testOptions, rollupConfig: 'custom-rollup.config.ts' },
{ root: '/root' } as any,
Expand All @@ -85,6 +89,7 @@ describe('rollupExecutor', () => {
'/root/src',
[]
);

expect(result.map((x) => x.prop)).toEqual(['my-val', 'my-val']);
});

Expand All @@ -103,7 +108,7 @@ describe('rollupExecutor', () => {
}),
{ virtual: true }
);
const result: any = createRollupOptions(
const result: any = await createRollupOptions(
normalizeRollupExecutorOptions(
{
...testOptions,
Expand All @@ -121,15 +126,16 @@ describe('rollupExecutor', () => {
'/root/src',
[]
);

expect(result.map((x) => x.prop1)).toEqual([
'my-val-my-val-2',
'my-val-my-val-2',
]);
expect(result.map((x) => x.prop2)).toEqual(['my-val-2', 'my-val-2']);
});

it(`should always use forward slashes for asset paths`, () => {
createRollupOptions(
it(`should always use forward slashes for asset paths`, async () => {
await createRollupOptions(
{
...normalizeRollupExecutorOptions(
testOptions,
Expand All @@ -156,8 +162,8 @@ describe('rollupExecutor', () => {
});
});

it(`should treat npm dependencies as external if external is all`, () => {
const options = createRollupOptions(
it(`should treat npm dependencies as external if external is all`, async () => {
const options = await createRollupOptions(
normalizeRollupExecutorOptions(
{ ...testOptions, external: 'all' },
{ root: '/root' } as any,
Expand All @@ -177,8 +183,8 @@ describe('rollupExecutor', () => {
expect(external('rxjs', '', false)).toBe(false);
});

it(`should not treat npm dependencies as external if external is none`, () => {
const options = createRollupOptions(
it(`should not treat npm dependencies as external if external is none`, async () => {
const options = await createRollupOptions(
normalizeRollupExecutorOptions(
{ ...testOptions, external: 'none' },
{ root: '/root' } as any,
Expand All @@ -198,8 +204,8 @@ describe('rollupExecutor', () => {
expect(external('rxjs', '', false)).toBe(false);
});

it(`should set external based on options`, () => {
const options = createRollupOptions(
it(`should set external based on options`, async () => {
const options = await createRollupOptions(
normalizeRollupExecutorOptions(
{ ...testOptions, external: ['rxjs'] },
{ root: '/root' } as any,
Expand Down
40 changes: 33 additions & 7 deletions packages/rollup/src/executors/rollup/rollup.impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { analyze } from './lib/analyze-plugin';
import { deleteOutputDir } from '../../utils/fs';
import { swc } from './lib/swc-plugin';
import { updatePackageJson } from './lib/update-package-json';
import { loadConfigFile } from '@nx/devkit/src/utils/config-utils';

export type RollupExecutorEvent = {
success: boolean;
Expand Down Expand Up @@ -74,7 +75,7 @@ export async function* rollupExecutor(
.filter((d) => d.target.startsWith('npm:'))
.map((d) => d.target.slice(4));

const rollupOptions = createRollupOptions(
const rollupOptions = await createRollupOptions(
options,
dependencies,
context,
Expand Down Expand Up @@ -155,14 +156,14 @@ export async function* rollupExecutor(

// -----------------------------------------------------------------------------

export function createRollupOptions(
export async function createRollupOptions(
options: NormalizedRollupExecutorOptions,
dependencies: DependentBuildableProjectNode[],
context: ExecutorContext,
packageJson: PackageJson,
sourceRoot: string,
npmDeps: string[]
): rollup.InputOptions[] {
): Promise<rollup.InputOptions[]> {
const useBabel = options.compiler === 'babel';
const useTsc = options.compiler === 'tsc';
const useSwc = options.compiler === 'swc';
Expand Down Expand Up @@ -195,7 +196,7 @@ export function createRollupOptions(
options.format = ['cjs'];
}

return options.format.map((format, idx) => {
const _rollupOptions = options.format.map(async (format, idx) => {
// Either we're generating only one format, so we should bundle types
// OR we are generating dual formats, so only bundle types for CJS.
const shouldBundleTypes = options.format.length === 1 || format === 'cjs';
Expand Down Expand Up @@ -310,10 +311,35 @@ export function createRollupOptions(
plugins,
};

return options.rollupConfig.reduce((currentConfig, plugin) => {
return require(plugin)(currentConfig, options);
}, rollupConfig);
const userDefinedRollupConfigs = options.rollupConfig.map((plugin) =>
loadConfigFile(plugin)
);
let finalConfig: rollup.InputOptions = rollupConfig;
for (const _config of userDefinedRollupConfigs) {
const config = await _config;
if (typeof config === 'function') {
finalConfig = config(finalConfig, options);
} else {
finalConfig = {
...finalConfig,
...config,
plugins: [
...(finalConfig.plugins?.length > 0 ? finalConfig.plugins : []),
...(config.plugins?.length > 0 ? config.plugins : []),
],
};
}
}

return finalConfig;
});

const rollupOptions = [];
for (const rollupOption of _rollupOptions) {
rollupOptions.push(await rollupOption);
}

return rollupOptions;
}

function createTsCompilerOptions(
Expand Down

0 comments on commit de4ec26

Please sign in to comment.