-
-
Save nerdyman/2f97b24ab826623bff9202750013f99e to your computer and use it in GitHub Desktop.
const { resolve } = require('path'); | |
/** | |
* Resolve tsconfig.json paths to Webpack aliases | |
* @param {string} tsconfigPath - Path to tsconfig | |
* @param {string} webpackConfigBasePath - Path from tsconfig to Webpack config to create absolute aliases | |
* @return {object} - Webpack alias config | |
*/ | |
function resolveTsconfigPathsToAlias({ | |
tsconfigPath = './tsconfig.json', | |
webpackConfigBasePath = __dirname, | |
} = {}) { | |
const { paths } = require(tsconfigPath).compilerOptions; | |
const aliases = {}; | |
Object.keys(paths).forEach((item) => { | |
const key = item.replace('/*', ''); | |
const value = resolve(webpackConfigBasePath, paths[item][0].replace('/*', '').replace('*', '')); | |
aliases[key] = value; | |
}); | |
return aliases; | |
} | |
module.exports = resolveTsconfigPathsToAlias; |
{ | |
"compilerOptions": { | |
"module": "commonjs", | |
"moduleResolution": "node", | |
"outDir": "./dist", | |
"allowJs": true, | |
"target": "es6", | |
"jsx": "react", | |
"sourceMap": true, | |
"noImplicitAny": true, | |
"strictNullChecks": true, | |
"baseUrl": "./", | |
"lib": [ | |
"DOM", | |
"ES5", | |
"ES6", | |
"es2017.object" | |
], | |
"paths": { | |
"Root/*": ["src/*"], | |
"Components/*": ["src/components/*"], | |
"Data/*": ["src/data/*"], | |
} | |
}, |
import Banner from 'Components/banner'; |
// add paths to webpack | |
const resolveTsconfigPathsToAlias = require('./resolve-tsconfig-path-to-webpack-alias'); | |
module.exports = { | |
// ... | |
resolve: { | |
// ... | |
alias: resolveTsconfigPathsToAlias({ | |
tsconfigPath: '../tsconfig.json', // Using custom path | |
webpackConfigBasePath: '../', // Using custom path | |
}), | |
} | |
} |
At lease tsconfig-paths-webpack-plugin doesn't work with webpack:^5:11.1 as it seems now.
I really appreciate this @nerdyman
Not sure you folks are aware of this https://www.npmjs.com/package/tsconfig-paths-webpack-plugin. May be it can help someone in the future.
this plugins replaces the context of resolve.alias object so u will not be able to add any custom aliases to your webpack configuration, and will be left in hands with only the one mentioned in tsconfig - what is kinda .... complicated )
@MisaGu Have you heard of the spread operator?
// add paths to webpack
const resolveTsconfigPathsToAlias = require('./resolve-tsconfig-path-to-webpack-alias');
module.exports = {
// ...
resolve: {
// ...
alias: {
...resolveTsconfigPathsToAlias({
tsconfigPath: '../tsconfig.json', // Using custom path
webpackConfigBasePath: '../', // Using custom path
}),
Utilities: path.resolve(__dirname, 'src/utilities/'),
Templates: path.resolve(__dirname, 'src/templates/'),
}
}
}
@nerdyman It seems to me that this gist is missing the baseUrl
. I had to edit to this to get it working.
const { resolve } = require('path');
/**
* Resolve tsconfig.json paths to Webpack aliases
* @param {string} tsconfigPath - Path to tsconfig
* @param {string} webpackConfigBasePath - Path from tsconfig to Webpack config to create absolute aliases
* @return {object} - Webpack alias config
*/
function resolveTsconfigPathsToAlias({
tsconfigPath = './tsconfig.json',
webpackConfigBasePath = __dirname,
} = {}) {
const { paths, baseUrl } = require(tsconfigPath).compilerOptions;
const aliases = {};
Object.keys(paths).forEach((item) => {
const key = item.replace('/*', '');
const value = resolve(webpackConfigBasePath, baseUrl, paths[item][0].replace('/*', '').replace('*', ''));
aliases[key] = value;
});
return aliases;
}
module.exports = resolveTsconfigPathsToAlias;
there is an issue in this configuration, because the first matched alias is selected instead of the most specific one
@its-dibo moved more specific first in the tsconfig paths as a workaround...
Hi!
There will be an error if the file does not have the 'paths' section
- [webpack-cli] TypeError: Cannot convert undefined or null to object
There will be an error if there is an extra comma or comment
- [webpack-cli] SyntaxError: tsconfig.json: Unexpected token ']', ..."*",},
"... is not valid JSON
Here is the solution. I'll leave it here, maybe someone will find it useful.
// tsconfig.json
{
"compilerOptions": {
// comment
"paths": {
"Root/*": ["src/*",],
"Components/*": ["src/components/*",],
"Data/*": ["src/data/*",],
}
},
}
// tsconfig-paths.mjs
import { dirname, resolve } from 'node:path';
import ts from 'typescript';
/** @typedef {Record<"compilerOptions", ts.server.protocol.CompilerOptions>} CompilerOptions */
const tsParsedCmd =
/** @type {Record<"raw", CompilerOptions>} */
(
ts.getParsedCommandLineOfConfigFile('tsconfig.json', undefined, {
...ts.sys,
onUnRecoverableConfigFileDiagnostic(diagnostic) {
throw new Error(`${diagnostic.messageText}`);
},
})
);
export function tsconfigPaths() {
const res = /** @type {ts.MapLike<string[]>} */ ({});
const { paths } = tsParsedCmd.raw.compilerOptions;
if (paths) {
for (const k of Object.keys(paths)) {
const val = paths[k];
res[dirname(k)] = val.map((path) => {
return resolve(process.cwd(), dirname(path));
});
}
}
return res;
}
// webpack.config.mjs
/** @type {import("webpack").Configuration} */
export default {
resolve: {
alias: tsconfigPaths(),
},
}
Not sure you folks are aware of this https://www.npmjs.com/package/tsconfig-paths-webpack-plugin. May be it can help someone in the future.