Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 18 additions & 5 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,24 @@ matrix:
os: linux
script: node tests/run_e2e.js --nb-shards=4 --shard=3 --nosilent
env: e2e-3

- node_js: "6"
os: linux
script: node tests/run_e2e.js --nb-shards=4 --shard=0 --nosilent --nightly
env: nightly-0
- node_js: "6"
os: linux
script: node tests/run_e2e.js --nb-shards=4 --shard=1 --nosilent --nightly
env: nightly-1
- node_js: "6"
os: linux
script: node tests/run_e2e.js --nb-shards=4 --shard=2 --nosilent --nightly
env: nightly-2
- node_js: "6"
os: linux
script: node tests/run_e2e.js --nb-shards=4 --shard=3 --nosilent --nightly
env: nightly-3

- node_js: "6"
os: linux
script: node tests/run_e2e.js --eject "--glob=tests/build/**"
Expand All @@ -54,11 +72,6 @@ matrix:
before_script: if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then exit 0; fi
script: node tests/run_e2e.js --ng2 "--glob=tests/{build,test,misc}/**"
env: ng2
- node_js: "6"
os: linux
before_script: if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then exit 0; fi
script: node tests/run_e2e.js "--nightly --glob=tests/{build,test,misc}/**"
env: nightly
- node_js: "7"
os: linux
before_script: if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then exit 0; fi
Expand Down
16 changes: 16 additions & 0 deletions lib/bootstrap-local.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,14 @@ require.extensions['.ts'] = function (m, filename) {
// lazy: true
// });

const resolve = require('resolve');


// Look if there's a .angular-cli.json file, and if so toggle process.cwd() resolution.
const isAngularProject = fs.existsSync(path.join(process.cwd(), '.angular-cli.json'))
|| fs.existsSync(path.join(process.cwd(), 'angular-cli.json'));


// If we're running locally, meaning npm linked. This is basically "developer mode".
if (!__dirname.match(new RegExp(`\\${path.sep}node_modules\\${path.sep}`))) {
const packages = require('./packages').packages;
Expand All @@ -71,6 +79,14 @@ if (!__dirname.match(new RegExp(`\\${path.sep}node_modules\\${path.sep}`))) {
const p = path.join(packages[match].root, request.substr(match.length));
return oldLoad.call(this, p, parent);
} else {
try {
if (isAngularProject) {
return oldLoad.call(this, resolve.sync(request, { basedir: process.cwd() }), parent);
}
} catch (e) {
// Do nothing. Fallback to the old method.
}

return oldLoad.apply(this, arguments);
}
}
Expand Down
9 changes: 7 additions & 2 deletions packages/@angular/cli/models/webpack-configs/typescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,9 @@ export function getAotConfig(wco: WebpackConfigOptions) {
// Fallback to exclude spec files from AoT compilation on projects using a shared tsconfig.
if (testTsConfigPath === tsConfigPath) {
let exclude = [ '**/*.spec.ts' ];
if (appConfig.test) { exclude.push(path.join(projectRoot, appConfig.root, appConfig.test)); }
if (appConfig.test) {
exclude.push(path.join(projectRoot, appConfig.root, appConfig.test));
}
pluginOptions.exclude = exclude;
}

Expand Down Expand Up @@ -164,7 +166,10 @@ export function getNonAotTestConfig(wco: WebpackConfigOptions) {
// Force include main and polyfills.
// This is needed for AngularCompilerPlugin compatibility with existing projects,
// since TS compilation there is stricter and tsconfig.spec.ts doesn't include them.
const include = [appConfig.main, appConfig.polyfills];
const include = [appConfig.main, appConfig.polyfills, '**/*.spec.ts'];
if (appConfig.test) {
include.push(appConfig.test);
}

let pluginOptions: any = { tsConfigPath, skipCodeGeneration: true, include };

Expand Down
55 changes: 51 additions & 4 deletions packages/@ngtools/webpack/src/angular_compiler_plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,11 @@ import {
CompilerHost,
Diagnostics,
CustomTransformers,
EmitFlags,
LazyRoute,
createProgram,
createCompilerHost,
formatDiagnostics,
EmitFlags,
} from './ngtools_api';
import { findAstNodes } from './transformers/ast_helpers';

Expand Down Expand Up @@ -87,7 +88,7 @@ export class AngularCompilerPlugin implements Tapable {
private _compilerOptions: ts.CompilerOptions;
private _angularCompilerOptions: CompilerOptions;
private _tsFilenames: string[];
private _program: ts.Program | Program;
private _program: (ts.Program | Program);
private _compilerHost: WebpackCompilerHost;
private _moduleResolutionCache: ts.ModuleResolutionCache;
private _angularCompilerHost: WebpackCompilerHost & CompilerHost;
Expand All @@ -111,6 +112,14 @@ export class AngularCompilerPlugin implements Tapable {
private _forkTypeChecker = true;
private _typeCheckerProcess: ChildProcess;

private get _ngCompilerSupportsNewApi() {
if (this._JitMode) {
return false;
} else {
return !!(this._program as Program).listLazyRoutes;
}
}

constructor(options: AngularCompilerPluginOptions) {
CompilerCliIsSupported();
this._options = Object.assign({}, options);
Expand Down Expand Up @@ -364,8 +373,10 @@ export class AngularCompilerPlugin implements Tapable {
timeEnd('AngularCompilerPlugin._createOrUpdateProgram.ng.createProgram');

time('AngularCompilerPlugin._createOrUpdateProgram.ng.loadNgStructureAsync');
return this._program.loadNgStructureAsync().then(() =>
timeEnd('AngularCompilerPlugin._createOrUpdateProgram.ng.loadNgStructureAsync'));
return this._program.loadNgStructureAsync()
.then(() => {
timeEnd('AngularCompilerPlugin._createOrUpdateProgram.ng.loadNgStructureAsync');
});
}
}

Expand Down Expand Up @@ -409,6 +420,32 @@ export class AngularCompilerPlugin implements Tapable {
return result;
}

private _listLazyRoutesFromProgram(): LazyRouteMap {
const ngProgram = this._program as Program;
if (!ngProgram.listLazyRoutes) {
throw new Error('_listLazyRoutesFromProgram was called with an old program.');
}

const lazyRoutes = ngProgram.listLazyRoutes();

return lazyRoutes.reduce(
(acc: LazyRouteMap, curr: LazyRoute) => {
const ref = curr.route;
if (ref in acc && acc[ref] !== curr.referencedModule.filePath) {
throw new Error(
+ `Duplicated path in loadChildren detected: "${ref}" is used in 2 loadChildren, `
+ `but they point to different modules "(${acc[ref]} and `
+ `"${curr.referencedModule.filePath}"). Webpack cannot distinguish on context and `
+ 'would fail to load the proper one.'
);
}
acc[ref] = curr.referencedModule.filePath;
return acc;
},
{} as LazyRouteMap
);
}

// Process the lazy routes discovered, adding then to _lazyRoutes.
// TODO: find a way to remove lazy routes that don't exist anymore.
// This will require a registry of known references to a lazy route, removing it when no
Expand Down Expand Up @@ -666,6 +703,10 @@ export class AngularCompilerPlugin implements Tapable {

return Promise.resolve()
.then(() => {
if (this._ngCompilerSupportsNewApi) {
return;
}

// Try to find lazy routes.
// We need to run the `listLazyRoutes` the first time because it also navigates libraries
// and other things that we might miss using the (faster) findLazyRoutesInAst.
Expand All @@ -684,6 +725,12 @@ export class AngularCompilerPlugin implements Tapable {
return this._createOrUpdateProgram();
}
})
.then(() => {
if (this._ngCompilerSupportsNewApi) {
// TODO: keep this when the new ngCompiler supports the new lazy routes API.
this._lazyRoutes = this._listLazyRoutesFromProgram();
}
})
.then(() => {
// Build transforms, emit and report errors if there are changes or it's the first run.
if (changedFiles.length > 0 || this._firstRun) {
Expand Down
7 changes: 7 additions & 0 deletions packages/@ngtools/webpack/src/ngtools_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ export interface Program {
getNgSemanticDiagnostics(fileName?: string, cancellationToken?: ts.CancellationToken):
Diagnostic[];
loadNgStructureAsync(): Promise<void>;
listLazyRoutes?(): LazyRoute[];
emit({ emitFlags, cancellationToken, customTransformers, emitCallback }: {
emitFlags?: any;
cancellationToken?: ts.CancellationToken;
Expand All @@ -84,6 +85,12 @@ export interface Program {
}): ts.EmitResult;
}

export interface LazyRoute {
route: string;
module: { name: string, filePath: string };
referencedModule: { name: string, filePath: string };
}

export declare type Diagnostics = Array<ts.Diagnostic | Diagnostic>;

// Interfaces for the function declarations.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export function exportLazyModuleMap(
let [, moduleName] = loadChildrenString.split('#');
let modulePath = lazyRoutes[loadChildrenString];

if (modulePath.endsWith('.ngfactory.ts')) {
if (modulePath.match(/\.ngfactory\.[jt]s$/)) {
modulePath = modulePath.replace('.ngfactory', '');
moduleName = moduleName.replace('NgFactory', '');
loadChildrenString = loadChildrenString
Expand Down