Skip to content

fix(@ngtools/webpack): fix resolution fallback of paths-plugin #11524

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 12, 2018
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
2 changes: 1 addition & 1 deletion packages/angular_devkit/build_angular/test/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { join, normalize } from '@angular-devkit/core';


const devkitRoot = normalize((global as any)._DevKitRoot); // tslint:disable-line:no-any
const workspaceRoot = join(devkitRoot, 'tests/@angular_devkit/build_angular/hello-world-app/');
const workspaceRoot = join(devkitRoot, 'tests/angular_devkit/build_angular/hello-world-app/');
export const host = new TestProjectHost(workspaceRoot);
export const outputPath = normalize('dist');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { tap } from 'rxjs/operators';


const devkitRoot = normalize((global as any)._DevKitRoot); // tslint:disable-line:no-any
const workspaceRoot = join(devkitRoot, 'tests/@angular_devkit/build_ng_packagr/ng-packaged/');
const workspaceRoot = join(devkitRoot, 'tests/angular_devkit/build_ng_packagr/ng-packaged/');
export const host = new TestProjectHost(workspaceRoot);

describe('NgPackagr Builder', () => {
Expand Down
4 changes: 2 additions & 2 deletions packages/angular_devkit/build_webpack/src/test-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { join, normalize } from '@angular-devkit/core';


const devkitRoot = normalize((global as any)._DevKitRoot); // tslint:disable-line:no-any
const basicWorkspaceRoot = join(devkitRoot, 'tests/@angular_devkit/build_webpack/basic-app/');
const basicWorkspaceRoot = join(devkitRoot, 'tests/angular_devkit/build_webpack/basic-app/');
export const basicHost = new TestProjectHost(basicWorkspaceRoot);
const angularWorkspaceRoot = join(devkitRoot, 'tests/@angular_devkit/build_webpack/angular-app/');
const angularWorkspaceRoot = join(devkitRoot, 'tests/angular_devkit/build_webpack/angular-app/');
export const angularHost = new TestProjectHost(angularWorkspaceRoot);
4 changes: 2 additions & 2 deletions packages/angular_devkit/core/src/workspace/workspace_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ describe('Workspace', () => {
const host = new NodeJsSyncHost();
const root = normalize(__dirname);
// The content of this JSON object should be kept in sync with the path below:
// tests/@angular_devkit/workspace/angular-workspace.json
// tests/angular_devkit/core/workspace/angular-workspace.json
const workspaceJson: WorkspaceSchema = {
version: 1,
newProjectRoot: './projects',
Expand Down Expand Up @@ -118,7 +118,7 @@ describe('Workspace', () => {

it('loads workspace from host', (done) => {
const devkitRoot = normalize((global as any)._DevKitRoot); // tslint:disable-line:no-any
const workspaceRoot = join(devkitRoot, 'tests/@angular_devkit/core/workspace');
const workspaceRoot = join(devkitRoot, 'tests/angular_devkit/core/workspace');
const workspace = new Workspace(workspaceRoot, host);
workspace.loadWorkspaceFromHost(normalize('angular-workspace.json')).pipe(
tap((ws) => expect(ws.getProject('app').root).toEqual(workspaceJson.projects['app'].root)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ describe('FileSystemEngineHost', () => {
const devkitRoot = (global as any)._DevKitRoot;
const root = path.join(
devkitRoot,
'tests/@angular_devkit/schematics/tools/file-system-engine-host',
'tests/angular_devkit/schematics/tools/file-system-engine-host',
);

it('works', () => {
Expand Down
41 changes: 33 additions & 8 deletions packages/ngtools/webpack/src/paths-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,15 +160,40 @@ export function resolveWithPaths(
const jsFilePath = `${pathNoExtension}.js`;

if (host.fileExists(pathNoExtension)) {
// This is mainly for secondary entry points
// ex: 'node_modules/@angular/core/testing.d.ts' -> 'node_modules/@angular/core/testing'
request.request = pathNoExtension;
} else if (host.fileExists(packageRootPath)) {
// Let webpack resolve the correct module format
request.request = pathDirName;
} else if (host.fileExists(jsFilePath)) {
// This is mainly for secondary entry points
// ex: 'node_modules/@angular/core/testing.d.ts' -> 'node_modules/@angular/core/testing'
request.request = pathNoExtension;
} else {
const packageJsonContent = host.readFile(packageRootPath);
let newRequest: string | undefined;

if (packageJsonContent) {
try {
const packageJson = JSON.parse(packageJsonContent);

// Let webpack resolve the correct module format IIF there is a module resolution field
// in the package.json. These are all official fields that Angular uses.
if (typeof packageJson.main == 'string'
|| typeof packageJson.browser == 'string'
|| typeof packageJson.module == 'string'
|| typeof packageJson.es2015 == 'string'
|| typeof packageJson.fesm5 == 'string'
|| typeof packageJson.fesm2015 == 'string') {
newRequest = pathDirName;
}
} catch {
// Ignore exceptions and let it fall through (ie. if package.json file is invalid).
}
}

if (newRequest === undefined && host.fileExists(jsFilePath)) {
// Otherwise, if there is a file with a .js extension use that
request.request = jsFilePath;
newRequest = jsFilePath;
}

if (newRequest !== undefined) {
request.request = newRequest;
}
}

callback(null, request);
Expand Down
1 change: 0 additions & 1 deletion tests/@angular/schematics/assets/1/hello

This file was deleted.

Empty file.
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"tsConfigPath": "./src/tsconfig.json",
"mainPath": "app/main.jit.ts"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "test",
"license": "MIT",
"dependencies": {
"@angular/common": "^5.0.0-rc.8",
"@angular/compiler": "^5.0.0-rc.8",
"@angular/compiler-cli": "^5.0.0-rc.8",
"@angular/core": "^5.0.0-rc.8",
"@angular/http": "^5.0.0-rc.8",
"@angular/platform-browser": "^5.0.0-rc.8",
"@angular/platform-browser-dynamic": "^5.0.0-rc.8",
"@angular/platform-server": "^5.0.0-rc.8",
"@angular/router": "^5.0.0-rc.8",
"@ngtools/webpack": "0.0.0",
"core-js": "^2.4.1",
"rxjs": "^5.5.0",
"zone.js": "^0.8.14"
},
"devDependencies": {
"node-sass": "^4.7.0",
"performance-now": "^0.2.0",
"preprocess-loader": "^0.2.2",
"raw-loader": "^0.5.1",
"sass-loader": "^6.0.0",
"typescript": "~2.4.2",
"webpack": "~4.0.1",
"webpack-cli": "~2.0.9"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* @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 { Component, NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { Foo } from 'foo/foo';

console.log(Foo); // Make sure it's used.

@Component({
selector: 'home-view',
template: 'home!',
})
export class HomeView {}

@NgModule({
declarations: [
HomeView,
],
imports: [
BrowserModule,
],
bootstrap: [HomeView],
})
export class AppModule { }
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import 'core-js/es7/reflect';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {AppModule} from './app.module';

platformBrowserDynamic().bootstrapModule(AppModule);
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/**
* @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
*/

export class Foo {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

console.log('NGTOOLS_WEBPACK_TEST_WRONG_FILE');

module.exports = {
Foo: () => {}, // Empty "class".
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"main": "right/foo.js"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

console.log('NGTOOLS_WEBPACK_TEST_RIGHT_FILE');

module.exports = {
Foo: () => {}, // Empty "class".
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
<base href="">
</head>
<body>
<app-root></app-root>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="dist/app.main.js"></script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"compilerOptions": {
"module": "es2015",
"moduleResolution": "node",
"target": "es5",
"baseUrl": ".",
"noImplicitAny": false,
"sourceMap": true,
"mapRoot": "",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": [
"es2017",
"dom"
],
"outDir": "lib",
"skipLibCheck": true,
"rootDir": ".",
"paths": {
"foo/*": [
"./foo/*",
"*"
]
}
},
"angularCompilerOptions": {
"genDir": "app/generated/",
"entryModule": "app/app.module#AppModule"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/**
* @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
*/
const ngToolsWebpack = require('@ngtools/webpack');
const path = require('path');

const flags = require('./webpack.flags.json');

const preprocessLoader = 'preprocess-loader' + (flags.DEBUG ? '?+DEBUG' : '');


module.exports = {
resolve: {
extensions: ['.ts', '.js']
},
entry: './src/app/main.jit.ts',
output: {
path: path.resolve('./dist'),
publicPath: 'dist/',
filename: 'app.main.js'
},
plugins: [
new ngToolsWebpack.AngularCompilerPlugin(require('./aotplugin.config.json'))
],
module: {
rules: [
{ test: /\.scss$/, loaders: ['raw-loader', 'sass-loader', preprocessLoader] },
{ test: /\.css$/, loader: 'raw-loader' },
{ test: /\.html$/, loaders: ['raw-loader', preprocessLoader] },
// Use preprocess to remove DEBUG only code.
// @ngtools/webpack must be the first (right most) loader.
{ test: /\.ts$/, use: [
{ loader: preprocessLoader },
{ loader: '@ngtools/webpack' }
] }
]
},
devServer: {
historyApiFallback: true
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"DEBUG": false
}
13 changes: 13 additions & 0 deletions tests/legacy-cli/e2e/tests/packages/webpack/test-path-mapping.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import {normalize} from 'path';
import {createProjectFromAsset} from '../../../utils/assets';
import {exec} from '../../../utils/process';
import {expectFileSizeToBeUnder, replaceInFile, expectFileToMatch} from '../../../utils/fs';


export default function(skipCleaning: () => void) {
return Promise.resolve()
.then(() => createProjectFromAsset('webpack/test-app-path-mapping'))
.then(() => exec(normalize('node_modules/.bin/webpack-cli')))
.then(() => expectFileToMatch('dist/app.main.js', 'NGTOOLS_WEBPACK_TEST_RIGHT_FILE'))
.then(() => skipCleaning());
}