From c3f4d4e506d22addb1a89dd410e8669356c34900 Mon Sep 17 00:00:00 2001 From: sverweij Date: Sun, 2 Jul 2023 12:58:15 +0200 Subject: [PATCH] fix(main): when baseUrl is tsconfig still load tsconfig-paths-webpack-plugin --- src/main/resolve-options/normalize.mjs | 36 ++++++++++++++------ test/main/resolve-options/normalize.spec.mjs | 27 +++++++++++++-- 2 files changed, 50 insertions(+), 13 deletions(-) diff --git a/src/main/resolve-options/normalize.mjs b/src/main/resolve-options/normalize.mjs index cae25859f..7b373bf70 100644 --- a/src/main/resolve-options/normalize.mjs +++ b/src/main/resolve-options/normalize.mjs @@ -63,10 +63,7 @@ function pushPlugin(pPlugins, pPluginToPush) { return (pPlugins || []).concat(pPluginToPush); } -function isTsConfigPathsEligible(pTSConfig) { - return has(pTSConfig, "options.baseUrl"); -} - +// eslint-disable-next-line max-lines-per-function async function compileResolveOptions( pResolveOptions, pTSConfig, @@ -74,16 +71,12 @@ async function compileResolveOptions( ) { let lResolveOptions = {}; - // TsConfigPathsPlugin requires a baseUrl to be present in the tsconfig, - // otherwise it prints scary messages that it didn't and read the tsConfig - // (potentially making users think it's dependency-cruiser disregarding the - // tsconfig). Hence: only load TsConfigPathsPlugin when an options.baseUrl exists - // Also: there's a performance impact of ~1 ms per resolve even when there + // There's a performance impact of ~1 ms per resolve even when there // are 0 paths in the tsconfig, so not loading it when not necessary // will be a win. // Also: requiring the plugin only when it's necessary will save some // startup time (especially on a cold require cache) - if (pResolveOptions.tsConfig && isTsConfigPathsEligible(pTSConfig)) { + if (pResolveOptions.tsConfig) { const { default: TsConfigPathsPlugin } = await import( "tsconfig-paths-webpack-plugin" ); @@ -92,6 +85,29 @@ async function compileResolveOptions( // @ts-expect-error TS2351 "TsConfPathsPlugin is not constructable" - is unjustified new TsConfigPathsPlugin({ configFile: pResolveOptions.tsConfig, + // TsConfigPathsPlugin requires a baseUrl to be present in the tsconfig, + // otherwise it prints scary messages that it didn't and read the tsConfig + // (potentially making users think it's dependency-cruiser disregarding the + // tsconfig). Hence up till version 13.0.4 dependency-cruiser only loaded + // TsConfigPathsPlugin when an options.baseUrl existed. However, this + // isn't necessary anymore: + // - [tsconfig#baseUrl documentation](https://www.typescriptlang.org/tsconfig#baseUrl) + // UNrecommends the use of the baseUrl for non-AMD projects + // - [tsconfig-paths PR #207](https://github.com/dividab/tsconfig-paths/pull/208) + // 'tolerates' undefined baseUrls + // + // Hence, until + // [tpwp issue #99](https://github.com/dividab/tsconfig-paths-webpack-plugin/issues/99) + // lands: + // - pass a default baseUrl to TsConfigPathsPlugin if the baseUrl isn't available + // - pass undefined in all other cases; TsConfigPathsPlugin will read + // it from the tsconfig.json in that case. Passing the processed baseUrl + // (pTSConfig?.options?.baseUrl) instead would've been more obvious, but + // doesn't work, as that is an absolute path and tsconfig-paths(-wpp) + // seems to process that again resulting in invalid paths and unresolved + // or erroneous dependencies + // eslint-disable-next-line no-undefined + baseUrl: pTSConfig?.options?.baseUrl ? undefined : "./", // TsConfigPathsPlugin doesn't (can't) read enhanced-resolve's // list of extensions, and the default it uses for extensions // so we do it ourselves - either with the extensions passed diff --git a/test/main/resolve-options/normalize.spec.mjs b/test/main/resolve-options/normalize.spec.mjs index 8ebd7e201..b9df4ff19 100644 --- a/test/main/resolve-options/normalize.spec.mjs +++ b/test/main/resolve-options/normalize.spec.mjs @@ -31,11 +31,11 @@ describe("[I] main/resolve-options/normalize", () => { expect(lNormalizedOptions.useSyncFileSystemCalls).to.equal(true); }); - it("does not add the typescript paths plugin to the plugins if a tsConfig is specified without a baseUrl", async () => { + it("does not add the typescript paths plugin to the plugins if no tsConfig is specified", async () => { const lNormalizedOptions = await normalizeResolveOptions( {}, normalizeCruiseOptions({ - ruleSet: { options: { tsConfig: { fileName: TEST_TSCONFIG } } }, + ruleSet: { options: {} }, }), lTsconfigContents ); @@ -44,7 +44,7 @@ describe("[I] main/resolve-options/normalize", () => { lDefaultNoOfResolveOptions ); expect(lNormalizedOptions.symlinks).to.equal(false); - expect(lNormalizedOptions.tsConfig).to.equal(TEST_TSCONFIG); + expect(lNormalizedOptions.tsConfig).to.equal(null); expect(lNormalizedOptions.combinedDependencies).to.equal(false); expect(lNormalizedOptions).to.ownProperty("extensions"); expect(lNormalizedOptions).to.ownProperty("fileSystem"); @@ -52,6 +52,27 @@ describe("[I] main/resolve-options/normalize", () => { expect(lNormalizedOptions.useSyncFileSystemCalls).to.equal(true); }); + it("adds the typescript paths plugin to the plugins if a tsConfig is specified, even without a baseUrl", async () => { + const lNormalizedOptions = await normalizeResolveOptions( + {}, + normalizeCruiseOptions({ + ruleSet: { options: { tsConfig: { fileName: TEST_TSCONFIG } } }, + }), + lTsconfigContents + ); + + expect(Object.keys(lNormalizedOptions).length).to.equal( + lDefaultNoOfResolveOptions + 1 + ); + expect(lNormalizedOptions.symlinks).to.equal(false); + expect(lNormalizedOptions.tsConfig).to.equal(TEST_TSCONFIG); + expect(lNormalizedOptions.combinedDependencies).to.equal(false); + expect(lNormalizedOptions).to.ownProperty("extensions"); + expect(lNormalizedOptions).to.ownProperty("fileSystem"); + expect((lNormalizedOptions.plugins || []).length).to.equal(1); + expect(lNormalizedOptions.useSyncFileSystemCalls).to.equal(true); + }); + it("adds the typescript paths plugin to the plugins if a tsConfig is specified with a baseUrl and actual paths", async () => { const lNormalizedOptions = await normalizeResolveOptions( {},