Currently, cli-plugin-typescript creates tsconfig.json with aliases setup that repeats vue-cli's webpack aliases, namely:
"baseUrl": ".",
"paths": {
"@/*": [
"src/*"
]
}
If a developer changes or extends this setup, the code will fail to compile with webpack (because webpack ignores tsconfig.json and uses its own resolve.aliases setup).
Changing the defaults is not the edge case, but rather a probable scenario because the default setup is far from ideal for real use: "baseUrl": "." pollutes the root Node.js module namespace with everything that happens to reside in the project root. For example, in my project I switch it to this:
"baseUrl": "./src",
"paths": {
"@/*": [
"myproject/*"
]
},
To complete that setup, the developer is forced to put alias updates in two files: tsconfig.json and vue.config.js under chainWebpack and keep them synchronised.
Misleading tsconfig.json setup that can't really be changed without changing its webpack counterpart, and having to support two aliases setups is the problem that I propose to solve.
https://github.com/dividab/tsconfig-paths-webpack-plugin allows webpack to pull aliases setup from tsconfig.json and make it the single source of truth. It can be enabled like this in vue.config.js:
module.exports = {
chainWebpack(config) {
config.resolve.alias.delete("@")
config.resolve
.plugin("tsconfig-paths")
.use(require("tsconfig-paths-webpack-plugin"))
},
}
I propose to make this the default setup when cli-plugin-typescript is used. At the very least, this recipe should be added to the documentation in a new chapter that explains that changing tsconfig paths is not possible without updating webpack setup.
From the end-user point of view, nothing will change. The defaults will be the same. However, should user modify tsconfig baseUrl/paths, everything will transparently continue to work in webpack.
Nice Suggestion.
But I have a few doubts:
Honestly, both are fair points and I can't really argue. So I'll understand if you just wontfix this issue.
Still, my observations on the above:
I believe Typescript folks are get used to using tsconfig, so if it's clearly documented it's not going to be a problem. After all, tsconfig can be considered a first class language-native setup, and webpack becoming dependent on it is nothing unusual. But, again, I agree that it's backwards incompatible and somewhat confusing.
ts-jest provides the built-in moduleNameMapper helper for this case: https://kulshekhar.github.io/ts-jest/user/config/#paths-mapping — I'm not sure if it can be easily enabled with vue-cli or not. (Personally, I hate Jest in particular because it introduces one more babel bundler, and because of its other injected magic. I switched to node-tap which is language-agnostic and free of any kind of magic and I couldn't be more happy.)
+1 for at least documenting the situation clearly. As a TS developer, I was bitten by this.
Actually as far as I can see the default paths property set in tsconfig.json does not seem to work at all, unless I add tsconfig-paths-webpack-plugin as described by @IlyaSemenov.
Actually as far as I can see the default paths property set in tsconfig.json does not seem to work at all
What happens thatmakes you say that?
In mine it works fine.
After running vue create, I added my own paths to tsconfig.json. npm run serve resulted in an import error that should have been resolved by the new paths. Adding tsconfig-paths-webpack-plugin and @IlyaSemenov's vue.config.js example worked for me.
I assume plugins can present installation options? Maybe this should be an installation option?
Just my 0,02: also bitten by this with TS, spent hours today trying to figure out why tsconfig paths were being ignored and only figured out there was a problem with trial and error (ultimately scaffolding a new project and seeing the same issue).
This requires documentation.
Also thanks @IlyaSemenov you saved me from a useless all-nighter.
@IlyaSemenov
Be attention that it works only for one record in tsconfig.json paths.