fix(angular): support dynamic imports in buildable libs (#5560)
This commit is contained in:
parent
6aadf98fca
commit
939da0a1c3
@ -5,6 +5,7 @@
|
|||||||
* since these libraries will be compiled by the ngtsc.
|
* since these libraries will be compiled by the ngtsc.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { InjectionToken } from 'injection-js';
|
||||||
import {
|
import {
|
||||||
Transform,
|
Transform,
|
||||||
transformFromPromise,
|
transformFromPromise,
|
||||||
@ -13,7 +14,6 @@ import {
|
|||||||
provideTransform,
|
provideTransform,
|
||||||
TransformProvider,
|
TransformProvider,
|
||||||
} from 'ng-packagr/lib/graph/transform.di';
|
} from 'ng-packagr/lib/graph/transform.di';
|
||||||
import { COMPILE_NGC_TOKEN } from 'ng-packagr/lib/ng-package/entry-point/compile-ngc.di';
|
|
||||||
import {
|
import {
|
||||||
EntryPointNode,
|
EntryPointNode,
|
||||||
isEntryPoint,
|
isEntryPoint,
|
||||||
@ -26,7 +26,7 @@ import { setDependenciesTsConfigPaths } from 'ng-packagr/lib/ts/tsconfig';
|
|||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as ts from 'typescript';
|
import * as ts from 'typescript';
|
||||||
|
|
||||||
export const compileNgcTransformFactory = (
|
export const nxCompileNgcTransformFactory = (
|
||||||
StylesheetProcessor: typeof StylesheetProcessorClass
|
StylesheetProcessor: typeof StylesheetProcessorClass
|
||||||
): Transform => {
|
): Transform => {
|
||||||
return transformFromPromise(async (graph) => {
|
return transformFromPromise(async (graph) => {
|
||||||
@ -73,8 +73,11 @@ export const compileNgcTransformFactory = (
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const NX_COMPILE_NGC_TOKEN = new InjectionToken<Transform>(
|
||||||
|
`nx.v1.compileNgc`
|
||||||
|
);
|
||||||
export const NX_COMPILE_NGC_TRANSFORM: TransformProvider = provideTransform({
|
export const NX_COMPILE_NGC_TRANSFORM: TransformProvider = provideTransform({
|
||||||
provide: COMPILE_NGC_TOKEN,
|
provide: NX_COMPILE_NGC_TOKEN,
|
||||||
useFactory: compileNgcTransformFactory,
|
useFactory: nxCompileNgcTransformFactory,
|
||||||
deps: [STYLESHEET_PROCESSOR_TOKEN],
|
deps: [STYLESHEET_PROCESSOR_TOKEN],
|
||||||
});
|
});
|
||||||
|
|||||||
@ -4,23 +4,18 @@
|
|||||||
* where Nx takes over with Nx specific functions
|
* where Nx takes over with Nx specific functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { COMPILE_NGC_TOKEN } from 'ng-packagr/lib/ng-package/entry-point/compile-ngc.di';
|
|
||||||
import {
|
|
||||||
NX_WRITE_BUNDLES_TRANSFORM,
|
|
||||||
NX_WRITE_BUNDLES_TRANSFORM_TOKEN,
|
|
||||||
} from './write-bundles';
|
|
||||||
import {
|
|
||||||
WRITE_PACKAGE_TRANSFORM,
|
|
||||||
WRITE_PACKAGE_TRANSFORM_TOKEN,
|
|
||||||
} from 'ng-packagr/lib/ng-package/entry-point/write-package.di';
|
|
||||||
import { InjectionToken, Provider } from 'injection-js';
|
import { InjectionToken, Provider } from 'injection-js';
|
||||||
import { Transform } from 'ng-packagr/lib/graph/transform';
|
import { Transform } from 'ng-packagr/lib/graph/transform';
|
||||||
import {
|
import {
|
||||||
provideTransform,
|
provideTransform,
|
||||||
TransformProvider,
|
TransformProvider,
|
||||||
} from 'ng-packagr/lib/graph/transform.di';
|
} from 'ng-packagr/lib/graph/transform.di';
|
||||||
import { entryPointTransformFactory } from 'ng-packagr/lib/ng-package/entry-point/entry-point.transform';
|
import { NX_COMPILE_NGC_TOKEN, NX_COMPILE_NGC_TRANSFORM } from './compile-ngc';
|
||||||
import { NX_COMPILE_NGC_TRANSFORM } from './compile-ngc';
|
import { nxEntryPointTransformFactory } from './entry-point';
|
||||||
|
import {
|
||||||
|
NX_WRITE_PACKAGE_TRANSFORM,
|
||||||
|
NX_WRITE_PACKAGE_TRANSFORM_TOKEN,
|
||||||
|
} from './write-package.di';
|
||||||
|
|
||||||
export const NX_ENTRY_POINT_TRANSFORM_TOKEN = new InjectionToken<Transform>(
|
export const NX_ENTRY_POINT_TRANSFORM_TOKEN = new InjectionToken<Transform>(
|
||||||
`nx.v1.entryPointTransform`
|
`nx.v1.entryPointTransform`
|
||||||
@ -28,17 +23,12 @@ export const NX_ENTRY_POINT_TRANSFORM_TOKEN = new InjectionToken<Transform>(
|
|||||||
|
|
||||||
export const NX_ENTRY_POINT_TRANSFORM: TransformProvider = provideTransform({
|
export const NX_ENTRY_POINT_TRANSFORM: TransformProvider = provideTransform({
|
||||||
provide: NX_ENTRY_POINT_TRANSFORM_TOKEN,
|
provide: NX_ENTRY_POINT_TRANSFORM_TOKEN,
|
||||||
useFactory: entryPointTransformFactory,
|
useFactory: nxEntryPointTransformFactory,
|
||||||
deps: [
|
deps: [NX_COMPILE_NGC_TOKEN, NX_WRITE_PACKAGE_TRANSFORM_TOKEN],
|
||||||
COMPILE_NGC_TOKEN,
|
|
||||||
NX_WRITE_BUNDLES_TRANSFORM_TOKEN,
|
|
||||||
WRITE_PACKAGE_TRANSFORM_TOKEN,
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export const NX_ENTRY_POINT_PROVIDERS: Provider[] = [
|
export const NX_ENTRY_POINT_PROVIDERS: Provider[] = [
|
||||||
NX_ENTRY_POINT_TRANSFORM,
|
NX_ENTRY_POINT_TRANSFORM,
|
||||||
NX_COMPILE_NGC_TRANSFORM,
|
NX_COMPILE_NGC_TRANSFORM,
|
||||||
NX_WRITE_BUNDLES_TRANSFORM,
|
NX_WRITE_PACKAGE_TRANSFORM,
|
||||||
WRITE_PACKAGE_TRANSFORM,
|
|
||||||
];
|
];
|
||||||
|
|||||||
@ -0,0 +1,66 @@
|
|||||||
|
/**
|
||||||
|
* Adapted from original ng-packagr source
|
||||||
|
*
|
||||||
|
* Remove writing bundles as they are not needed
|
||||||
|
* for incremental builds.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { logger } from '@nrwl/devkit';
|
||||||
|
import { STATE_DONE } from 'ng-packagr/lib/graph/node';
|
||||||
|
import { isInProgress } from 'ng-packagr/lib/graph/select';
|
||||||
|
import {
|
||||||
|
Transform,
|
||||||
|
transformFromPromise,
|
||||||
|
} from 'ng-packagr/lib/graph/transform';
|
||||||
|
import { byEntryPoint } from 'ng-packagr/lib/ng-package/nodes';
|
||||||
|
import { pipe } from 'rxjs';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A re-write of the `transformSources()` script that transforms an entry point from sources to distributable format.
|
||||||
|
*
|
||||||
|
* Sources are TypeScript source files accompanied by HTML templates and xCSS stylesheets.
|
||||||
|
* See the Angular Package Format for a detailed description of what the distributables include.
|
||||||
|
*
|
||||||
|
* The current transformation pipeline can be thought of as:
|
||||||
|
*
|
||||||
|
* - clean
|
||||||
|
* - compileTs
|
||||||
|
* - downlevelTs
|
||||||
|
* - relocateSourceMaps
|
||||||
|
* - writePackage
|
||||||
|
* - copyStagedFiles (esm, dts, metadata, sourcemaps)
|
||||||
|
* - writePackageJson
|
||||||
|
*
|
||||||
|
* The transformation pipeline is pluggable through the dependency injection system.
|
||||||
|
* Sub-transformations are passed to this factory function as arguments.
|
||||||
|
*
|
||||||
|
* @param compileTs Transformation compiling typescript sources to ES2015 modules.
|
||||||
|
* @param writePackage Transformation writing a distribution-ready `package.json` (for publishing to npm registry).
|
||||||
|
*/
|
||||||
|
export const nxEntryPointTransformFactory = (
|
||||||
|
compileTs: Transform,
|
||||||
|
writePackage: Transform
|
||||||
|
): Transform =>
|
||||||
|
pipe(
|
||||||
|
transformFromPromise(async (graph) => {
|
||||||
|
// Peek the first entry point from the graph
|
||||||
|
const entryPoint = graph.find(byEntryPoint().and(isInProgress));
|
||||||
|
logger.info(
|
||||||
|
'\n------------------------------------------------------------------------------'
|
||||||
|
);
|
||||||
|
logger.info(
|
||||||
|
`Building entry point '${entryPoint.data.entryPoint.moduleId}'`
|
||||||
|
);
|
||||||
|
logger.info(
|
||||||
|
'------------------------------------------------------------------------------'
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
// TypeScript sources compilation
|
||||||
|
compileTs,
|
||||||
|
// After TypeScript: write package
|
||||||
|
writePackage,
|
||||||
|
transformFromPromise(async (graph) => {
|
||||||
|
const entryPoint = graph.find(byEntryPoint().and(isInProgress));
|
||||||
|
entryPoint.state = STATE_DONE;
|
||||||
|
})
|
||||||
|
);
|
||||||
@ -1,121 +0,0 @@
|
|||||||
/**
|
|
||||||
* Adapted from original ng-packagr
|
|
||||||
*
|
|
||||||
* Exclude the UMD bundling and minification
|
|
||||||
* which is not needed for incremental compilation
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { InjectionToken } from 'injection-js';
|
|
||||||
import {
|
|
||||||
Transform,
|
|
||||||
transformFromPromise,
|
|
||||||
} from 'ng-packagr/lib/graph/transform';
|
|
||||||
import {
|
|
||||||
provideTransform,
|
|
||||||
TransformProvider,
|
|
||||||
} from 'ng-packagr/lib/graph/transform.di';
|
|
||||||
import {
|
|
||||||
EntryPointNode,
|
|
||||||
isEntryPoint,
|
|
||||||
isEntryPointInProgress,
|
|
||||||
} from 'ng-packagr/lib/ng-package/nodes';
|
|
||||||
import { NgEntryPoint } from 'ng-packagr/lib/ng-package/entry-point/entry-point';
|
|
||||||
import { rollupBundleFile } from 'ng-packagr/lib/flatten/rollup';
|
|
||||||
import * as log from 'ng-packagr/lib/utils/log';
|
|
||||||
import { DependencyList } from 'ng-packagr/lib/flatten/external-module-id-strategy';
|
|
||||||
import { BuildGraph } from 'ng-packagr/lib/graph/build-graph';
|
|
||||||
import { unique } from 'ng-packagr/lib/utils/array';
|
|
||||||
|
|
||||||
export const nxWriteBundlesTransform: Transform = transformFromPromise(
|
|
||||||
async (graph) => {
|
|
||||||
const entryPoint = graph.find(isEntryPointInProgress()) as EntryPointNode;
|
|
||||||
const {
|
|
||||||
destinationFiles,
|
|
||||||
entryPoint: ngEntryPoint,
|
|
||||||
tsConfig,
|
|
||||||
} = entryPoint.data;
|
|
||||||
const cache = entryPoint.cache;
|
|
||||||
|
|
||||||
// Add UMD module IDs for dependencies
|
|
||||||
const dependencyUmdIds = entryPoint
|
|
||||||
.filter(isEntryPoint)
|
|
||||||
.map((ep) => ep.data.entryPoint)
|
|
||||||
.reduce((prev, ep: NgEntryPoint) => {
|
|
||||||
prev[ep.moduleId] = ep.umdId;
|
|
||||||
|
|
||||||
return prev;
|
|
||||||
}, {});
|
|
||||||
|
|
||||||
const { fesm2015, esm2015 } = destinationFiles;
|
|
||||||
|
|
||||||
const opts = {
|
|
||||||
sourceRoot: tsConfig.options.sourceRoot,
|
|
||||||
amd: { id: ngEntryPoint.amdId },
|
|
||||||
umdModuleIds: {
|
|
||||||
...ngEntryPoint.umdModuleIds,
|
|
||||||
...dependencyUmdIds,
|
|
||||||
},
|
|
||||||
entry: esm2015,
|
|
||||||
dependencyList: getDependencyListForGraph(graph),
|
|
||||||
};
|
|
||||||
|
|
||||||
log.info('Bundling to FESM2015');
|
|
||||||
// @ts-ignore
|
|
||||||
cache.rollupFESMCache = await rollupBundleFile({
|
|
||||||
...opts,
|
|
||||||
moduleName: ngEntryPoint.moduleId,
|
|
||||||
format: 'es',
|
|
||||||
dest: fesm2015,
|
|
||||||
// @ts-ignore
|
|
||||||
cache: cache.rollupFESMCache,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
/** Get all list of dependencies for the entire 'BuildGraph' */
|
|
||||||
function getDependencyListForGraph(graph: BuildGraph): DependencyList {
|
|
||||||
// We need to do this because if A dependency on bundled B
|
|
||||||
// And A has a secondary entry point A/1 we want only to bundle B if it's used.
|
|
||||||
// Also if A/1 depends on A we don't want to bundle A thus we mark this a dependency.
|
|
||||||
|
|
||||||
const dependencyList: DependencyList = {
|
|
||||||
dependencies: [],
|
|
||||||
bundledDependencies: [],
|
|
||||||
};
|
|
||||||
|
|
||||||
for (const entry of graph.filter(isEntryPoint)) {
|
|
||||||
const {
|
|
||||||
bundledDependencies = [],
|
|
||||||
dependencies = {},
|
|
||||||
peerDependencies = {},
|
|
||||||
} = entry.data.entryPoint.packageJson;
|
|
||||||
dependencyList.bundledDependencies = unique(
|
|
||||||
dependencyList.bundledDependencies.concat(bundledDependencies)
|
|
||||||
);
|
|
||||||
dependencyList.dependencies = unique(
|
|
||||||
dependencyList.dependencies.concat(
|
|
||||||
Object.keys(dependencies),
|
|
||||||
Object.keys(peerDependencies),
|
|
||||||
entry.data.entryPoint.moduleId
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dependencyList.bundledDependencies.length) {
|
|
||||||
log.warn(
|
|
||||||
`Inlining of 'bundledDependencies' has been deprecated in version 5 and will be removed in future versions.` +
|
|
||||||
'\n' +
|
|
||||||
`List the dependency in the 'peerDependencies' section instead.`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return dependencyList;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const NX_WRITE_BUNDLES_TRANSFORM_TOKEN = new InjectionToken<Transform>(
|
|
||||||
`nx.v1.writeBundlesTransform`
|
|
||||||
);
|
|
||||||
export const NX_WRITE_BUNDLES_TRANSFORM: TransformProvider = provideTransform({
|
|
||||||
provide: NX_WRITE_BUNDLES_TRANSFORM_TOKEN,
|
|
||||||
useFactory: () => nxWriteBundlesTransform,
|
|
||||||
});
|
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
import { InjectionToken } from 'injection-js';
|
||||||
|
import { Transform } from 'ng-packagr/lib/graph/transform';
|
||||||
|
import {
|
||||||
|
provideTransform,
|
||||||
|
TransformProvider,
|
||||||
|
} from 'ng-packagr/lib/graph/transform.di';
|
||||||
|
import { nxWritePackageTransform } from './write-package';
|
||||||
|
|
||||||
|
export const NX_WRITE_PACKAGE_TRANSFORM_TOKEN = new InjectionToken<Transform>(
|
||||||
|
`nx.v1.writePackageTransform`
|
||||||
|
);
|
||||||
|
export const NX_WRITE_PACKAGE_TRANSFORM: TransformProvider = provideTransform({
|
||||||
|
provide: NX_WRITE_PACKAGE_TRANSFORM_TOKEN,
|
||||||
|
useFactory: () => nxWritePackageTransform,
|
||||||
|
});
|
||||||
@ -0,0 +1,276 @@
|
|||||||
|
/**
|
||||||
|
* Adapted from original ng-packagr
|
||||||
|
*
|
||||||
|
* Change the package.json metadata to only use
|
||||||
|
* the ESM2015 output as it's the only one generated.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { logger } from '@nrwl/devkit';
|
||||||
|
import { Node } from 'ng-packagr/lib/graph/node';
|
||||||
|
import {
|
||||||
|
Transform,
|
||||||
|
transformFromPromise,
|
||||||
|
} from 'ng-packagr/lib/graph/transform';
|
||||||
|
import { NgEntryPoint } from 'ng-packagr/lib/ng-package/entry-point/entry-point';
|
||||||
|
import {
|
||||||
|
EntryPointNode,
|
||||||
|
fileUrl,
|
||||||
|
isEntryPointInProgress,
|
||||||
|
isPackage,
|
||||||
|
PackageNode,
|
||||||
|
} from 'ng-packagr/lib/ng-package/nodes';
|
||||||
|
import { NgPackage } from 'ng-packagr/lib/ng-package/package';
|
||||||
|
import {
|
||||||
|
copyFile,
|
||||||
|
exists,
|
||||||
|
rimraf,
|
||||||
|
stat,
|
||||||
|
writeFile,
|
||||||
|
} from 'ng-packagr/lib/utils/fs';
|
||||||
|
import { globFiles } from 'ng-packagr/lib/utils/glob';
|
||||||
|
import { ensureUnixPath } from 'ng-packagr/lib/utils/path';
|
||||||
|
import * as path from 'path';
|
||||||
|
|
||||||
|
export const nxWritePackageTransform: Transform = transformFromPromise(
|
||||||
|
async (graph) => {
|
||||||
|
const entryPoint: EntryPointNode = graph.find(isEntryPointInProgress());
|
||||||
|
const ngEntryPoint: NgEntryPoint = entryPoint.data.entryPoint;
|
||||||
|
const ngPackageNode: PackageNode = graph.find(isPackage);
|
||||||
|
const ngPackage = ngPackageNode.data;
|
||||||
|
const { destinationFiles } = entryPoint.data;
|
||||||
|
const ignorePaths: string[] = [
|
||||||
|
'.gitkeep',
|
||||||
|
'**/.DS_Store',
|
||||||
|
'**/Thumbs.db',
|
||||||
|
'**/node_modules/**',
|
||||||
|
`${ngPackage.dest}/**`,
|
||||||
|
];
|
||||||
|
|
||||||
|
if (ngPackage.assets.length && !ngEntryPoint.isSecondaryEntryPoint) {
|
||||||
|
const assetFiles: string[] = [];
|
||||||
|
|
||||||
|
// COPY ASSET FILES TO DESTINATION
|
||||||
|
logger.log('Copying assets');
|
||||||
|
|
||||||
|
try {
|
||||||
|
for (let asset of ngPackage.assets) {
|
||||||
|
asset = path.join(ngPackage.src, asset);
|
||||||
|
|
||||||
|
if (await exists(asset)) {
|
||||||
|
const stats = await stat(asset);
|
||||||
|
if (stats.isFile()) {
|
||||||
|
assetFiles.push(asset);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stats.isDirectory()) {
|
||||||
|
asset = path.join(asset, '**/*');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const files = await globFiles(asset, {
|
||||||
|
ignore: ignorePaths,
|
||||||
|
cache: ngPackageNode.cache.globCache,
|
||||||
|
dot: true,
|
||||||
|
nodir: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (files.length) {
|
||||||
|
assetFiles.push(...files);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const file of assetFiles) {
|
||||||
|
const relativePath = path.relative(ngPackage.src, file);
|
||||||
|
const destination = path.resolve(ngPackage.dest, relativePath);
|
||||||
|
const nodeUri = fileUrl(ensureUnixPath(file));
|
||||||
|
let node = graph.get(nodeUri);
|
||||||
|
if (!node) {
|
||||||
|
node = new Node(nodeUri);
|
||||||
|
graph.put(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
entryPoint.dependsOn(node);
|
||||||
|
await copyFile(file, destination);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. WRITE PACKAGE.JSON
|
||||||
|
try {
|
||||||
|
logger.info('Writing package metadata');
|
||||||
|
const relativeUnixFromDestPath = (filePath: string) =>
|
||||||
|
ensureUnixPath(path.relative(ngEntryPoint.destinationPath, filePath));
|
||||||
|
|
||||||
|
const isIvy = !!entryPoint.data.tsConfig.options.enableIvy;
|
||||||
|
|
||||||
|
await writePackageJson(
|
||||||
|
ngEntryPoint,
|
||||||
|
ngPackage,
|
||||||
|
{
|
||||||
|
module: relativeUnixFromDestPath(destinationFiles.esm2015),
|
||||||
|
esm2015: relativeUnixFromDestPath(destinationFiles.esm2015),
|
||||||
|
typings: relativeUnixFromDestPath(destinationFiles.declarations),
|
||||||
|
// Ivy doesn't generate metadata files
|
||||||
|
metadata: isIvy
|
||||||
|
? undefined
|
||||||
|
: relativeUnixFromDestPath(destinationFiles.metadata),
|
||||||
|
// webpack v4+ specific flag to enable advanced optimizations and code splitting
|
||||||
|
sideEffects: ngEntryPoint.sideEffects,
|
||||||
|
},
|
||||||
|
isIvy
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
logger.info(`Built ${ngEntryPoint.moduleId}`);
|
||||||
|
|
||||||
|
return graph;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and writes a `package.json` file of the entry point used by the `node_module`
|
||||||
|
* resolution strategies.
|
||||||
|
*
|
||||||
|
* #### Example
|
||||||
|
*
|
||||||
|
* A consumer of the entry point depends on it by `import {..} from '@my/module/id';`.
|
||||||
|
* The module id `@my/module/id` will be resolved to the `package.json` file that is written by
|
||||||
|
* this build step.
|
||||||
|
* The properties `main`, `module`, `typings` (and so on) in the `package.json` point to the
|
||||||
|
* flattened JavaScript bundles, type definitions, (...).
|
||||||
|
*
|
||||||
|
* @param entryPoint An entry point of an Angular package / library
|
||||||
|
* @param additionalProperties Additional properties, e.g. binary artefacts (bundle files), to merge into `package.json`
|
||||||
|
*/
|
||||||
|
async function writePackageJson(
|
||||||
|
entryPoint: NgEntryPoint,
|
||||||
|
pkg: NgPackage,
|
||||||
|
additionalProperties: { [key: string]: string | boolean | string[] },
|
||||||
|
isIvy: boolean
|
||||||
|
): Promise<void> {
|
||||||
|
// set additional properties
|
||||||
|
const packageJson = { ...entryPoint.packageJson, ...additionalProperties };
|
||||||
|
|
||||||
|
// read tslib version from `@angular/compiler` so that our tslib
|
||||||
|
// version at least matches that of angular if we use require('tslib').version
|
||||||
|
// it will get what installed and not the minimum version nor if it is a `~` or `^`
|
||||||
|
// this is only required for primary
|
||||||
|
if (!entryPoint.isSecondaryEntryPoint) {
|
||||||
|
if (
|
||||||
|
!packageJson.peerDependencies?.tslib &&
|
||||||
|
!packageJson.dependencies?.tslib
|
||||||
|
) {
|
||||||
|
const {
|
||||||
|
peerDependencies: angularPeerDependencies = {},
|
||||||
|
dependencies: angularDependencies = {},
|
||||||
|
} = require('@angular/compiler/package.json');
|
||||||
|
const tsLibVersion =
|
||||||
|
angularPeerDependencies.tslib || angularDependencies.tslib;
|
||||||
|
|
||||||
|
if (tsLibVersion) {
|
||||||
|
packageJson.dependencies = {
|
||||||
|
...packageJson.dependencies,
|
||||||
|
tslib: tsLibVersion,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} else if (packageJson.peerDependencies?.tslib) {
|
||||||
|
logger.warn(
|
||||||
|
`'tslib' is no longer recommended to be used as a 'peerDependencies'. Moving it to 'dependencies'.`
|
||||||
|
);
|
||||||
|
packageJson.dependencies = {
|
||||||
|
...(packageJson.dependencies || {}),
|
||||||
|
tslib: packageJson.peerDependencies.tslib,
|
||||||
|
};
|
||||||
|
|
||||||
|
delete packageJson.peerDependencies.tslib;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify non-peerDependencies as they can easily lead to duplicate installs or version conflicts
|
||||||
|
// in the node_modules folder of an application
|
||||||
|
const allowedList = pkg.allowedNonPeerDependencies.map(
|
||||||
|
(value) => new RegExp(value)
|
||||||
|
);
|
||||||
|
try {
|
||||||
|
checkNonPeerDependencies(packageJson, 'dependencies', allowedList);
|
||||||
|
} catch (e) {
|
||||||
|
await rimraf(entryPoint.destinationPath);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Removes scripts from package.json after build
|
||||||
|
if (packageJson.scripts) {
|
||||||
|
if (pkg.keepLifecycleScripts !== true) {
|
||||||
|
logger.info(
|
||||||
|
`Removing scripts section in package.json as it's considered a potential security vulnerability.`
|
||||||
|
);
|
||||||
|
delete packageJson.scripts;
|
||||||
|
} else {
|
||||||
|
logger.warn(
|
||||||
|
`You enabled keepLifecycleScripts explicitly. The scripts section in package.json will be published to npm.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isIvy && !entryPoint.isSecondaryEntryPoint) {
|
||||||
|
const scripts = packageJson.scripts || (packageJson.scripts = {});
|
||||||
|
scripts.prepublishOnly =
|
||||||
|
'node --eval "console.error(\'' +
|
||||||
|
'ERROR: Trying to publish a package that has been compiled by Ivy. This is not allowed.\\n' +
|
||||||
|
'Please delete and rebuild the package, without compiling with Ivy, before attempting to publish.\\n' +
|
||||||
|
'\')" ' +
|
||||||
|
'&& exit 1';
|
||||||
|
}
|
||||||
|
|
||||||
|
// keep the dist package.json clean
|
||||||
|
// this will not throw if ngPackage field does not exist
|
||||||
|
delete packageJson.ngPackage;
|
||||||
|
|
||||||
|
const packageJsonPropertiesToDelete = [
|
||||||
|
'stylelint',
|
||||||
|
'prettier',
|
||||||
|
'browserslist',
|
||||||
|
'devDependencies',
|
||||||
|
'jest',
|
||||||
|
'workspaces',
|
||||||
|
'husky',
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const prop of packageJsonPropertiesToDelete) {
|
||||||
|
if (prop in packageJson) {
|
||||||
|
delete packageJson[prop];
|
||||||
|
logger.info(`Removing ${prop} section in package.json.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
packageJson.name = entryPoint.moduleId;
|
||||||
|
await writeFile(
|
||||||
|
path.join(entryPoint.destinationPath, 'package.json'),
|
||||||
|
JSON.stringify(packageJson, undefined, 2)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkNonPeerDependencies(
|
||||||
|
packageJson: Record<string, unknown>,
|
||||||
|
property: string,
|
||||||
|
allowed: RegExp[]
|
||||||
|
) {
|
||||||
|
if (!packageJson[property]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const dep of Object.keys(packageJson[property])) {
|
||||||
|
if (!allowed.some((regex) => regex.test(dep))) {
|
||||||
|
logger.warn(
|
||||||
|
`Distributing npm packages with '${property}' is not recommended. Please consider adding ${dep} to 'peerDependencies' or remove it from '${property}'.`
|
||||||
|
);
|
||||||
|
throw new Error(
|
||||||
|
`Dependency ${dep} must be explicitly allowed using the "allowedNonPeerDependencies" option.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -7,6 +7,7 @@ const IGNORE_MATCHES = {
|
|||||||
'@angular-devkit/architect',
|
'@angular-devkit/architect',
|
||||||
'@angular-devkit/build-angular',
|
'@angular-devkit/build-angular',
|
||||||
'@angular-devkit/core',
|
'@angular-devkit/core',
|
||||||
|
'@angular/compiler',
|
||||||
'@angular/compiler-cli',
|
'@angular/compiler-cli',
|
||||||
'@angular/core',
|
'@angular/core',
|
||||||
'@angular/router',
|
'@angular/router',
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user