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.
|
||||
*/
|
||||
|
||||
import { InjectionToken } from 'injection-js';
|
||||
import {
|
||||
Transform,
|
||||
transformFromPromise,
|
||||
@ -13,7 +14,6 @@ import {
|
||||
provideTransform,
|
||||
TransformProvider,
|
||||
} from 'ng-packagr/lib/graph/transform.di';
|
||||
import { COMPILE_NGC_TOKEN } from 'ng-packagr/lib/ng-package/entry-point/compile-ngc.di';
|
||||
import {
|
||||
EntryPointNode,
|
||||
isEntryPoint,
|
||||
@ -26,7 +26,7 @@ import { setDependenciesTsConfigPaths } from 'ng-packagr/lib/ts/tsconfig';
|
||||
import * as path from 'path';
|
||||
import * as ts from 'typescript';
|
||||
|
||||
export const compileNgcTransformFactory = (
|
||||
export const nxCompileNgcTransformFactory = (
|
||||
StylesheetProcessor: typeof StylesheetProcessorClass
|
||||
): Transform => {
|
||||
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({
|
||||
provide: COMPILE_NGC_TOKEN,
|
||||
useFactory: compileNgcTransformFactory,
|
||||
provide: NX_COMPILE_NGC_TOKEN,
|
||||
useFactory: nxCompileNgcTransformFactory,
|
||||
deps: [STYLESHEET_PROCESSOR_TOKEN],
|
||||
});
|
||||
|
||||
@ -4,23 +4,18 @@
|
||||
* 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 { Transform } from 'ng-packagr/lib/graph/transform';
|
||||
import {
|
||||
provideTransform,
|
||||
TransformProvider,
|
||||
} from 'ng-packagr/lib/graph/transform.di';
|
||||
import { entryPointTransformFactory } from 'ng-packagr/lib/ng-package/entry-point/entry-point.transform';
|
||||
import { NX_COMPILE_NGC_TRANSFORM } from './compile-ngc';
|
||||
import { NX_COMPILE_NGC_TOKEN, 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>(
|
||||
`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({
|
||||
provide: NX_ENTRY_POINT_TRANSFORM_TOKEN,
|
||||
useFactory: entryPointTransformFactory,
|
||||
deps: [
|
||||
COMPILE_NGC_TOKEN,
|
||||
NX_WRITE_BUNDLES_TRANSFORM_TOKEN,
|
||||
WRITE_PACKAGE_TRANSFORM_TOKEN,
|
||||
],
|
||||
useFactory: nxEntryPointTransformFactory,
|
||||
deps: [NX_COMPILE_NGC_TOKEN, NX_WRITE_PACKAGE_TRANSFORM_TOKEN],
|
||||
});
|
||||
|
||||
export const NX_ENTRY_POINT_PROVIDERS: Provider[] = [
|
||||
NX_ENTRY_POINT_TRANSFORM,
|
||||
NX_COMPILE_NGC_TRANSFORM,
|
||||
NX_WRITE_BUNDLES_TRANSFORM,
|
||||
WRITE_PACKAGE_TRANSFORM,
|
||||
NX_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/build-angular',
|
||||
'@angular-devkit/core',
|
||||
'@angular/compiler',
|
||||
'@angular/compiler-cli',
|
||||
'@angular/core',
|
||||
'@angular/router',
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user