From 359a4c4c6200bbe522516c9c7eda30614b2ede3c Mon Sep 17 00:00:00 2001 From: Gerkin Date: Tue, 7 Sep 2021 12:43:33 +0200 Subject: [PATCH] fix(custom-webpack): register ts-node only once (#1035) * test(custom-webpack): add failing test for #1031 * fix(custom-webpack): actual fix for #1031 Closes #1031 --- .../src/transform-factories.spec.ts | 43 +++++++++++++++++++ packages/custom-webpack/src/utils.ts | 33 ++++++++++---- 2 files changed, 68 insertions(+), 8 deletions(-) create mode 100644 packages/custom-webpack/src/transform-factories.spec.ts diff --git a/packages/custom-webpack/src/transform-factories.spec.ts b/packages/custom-webpack/src/transform-factories.spec.ts new file mode 100644 index 000000000..db439cf09 --- /dev/null +++ b/packages/custom-webpack/src/transform-factories.spec.ts @@ -0,0 +1,43 @@ +jest.mock('ts-node', () => ({ + register: jest.fn(), +})); +jest.mock('tsconfig-paths', () => ({ + loadConfig: jest.fn().mockReturnValue({}), +})); +import * as utils from './utils'; +jest.spyOn(utils, 'tsNodeRegister'); + +import { getTransforms } from './transform-factories'; + +describe('getTransforms', () => { + beforeEach(() => { + jest.resetModules(); + }); + it('should call ts-node register once with typescript index-html-transform & custom-webpack-config', () => { + jest.mock('test/index-transform.test.ts', () => jest.fn(), { virtual: true }); + jest.mock('test/webpack.test.config.ts', () => jest.fn(), { virtual: true }); + const tsNode = require('ts-node') as jest.Mocked; + + const transforms = getTransforms( + { + customWebpackConfig: { + path: 'webpack.test.config.ts', + }, + indexTransform: 'index-transform.test.ts', + tsConfig: 'tsconfig.test.json', + }, + { workspaceRoot: './test' } as any + ); + transforms.webpackConfiguration({}); + + expect(utils.tsNodeRegister).toHaveBeenCalledWith( + 'test/webpack.test.config.ts', + 'test/tsconfig.test.json' + ); + expect(utils.tsNodeRegister).toHaveBeenCalledWith( + 'index-transform.test.ts', + 'test/tsconfig.test.json' + ); + expect(tsNode.register).toHaveBeenCalledTimes(1); + }); +}); diff --git a/packages/custom-webpack/src/utils.ts b/packages/custom-webpack/src/utils.ts index 9c508e70e..6c77f9ea1 100644 --- a/packages/custom-webpack/src/utils.ts +++ b/packages/custom-webpack/src/utils.ts @@ -1,11 +1,16 @@ -/** - * check for TS node registration - * @param file: file name or file directory are allowed - * @todo tsNodeRegistration: require ts-node if file extension is TypeScript - */ -export function tsNodeRegister(file: string = '', tsConfig?: string) { - if (file && file.endsWith('.ts')) { - // Register TS compiler lazily +const _tsNodeRegister = (() => { + let lastTsConfig: string | null | undefined; + return (tsConfig?: string) => { + // Check if the function was previously called with the same tsconfig + if (typeof lastTsConfig !== 'undefined' && (tsConfig ?? null) !== lastTsConfig) { + throw new Error('Called with multiple tsconfigs.'); + } + if (lastTsConfig) { + return; + } + lastTsConfig = tsConfig ?? null; + + // Register ts-node require('ts-node').register({ project: tsConfig, compilerOptions: { @@ -22,5 +27,17 @@ export function tsNodeRegister(file: string = '', tsConfig?: string) { if (baseUrl && paths) { tsconfigPaths.register({ baseUrl, paths }); } + }; +})(); + +/** + * check for TS node registration + * @param file: file name or file directory are allowed + * @todo tsNodeRegistration: require ts-node if file extension is TypeScript + */ +export function tsNodeRegister(file: string = '', tsConfig?: string) { + if (file && file.endsWith('.ts')) { + // Register TS compiler lazily + _tsNodeRegister(tsConfig); } }