From 857ee73142f1357e307286b975f7a66570247b96 Mon Sep 17 00:00:00 2001 From: Jason Jean Date: Fri, 5 Apr 2019 16:18:17 -0400 Subject: [PATCH] fix(frontend): tsconfig paths resolution --- package.json | 5 ++- packages/builders/package.json | 1 + .../src/builders/build/build.builder.spec.ts | 3 ++ packages/node/src/utils/config.spec.ts | 14 +++++--- packages/node/src/utils/config.ts | 32 +++++++++---------- packages/node/src/utils/node.config.spec.ts | 5 ++- .../src/builders/build/build.builder.spec.ts | 3 ++ .../web/src/utils/devserver.config.spec.ts | 7 ++-- packages/web/src/utils/web.config.spec.ts | 3 ++ yarn.lock | 30 +++++++++++++++++ 10 files changed, 75 insertions(+), 28 deletions(-) diff --git a/package.json b/package.json index baaa7d2ab3946..83040c24a1bb8 100644 --- a/package.json +++ b/package.json @@ -105,6 +105,8 @@ "strip-json-comments": "2.0.1", "tmp": "0.0.33", "ts-loader": "^5.3.1", + "ts-node": "^8.0.2", + "tsconfig-paths-webpack-plugin": "^3.2.0", "tsickle": "^0.33.0", "tslib": "^1.9.3", "tslint": "5.11.0", @@ -139,8 +141,5 @@ "commitizen": { "path": "./node_modules/cz-conventional-changelog" } - }, - "dependencies": { - "ts-node": "^8.0.2" } } diff --git a/packages/builders/package.json b/packages/builders/package.json index e90c071405d7c..044fd77ae9a49 100644 --- a/packages/builders/package.json +++ b/packages/builders/package.json @@ -35,6 +35,7 @@ "rxjs": "6.3.3", "source-map-support": "0.5.11", "ts-loader": "5.3.1", + "tsconfig-paths-webpack-plugin": "3.2.0", "webpack": "4.29.0", "webpack-dev-server": "3.1.14", "webpack-node-externals": "1.7.2", diff --git a/packages/node/src/builders/build/build.builder.spec.ts b/packages/node/src/builders/build/build.builder.spec.ts index 4ae9a569fdadf..01c176c0d1022 100644 --- a/packages/node/src/builders/build/build.builder.spec.ts +++ b/packages/node/src/builders/build/build.builder.spec.ts @@ -1,5 +1,7 @@ import { join, normalize } from '@angular-devkit/core'; import { TestLogger } from '@angular-devkit/architect/testing'; +jest.mock('tsconfig-paths-webpack-plugin'); +import TsConfigPathsPlugin from 'tsconfig-paths-webpack-plugin'; import BuildNodeBuilder from './build.builder'; import { BuildNodeBuilderOptions } from './build.builder'; import { of } from 'rxjs'; @@ -42,6 +44,7 @@ describe('NodeBuildBuilder', () => { assets: [], statsJson: false }; + (TsConfigPathsPlugin).mockImplementation(class MockPathsPlugin {}); }); describe('run', () => { diff --git a/packages/node/src/utils/config.spec.ts b/packages/node/src/utils/config.spec.ts index 4c8f5e4fb393c..3477a4b1d9546 100644 --- a/packages/node/src/utils/config.spec.ts +++ b/packages/node/src/utils/config.spec.ts @@ -5,6 +5,8 @@ import * as ts from 'typescript'; import { LicenseWebpackPlugin } from 'license-webpack-plugin'; import CircularDependencyPlugin = require('circular-dependency-plugin'); import ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); +jest.mock('tsconfig-paths-webpack-plugin'); +import TsConfigPathsPlugin from 'tsconfig-paths-webpack-plugin'; import { ProgressPlugin } from 'webpack'; import { BuildBuilderOptions } from './types'; @@ -19,6 +21,7 @@ describe('getBaseWebpackPartial', () => { root: getSystemPath(normalize('/root')), statsJson: false }; + (TsConfigPathsPlugin).mockImplementation(class MockPathsPlugin {}); }); describe('unconditional options', () => { @@ -127,7 +130,7 @@ describe('getBaseWebpackPartial', () => { expect(typeCheckerPlugin.options.tsconfig).toBe('tsconfig.json'); }); - it('should set aliases for compilerOptionPaths', () => { + it('should add the TsConfigPathsPlugin for resolving', () => { spyOn(ts, 'parseJsonConfigFileContent').and.returnValue({ options: { paths: { @@ -135,11 +138,12 @@ describe('getBaseWebpackPartial', () => { } } }); - const result = getBaseWebpackPartial(input); - expect(result.resolve.alias).toEqual({ - '@npmScope/libraryName': '/root/libs/libraryName/src/index.ts' - }); + expect( + result.resolve.plugins.some( + plugin => plugin instanceof TsConfigPathsPlugin + ) + ).toEqual(true); }); it('should include es2015 in mainFields if typescript is set es2015', () => { diff --git a/packages/node/src/utils/config.ts b/packages/node/src/utils/config.ts index ccd5120e0b1e2..023ebc0280b64 100644 --- a/packages/node/src/utils/config.ts +++ b/packages/node/src/utils/config.ts @@ -7,6 +7,7 @@ import { resolve } from 'path'; import { LicenseWebpackPlugin } from 'license-webpack-plugin'; import CircularDependencyPlugin = require('circular-dependency-plugin'); import ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); +import TsConfigPathsPlugin from 'tsconfig-paths-webpack-plugin'; import * as CopyWebpackPlugin from 'copy-webpack-plugin'; import { readTsConfig } from '@nrwl/workspace'; import { BuildBuilderOptions } from './types'; @@ -20,6 +21,8 @@ export function getBaseWebpackPartial( const supportsEs2015 = compilerOptions.target !== ts.ScriptTarget.ES3 && compilerOptions.target !== ts.ScriptTarget.ES5; + const mainFields = [...(supportsEs2015 ? ['es2015'] : []), 'module', 'main']; + const extensions = ['.ts', '.tsx', '.mjs', '.js', '.jsx']; const webpackConfig: Configuration = { entry: { main: [options.main] @@ -45,9 +48,16 @@ export function getBaseWebpackPartial( ] }, resolve: { - extensions: ['.ts', '.tsx', '.mjs', '.js', '.jsx'], - alias: getAliases(options, compilerOptions), - mainFields: [...(supportsEs2015 ? ['es2015'] : []), 'module', 'main'] + extensions, + alias: getAliases(options), + plugins: [ + new TsConfigPathsPlugin({ + configFile: options.tsConfig, + extensions, + mainFields + }) + ], + mainFields }, performance: { hints: false @@ -120,20 +130,8 @@ export function getBaseWebpackPartial( return webpackConfig; } -function getAliases( - options: BuildBuilderOptions, - compilerOptions: ts.CompilerOptions -): { [key: string]: string } { - const replacements = [ - ...options.fileReplacements, - ...(compilerOptions.paths - ? Object.entries(compilerOptions.paths).map(([importPath, values]) => ({ - replace: importPath, - with: resolve(options.root, values[0]) - })) - : []) - ]; - return replacements.reduce( +function getAliases(options: BuildBuilderOptions): { [key: string]: string } { + return options.fileReplacements.reduce( (aliases, replacement) => ({ ...aliases, [replacement.replace]: replacement.with diff --git a/packages/node/src/utils/node.config.spec.ts b/packages/node/src/utils/node.config.spec.ts index e63d858d537c1..11511f27f1f32 100644 --- a/packages/node/src/utils/node.config.spec.ts +++ b/packages/node/src/utils/node.config.spec.ts @@ -1,7 +1,9 @@ -import { getNodeWebpackConfig } from './node.config'; import { getSystemPath, normalize } from '@angular-devkit/core'; +jest.mock('tsconfig-paths-webpack-plugin'); +import TsConfigPathsPlugin from 'tsconfig-paths-webpack-plugin'; import { BannerPlugin } from 'webpack'; import { BuildNodeBuilderOptions } from '../builders/build/build.builder'; +import { getNodeWebpackConfig } from './node.config'; describe('getNodePartial', () => { let input: BuildNodeBuilderOptions; @@ -15,6 +17,7 @@ describe('getNodePartial', () => { root: getSystemPath(normalize('/root')), statsJson: false }; + (TsConfigPathsPlugin).mockImplementation(class MockPathsPlugin {}); }); describe('unconditionally', () => { diff --git a/packages/web/src/builders/build/build.builder.spec.ts b/packages/web/src/builders/build/build.builder.spec.ts index 190f925013583..a9bc3e1e57dda 100644 --- a/packages/web/src/builders/build/build.builder.spec.ts +++ b/packages/web/src/builders/build/build.builder.spec.ts @@ -1,5 +1,7 @@ import { normalize, join } from '@angular-devkit/core'; import { TestLogger } from '@angular-devkit/architect/testing'; +jest.mock('tsconfig-paths-webpack-plugin'); +import TsConfigPathsPlugin from 'tsconfig-paths-webpack-plugin'; import WebBuildBuilder from './build.builder'; import { WebBuildBuilderOptions } from './build.builder'; import { of } from 'rxjs'; @@ -45,6 +47,7 @@ describe('WebBuildBuilder', () => { assets: [], statsJson: false }; + (TsConfigPathsPlugin).mockImplementation(class MockPathsPlugin {}); }); describe('run', () => { diff --git a/packages/web/src/utils/devserver.config.spec.ts b/packages/web/src/utils/devserver.config.spec.ts index 45bda9d0a0287..1bbebe76ec60c 100644 --- a/packages/web/src/utils/devserver.config.spec.ts +++ b/packages/web/src/utils/devserver.config.spec.ts @@ -1,6 +1,8 @@ import { getSystemPath, normalize, join } from '@angular-devkit/core'; import { getDevServerConfig } from './devserver.config'; import { Logger } from '@angular-devkit/core/src/logger'; +jest.mock('tsconfig-paths-webpack-plugin'); +import TsConfigPathsPlugin from 'tsconfig-paths-webpack-plugin'; import * as ts from 'typescript'; import * as fs from 'fs'; import { WebBuildBuilderOptions } from '../builders/build/build.builder'; @@ -48,9 +50,10 @@ describe('getDevServerConfig', () => { watch: true }; + (TsConfigPathsPlugin).mockImplementation(class MockPathsPlugin {}); + mockCompilerOptions = { - target: 'es2015', - paths: { path: ['mapped/path'] } + target: 'es2015' }; spyOn(ts, 'readConfigFile').and.callFake(() => ({ diff --git a/packages/web/src/utils/web.config.spec.ts b/packages/web/src/utils/web.config.spec.ts index aaa56190bd152..798884b15ea29 100644 --- a/packages/web/src/utils/web.config.spec.ts +++ b/packages/web/src/utils/web.config.spec.ts @@ -1,4 +1,6 @@ import { getSystemPath, normalize } from '@angular-devkit/core'; +jest.mock('tsconfig-paths-webpack-plugin'); +import TsConfigPathsPlugin from 'tsconfig-paths-webpack-plugin'; import { getWebConfig as getWebPartial } from './web.config'; import { createConsoleLogger } from '@angular-devkit/core/node'; import { Logger } from '@angular-devkit/core/src/logger'; @@ -41,6 +43,7 @@ describe('getWebConfig', () => { target: 'es2015', paths: { path: ['mapped/path'] } }; + (TsConfigPathsPlugin).mockImplementation(class MockPathsPlugin {}); spyOn(ts, 'readConfigFile').and.callFake(() => ({ config: { diff --git a/yarn.lock b/yarn.lock index 514fda1522ef5..899c5cb923d14 100644 --- a/yarn.lock +++ b/yarn.lock @@ -659,6 +659,11 @@ version "3.2.16" resolved "https://registry.yarnpkg.com/@types/jquery/-/jquery-3.2.16.tgz#04419c404a3194350e7d3f339a90e72c88db3111" +"@types/json5@^0.0.29": + version "0.0.29" + resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" + integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= + "@types/lodash@4.14.87": version "4.14.87" resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.87.tgz#55f92183b048c2c64402afe472f8333f4e319a6b" @@ -3496,6 +3501,11 @@ deep-is@~0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" +deepmerge@^2.0.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-2.2.1.tgz#5d3ff22a01c00f645405a2fbc17d0778a1801170" + integrity sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA== + default-gateway@^2.6.0: version "2.7.2" resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-2.7.2.tgz#b7ef339e5e024b045467af403d50348db4642d0f" @@ -10555,6 +10565,26 @@ ts-node@^8.0.2: source-map-support "^0.5.6" yn "^3.0.0" +tsconfig-paths-webpack-plugin@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-3.2.0.tgz#6e70bd42915ad0efb64d3385163f0c1270f3e04d" + integrity sha512-S/gOOPOkV8rIL4LurZ1vUdYCVgo15iX9ZMJ6wx6w2OgcpT/G4wMyHB6WM+xheSqGMrWKuxFul+aXpCju3wmj/g== + dependencies: + chalk "^2.3.0" + enhanced-resolve "^4.0.0" + tsconfig-paths "^3.4.0" + +tsconfig-paths@^3.4.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.8.0.tgz#4e34202d5b41958f269cf56b01ed95b853d59f72" + integrity sha512-zZEYFo4sjORK8W58ENkRn9s+HmQFkkwydDG7My5s/fnfr2YYCaiyXe/HBUcIgU8epEKOXwiahOO+KZYjiXlWyQ== + dependencies: + "@types/json5" "^0.0.29" + deepmerge "^2.0.1" + json5 "^1.0.1" + minimist "^1.2.0" + strip-bom "^3.0.0" + tsickle@^0.33.0: version "0.33.1" resolved "https://registry.yarnpkg.com/tsickle/-/tsickle-0.33.1.tgz#eee4ebabeda3bcd8afc32cee34c822cbe3e839ec"