Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Convert TypeScript tsconfig paths to webpack alias paths
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
}),
}
}
@chrisabrams

This comment has been minimized.

Copy link

@chrisabrams chrisabrams commented Aug 14, 2018

I can confirm this worked for me!

@Paradoxia

This comment has been minimized.

Copy link

@Paradoxia Paradoxia commented Sep 23, 2018

I use IntelliJ and it uses tsconfig.json to resolve stuff in the IDE. Your code works perfectly. Thank you very much :)

@eralvarez

This comment has been minimized.

Copy link

@eralvarez eralvarez commented Dec 16, 2018

this worked for me too, thx!

@bndynet

This comment has been minimized.

Copy link

@bndynet bndynet commented Jan 7, 2019

Great! I look for it some days.

@ridaamirini

This comment has been minimized.

Copy link

@ridaamirini ridaamirini commented Feb 20, 2019

+1

@adjiganoff

This comment has been minimized.

Copy link

@adjiganoff adjiganoff commented May 27, 2019

Working, yay!

@arzyu

This comment has been minimized.

Copy link

@arzyu arzyu commented Sep 10, 2019

@UberMouse

This comment has been minimized.

Copy link

@UberMouse UberMouse commented Oct 2, 2019

One problem I encountered, if you have an alias such as "root" which is aliased to the root of your source code. Set up like this
"root": ["*"]
Then it will incorrectly be expanded to ${webpackConfigBasePath}/* instead of ${webpackConfigBasePath}. This can be fixed by appending .replace("*", "") to line 19

@nerdyman

This comment has been minimized.

Copy link
Owner Author

@nerdyman nerdyman commented Oct 3, 2019

Is that a common use case UberMouse? I haven't seen root aliased by * before, would using * not include node_modules too?

Usually, I use "Root/*": ["src/*"].

Also, glad people found this useful! 😄

@UberMouse

This comment has been minimized.

Copy link

@UberMouse UberMouse commented Oct 3, 2019

It's probably not, just a quirk of how ours are setup (our path prefixes point directly to src/ in your example, not to the folder containing src).

Definitely useful, I used to maintain three mappings. One for tsconfig, one for jest and one for Webpack. I set this up yesterday and a Jest equivalent the other day so now I just need to maintain one set of mapping which is great.

@nicolad

This comment has been minimized.

Copy link

@nicolad nicolad commented Feb 6, 2020

Works great, many thx @nerdyman

@phuctm97

This comment has been minimized.

Copy link

@phuctm97 phuctm97 commented Apr 12, 2020

Great idea! Thank you!

However, there're couple of things can be improved. I wrote my modification which helps improve:

  • Handle and ignore cases in which paths.values is empty.
  • Cleaner code as it's written in a more declarative manner.
  • More performant as it doesn't alter the object, instead it returns a constant which can be cached by either Node.js or Webpack.

See https://gist.github.com/phuctm97/7470a3b981fd80a501b4047e1e99a9f4 for more details or appreciation. Thank you!

const path = require('path');

/**
 * Helper function infers Webpack aliases from tsconfig.json compilerOptions.baseUrl and
 * compilerOptions.paths.
 *
 * @param {string} tsconfigPath - Path to tsconfig.json (Can be either relative or absolute path).
 * @return {object} An object representing corresponding Webpack alias.
 */
module.exports = (tsconfigPath = './tsconfig.json') => {
  const tsconfig = require(tsconfigPath);
  const { paths, baseUrl } = tsconfig.compilerOptions;

  return Object.fromEntries(Object.entries(paths)
    .filter(([, pathValues]) => pathValues.length > 0)
    .map(([pathKey, pathValues]) => {
      const key = pathKey.replace('/*', '');
      const value = path.resolve(path.dirname(tsconfigPath),
        baseUrl, pathValues[0].replace('/*', ''));
      return [key, value];
    }));
};
@jraoult

This comment has been minimized.

Copy link

@jraoult jraoult commented Apr 29, 2020

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.

@cdpark0530

This comment has been minimized.

Copy link

@cdpark0530 cdpark0530 commented Dec 31, 2020

At lease tsconfig-paths-webpack-plugin doesn't work with webpack:^5:11.1 as it seems now.
I really appreciate this @nerdyman

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.