feat(@ngtools/webpack): allow passing in the right ContextElementDependency class

This should allow multiple webpack versions in the workspace dependencies with no weird errors.

Fix https://github.com/angular/angular-cli/issues/6417 for good.
This commit is contained in:
Filipe Silva 2018-06-07 16:45:52 +01:00
parent 182c890979
commit fb6b3ad0ca
2 changed files with 21 additions and 3 deletions

View File

@ -42,6 +42,7 @@ The loader works with webpack plugin to compile your TypeScript. It's important
* `skipCodeGeneration`. Optional, defaults to false. Disable code generation and do not refactor the code to bootstrap. This replaces `templateUrl: "string"` with `template: require("string")` (and similar for styles) to allow for webpack to properly link the resources.
* `sourceMap`. Optional. Include sourcemaps.
* `compilerOptions`. Optional. Override options in `tsconfig.json`.
* `contextElementDependencyConstructor`. Optional. Set to `require('webpack/lib/dependencies/ContextElementDependency')` if you are having `No module factory available for dependency type: ContextElementDependency` errors.
## Features
The benefits and ability of using [`@ngtools/webpack`](https://www.npmjs.com/~ngtools) standalone from the Angular CLI as presented in [Stephen Fluin's Angular CLI talk](https://youtu.be/uBRK6cTr4Vk?t=6m45s) at Angular Connect 2016:

View File

@ -54,10 +54,13 @@ import {
VirtualWatchFileSystemDecorator,
} from './virtual_file_system_decorator';
const ContextElementDependency = require('webpack/lib/dependencies/ContextElementDependency');
const treeKill = require('tree-kill');
export interface ContextElementDependency {}
export interface ContextElementDependencyConstructor {
new(modulePath: string, name: string): ContextElementDependency;
}
/**
* Option Constants
@ -86,6 +89,10 @@ export interface AngularCompilerPluginOptions {
// added to the list of lazy routes
additionalLazyModules?: { [module: string]: string };
// The ContextElementDependency of correct Webpack compilation.
// This is needed when there are multiple Webpack installs.
contextElementDependencyConstructor?: ContextElementDependencyConstructor;
// Use tsconfig to include path globs.
compilerOptions?: ts.CompilerOptions;
@ -128,6 +135,7 @@ export class AngularCompilerPlugin {
private _normalizedLocale: string | null;
private _warnings: (string | Error)[] = [];
private _errors: (string | Error)[] = [];
private _contextElementDependencyConstructor: ContextElementDependencyConstructor;
// TypeChecker process.
private _forkTypeChecker = true;
@ -267,6 +275,15 @@ export class AngularCompilerPlugin {
this._platformTransformers = options.platformTransformers;
}
// Default ContextElementDependency to the one we can import from here.
// Failing to use the right ContextElementDependency will throw the error below:
// "No module factory available for dependency type: ContextElementDependency"
// Hoisting together with peer dependencies can make it so the imported
// ContextElementDependency does not come from the same Webpack instance that is used
// in the compilation. In that case, we can pass the right one as an option to the plugin.
this._contextElementDependencyConstructor = options.contextElementDependencyConstructor
|| require('webpack/lib/dependencies/ContextElementDependency');
// Create the webpack compiler host.
const webpackCompilerHost = new WebpackCompilerHost(
this._compilerOptions,
@ -633,7 +650,7 @@ export class AngularCompilerPlugin {
if (modulePath !== null) {
const name = importPath.replace(/(\.ngfactory)?\.(js|ts)$/, '');
return new ContextElementDependency(modulePath, name);
return new this._contextElementDependencyConstructor(modulePath, name);
} else {
return null;
}