feat(bundling): add for esbuild to enable/disable package.json generation (#15777)
This commit is contained in:
parent
f10ecc1c8e
commit
7ebca5107e
@ -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).",
|
||||||
|
|||||||
@ -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/);
|
||||||
|
|
||||||
|
|||||||
@ -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",
|
||||||
|
|||||||
@ -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) {
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -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: [],
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -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:
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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).",
|
||||||
|
|||||||
@ -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}`,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -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,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -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();
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -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);
|
||||||
|
}
|
||||||
@ -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';
|
||||||
|
|||||||
@ -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'.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user