feat(bundling): add for esbuild to enable/disable package.json generation (#15777)

This commit is contained in:
Jack Hsu 2023-03-21 08:48:16 -04:00 committed by GitHub
parent f10ecc1c8e
commit 7ebca5107e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 305 additions and 69 deletions

View File

@ -147,6 +147,11 @@
"default": false, "default": false,
"x-priority": "internal" "x-priority": "internal"
}, },
"generatePackageJson": {
"type": "boolean",
"description": "Generates a `package.json` and pruned lock file with the project's `node_module` dependencies populated for installing in a container. If a `package.json` exists in the project's directory, it will be reused with dependencies populated.",
"default": false
},
"thirdParty": { "thirdParty": {
"type": "boolean", "type": "boolean",
"description": "Includes third-party packages in the bundle (i.e. npm packages).", "description": "Includes third-party packages in the bundle (i.e. npm packages).",

View File

@ -34,6 +34,17 @@ describe('EsBuild Plugin', () => {
updateFile(`libs/${myPkg}/assets/a.md`, 'file a'); updateFile(`libs/${myPkg}/assets/a.md`, 'file a');
updateFile(`libs/${myPkg}/assets/b.md`, 'file b'); updateFile(`libs/${myPkg}/assets/b.md`, 'file b');
// Copy package.json as asset rather than generate with Nx-detected fields.
runCLI(`build ${myPkg} --generatePackageJson=false`);
const packageJson = readJson(`libs/${myPkg}/package.json`);
// This is the file that is generated by lib generator (no deps, no main, etc.).
expect(packageJson).toEqual({
name: `@proj/${myPkg}`,
version: '0.0.1',
type: 'commonjs',
});
// Build normally with package.json generation.
runCLI(`build ${myPkg}`); runCLI(`build ${myPkg}`);
expect(runCommand(`node dist/libs/${myPkg}/index.js`)).toMatch(/Hello/); expect(runCommand(`node dist/libs/${myPkg}/index.js`)).toMatch(/Hello/);
@ -41,6 +52,9 @@ describe('EsBuild Plugin', () => {
checkFilesExist(`dist/libs/${myPkg}/package.json`); checkFilesExist(`dist/libs/${myPkg}/package.json`);
expect(runCommand(`node dist/libs/${myPkg}`)).toMatch(/Hello/); expect(runCommand(`node dist/libs/${myPkg}`)).toMatch(/Hello/);
expect(runCommand(`node dist/libs/${myPkg}/index.js`)).toMatch(/Hello/);
// main field should be set correctly in package.json
expect(readFile(`dist/libs/${myPkg}/assets/a.md`)).toMatch(/file a/); expect(readFile(`dist/libs/${myPkg}/assets/a.md`)).toMatch(/file a/);
expect(readFile(`dist/libs/${myPkg}/assets/b.md`)).toMatch(/file b/); expect(readFile(`dist/libs/${myPkg}/assets/b.md`)).toMatch(/file b/);

View File

@ -1,5 +1,12 @@
{ {
"generators": {}, "generators": {
"set-generate-package-json": {
"cli": "nx",
"version": "15.8.7-beta.0",
"description": "Set generatePackageJson to true to maintain existing behavior of generating package.json in output path.",
"factory": "./src/migrations/update-15-8-7/set-generate-package-json"
}
},
"packageJsonUpdates": { "packageJsonUpdates": {
"15.7.0": { "15.7.0": {
"version": "15.7.0-beta.0", "version": "15.7.0-beta.0",

View File

@ -41,7 +41,7 @@ export async function* esbuildExecutor(
_options: EsBuildExecutorOptions, _options: EsBuildExecutorOptions,
context: ExecutorContext context: ExecutorContext
) { ) {
const options = normalizeOptions(_options); const options = normalizeOptions(_options, context);
if (options.deleteOutputPath) removeSync(options.outputPath); if (options.deleteOutputPath) removeSync(options.outputPath);
const assetsResult = await copyAssets(options, context); const assetsResult = await copyAssets(options, context);
@ -70,24 +70,27 @@ export async function* esbuildExecutor(
} }
} }
const cpjOptions: CopyPackageJsonOptions = { let packageJsonResult;
...options, if (options.generatePackageJson) {
// TODO(jack): make types generate with esbuild const cpjOptions: CopyPackageJsonOptions = {
skipTypings: true, ...options,
outputFileExtensionForCjs: getOutExtension('cjs', options), // TODO(jack): make types generate with esbuild
excludeLibsInPackageJson: !options.thirdParty, skipTypings: true,
updateBuildableProjectDepsInPackageJson: externalDependencies.length > 0, outputFileExtensionForCjs: getOutExtension('cjs', options),
}; excludeLibsInPackageJson: !options.thirdParty,
updateBuildableProjectDepsInPackageJson: externalDependencies.length > 0,
};
// If we're bundling third-party packages, then any extra deps from external should be the only deps in package.json // If we're bundling third-party packages, then any extra deps from external should be the only deps in package.json
if (options.thirdParty && externalDependencies.length > 0) { if (options.thirdParty && externalDependencies.length > 0) {
cpjOptions.overrideDependencies = externalDependencies; cpjOptions.overrideDependencies = externalDependencies;
} else { } else {
cpjOptions.extraDependencies = externalDependencies; cpjOptions.extraDependencies = externalDependencies;
}
packageJsonResult = await copyPackageJson(cpjOptions, context);
} }
const packageJsonResult = await copyPackageJson(cpjOptions, context);
if ('context' in esbuild) { if ('context' in esbuild) {
// 0.17.0+ adds esbuild.context and context.watch() // 0.17.0+ adds esbuild.context and context.watch()
if (options.watch) { if (options.watch) {

View File

@ -45,7 +45,6 @@ describe('buildEsbuildOptions', () => {
main: 'apps/myapp/src/index.ts', main: 'apps/myapp/src/index.ts',
outputPath: 'dist/apps/myapp', outputPath: 'dist/apps/myapp',
tsConfig: 'apps/myapp/tsconfig.app.json', tsConfig: 'apps/myapp/tsconfig.app.json',
project: 'apps/myapp/package.json',
assets: [], assets: [],
outputFileName: 'index.js', outputFileName: 'index.js',
singleEntry: true, singleEntry: true,
@ -82,7 +81,6 @@ describe('buildEsbuildOptions', () => {
additionalEntryPoints: ['apps/myapp/src/extra-entry.ts'], additionalEntryPoints: ['apps/myapp/src/extra-entry.ts'],
outputPath: 'dist/apps/myapp', outputPath: 'dist/apps/myapp',
tsConfig: 'apps/myapp/tsconfig.app.json', tsConfig: 'apps/myapp/tsconfig.app.json',
project: 'apps/myapp/package.json',
assets: [], assets: [],
outputFileName: 'index.js', outputFileName: 'index.js',
singleEntry: false, singleEntry: false,
@ -118,7 +116,6 @@ describe('buildEsbuildOptions', () => {
main: 'apps/myapp/src/index.ts', main: 'apps/myapp/src/index.ts',
outputPath: 'dist/apps/myapp', outputPath: 'dist/apps/myapp',
tsConfig: 'apps/myapp/tsconfig.app.json', tsConfig: 'apps/myapp/tsconfig.app.json',
project: 'apps/myapp/package.json',
assets: [], assets: [],
outputFileName: 'index.js', outputFileName: 'index.js',
singleEntry: true, singleEntry: true,
@ -154,7 +151,6 @@ describe('buildEsbuildOptions', () => {
main: 'apps/myapp/src/index.ts', main: 'apps/myapp/src/index.ts',
outputPath: 'dist/apps/myapp', outputPath: 'dist/apps/myapp',
tsConfig: 'apps/myapp/tsconfig.app.json', tsConfig: 'apps/myapp/tsconfig.app.json',
project: 'apps/myapp/package.json',
assets: [], assets: [],
outputFileName: 'index.js', outputFileName: 'index.js',
singleEntry: true, singleEntry: true,
@ -187,7 +183,6 @@ describe('buildEsbuildOptions', () => {
main: 'apps/myapp/src/index.ts', main: 'apps/myapp/src/index.ts',
outputPath: 'dist/apps/myapp', outputPath: 'dist/apps/myapp',
tsConfig: 'apps/myapp/tsconfig.app.json', tsConfig: 'apps/myapp/tsconfig.app.json',
project: 'apps/myapp/package.json',
outputFileName: 'index.js', outputFileName: 'index.js',
assets: [], assets: [],
singleEntry: true, singleEntry: true,
@ -223,7 +218,6 @@ describe('buildEsbuildOptions', () => {
main: 'apps/myapp/src/index.ts', main: 'apps/myapp/src/index.ts',
outputPath: 'dist/apps/myapp', outputPath: 'dist/apps/myapp',
tsConfig: 'apps/myapp/tsconfig.app.json', tsConfig: 'apps/myapp/tsconfig.app.json',
project: 'apps/myapp/package.json',
outputFileName: 'index.js', outputFileName: 'index.js',
assets: [], assets: [],
singleEntry: true, singleEntry: true,
@ -260,7 +254,6 @@ describe('buildEsbuildOptions', () => {
main: 'apps/myapp/src/index.ts', main: 'apps/myapp/src/index.ts',
outputPath: 'dist/apps/myapp', outputPath: 'dist/apps/myapp',
tsConfig: 'apps/myapp/tsconfig.app.json', tsConfig: 'apps/myapp/tsconfig.app.json',
project: 'apps/myapp/package.json',
outputFileName: 'index.js', outputFileName: 'index.js',
assets: [], assets: [],
singleEntry: true, singleEntry: true,
@ -298,10 +291,9 @@ describe('buildEsbuildOptions', () => {
main: 'apps/myapp/src/index.ts', main: 'apps/myapp/src/index.ts',
outputPath: 'dist/apps/myapp', outputPath: 'dist/apps/myapp',
tsConfig: 'apps/myapp/tsconfig.app.json', tsConfig: 'apps/myapp/tsconfig.app.json',
project: 'apps/myapp/package.json',
outputFileName: 'index.js',
assets: [], assets: [],
singleEntry: true, singleEntry: true,
outputFileName: 'index.js',
external: ['foo'], external: ['foo'],
esbuildOptions: { esbuildOptions: {
external: ['bar'], external: ['bar'],
@ -334,8 +326,6 @@ describe('buildEsbuildOptions', () => {
main: 'apps/myapp/src/index.ts', main: 'apps/myapp/src/index.ts',
outputPath: 'dist/apps/myapp', outputPath: 'dist/apps/myapp',
tsConfig: 'apps/myapp/tsconfig.app.json', tsConfig: 'apps/myapp/tsconfig.app.json',
project: 'apps/myapp/package.json',
outputFileName: 'index.js',
assets: [], assets: [],
singleEntry: true, singleEntry: true,
external: ['foo'], external: ['foo'],
@ -367,7 +357,40 @@ describe('buildEsbuildOptions', () => {
main: 'apps/myapp/src/index.ts', main: 'apps/myapp/src/index.ts',
outputPath: 'dist/apps/myapp', outputPath: 'dist/apps/myapp',
tsConfig: 'apps/myapp/tsconfig.app.json', tsConfig: 'apps/myapp/tsconfig.app.json',
project: 'apps/myapp/package.json', outputFileName: 'index.js',
assets: [],
singleEntry: true,
sourcemap: true,
external: [],
},
context
)
).toEqual({
bundle: false,
entryNames: '[dir]/[name]',
entryPoints: ['apps/myapp/src/index.ts'],
format: 'esm',
platform: 'node',
outdir: 'dist/apps/myapp',
tsconfig: 'apps/myapp/tsconfig.app.json',
external: undefined,
sourcemap: true,
outExtension: {
'.js': '.js',
},
});
});
it('should set sourcemap', () => {
expect(
buildEsbuildOptions(
'esm',
{
bundle: false,
platform: 'node',
main: 'apps/myapp/src/index.ts',
outputPath: 'dist/apps/myapp',
tsConfig: 'apps/myapp/tsconfig.app.json',
outputFileName: 'index.js', outputFileName: 'index.js',
assets: [], assets: [],
singleEntry: true, singleEntry: true,

View File

@ -1,21 +1,45 @@
import { normalizeOptions } from './normalize'; import { normalizeOptions } from './normalize';
import { ExecutorContext } from '@nrwl/devkit';
describe('normalizeOptions', () => { describe('normalizeOptions', () => {
const context: ExecutorContext = {
root: '/',
cwd: '/',
isVerbose: false,
projectName: 'myapp',
projectGraph: {
nodes: {
myapp: {
type: 'app',
name: 'myapp',
data: {
root: 'apps/myapp',
files: [],
},
},
},
dependencies: {},
},
};
it('should handle single entry point options', () => { it('should handle single entry point options', () => {
expect( expect(
normalizeOptions({ normalizeOptions(
main: 'apps/myapp/src/index.ts', {
outputPath: 'dist/apps/myapp', main: 'apps/myapp/src/index.ts',
tsConfig: 'apps/myapp/tsconfig.app.json', outputPath: 'dist/apps/myapp',
project: 'apps/myapp/package.json', tsConfig: 'apps/myapp/tsconfig.app.json',
assets: [], generatePackageJson: true,
}) assets: [],
},
context
)
).toEqual({ ).toEqual({
main: 'apps/myapp/src/index.ts', main: 'apps/myapp/src/index.ts',
outputPath: 'dist/apps/myapp', outputPath: 'dist/apps/myapp',
tsConfig: 'apps/myapp/tsconfig.app.json', tsConfig: 'apps/myapp/tsconfig.app.json',
project: 'apps/myapp/package.json',
assets: [], assets: [],
generatePackageJson: true,
outputFileName: 'index.js', outputFileName: 'index.js',
singleEntry: true, singleEntry: true,
external: [], external: [],
@ -24,20 +48,23 @@ describe('normalizeOptions', () => {
it('should handle multiple entry point options', () => { it('should handle multiple entry point options', () => {
expect( expect(
normalizeOptions({ normalizeOptions(
main: 'apps/myapp/src/index.ts', {
outputPath: 'dist/apps/myapp', main: 'apps/myapp/src/index.ts',
tsConfig: 'apps/myapp/tsconfig.app.json', outputPath: 'dist/apps/myapp',
project: 'apps/myapp/package.json', tsConfig: 'apps/myapp/tsconfig.app.json',
assets: [], assets: [],
additionalEntryPoints: ['apps/myapp/src/extra-entry.ts'], generatePackageJson: true,
}) additionalEntryPoints: ['apps/myapp/src/extra-entry.ts'],
},
context
)
).toEqual({ ).toEqual({
main: 'apps/myapp/src/index.ts', main: 'apps/myapp/src/index.ts',
outputPath: 'dist/apps/myapp', outputPath: 'dist/apps/myapp',
tsConfig: 'apps/myapp/tsconfig.app.json', tsConfig: 'apps/myapp/tsconfig.app.json',
project: 'apps/myapp/package.json',
assets: [], assets: [],
generatePackageJson: true,
outputFileName: 'index.js', outputFileName: 'index.js',
additionalEntryPoints: ['apps/myapp/src/extra-entry.ts'], additionalEntryPoints: ['apps/myapp/src/extra-entry.ts'],
singleEntry: false, singleEntry: false,
@ -47,20 +74,23 @@ describe('normalizeOptions', () => {
it('should support custom output file name', () => { it('should support custom output file name', () => {
expect( expect(
normalizeOptions({ normalizeOptions(
main: 'apps/myapp/src/index.ts', {
outputPath: 'dist/apps/myapp', main: 'apps/myapp/src/index.ts',
tsConfig: 'apps/myapp/tsconfig.app.json', outputPath: 'dist/apps/myapp',
project: 'apps/myapp/package.json', tsConfig: 'apps/myapp/tsconfig.app.json',
assets: [], assets: [],
outputFileName: 'test.js', generatePackageJson: true,
}) outputFileName: 'test.js',
},
context
)
).toEqual({ ).toEqual({
main: 'apps/myapp/src/index.ts', main: 'apps/myapp/src/index.ts',
outputPath: 'dist/apps/myapp', outputPath: 'dist/apps/myapp',
tsConfig: 'apps/myapp/tsconfig.app.json', tsConfig: 'apps/myapp/tsconfig.app.json',
project: 'apps/myapp/package.json',
assets: [], assets: [],
generatePackageJson: true,
outputFileName: 'test.js', outputFileName: 'test.js',
singleEntry: true, singleEntry: true,
external: [], external: [],
@ -69,15 +99,42 @@ describe('normalizeOptions', () => {
it('should validate against multiple entry points + outputFileName', () => { it('should validate against multiple entry points + outputFileName', () => {
expect(() => expect(() =>
normalizeOptions({ normalizeOptions(
main: 'apps/myapp/src/index.ts', {
outputPath: 'dist/apps/myapp', main: 'apps/myapp/src/index.ts',
tsConfig: 'apps/myapp/tsconfig.app.json', outputPath: 'dist/apps/myapp',
project: 'apps/myapp/package.json', tsConfig: 'apps/myapp/tsconfig.app.json',
assets: [], assets: [],
additionalEntryPoints: ['apps/myapp/src/extra-entry.ts'], generatePackageJson: true,
outputFileName: 'test.js', additionalEntryPoints: ['apps/myapp/src/extra-entry.ts'],
}) outputFileName: 'test.js',
},
context
)
).toThrow(/Cannot use/); ).toThrow(/Cannot use/);
}); });
it('should add package.json to assets array if generatePackageJson is false', () => {
expect(
normalizeOptions(
{
main: 'apps/myapp/src/index.ts',
outputPath: 'dist/apps/myapp',
tsConfig: 'apps/myapp/tsconfig.app.json',
generatePackageJson: false,
assets: [],
},
context
)
).toEqual({
main: 'apps/myapp/src/index.ts',
outputPath: 'dist/apps/myapp',
tsConfig: 'apps/myapp/tsconfig.app.json',
assets: ['apps/myapp/package.json'],
generatePackageJson: false,
outputFileName: 'index.js',
singleEntry: true,
external: [],
});
});
}); });

View File

@ -3,10 +3,23 @@ import {
EsBuildExecutorOptions, EsBuildExecutorOptions,
NormalizedEsBuildExecutorOptions, NormalizedEsBuildExecutorOptions,
} from '../schema'; } from '../schema';
import { ExecutorContext, joinPathFragments } from '@nrwl/devkit';
export function normalizeOptions( export function normalizeOptions(
options: EsBuildExecutorOptions options: EsBuildExecutorOptions,
context: ExecutorContext
): NormalizedEsBuildExecutorOptions { ): NormalizedEsBuildExecutorOptions {
// If we're not generating package.json file, then copy it as-is as an asset.
const assets = options.generatePackageJson
? options.assets
: [
...options.assets,
joinPathFragments(
context.projectGraph.nodes[context.projectName].data.root,
'package.json'
),
];
if (options.additionalEntryPoints?.length > 0) { if (options.additionalEntryPoints?.length > 0) {
const { outputFileName, ...rest } = options; const { outputFileName, ...rest } = options;
if (outputFileName) { if (outputFileName) {
@ -16,6 +29,7 @@ export function normalizeOptions(
} }
return { return {
...rest, ...rest,
assets,
external: options.external ?? [], external: options.external ?? [],
singleEntry: false, singleEntry: false,
// Use the `main` file name as the output file name. // Use the `main` file name as the output file name.
@ -26,6 +40,7 @@ export function normalizeOptions(
} else { } else {
return { return {
...options, ...options,
assets,
external: options.external ?? [], external: options.external ?? [],
singleEntry: true, singleEntry: true,
outputFileName: outputFileName:

View File

@ -4,7 +4,7 @@ type Compiler = 'babel' | 'swc';
export interface EsBuildExecutorOptions { export interface EsBuildExecutorOptions {
additionalEntryPoints?: string[]; additionalEntryPoints?: string[];
assets: AssetGlob[]; assets: (AssetGlob | string)[];
buildableProjectDepsInPackageJsonType?: 'dependencies' | 'peerDependencies'; buildableProjectDepsInPackageJsonType?: 'dependencies' | 'peerDependencies';
bundle?: boolean; bundle?: boolean;
deleteOutputPath?: boolean; deleteOutputPath?: boolean;
@ -20,7 +20,6 @@ export interface EsBuildExecutorOptions {
outputHashing?: 'none' | 'all'; outputHashing?: 'none' | 'all';
outputPath: string; outputPath: string;
platform?: 'node' | 'browser' | 'neutral'; platform?: 'node' | 'browser' | 'neutral';
project: string;
sourcemap?: boolean | 'linked' | 'inline' | 'external' | 'both'; sourcemap?: boolean | 'linked' | 'inline' | 'external' | 'both';
skipTypeCheck?: boolean; skipTypeCheck?: boolean;
target?: string; target?: string;

View File

@ -122,6 +122,11 @@
"default": false, "default": false,
"x-priority": "internal" "x-priority": "internal"
}, },
"generatePackageJson": {
"type": "boolean",
"description": "Generates a `package.json` and pruned lock file with the project's `node_module` dependencies populated for installing in a container. If a `package.json` exists in the project's directory, it will be reused with dependencies populated.",
"default": false
},
"thirdParty": { "thirdParty": {
"type": "boolean", "type": "boolean",
"description": "Includes third-party packages in the bundle (i.e. npm packages).", "description": "Includes third-party packages in the bundle (i.e. npm packages).",

View File

@ -36,7 +36,6 @@ describe('esbuildProjectGenerator', () => {
main: `libs/mypkg/src/${main}`, main: `libs/mypkg/src/${main}`,
outputFileName: 'main.js', outputFileName: 'main.js',
outputPath: 'dist/libs/mypkg', outputPath: 'dist/libs/mypkg',
project: 'libs/mypkg/package.json',
tsConfig: `libs/mypkg/${tsConfig}`, tsConfig: `libs/mypkg/${tsConfig}`,
}); });
}); });

View File

@ -55,7 +55,6 @@ function addBuildTarget(tree: Tree, options: EsBuildProjectSchema) {
outputPath: joinPathFragments('dist', project.root), outputPath: joinPathFragments('dist', project.root),
outputFileName: 'main.js', outputFileName: 'main.js',
tsConfig, tsConfig,
project: `${project.root}/package.json`,
assets: [], assets: [],
platform: options.platform, platform: options.platform,
}; };

View File

@ -0,0 +1,73 @@
import {
addProjectConfiguration,
readProjectConfiguration,
Tree,
} from '@nrwl/devkit';
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
import update from './set-generate-package-json';
describe('Migration: Set generatePackageJson', () => {
let tree: Tree;
beforeEach(() => {
tree = createTreeWithEmptyWorkspace();
});
it('should keep existing generatePackageJson option if it exists', async () => {
addProjectConfiguration(tree, 'myapp', {
root: 'myapp',
targets: {
build: {
executor: '@nrwl/esbuild:esbuild',
options: {
generatePackageJson: false,
},
},
},
});
await update(tree);
const config = readProjectConfiguration(tree, 'myapp');
expect(config.targets.build.options).toEqual({
generatePackageJson: false,
});
});
it('should set generatePackageJson to true for esbuild targets', async () => {
addProjectConfiguration(tree, 'myapp', {
root: 'myapp',
targets: {
build: {
executor: '@nrwl/esbuild:esbuild',
},
},
});
await update(tree);
const config = readProjectConfiguration(tree, 'myapp');
expect(config.targets.build.options).toEqual({
generatePackageJson: true,
});
});
it('should ignore targets not using esbuild', async () => {
addProjectConfiguration(tree, 'myapp', {
root: 'myapp',
targets: {
build: {
executor: '@nrwl/webpack:webpack',
},
},
});
await update(tree);
const config = readProjectConfiguration(tree, 'myapp');
expect(config.targets.build.options).toBeUndefined();
});
});

View File

@ -0,0 +1,32 @@
import type { Tree } from '@nrwl/devkit';
import {
formatFiles,
getProjects,
updateProjectConfiguration,
} from '@nrwl/devkit';
export default async function update(tree: Tree): Promise<void> {
const projects = getProjects(tree);
projects.forEach((projectConfig, projectName) => {
let shouldUpdate = false;
Object.entries(projectConfig.targets).forEach(
([targetName, targetConfig]) => {
if (targetConfig.executor === '@nrwl/esbuild:esbuild') {
shouldUpdate = true;
projectConfig.targets[targetName].options ??= {};
projectConfig.targets[targetName].options.generatePackageJson ??=
true;
}
}
);
if (shouldUpdate) {
updateProjectConfiguration(tree, projectName, projectConfig);
}
});
await formatFiles(tree);
}

View File

@ -163,6 +163,10 @@ function addProject(
}, },
}; };
if (options.bundler === 'esbuild') {
projectConfiguration.targets.build.options.generatePackageJson = true;
}
if (options.bundler === 'rollup') { if (options.bundler === 'rollup') {
projectConfiguration.targets.build.options.project = `${options.projectRoot}/package.json`; projectConfiguration.targets.build.options.project = `${options.projectRoot}/package.json`;
projectConfiguration.targets.build.options.compiler = 'swc'; projectConfiguration.targets.build.options.compiler = 'swc';

View File

@ -110,6 +110,7 @@ function getEsBuildConfig(
), ),
tsConfig: joinPathFragments(options.appProjectRoot, 'tsconfig.app.json'), tsConfig: joinPathFragments(options.appProjectRoot, 'tsconfig.app.json'),
assets: [joinPathFragments(project.sourceRoot, 'assets')], assets: [joinPathFragments(project.sourceRoot, 'assets')],
generatePackageJson: true,
esbuildOptions: { esbuildOptions: {
sourcemap: true, sourcemap: true,
// Generate CJS files as .js so imports can be './foo' rather than './foo.cjs'. // Generate CJS files as .js so imports can be './foo' rather than './foo.cjs'.