Getting module aliases working with @wordpress/scripts, Webpack, Typescript & ESLint
When working on a larger plugin, theme or other project using the @wordpress/scripts library (or likely any Webpack based toolkit), you may find you want to stop using relative paths and start treating your code like proper packages.
This is handled by resolvers typically, but in this scenario, to get all of the tooling speaking the same language, it requires changes to multiple configurations.
Following most guides online I was able to resolve one issue after another, so I figured I would share my experience, the problems I faced and the solutions that brought it together.
The usual recommendations start with adding something like a "paths"
object to your tsconfig.json
file unfortunately that doesn’t work out of the box on its own with your IDE or the greater wp-scripts build
routines. It takes multiple changes to get it all respecting your custom aliases.
The examples below are based on real code, with files structured as
- src
- components
- controlled-tab-panel
-index.tsx
- settings-page
- container
- index.tsx
And we want to switch from
import TabPanel from '../../components/controlled-tab-panel';
To something simple such as
import TabPanel from '@components/controlled-tab-panel';
Problems this helps solve.
Typescript Error: Cannot find module ‘@components/controlled-tab-panel’ or its corresponding type declarations.ts(2307)
ESLint Issues in VS Code: Unable to resolve path to module ‘@components/controlled-tab-panel’.eslintimport/no-unresolved
Webpack builds fail: Module not found: Error: Can’t resolve ‘@components/controlled-tab-panel’
Get resolvers working in Typescript
First up get it working in Typescript. Edit your tsconfig.json
, make sure “baseUrl” is set and add a “paths” object that includes aliases and their src path. Assuming the example setup described above.
{
"compilerOptions": {
"baseUrl": "./src",
"paths": {
"@components/*": [
"components/*"
]
},
}
}
Get wp-scripts/ Webpack builds working again.
If you haven’t already extend the default WP config with your own.
Modify your config accordingly like so.
// defaultConfig references imported base config from @wordpress/scripts
{
resolve: {
...defaultConfig.resolve,
alias: {
...defaultConfig.resolve.alias,
// add as many aliases as you like!
'@components': path.resolve( __dirname, 'src/components' ),
},
},
}
Fix eslint issues with the same resolvers
With the above, everything technically “works”, but the IDE (VS Code for me) still shows warnings from linting, and wp-scripts linter will throw those same issues.
The first thing you need to do is make your life easier, install eslint-import-resolver-webpack
. I also have eslint-plugin-import
set up before, so not sure if it was part of the overall solution or not. Further our config extends the plugin:@wordpress/eslint-plugin/recommended
library.
Merge the following into your .eslintrc.js
or similar file.
{
settings: {
'import/resolver': {
webpack: {
config: 'webpack.config.js',
},
}
}
}
The above simply maps your current working webpack resolver config to also be used for eslint.
Hope that helps someone out there, took me hours to work out all the individual issues and solutions.
I am a founder & CEO of Code Atlantic and I've been working with WordPress for over 15 years creating plugins to help WP site owners grow for more than 10 of those. We have developed and maintained popular plugins including the best wordpress popup plugin, Popup Maker with over 4k 5 star reviews, as well as Content Control, Ahoy & User Menus.