Rollup+TS环境下,如何用tsconfig paths实现Svelte文件绝对导入?
Svelte+Rollup+TypeScript中tsconfig paths解析*.svelte文件的问题解决
问题背景
尝试将Svelte+Rollup+TypeScript项目中的相对导入改为使用tsconfig paths的绝对导入,但解析.svelte文件时出现依赖未解析的错误。
当前配置
tsconfig.json
{ "extends": "@tsconfig/svelte/tsconfig.json", "compilerOptions": { "baseUrl": ".", "lib": [ "dom", "es2020" ], "paths": { "~/*": [ "src/*" ] }, "strict": true }, "include": [ "src/**/*" ], "exclude": [ "node_modules/*", "public/*" ] }
rollup.config.js 片段
import commonjs from "@rollup/plugin-commonjs"; import resolve from "@rollup/plugin-node-resolve"; import typescript from "@rollup/plugin-typescript"; // ... plugins: [ // ... resolve({ browser: true, dedupe: ["svelte"], }), commonjs(), typescript({ sourceMap: !production, inlineSources: !production, }), // ... ],
src/App.svelte 导入代码
<script lang="ts"> import Test from '~/Test.svelte'; // 报错的导入方式 //import Test from './Test.svelte'; // 相对导入可正常工作 </script> <Test />
错误信息
Rollup构建警告
$ rollup -c -w rollup v2.44.0 bundles src/main.ts → public\build\bundle.js... LiveReload enabled on port 35730 (!) Unresolved dependencies https://rollupjs.org/guide/en/#warning-treating-module-as-external-dependency ~/Test.svelte (imported by src\App.svelte) (!) Missing global variable name Use output.globals to specify browser global variable names corresponding to external modules ~/Test.svelte (guessing 'Test') created public\build\bundle.js in 845ms
浏览器运行时错误
Uncaught ReferenceError: Test is not defined at bundle.js:367:3
可行解决方法
方法1:通过插件自动读取tsconfig paths
由于Rollup本身不会识别tsconfig中的paths配置,而.svelte文件的导入由Rollup的resolve插件处理,因此需要用@rollup/plugin-alias配合tsconfig-paths插件自动同步路径配置:
- 安装依赖:
npm install @rollup/plugin-alias tsconfig-paths --save-dev
- 修改rollup.config.js:
import alias from "@rollup/plugin-alias"; import { loadConfig } from 'tsconfig-paths'; // 加载tsconfig中的paths配置并转换为Rollup别名格式 const tsConfig = loadConfig(); const aliasEntries = Object.entries(tsConfig.paths).map(([find, replacements]) => ({ find: find.replace('/*', ''), // 移除通配符,如把"~/*"转为"~" replacement: replacements[0].replace('/*', '') // 把"src/*"转为"./src" })); export default { // ...其他配置 plugins: [ alias({ entries: aliasEntries }), // 必须放在resolve插件之前 resolve({ browser: true, dedupe: ["svelte"], }), commonjs(), typescript({ sourceMap: !production, inlineSources: !production, }), // ...其他插件 ], };
方法2:手动配置Rollup别名
如果不想额外安装依赖,可以直接手动在Rollup中配置与tsconfig paths对应的别名:
- 安装
@rollup/plugin-alias:
npm install @rollup/plugin-alias --save-dev
- 修改rollup.config.js:
import alias from "@rollup/plugin-alias"; export default { // ...其他配置 plugins: [ alias({ entries: [ { find: '~', replacement: './src' } ] }), resolve({ browser: true, dedupe: ["svelte"], }), // ...其他插件 ], };
问题原因说明
TypeScript的paths配置仅对TypeScript编译器的模块解析生效,而.svelte文件中的导入语句是由Rollup的resolve插件处理的,Rollup本身不会读取tsconfig的路径规则。@rollup/plugin-typescript仅负责编译TypeScript代码,不会修改或处理.svelte文件中的导入解析,因此必须单独为Rollup配置别名来匹配tsconfig的paths规则。
内容的提问来源于stack exchange,提问作者Evgeny A.
相关产品推荐
相关产品推荐

