feat(ivy): customize ngcc via configuration files (#30591)
There are scenarios where it is not possible for ngcc to guess the format or configuration of an entry-point just from the files on disk. Such scenarios include: 1) Unwanted entry-points: A spurious package.json makes ngcc think there is an entry-point when there should not be one. 2) Deep-import entry-points: some packages allow deep-imports but do not provide package.json files to indicate to ngcc that the imported path is actually an entry-point to be processed. 3) Invalid/missing package.json properties: For example, an entry-point that does not provide a valid property to a required format. The configuration is provided by one or more `ngcc.config.js` files: * If placed at the root of the project, this file can provide configuration for named packages (and their entry-points) that have been npm installed into the project. * If published as part of a package, the file can provide configuration for entry-points of the package. The configured of a package at the project level will override any configuration provided by the package itself. PR Close #30591
This commit is contained in:
parent
4004d15ba5
commit
7c4c676413
|
@ -5,7 +5,7 @@
|
|||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
import {AbsoluteFsPath, FileSystem, absoluteFrom, getFileSystem, resolve} from '../../src/ngtsc/file_system';
|
||||
import {AbsoluteFsPath, FileSystem, absoluteFrom, dirname, getFileSystem, resolve} from '../../src/ngtsc/file_system';
|
||||
import {CommonJsDependencyHost} from './dependencies/commonjs_dependency_host';
|
||||
import {DependencyResolver} from './dependencies/dependency_resolver';
|
||||
import {EsmDependencyHost} from './dependencies/esm_dependency_host';
|
||||
|
@ -14,6 +14,7 @@ import {UmdDependencyHost} from './dependencies/umd_dependency_host';
|
|||
import {ConsoleLogger, LogLevel} from './logging/console_logger';
|
||||
import {Logger} from './logging/logger';
|
||||
import {hasBeenProcessed, markAsProcessed} from './packages/build_marker';
|
||||
import {NgccConfiguration} from './packages/configuration';
|
||||
import {EntryPointFormat, EntryPointJsonProperty, SUPPORTED_FORMAT_PROPERTIES, getEntryPointFormat} from './packages/entry_point';
|
||||
import {makeEntryPointBundle} from './packages/entry_point_bundle';
|
||||
import {EntryPointFinder} from './packages/entry_point_finder';
|
||||
|
@ -92,7 +93,8 @@ export function mainNgcc(
|
|||
umd: umdDependencyHost,
|
||||
commonjs: commonJsDependencyHost
|
||||
});
|
||||
const finder = new EntryPointFinder(fileSystem, logger, resolver);
|
||||
const config = new NgccConfiguration(fileSystem, dirname(absoluteFrom(basePath)));
|
||||
const finder = new EntryPointFinder(fileSystem, config, logger, resolver);
|
||||
const fileWriter = getFileWriter(fileSystem, createNewEntryPointFormats);
|
||||
|
||||
const absoluteTargetEntryPointPath =
|
||||
|
@ -192,6 +194,10 @@ function hasProcessedTargetEntryPoint(
|
|||
fs: FileSystem, targetPath: AbsoluteFsPath, propertiesToConsider: string[],
|
||||
compileAllFormats: boolean) {
|
||||
const packageJsonPath = resolve(targetPath, 'package.json');
|
||||
// It might be that this target is configured in which case its package.json might not exist.
|
||||
if (!fs.exists(packageJsonPath)) {
|
||||
return false;
|
||||
}
|
||||
const packageJson = JSON.parse(fs.readFile(packageJsonPath));
|
||||
|
||||
for (const property of propertiesToConsider) {
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
import {AbsoluteFsPath, FileSystem} from '../../../src/ngtsc/file_system';
|
||||
import {AbsoluteFsPath, FileSystem, dirname} from '../../../src/ngtsc/file_system';
|
||||
import {EntryPointJsonProperty, EntryPointPackageJson} from './entry_point';
|
||||
|
||||
export const NGCC_VERSION = '0.0.0-PLACEHOLDER';
|
||||
|
@ -49,5 +49,8 @@ export function markAsProcessed(
|
|||
format: EntryPointJsonProperty) {
|
||||
if (!packageJson.__processed_by_ivy_ngcc__) packageJson.__processed_by_ivy_ngcc__ = {};
|
||||
packageJson.__processed_by_ivy_ngcc__[format] = NGCC_VERSION;
|
||||
// Just in case this package.json was synthesized due to a custom configuration
|
||||
// we will ensure that the path to the containing folder exists before we write the file.
|
||||
fs.ensureDir(dirname(packageJsonPath));
|
||||
fs.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
||||
}
|
||||
|
|
|
@ -0,0 +1,124 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
import * as vm from 'vm';
|
||||
import {AbsoluteFsPath, FileSystem, dirname, join, resolve} from '../../../src/ngtsc/file_system';
|
||||
import {PackageJsonFormatProperties} from './entry_point';
|
||||
|
||||
/**
|
||||
* The format of a project level configuration file.
|
||||
*/
|
||||
export interface NgccProjectConfig { packages: {[packagePath: string]: NgccPackageConfig}; }
|
||||
|
||||
/**
|
||||
* The format of a package level configuration file.
|
||||
*/
|
||||
export interface NgccPackageConfig {
|
||||
/**
|
||||
* The entry-points to configure for this package.
|
||||
*
|
||||
* In the config file the keys can be paths relative to the package path;
|
||||
* but when being read back from the `NgccConfiguration` service, these paths
|
||||
* will be absolute.
|
||||
*/
|
||||
entryPoints: {[entryPointPath: string]: NgccEntryPointConfig;};
|
||||
}
|
||||
|
||||
/**
|
||||
* Configuration options for an entry-point.
|
||||
*
|
||||
* The existence of a configuration for a path tells ngcc that this should be considered for
|
||||
* processing as an entry-point.
|
||||
*/
|
||||
export interface NgccEntryPointConfig {
|
||||
/** Do not process (or even acknowledge the existence of) this entry-point, if true. */
|
||||
ignore?: boolean;
|
||||
/**
|
||||
* This property, if provided, holds values that will override equivalent properties in an
|
||||
* entry-point's package.json file.
|
||||
*/
|
||||
override?: PackageJsonFormatProperties;
|
||||
}
|
||||
|
||||
const NGCC_CONFIG_FILENAME = 'ngcc.config.js';
|
||||
|
||||
export class NgccConfiguration {
|
||||
// TODO: change string => ModuleSpecifier when we tighten the path types in #30556
|
||||
private cache = new Map<string, NgccPackageConfig>();
|
||||
|
||||
constructor(private fs: FileSystem, baseDir: AbsoluteFsPath) {
|
||||
const projectConfig = this.loadProjectConfig(baseDir);
|
||||
for (const packagePath in projectConfig.packages) {
|
||||
const absPackagePath = resolve(baseDir, 'node_modules', packagePath);
|
||||
const packageConfig = projectConfig.packages[packagePath];
|
||||
packageConfig.entryPoints =
|
||||
this.processEntryPoints(absPackagePath, packageConfig.entryPoints);
|
||||
this.cache.set(absPackagePath, packageConfig);
|
||||
}
|
||||
}
|
||||
|
||||
getConfig(packagePath: AbsoluteFsPath): NgccPackageConfig {
|
||||
if (this.cache.has(packagePath)) {
|
||||
return this.cache.get(packagePath) !;
|
||||
}
|
||||
|
||||
const packageConfig = this.loadPackageConfig(packagePath);
|
||||
packageConfig.entryPoints = this.processEntryPoints(packagePath, packageConfig.entryPoints);
|
||||
this.cache.set(packagePath, packageConfig);
|
||||
return packageConfig;
|
||||
}
|
||||
|
||||
private loadProjectConfig(baseDir: AbsoluteFsPath): NgccProjectConfig {
|
||||
const configFilePath = join(baseDir, NGCC_CONFIG_FILENAME);
|
||||
if (this.fs.exists(configFilePath)) {
|
||||
try {
|
||||
return this.evalSrcFile(configFilePath);
|
||||
} catch (e) {
|
||||
throw new Error(`Invalid project configuration file at "${configFilePath}": ` + e.message);
|
||||
}
|
||||
} else {
|
||||
return {packages: {}};
|
||||
}
|
||||
}
|
||||
|
||||
private loadPackageConfig(packagePath: AbsoluteFsPath): NgccPackageConfig {
|
||||
const configFilePath = join(packagePath, NGCC_CONFIG_FILENAME);
|
||||
if (this.fs.exists(configFilePath)) {
|
||||
try {
|
||||
return this.evalSrcFile(configFilePath);
|
||||
} catch (e) {
|
||||
throw new Error(`Invalid package configuration file at "${configFilePath}": ` + e.message);
|
||||
}
|
||||
} else {
|
||||
return {entryPoints: {}};
|
||||
}
|
||||
}
|
||||
|
||||
private evalSrcFile(srcPath: AbsoluteFsPath): any {
|
||||
const src = this.fs.readFile(srcPath);
|
||||
const theExports = {};
|
||||
const sandbox = {
|
||||
module: {exports: theExports},
|
||||
exports: theExports, require,
|
||||
__dirname: dirname(srcPath),
|
||||
__filename: srcPath
|
||||
};
|
||||
vm.runInNewContext(src, sandbox, {filename: srcPath});
|
||||
return sandbox.module.exports;
|
||||
}
|
||||
|
||||
private processEntryPoints(
|
||||
packagePath: AbsoluteFsPath, entryPoints: {[entryPointPath: string]: NgccEntryPointConfig;}):
|
||||
{[entryPointPath: string]: NgccEntryPointConfig;} {
|
||||
const processedEntryPoints: {[entryPointPath: string]: NgccEntryPointConfig;} = {};
|
||||
for (const entryPointPath in entryPoints) {
|
||||
// Change the keys to be absolute paths
|
||||
processedEntryPoints[resolve(packagePath, entryPointPath)] = entryPoints[entryPointPath];
|
||||
}
|
||||
return processedEntryPoints;
|
||||
}
|
||||
}
|
|
@ -5,10 +5,13 @@
|
|||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
import {relative} from 'canonical-path';
|
||||
import {basename} from 'path';
|
||||
import * as ts from 'typescript';
|
||||
import {AbsoluteFsPath, FileSystem, join, resolve} from '../../../src/ngtsc/file_system';
|
||||
import {parseStatementForUmdModule} from '../host/umd_host';
|
||||
import {Logger} from '../logging/logger';
|
||||
import {NgccConfiguration, NgccEntryPointConfig} from './configuration';
|
||||
|
||||
/**
|
||||
* The possible values for the format of an entry-point.
|
||||
|
@ -34,7 +37,7 @@ export interface EntryPoint {
|
|||
compiledByAngular: boolean;
|
||||
}
|
||||
|
||||
interface PackageJsonFormatProperties {
|
||||
export interface PackageJsonFormatProperties {
|
||||
fesm2015?: string;
|
||||
fesm5?: string;
|
||||
es2015?: string; // if exists then it is actually FESM2015
|
||||
|
@ -67,18 +70,25 @@ export const SUPPORTED_FORMAT_PROPERTIES: EntryPointJsonProperty[] =
|
|||
* @returns An entry-point if it is valid, `null` otherwise.
|
||||
*/
|
||||
export function getEntryPointInfo(
|
||||
fs: FileSystem, logger: Logger, packagePath: AbsoluteFsPath,
|
||||
fs: FileSystem, config: NgccConfiguration, logger: Logger, packagePath: AbsoluteFsPath,
|
||||
entryPointPath: AbsoluteFsPath): EntryPoint|null {
|
||||
const packageJsonPath = resolve(entryPointPath, 'package.json');
|
||||
if (!fs.exists(packageJsonPath)) {
|
||||
const entryPointConfig = config.getConfig(packagePath).entryPoints[entryPointPath];
|
||||
if (entryPointConfig === undefined && !fs.exists(packageJsonPath)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const entryPointPackageJson = loadEntryPointPackage(fs, logger, packageJsonPath);
|
||||
if (!entryPointPackageJson) {
|
||||
if (entryPointConfig !== undefined && entryPointConfig.ignore === true) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const loadedEntryPointPackageJson =
|
||||
loadEntryPointPackage(fs, logger, packageJsonPath, entryPointConfig !== undefined);
|
||||
const entryPointPackageJson = mergeConfigAndPackageJson(
|
||||
loadedEntryPointPackageJson, entryPointConfig, packagePath, entryPointPath);
|
||||
if (entryPointPackageJson === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// We must have a typings property
|
||||
const typings = entryPointPackageJson.typings || entryPointPackageJson.types;
|
||||
|
@ -86,16 +96,18 @@ export function getEntryPointInfo(
|
|||
return null;
|
||||
}
|
||||
|
||||
// Also there must exist a `metadata.json` file next to the typings entry-point.
|
||||
// An entry-point is assumed to be compiled by Angular if there is either:
|
||||
// * a `metadata.json` file next to the typings entry-point
|
||||
// * a custom config for this entry-point
|
||||
const metadataPath = resolve(entryPointPath, typings.replace(/\.d\.ts$/, '') + '.metadata.json');
|
||||
const compiledByAngular = entryPointConfig !== undefined || fs.exists(metadataPath);
|
||||
|
||||
const entryPointInfo: EntryPoint = {
|
||||
name: entryPointPackageJson.name,
|
||||
packageJson: entryPointPackageJson,
|
||||
package: packagePath,
|
||||
path: entryPointPath,
|
||||
typings: resolve(entryPointPath, typings),
|
||||
compiledByAngular: fs.exists(metadataPath),
|
||||
typings: resolve(entryPointPath, typings), compiledByAngular,
|
||||
};
|
||||
|
||||
return entryPointInfo;
|
||||
|
@ -140,12 +152,15 @@ export function getEntryPointFormat(
|
|||
* @returns JSON from the package.json file if it is valid, `null` otherwise.
|
||||
*/
|
||||
function loadEntryPointPackage(
|
||||
fs: FileSystem, logger: Logger, packageJsonPath: AbsoluteFsPath): EntryPointPackageJson|null {
|
||||
fs: FileSystem, logger: Logger, packageJsonPath: AbsoluteFsPath,
|
||||
hasConfig: boolean): EntryPointPackageJson|null {
|
||||
try {
|
||||
return JSON.parse(fs.readFile(packageJsonPath));
|
||||
} catch (e) {
|
||||
// We may have run into a package.json with unexpected symbols
|
||||
logger.warn(`Failed to read entry point info from ${packageJsonPath} with error ${e}.`);
|
||||
if (!hasConfig) {
|
||||
// We may have run into a package.json with unexpected symbols
|
||||
logger.warn(`Failed to read entry point info from ${packageJsonPath} with error ${e}.`);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -156,3 +171,23 @@ function isUmdModule(fs: FileSystem, sourceFilePath: AbsoluteFsPath): boolean {
|
|||
return sourceFile.statements.length > 0 &&
|
||||
parseStatementForUmdModule(sourceFile.statements[0]) !== null;
|
||||
}
|
||||
|
||||
function mergeConfigAndPackageJson(
|
||||
entryPointPackageJson: EntryPointPackageJson | null,
|
||||
entryPointConfig: NgccEntryPointConfig | undefined, packagePath: AbsoluteFsPath,
|
||||
entryPointPath: AbsoluteFsPath): EntryPointPackageJson|null {
|
||||
if (entryPointPackageJson !== null) {
|
||||
if (entryPointConfig === undefined) {
|
||||
return entryPointPackageJson;
|
||||
} else {
|
||||
return {...entryPointPackageJson, ...entryPointConfig.override};
|
||||
}
|
||||
} else {
|
||||
if (entryPointConfig === undefined) {
|
||||
return null;
|
||||
} else {
|
||||
const name = `${basename(packagePath)}/${relative(packagePath, entryPointPath)}`;
|
||||
return {name, ...entryPointConfig.override};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,12 +9,13 @@ import {AbsoluteFsPath, FileSystem, join, resolve} from '../../../src/ngtsc/file
|
|||
import {DependencyResolver, SortedEntryPointsInfo} from '../dependencies/dependency_resolver';
|
||||
import {Logger} from '../logging/logger';
|
||||
import {PathMappings} from '../utils';
|
||||
|
||||
import {NgccConfiguration} from './configuration';
|
||||
import {EntryPoint, getEntryPointInfo} from './entry_point';
|
||||
|
||||
export class EntryPointFinder {
|
||||
constructor(
|
||||
private fs: FileSystem, private logger: Logger, private resolver: DependencyResolver) {}
|
||||
private fs: FileSystem, private config: NgccConfiguration, private logger: Logger,
|
||||
private resolver: DependencyResolver) {}
|
||||
/**
|
||||
* Search the given directory, and sub-directories, for Angular package entry points.
|
||||
* @param sourceDirectory An absolute path to the directory to search for entry points.
|
||||
|
@ -111,7 +112,8 @@ export class EntryPointFinder {
|
|||
const entryPoints: EntryPoint[] = [];
|
||||
|
||||
// Try to get an entry point from the top level package directory
|
||||
const topLevelEntryPoint = getEntryPointInfo(this.fs, this.logger, packagePath, packagePath);
|
||||
const topLevelEntryPoint =
|
||||
getEntryPointInfo(this.fs, this.config, this.logger, packagePath, packagePath);
|
||||
|
||||
// If there is no primary entry-point then exit
|
||||
if (topLevelEntryPoint === null) {
|
||||
|
@ -120,8 +122,11 @@ export class EntryPointFinder {
|
|||
|
||||
// Otherwise store it and search for secondary entry-points
|
||||
entryPoints.push(topLevelEntryPoint);
|
||||
this.walkDirectory(packagePath, subdir => {
|
||||
const subEntryPoint = getEntryPointInfo(this.fs, this.logger, packagePath, subdir);
|
||||
this.walkDirectory(packagePath, packagePath, (path, isDirectory) => {
|
||||
// If the path is a JS file then strip its extension and see if we can match an entry-point.
|
||||
const possibleEntryPointPath = isDirectory ? path : stripJsExtension(path);
|
||||
const subEntryPoint =
|
||||
getEntryPointInfo(this.fs, this.config, this.logger, packagePath, possibleEntryPointPath);
|
||||
if (subEntryPoint !== null) {
|
||||
entryPoints.push(subEntryPoint);
|
||||
}
|
||||
|
@ -136,22 +141,29 @@ export class EntryPointFinder {
|
|||
* @param dir the directory to recursively walk.
|
||||
* @param fn the function to apply to each directory.
|
||||
*/
|
||||
private walkDirectory(dir: AbsoluteFsPath, fn: (dir: AbsoluteFsPath) => void) {
|
||||
private walkDirectory(
|
||||
packagePath: AbsoluteFsPath, dir: AbsoluteFsPath,
|
||||
fn: (path: AbsoluteFsPath, isDirectory: boolean) => void) {
|
||||
return this.fs
|
||||
.readdir(dir)
|
||||
// Not interested in hidden files
|
||||
.filter(p => !p.startsWith('.'))
|
||||
.filter(path => !path.startsWith('.'))
|
||||
// Ignore node_modules
|
||||
.filter(p => p !== 'node_modules')
|
||||
// Only interested in directories (and only those that are not symlinks)
|
||||
.filter(p => {
|
||||
const stat = this.fs.lstat(resolve(dir, p));
|
||||
return stat.isDirectory() && !stat.isSymbolicLink();
|
||||
})
|
||||
.forEach(subDir => {
|
||||
const resolvedSubDir = resolve(dir, subDir);
|
||||
fn(resolvedSubDir);
|
||||
this.walkDirectory(resolvedSubDir, fn);
|
||||
.filter(path => path !== 'node_modules')
|
||||
.map(path => resolve(dir, path))
|
||||
.forEach(path => {
|
||||
const stat = this.fs.lstat(path);
|
||||
|
||||
if (stat.isSymbolicLink()) {
|
||||
// We are not interested in symbolic links
|
||||
return;
|
||||
}
|
||||
|
||||
fn(path, stat.isDirectory());
|
||||
|
||||
if (stat.isDirectory()) {
|
||||
this.walkDirectory(packagePath, path, fn);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -187,3 +199,7 @@ function removeDeeperPaths(value: AbsoluteFsPath, index: number, array: Absolute
|
|||
function values<T>(obj: {[key: string]: T}): T[] {
|
||||
return Object.keys(obj).map(key => obj[key]);
|
||||
}
|
||||
|
||||
function stripJsExtension<T extends string>(filePath: T): T {
|
||||
return filePath.replace(/\.js$/, '') as T;
|
||||
}
|
||||
|
|
|
@ -351,6 +351,92 @@ runInEachFileSystem(() => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('with configuration files', () => {
|
||||
it('should process a configured deep-import as an entry-point', () => {
|
||||
loadTestFiles([
|
||||
{
|
||||
name: _('/ngcc.config.js'),
|
||||
contents: `module.exports = { packages: {
|
||||
'deep_import': {
|
||||
entryPoints: {
|
||||
'./entry_point': { override: { typings: '../entry_point.d.ts', es2015: '../entry_point.js' } }
|
||||
}
|
||||
}
|
||||
}};`,
|
||||
},
|
||||
{
|
||||
name: _('/node_modules/deep_import/package.json'),
|
||||
contents: '{"name": "deep-import", "es2015": "./index.js", "typings": "./index.d.ts"}',
|
||||
},
|
||||
{
|
||||
name: _('/node_modules/deep_import/entry_point.js'),
|
||||
contents: `
|
||||
import {Component} from '@angular/core';
|
||||
@Component({selector: 'entry-point'})
|
||||
export class EntryPoint {}
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: _('/node_modules/deep_import/entry_point.d.ts'),
|
||||
contents: `
|
||||
import {Component} from '@angular/core';
|
||||
@Component({selector: 'entry-point'})
|
||||
export class EntryPoint {}
|
||||
`,
|
||||
},
|
||||
]);
|
||||
mainNgcc({
|
||||
basePath: '/node_modules',
|
||||
targetEntryPointPath: 'deep_import/entry_point',
|
||||
propertiesToConsider: ['es2015']
|
||||
});
|
||||
// The containing package is not processed
|
||||
expect(loadPackage('deep_import').__processed_by_ivy_ngcc__).toBeUndefined();
|
||||
// But the configured entry-point and its dependency (@angular/core) are processed.
|
||||
expect(loadPackage('deep_import/entry_point').__processed_by_ivy_ngcc__).toEqual({
|
||||
es2015: '0.0.0-PLACEHOLDER',
|
||||
typings: '0.0.0-PLACEHOLDER',
|
||||
});
|
||||
expect(loadPackage('@angular/core').__processed_by_ivy_ngcc__).toEqual({
|
||||
es2015: '0.0.0-PLACEHOLDER',
|
||||
typings: '0.0.0-PLACEHOLDER',
|
||||
});
|
||||
});
|
||||
|
||||
it('should not process ignored entry-points', () => {
|
||||
loadTestFiles([
|
||||
{
|
||||
name: _('/ngcc.config.js'),
|
||||
contents: `module.exports = { packages: {
|
||||
'@angular/core': {
|
||||
entryPoints: {
|
||||
'./testing': {ignore: true}
|
||||
},
|
||||
},
|
||||
'@angular/common': {
|
||||
entryPoints: {
|
||||
'.': {ignore: true}
|
||||
},
|
||||
}
|
||||
}};`,
|
||||
},
|
||||
]);
|
||||
mainNgcc({basePath: '/node_modules', propertiesToConsider: ['es2015']});
|
||||
// We process core but not core/testing.
|
||||
expect(loadPackage('@angular/core').__processed_by_ivy_ngcc__).toEqual({
|
||||
es2015: '0.0.0-PLACEHOLDER',
|
||||
typings: '0.0.0-PLACEHOLDER',
|
||||
});
|
||||
expect(loadPackage('@angular/core/testing').__processed_by_ivy_ngcc__).toBeUndefined();
|
||||
// We do not compile common but we do compile its sub-entry-points.
|
||||
expect(loadPackage('@angular/common').__processed_by_ivy_ngcc__).toBeUndefined();
|
||||
expect(loadPackage('@angular/common/http').__processed_by_ivy_ngcc__).toEqual({
|
||||
es2015: '0.0.0-PLACEHOLDER',
|
||||
typings: '0.0.0-PLACEHOLDER',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function loadPackage(
|
||||
packageName: string, basePath: AbsoluteFsPath = _('/node_modules')): EntryPointPackageJson {
|
||||
return JSON.parse(fs.readFile(fs.resolve(basePath, packageName, 'package.json')));
|
||||
|
|
|
@ -0,0 +1,168 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
import {FileSystem, absoluteFrom, getFileSystem} from '../../../src/ngtsc/file_system';
|
||||
import {runInEachFileSystem} from '../../../src/ngtsc/file_system/testing';
|
||||
import {loadTestFiles} from '../../../test/helpers';
|
||||
import {NgccConfiguration} from '../../src/packages/configuration';
|
||||
|
||||
|
||||
runInEachFileSystem(() => {
|
||||
let _Abs: typeof absoluteFrom;
|
||||
let fs: FileSystem;
|
||||
|
||||
beforeEach(() => {
|
||||
_Abs = absoluteFrom;
|
||||
fs = getFileSystem();
|
||||
});
|
||||
|
||||
describe('NgccConfiguration', () => {
|
||||
describe('constructor', () => {
|
||||
it('should error if a project level config file is badly formatted', () => {
|
||||
loadTestFiles([{name: _Abs('/project-1/ngcc.config.js'), contents: `bad js code`}]);
|
||||
expect(() => new NgccConfiguration(fs, _Abs('/project-1')))
|
||||
.toThrowError(
|
||||
`Invalid project configuration file at "${_Abs('/project-1/ngcc.config.js')}": Unexpected identifier`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getConfig()', () => {
|
||||
it('should return configuration for a package found in a package level file', () => {
|
||||
loadTestFiles([{
|
||||
name: _Abs('/project-1/node_modules/package-1/ngcc.config.js'),
|
||||
contents: `module.exports = {entryPoints: { './entry-point-1': {}}}`
|
||||
}]);
|
||||
const readFileSpy = spyOn(fs, 'readFile').and.callThrough();
|
||||
const configuration = new NgccConfiguration(fs, _Abs('/project-1'));
|
||||
const config = configuration.getConfig(_Abs('/project-1/node_modules/package-1'));
|
||||
|
||||
expect(config).toEqual(
|
||||
{entryPoints: {[_Abs('/project-1/node_modules/package-1/entry-point-1')]: {}}});
|
||||
expect(readFileSpy)
|
||||
.toHaveBeenCalledWith(_Abs('/project-1/node_modules/package-1/ngcc.config.js'));
|
||||
});
|
||||
|
||||
it('should cache configuration for a package found in a package level file', () => {
|
||||
loadTestFiles([{
|
||||
name: _Abs('/project-1/node_modules/package-1/ngcc.config.js'),
|
||||
contents: `
|
||||
module.exports = {
|
||||
entryPoints: {
|
||||
'./entry-point-1': {}
|
||||
},
|
||||
};`
|
||||
}]);
|
||||
const configuration = new NgccConfiguration(fs, _Abs('/project-1'));
|
||||
|
||||
// Populate the cache
|
||||
configuration.getConfig(_Abs('/project-1/node_modules/package-1'));
|
||||
|
||||
const readFileSpy = spyOn(fs, 'readFile').and.callThrough();
|
||||
const config = configuration.getConfig(_Abs('/project-1/node_modules/package-1'));
|
||||
|
||||
expect(config).toEqual(
|
||||
{entryPoints: {[_Abs('/project-1/node_modules/package-1/entry-point-1')]: {}}});
|
||||
expect(readFileSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should return an empty configuration object if there is no matching config file', () => {
|
||||
const configuration = new NgccConfiguration(fs, _Abs('/project-1'));
|
||||
const config = configuration.getConfig(_Abs('/project-1/node_modules/package-1'));
|
||||
expect(config).toEqual({entryPoints: {}});
|
||||
});
|
||||
|
||||
it('should error if a package level config file is badly formatted', () => {
|
||||
loadTestFiles([{
|
||||
name: _Abs('/project-1/node_modules/package-1/ngcc.config.js'),
|
||||
contents: `bad js code`
|
||||
}]);
|
||||
const configuration = new NgccConfiguration(fs, _Abs('/project-1'));
|
||||
expect(() => configuration.getConfig(_Abs('/project-1/node_modules/package-1')))
|
||||
.toThrowError(
|
||||
`Invalid package configuration file at "${_Abs('/project-1/node_modules/package-1/ngcc.config.js')}": Unexpected identifier`);
|
||||
});
|
||||
|
||||
it('should return configuration for a package found in a project level file', () => {
|
||||
loadTestFiles([{
|
||||
name: _Abs('/project-1/ngcc.config.js'),
|
||||
contents: `
|
||||
module.exports = {
|
||||
packages: {
|
||||
'package-1': {
|
||||
entryPoints: {
|
||||
'./entry-point-1': {}
|
||||
},
|
||||
},
|
||||
},
|
||||
};`
|
||||
}]);
|
||||
const readFileSpy = spyOn(fs, 'readFile').and.callThrough();
|
||||
const configuration = new NgccConfiguration(fs, _Abs('/project-1'));
|
||||
expect(readFileSpy).toHaveBeenCalledWith(_Abs('/project-1/ngcc.config.js'));
|
||||
|
||||
const config = configuration.getConfig(_Abs('/project-1/node_modules/package-1'));
|
||||
expect(config).toEqual(
|
||||
{entryPoints: {[_Abs('/project-1/node_modules/package-1/entry-point-1')]: {}}});
|
||||
});
|
||||
|
||||
it('should override package level config with project level config per package', () => {
|
||||
loadTestFiles([
|
||||
{
|
||||
name: _Abs('/project-1/ngcc.config.js'),
|
||||
contents: `
|
||||
module.exports = {
|
||||
packages: {
|
||||
'package-2': {
|
||||
entryPoints: {
|
||||
'./project-setting-entry-point': {}
|
||||
},
|
||||
},
|
||||
},
|
||||
};`,
|
||||
},
|
||||
{
|
||||
name: _Abs('/project-1/node_modules/package-1/ngcc.config.js'),
|
||||
contents: `
|
||||
module.exports = {
|
||||
entryPoints: {
|
||||
'./package-setting-entry-point': {}
|
||||
},
|
||||
};`,
|
||||
},
|
||||
{
|
||||
name: _Abs('/project-1/node_modules/package-2/ngcc.config.js'),
|
||||
contents: `
|
||||
module.exports = {
|
||||
entryPoints: {
|
||||
'./package-setting-entry-point': {}
|
||||
},
|
||||
};`,
|
||||
}
|
||||
]);
|
||||
const readFileSpy = spyOn(fs, 'readFile').and.callThrough();
|
||||
const configuration = new NgccConfiguration(fs, _Abs('/project-1'));
|
||||
expect(readFileSpy).toHaveBeenCalledWith(_Abs('/project-1/ngcc.config.js'));
|
||||
|
||||
const package1Config = configuration.getConfig(_Abs('/project-1/node_modules/package-1'));
|
||||
expect(package1Config).toEqual({
|
||||
entryPoints:
|
||||
{[_Abs('/project-1/node_modules/package-1/package-setting-entry-point')]: {}}
|
||||
});
|
||||
expect(readFileSpy)
|
||||
.toHaveBeenCalledWith(_Abs('/project-1/node_modules/package-1/ngcc.config.js'));
|
||||
|
||||
const package2Config = configuration.getConfig(_Abs('/project-1/node_modules/package-2'));
|
||||
expect(package2Config).toEqual({
|
||||
entryPoints:
|
||||
{[_Abs('/project-1/node_modules/package-2/project-setting-entry-point')]: {}}
|
||||
});
|
||||
expect(readFileSpy)
|
||||
.not.toHaveBeenCalledWith(_Abs('/project-1/node_modules/package-2/ngcc.config.js'));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -11,6 +11,7 @@ import {loadTestFiles} from '../../../test/helpers';
|
|||
import {DependencyResolver} from '../../src/dependencies/dependency_resolver';
|
||||
import {EsmDependencyHost} from '../../src/dependencies/esm_dependency_host';
|
||||
import {ModuleResolver} from '../../src/dependencies/module_resolver';
|
||||
import {NgccConfiguration} from '../../src/packages/configuration';
|
||||
import {EntryPoint} from '../../src/packages/entry_point';
|
||||
import {EntryPointFinder} from '../../src/packages/entry_point_finder';
|
||||
import {MockLogger} from '../helpers/mock_logger';
|
||||
|
@ -31,7 +32,8 @@ runInEachFileSystem(() => {
|
|||
spyOn(resolver, 'sortEntryPointsByDependency').and.callFake((entryPoints: EntryPoint[]) => {
|
||||
return {entryPoints, ignoredEntryPoints: [], ignoredDependencies: []};
|
||||
});
|
||||
finder = new EntryPointFinder(fs, new MockLogger(), resolver);
|
||||
finder =
|
||||
new EntryPointFinder(fs, new NgccConfiguration(fs, _('/')), new MockLogger(), resolver);
|
||||
});
|
||||
|
||||
it('should find sub-entry-points within a package', () => {
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
import {AbsoluteFsPath, FileSystem, absoluteFrom, getFileSystem} from '../../../src/ngtsc/file_system';
|
||||
import {runInEachFileSystem} from '../../../src/ngtsc/file_system/testing';
|
||||
import {loadTestFiles} from '../../../test/helpers';
|
||||
import {NgccConfiguration} from '../../src/packages/configuration';
|
||||
import {getEntryPointInfo} from '../../src/packages/entry_point';
|
||||
import {MockLogger} from '../helpers/mock_logger';
|
||||
|
||||
|
@ -19,8 +20,8 @@ runInEachFileSystem(() => {
|
|||
let fs: FileSystem;
|
||||
|
||||
beforeEach(() => {
|
||||
SOME_PACKAGE = absoluteFrom('/some_package');
|
||||
_ = absoluteFrom;
|
||||
SOME_PACKAGE = _('/project/node_modules/some_package');
|
||||
fs = getFileSystem();
|
||||
});
|
||||
|
||||
|
@ -28,51 +29,152 @@ runInEachFileSystem(() => {
|
|||
() => {
|
||||
loadTestFiles([
|
||||
{
|
||||
name: _('/some_package/valid_entry_point/package.json'),
|
||||
name: _('/project/node_modules/some_package/valid_entry_point/package.json'),
|
||||
contents: createPackageJson('valid_entry_point')
|
||||
},
|
||||
{
|
||||
name: _('/some_package/valid_entry_point/valid_entry_point.metadata.json'),
|
||||
name: _(
|
||||
'/project/node_modules/some_package/valid_entry_point/valid_entry_point.metadata.json'),
|
||||
contents: 'some meta data'
|
||||
},
|
||||
]);
|
||||
const config = new NgccConfiguration(fs, _('/project'));
|
||||
const entryPoint = getEntryPointInfo(
|
||||
fs, new MockLogger(), SOME_PACKAGE, _('/some_package/valid_entry_point'));
|
||||
fs, config, new MockLogger(), SOME_PACKAGE,
|
||||
_('/project/node_modules/some_package/valid_entry_point'));
|
||||
expect(entryPoint).toEqual({
|
||||
name: 'some-package/valid_entry_point',
|
||||
name: 'some_package/valid_entry_point',
|
||||
package: SOME_PACKAGE,
|
||||
path: _('/some_package/valid_entry_point'),
|
||||
typings: _(`/some_package/valid_entry_point/valid_entry_point.d.ts`),
|
||||
packageJson: loadPackageJson(fs, '/some_package/valid_entry_point'),
|
||||
path: _('/project/node_modules/some_package/valid_entry_point'),
|
||||
typings:
|
||||
_(`/project/node_modules/some_package/valid_entry_point/valid_entry_point.d.ts`),
|
||||
packageJson: loadPackageJson(fs, '/project/node_modules/some_package/valid_entry_point'),
|
||||
compiledByAngular: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('should return null if configured to ignore the specified entry-point', () => {
|
||||
loadTestFiles([
|
||||
{
|
||||
name: _('/project/node_modules/some_package/valid_entry_point/package.json'),
|
||||
contents: createPackageJson('valid_entry_point'),
|
||||
},
|
||||
{
|
||||
name: _(
|
||||
'/project/node_modules/some_package/valid_entry_point/valid_entry_point.metadata.json'),
|
||||
contents: 'some meta data',
|
||||
},
|
||||
]);
|
||||
const config = new NgccConfiguration(fs, _('/project'));
|
||||
spyOn(config, 'getConfig').and.returnValue({
|
||||
entryPoints:
|
||||
{[_('/project/node_modules/some_package/valid_entry_point')]: {ignore: true}}
|
||||
});
|
||||
const entryPoint = getEntryPointInfo(
|
||||
fs, config, new MockLogger(), SOME_PACKAGE,
|
||||
_('/project/node_modules/some_package/valid_entry_point'));
|
||||
expect(entryPoint).toBe(null);
|
||||
});
|
||||
|
||||
it('should override the properties on package.json if the entry-point is configured', () => {
|
||||
loadTestFiles([
|
||||
{
|
||||
name: _('/project/node_modules/some_package/valid_entry_point/package.json'),
|
||||
contents: createPackageJson('valid_entry_point'),
|
||||
},
|
||||
{
|
||||
name: _(
|
||||
'/project/node_modules/some_package/valid_entry_point/valid_entry_point.metadata.json'),
|
||||
contents: 'some meta data',
|
||||
},
|
||||
]);
|
||||
const config = new NgccConfiguration(fs, _('/project'));
|
||||
const override = {
|
||||
typings: './some_other.d.ts',
|
||||
esm2015: './some_other.js',
|
||||
};
|
||||
spyOn(config, 'getConfig').and.returnValue({
|
||||
entryPoints: {[_('/project/node_modules/some_package/valid_entry_point')]: {override}}
|
||||
});
|
||||
const entryPoint = getEntryPointInfo(
|
||||
fs, config, new MockLogger(), SOME_PACKAGE,
|
||||
_('/project/node_modules/some_package/valid_entry_point'));
|
||||
const overriddenPackageJson = {
|
||||
...loadPackageJson(fs, '/project/node_modules/some_package/valid_entry_point'),
|
||||
...override};
|
||||
expect(entryPoint).toEqual({
|
||||
name: 'some_package/valid_entry_point',
|
||||
package: SOME_PACKAGE,
|
||||
path: _('/project/node_modules/some_package/valid_entry_point'),
|
||||
typings: _('/project/node_modules/some_package/valid_entry_point/some_other.d.ts'),
|
||||
packageJson: overriddenPackageJson,
|
||||
compiledByAngular: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('should return null if there is no package.json at the entry-point path', () => {
|
||||
loadTestFiles([
|
||||
{
|
||||
name: _('/some_package/missing_package_json/missing_package_json.metadata.json'),
|
||||
name: _(
|
||||
'/project/node_modules/some_package/missing_package_json/missing_package_json.metadata.json'),
|
||||
contents: 'some meta data'
|
||||
},
|
||||
]);
|
||||
const config = new NgccConfiguration(fs, _('/project'));
|
||||
const entryPoint = getEntryPointInfo(
|
||||
fs, new MockLogger(), SOME_PACKAGE, _('/some_package/missing_package_json'));
|
||||
fs, config, new MockLogger(), SOME_PACKAGE,
|
||||
_('/project/node_modules/some_package/missing_package_json'));
|
||||
expect(entryPoint).toBe(null);
|
||||
});
|
||||
|
||||
it('should return a configured entry-point if there is no package.json at the entry-point path',
|
||||
() => {
|
||||
loadTestFiles([
|
||||
// no package.json!
|
||||
{
|
||||
name: _(
|
||||
'/project/node_modules/some_package/missing_package_json/missing_package_json.metadata.json'),
|
||||
contents: 'some meta data',
|
||||
},
|
||||
]);
|
||||
const config = new NgccConfiguration(fs, _('/project'));
|
||||
const override =
|
||||
JSON.parse(createPackageJson('missing_package_json', {excludes: ['name']}));
|
||||
spyOn(config, 'getConfig').and.returnValue({
|
||||
entryPoints:
|
||||
{[_('/project/node_modules/some_package/missing_package_json')]: {override}}
|
||||
});
|
||||
const entryPoint = getEntryPointInfo(
|
||||
fs, config, new MockLogger(), SOME_PACKAGE,
|
||||
_('/project/node_modules/some_package/missing_package_json'));
|
||||
expect(entryPoint).toEqual({
|
||||
name: 'some_package/missing_package_json',
|
||||
package: SOME_PACKAGE,
|
||||
path: _('/project/node_modules/some_package/missing_package_json'),
|
||||
typings: _(
|
||||
'/project/node_modules/some_package/missing_package_json/missing_package_json.d.ts'),
|
||||
packageJson: {name: 'some_package/missing_package_json', ...override},
|
||||
compiledByAngular: true,
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should return null if there is no typings or types field in the package.json', () => {
|
||||
loadTestFiles([
|
||||
{
|
||||
name: _('/some_package/missing_typings/package.json'),
|
||||
name: _('/project/node_modules/some_package/missing_typings/package.json'),
|
||||
contents: createPackageJson('missing_typings', {excludes: ['typings']})
|
||||
},
|
||||
{
|
||||
name: _('/some_package/missing_typings/missing_typings.metadata.json'),
|
||||
name:
|
||||
_('/project/node_modules/some_package/missing_typings/missing_typings.metadata.json'),
|
||||
contents: 'some meta data'
|
||||
},
|
||||
]);
|
||||
const entryPoint =
|
||||
getEntryPointInfo(fs, new MockLogger(), SOME_PACKAGE, _('/some_package/missing_typings'));
|
||||
const config = new NgccConfiguration(fs, _('/project'));
|
||||
const entryPoint = getEntryPointInfo(
|
||||
fs, config, new MockLogger(), SOME_PACKAGE,
|
||||
_('/project/node_modules/some_package/missing_typings'));
|
||||
expect(entryPoint).toBe(null);
|
||||
});
|
||||
|
||||
|
@ -80,42 +182,74 @@ runInEachFileSystem(() => {
|
|||
() => {
|
||||
loadTestFiles([
|
||||
{
|
||||
name: _('/some_package/missing_metadata/package.json'),
|
||||
name: _('/project/node_modules/some_package/missing_metadata/package.json'),
|
||||
contents: createPackageJson('missing_metadata')
|
||||
},
|
||||
]);
|
||||
const config = new NgccConfiguration(fs, _('/project'));
|
||||
const entryPoint = getEntryPointInfo(
|
||||
fs, new MockLogger(), SOME_PACKAGE, _('/some_package/missing_metadata'));
|
||||
fs, config, new MockLogger(), SOME_PACKAGE,
|
||||
_('/project/node_modules/some_package/missing_metadata'));
|
||||
expect(entryPoint).toEqual({
|
||||
name: 'some-package/missing_metadata',
|
||||
name: 'some_package/missing_metadata',
|
||||
package: SOME_PACKAGE,
|
||||
path: _('/some_package/missing_metadata'),
|
||||
typings: _(`/some_package/missing_metadata/missing_metadata.d.ts`),
|
||||
packageJson: loadPackageJson(fs, '/some_package/missing_metadata'),
|
||||
path: _('/project/node_modules/some_package/missing_metadata'),
|
||||
typings: _(`/project/node_modules/some_package/missing_metadata/missing_metadata.d.ts`),
|
||||
packageJson: loadPackageJson(fs, '/project/node_modules/some_package/missing_metadata'),
|
||||
compiledByAngular: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('should return an object with `compiledByAngular` set to true if there is no metadata.json file but the entry-point has a configuration',
|
||||
() => {
|
||||
loadTestFiles([
|
||||
{
|
||||
name: _('/project/node_modules/some_package/missing_metadata/package.json'),
|
||||
contents: createPackageJson('missing_metadata'),
|
||||
},
|
||||
// no metadata.json!
|
||||
]);
|
||||
const config = new NgccConfiguration(fs, _('/project'));
|
||||
spyOn(config, 'getConfig').and.returnValue({
|
||||
entryPoints: {[_('/project/node_modules/some_package/missing_metadata')]: {}}
|
||||
});
|
||||
const entryPoint = getEntryPointInfo(
|
||||
fs, config, new MockLogger(), SOME_PACKAGE,
|
||||
_('/project/node_modules/some_package/missing_metadata'));
|
||||
expect(entryPoint).toEqual({
|
||||
name: 'some_package/missing_metadata',
|
||||
package: SOME_PACKAGE,
|
||||
path: _('/project/node_modules/some_package/missing_metadata'),
|
||||
typings: _('/project/node_modules/some_package/missing_metadata/missing_metadata.d.ts'),
|
||||
packageJson: loadPackageJson(fs, '/project/node_modules/some_package/missing_metadata'),
|
||||
compiledByAngular: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('should work if the typings field is named `types', () => {
|
||||
loadTestFiles([
|
||||
{
|
||||
name: _('/some_package/types_rather_than_typings/package.json'),
|
||||
name: _('/project/node_modules/some_package/types_rather_than_typings/package.json'),
|
||||
contents: createPackageJson('types_rather_than_typings', {}, 'types')
|
||||
},
|
||||
{
|
||||
name:
|
||||
_('/some_package/types_rather_than_typings/types_rather_than_typings.metadata.json'),
|
||||
name: _(
|
||||
'/project/node_modules/some_package/types_rather_than_typings/types_rather_than_typings.metadata.json'),
|
||||
contents: 'some meta data'
|
||||
},
|
||||
]);
|
||||
const config = new NgccConfiguration(fs, _('/project'));
|
||||
const entryPoint = getEntryPointInfo(
|
||||
fs, new MockLogger(), SOME_PACKAGE, _('/some_package/types_rather_than_typings'));
|
||||
fs, config, new MockLogger(), SOME_PACKAGE,
|
||||
_('/project/node_modules/some_package/types_rather_than_typings'));
|
||||
expect(entryPoint).toEqual({
|
||||
name: 'some-package/types_rather_than_typings',
|
||||
name: 'some_package/types_rather_than_typings',
|
||||
package: SOME_PACKAGE,
|
||||
path: _('/some_package/types_rather_than_typings'),
|
||||
typings: _(`/some_package/types_rather_than_typings/types_rather_than_typings.d.ts`),
|
||||
packageJson: loadPackageJson(fs, '/some_package/types_rather_than_typings'),
|
||||
path: _('/project/node_modules/some_package/types_rather_than_typings'),
|
||||
typings: _(
|
||||
`/project/node_modules/some_package/types_rather_than_typings/types_rather_than_typings.d.ts`),
|
||||
packageJson:
|
||||
loadPackageJson(fs, '/project/node_modules/some_package/types_rather_than_typings'),
|
||||
compiledByAngular: true,
|
||||
});
|
||||
});
|
||||
|
@ -123,7 +257,7 @@ runInEachFileSystem(() => {
|
|||
it('should work with Angular Material style package.json', () => {
|
||||
loadTestFiles([
|
||||
{
|
||||
name: _('/some_package/material_style/package.json'),
|
||||
name: _('/project/node_modules/some_package/material_style/package.json'),
|
||||
contents: `{
|
||||
"name": "some_package/material_style",
|
||||
"typings": "./material_style.d.ts",
|
||||
|
@ -133,18 +267,20 @@ runInEachFileSystem(() => {
|
|||
}`
|
||||
},
|
||||
{
|
||||
name: _('/some_package/material_style/material_style.metadata.json'),
|
||||
name: _('/project/node_modules/some_package/material_style/material_style.metadata.json'),
|
||||
contents: 'some meta data'
|
||||
},
|
||||
]);
|
||||
const entryPoint =
|
||||
getEntryPointInfo(fs, new MockLogger(), SOME_PACKAGE, _('/some_package/material_style'));
|
||||
const config = new NgccConfiguration(fs, _('/project'));
|
||||
const entryPoint = getEntryPointInfo(
|
||||
fs, config, new MockLogger(), SOME_PACKAGE,
|
||||
_('/project/node_modules/some_package/material_style'));
|
||||
expect(entryPoint).toEqual({
|
||||
name: 'some_package/material_style',
|
||||
package: SOME_PACKAGE,
|
||||
path: _('/some_package/material_style'),
|
||||
typings: _(`/some_package/material_style/material_style.d.ts`),
|
||||
packageJson: loadPackageJson(fs, '/some_package/material_style'),
|
||||
path: _('/project/node_modules/some_package/material_style'),
|
||||
typings: _(`/project/node_modules/some_package/material_style/material_style.d.ts`),
|
||||
packageJson: loadPackageJson(fs, '/project/node_modules/some_package/material_style'),
|
||||
compiledByAngular: true,
|
||||
});
|
||||
});
|
||||
|
@ -155,12 +291,14 @@ runInEachFileSystem(() => {
|
|||
// for example, @schematics/angular contains a package.json blueprint
|
||||
// with unexpected symbols
|
||||
{
|
||||
name: _('/some_package/unexpected_symbols/package.json'),
|
||||
name: _('/project/node_modules/some_package/unexpected_symbols/package.json'),
|
||||
contents: '{"devDependencies": {<% if (!minimal) { %>"@types/jasmine": "~2.8.8" <% } %>}}'
|
||||
},
|
||||
]);
|
||||
const config = new NgccConfiguration(fs, _('/project'));
|
||||
const entryPoint = getEntryPointInfo(
|
||||
fs, new MockLogger(), SOME_PACKAGE, _('/some_package/unexpected_symbols'));
|
||||
fs, config, new MockLogger(), SOME_PACKAGE,
|
||||
_('/project/node_modules/some_package/unexpected_symbols'));
|
||||
expect(entryPoint).toBe(null);
|
||||
});
|
||||
});
|
||||
|
@ -169,7 +307,7 @@ runInEachFileSystem(() => {
|
|||
packageName: string, {excludes}: {excludes?: string[]} = {},
|
||||
typingsProp: string = 'typings'): string {
|
||||
const packageJson: any = {
|
||||
name: `some-package/${packageName}`,
|
||||
name: `some_package/${packageName}`,
|
||||
[typingsProp]: `./${packageName}.d.ts`,
|
||||
fesm2015: `./fesm2015/${packageName}.js`,
|
||||
esm2015: `./esm2015/${packageName}.js`,
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
import {FileSystem, absoluteFrom, getFileSystem} from '../../../src/ngtsc/file_system';
|
||||
import {runInEachFileSystem} from '../../../src/ngtsc/file_system/testing';
|
||||
import {loadTestFiles} from '../../../test/helpers';
|
||||
import {NgccConfiguration} from '../../src/packages/configuration';
|
||||
import {EntryPoint, EntryPointFormat, EntryPointJsonProperty, getEntryPointInfo} from '../../src/packages/entry_point';
|
||||
import {EntryPointBundle, makeEntryPointBundle} from '../../src/packages/entry_point_bundle';
|
||||
import {FileWriter} from '../../src/writing/file_writer';
|
||||
|
@ -86,8 +87,9 @@ runInEachFileSystem(() => {
|
|||
beforeEach(() => {
|
||||
fs = getFileSystem();
|
||||
fileWriter = new NewEntryPointFileWriter(fs);
|
||||
const config = new NgccConfiguration(fs, _('/'));
|
||||
entryPoint = getEntryPointInfo(
|
||||
fs, new MockLogger(), _('/node_modules/test'), _('/node_modules/test')) !;
|
||||
fs, config, new MockLogger(), _('/node_modules/test'), _('/node_modules/test')) !;
|
||||
esm5bundle = makeTestBundle(fs, entryPoint, 'module', 'esm5');
|
||||
esm2015bundle = makeTestBundle(fs, entryPoint, 'es2015', 'esm2015');
|
||||
});
|
||||
|
@ -174,8 +176,9 @@ runInEachFileSystem(() => {
|
|||
beforeEach(() => {
|
||||
fs = getFileSystem();
|
||||
fileWriter = new NewEntryPointFileWriter(fs);
|
||||
const config = new NgccConfiguration(fs, _('/'));
|
||||
entryPoint = getEntryPointInfo(
|
||||
fs, new MockLogger(), _('/node_modules/test'), _('/node_modules/test/a')) !;
|
||||
fs, config, new MockLogger(), _('/node_modules/test'), _('/node_modules/test/a')) !;
|
||||
esm5bundle = makeTestBundle(fs, entryPoint, 'module', 'esm5');
|
||||
esm2015bundle = makeTestBundle(fs, entryPoint, 'es2015', 'esm2015');
|
||||
});
|
||||
|
@ -251,8 +254,9 @@ runInEachFileSystem(() => {
|
|||
beforeEach(() => {
|
||||
fs = getFileSystem();
|
||||
fileWriter = new NewEntryPointFileWriter(fs);
|
||||
const config = new NgccConfiguration(fs, _('/'));
|
||||
entryPoint = getEntryPointInfo(
|
||||
fs, new MockLogger(), _('/node_modules/test'), _('/node_modules/test/b')) !;
|
||||
fs, config, new MockLogger(), _('/node_modules/test'), _('/node_modules/test/b')) !;
|
||||
esm5bundle = makeTestBundle(fs, entryPoint, 'module', 'esm5');
|
||||
esm2015bundle = makeTestBundle(fs, entryPoint, 'es2015', 'esm2015');
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue