一般来说,在项目中我们都会使用路径别名来简化模块引用,例如:
import { Button } from '@/components/Button'
路径别名固然是非常好,但是在项目中却需要在多处指定,即使你的项目足够简单,只要用了 TypeScript 基本上也需要指定两次。
例如使用 Webpack + TypeScript,需要在 webpack.config.js
和 tsconfig.json
中分别指定。
module.exports = {
// 其他配置
resolve: {
alias: {
'@': path.resolve(__dirname, 'src')
}
}
}
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
}
}
}
如果使用 Vite 也是要在 vite.config.ts
和 tsconfig.json
中指定。
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
resolve: {
alias: {
'@': path.resolve(__dirname, 'src')
}
}
})
多处指定就有可能漏写导致出错,当然我们可以通过 tsconfig-paths-webpack-plugin
和 vite-tsconfig-paths
分别来解决别名统一的问题。
import { defineConfig } from 'vite'
import tsconfigPaths from 'vite-tsconfig-paths'
export default defineConfig({
// 使用这个插件,插件会自动读取 tsconfig.json 中的配置。
plugins: [tsconfigPaths()]
// 其他配置...
})
但是现在我们有一种无需依赖第三方库即可配置路径别名的方法。而且这种方法允许使用别名而不需要构建步骤,重要的是一处指定,四处生效。
原生路径别名
从 Node.js v12.19.0
开始,开发人员可以使用 Subpath Imports 在 npm 包中声明路径别名。这可以通过 package.json
文件中的 imports 字段来完成。
不需要在 npm 上发布包。在任何目录中创建一个 package.json
文件就足够了。因此,这种方法也适用于私人项目。
my-awesome-project
├── src/
│ ├── components/
│ │ └── searchForm/
│ │ └── form/
│ │ └── index.ts
│ ├── pages/
│ │ └── login/
│ │ └── about/
│ │ └── home/
│ └── mock/
│ └── api/
│ └── index.ts
└── package.json
{
"name": "my-awesome-project",
"imports": {
"#*": "./*"
}
}
import { SearchForm } from '#src/components/searchForm'
使用原生路径别名的好处理论上有如下优点:
- 无需安装任何第三方库
- 无需预先构建或动态处理导入即可运行代码
- 任何使用 ESM 标准导入且基于 Node.js 的工具都支持别名
- 代码导航和自动完成编辑器默认支持,而不需要任何额外的设置
其他工具的支持情况
Webpack
Webpack 从 v5.0 开始支持导入字段。路径别名无需任何额外配置即可使用。
Vite
Vite 4.2.0 版本添加了对导入字段的支持。