diff --git a/package.json b/package.json index 342ab4ea7f4a0..b9f904e7fb134 100644 --- a/package.json +++ b/package.json @@ -104,6 +104,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", @@ -133,8 +135,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 d14dd253d4afa..1b4e5722133fd 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/builders/src/node/build/node-build.builder.spec.ts b/packages/builders/src/node/build/node-build.builder.spec.ts index 8ab13b80b476b..d65450dedcbcf 100644 --- a/packages/builders/src/node/build/node-build.builder.spec.ts +++ b/packages/builders/src/node/build/node-build.builder.spec.ts @@ -2,6 +2,8 @@ import { join, normalize } from '@angular-devkit/core'; import { TestLogger } from '@angular-devkit/architect/testing'; import BuildNodeBuilder from './node-build.builder'; import { BuildNodeBuilderOptions } from './node-build.builder'; +jest.mock('tsconfig-paths-webpack-plugin'); +import TsConfigPathsPlugin from 'tsconfig-paths-webpack-plugin'; import { of } from 'rxjs'; import * as fs from 'fs'; @@ -42,6 +44,7 @@ describe('NodeBuildBuilder', () => { assets: [], statsJson: false }; + (TsConfigPathsPlugin).mockImplementation(class MockPathsPlugin {}); }); describe('run', () => { diff --git a/packages/builders/src/utils/webpack/config.spec.ts b/packages/builders/src/utils/webpack/config.spec.ts index 9141cb16b357a..db3681c2c0bbe 100644 --- a/packages/builders/src/utils/webpack/config.spec.ts +++ b/packages/builders/src/utils/webpack/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/builders/src/utils/webpack/config.ts b/packages/builders/src/utils/webpack/config.ts index 296d2d7faf661..93d84d3d0632f 100644 --- a/packages/builders/src/utils/webpack/config.ts +++ b/packages/builders/src/utils/webpack/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 { AssetPatternObject } from '@angular-devkit/build-angular'; @@ -22,6 +23,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] @@ -47,9 +50,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 @@ -124,20 +134,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/builders/src/utils/webpack/devserver.config.spec.ts b/packages/builders/src/utils/webpack/devserver.config.spec.ts index 5cc4585b0ee23..784d2dda4d294 100644 --- a/packages/builders/src/utils/webpack/devserver.config.spec.ts +++ b/packages/builders/src/utils/webpack/devserver.config.spec.ts @@ -3,6 +3,8 @@ import { WebBuildBuilderOptions } from '../../web/build/web-build.builder'; import { WebDevServerOptions } from '../../web/dev-server/web-dev-server.builder'; 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'; @@ -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/builders/src/utils/webpack/node.config.spec.ts b/packages/builders/src/utils/webpack/node.config.spec.ts index 3f0f6c2510d00..0fe335c66f0f1 100644 --- a/packages/builders/src/utils/webpack/node.config.spec.ts +++ b/packages/builders/src/utils/webpack/node.config.spec.ts @@ -1,7 +1,9 @@ -import { getNodeWebpackConfig } from './node.config'; import { getSystemPath, normalize } from '@angular-devkit/core'; -import { BuildNodeBuilderOptions } from '../../node/build/node-build.builder'; import { BannerPlugin } from 'webpack'; +jest.mock('tsconfig-paths-webpack-plugin'); +import TsConfigPathsPlugin from 'tsconfig-paths-webpack-plugin'; +import { getNodeWebpackConfig } from './node.config'; +import { BuildNodeBuilderOptions } from '../../node/build/node-build.builder'; 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/builders/src/utils/webpack/web.config.spec.ts b/packages/builders/src/utils/webpack/web.config.spec.ts index b59bb63f4dc73..4652cb8210d31 100644 --- a/packages/builders/src/utils/webpack/web.config.spec.ts +++ b/packages/builders/src/utils/webpack/web.config.spec.ts @@ -1,4 +1,6 @@ import { getSystemPath, normalize, Path } 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 { WebBuildBuilderOptions } from '../../web/build/web-build.builder'; import { createConsoleLogger } from '@angular-devkit/core/node'; @@ -42,6 +44,7 @@ describe('getWebConfig', () => { target: 'es2015', paths: { path: ['mapped/path'] } }; + (TsConfigPathsPlugin).mockImplementation(class MockPathsPlugin {}); spyOn(ts, 'readConfigFile').and.callFake(() => ({ config: { diff --git a/packages/builders/src/web/build/web-build.builder.spec.ts b/packages/builders/src/web/build/web-build.builder.spec.ts index 6c55e0141ffd9..c76ac30b7116c 100644 --- a/packages/builders/src/web/build/web-build.builder.spec.ts +++ b/packages/builders/src/web/build/web-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 './web-build.builder'; import { WebBuildBuilderOptions } from './web-build.builder'; import { of } from 'rxjs'; @@ -45,6 +47,7 @@ describe('WebBuildBuilder', () => { assets: [], statsJson: false }; + (TsConfigPathsPlugin).mockImplementation(class MockPathsPlugin {}); }); describe('run', () => { diff --git a/yarn.lock b/yarn.lock index c3e824a4c25ec..a0afbbe9e35bb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -619,6 +619,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" @@ -3553,6 +3558,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" @@ -10988,6 +10998,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"