Webpack SSR场景嵌套Vue3+TS项目相对导入查找错误子目录问题
核心问题定位
从你提供的Webpack verbose日志可以直接定位两个核心问题:
- 抛出
./App找不到报错的代码来源,根本不是src/main.ts,而是src/views/Home.vue内部的导入语句。Home.vue本身存放在src/views目录下,按照相对路径的解析规则,写import App from './App'时,Webpack自然会在当前文件所在的src/views目录下查找文件,完全不会跳转到上一级的src根目录匹配App.ts,这也是日志里显示查找路径是src/views的根本原因。 - 你自定义的
webpack.server.js完全没有对齐Vue CLI生成项目的默认编译逻辑,缺失了三类核心配置,导致别名、TS文件解析全部失效:- 没有手动配置
@路径别名的映射规则——Webpack本身不会自动读取tsconfig.json里的paths配置,自然会把@/App当成第三方模块去node_modules目录下查找 - 没有给
.ts/.tsx后缀的文件配置对应的ts-loader解析规则 - 没有配置模块查找的根路径范围,进一步放大了别名解析的错位问题
- 没有手动配置
分步骤修复方案
- 第一步:修正源码内的错误导入路径
打开src/views/Home.vue文件,找到写为import App from './App'的语句,修改为import App from '../App',这一步可以直接解决日志里抛出的路径解析错位报错。 - 第二步:补全
webpack.server.js的缺失配置
替换原有配置的核心模块,补上别名映射、TS解析、模块查找范围的配置:const path = require('path') const nodeExternals = require('webpack-node-externals') const { VueLoaderPlugin } = require('vue-loader') module.exports = { entry: './server/index.js', target: 'node', externals: [nodeExternals()], output: { path: path.resolve('server-build'), filename: 'index.js', }, resolve: { // 保留原有后缀解析规则 extensions: ['.tsx', '.ts', '.js', '.jsx', '.css', '.scss', '.sass', '.vue'], alias: { // 手动配置@别名映射,和my-vue-app内的tsconfig配置对齐 '@': path.resolve(__dirname, 'my-vue-app/src') }, // 明确模块查找范围,避免@被识别为node_modules下的第三方包 modules: [ path.resolve(__dirname, 'node_modules'), path.resolve(__dirname, 'my-vue-app/node_modules') ] }, plugins: [new VueLoaderPlugin()], module: { rules: [ { test: /\.vue$/, loader: 'vue-loader', }, // 补上TS文件解析规则,原来的配置完全缺失这部分 { test: /\.tsx?$/, loader: 'ts-loader', exclude: /node_modules/, options: { // 指定ts-loader读取my-vue-app目录下的tsconfig,避免读根目录的错误配置 configFile: path.resolve(__dirname, 'my-vue-app/tsconfig.json'), appendTsSuffixTo: [/\.vue$/] } }, { test: /\.jsx?$/, loader: 'babel-loader', exclude: /node_modules/, options: { presets: ['@babel/preset-env'], }, }, ], }, }; - 第三步:修正Babel配置的路径错误
原有my-vue-app/babel.config.js里的extends: '../.babelrc'存在路径匹配错误:根目录的配置文件是带.json后缀的.babelrc.json,不是无后缀的.babelrc,需要改成正确的引用路径。同时删掉原有配置里多余的React相关预设(@babel/preset-react、@babel/plugin-transform-react-jsx),这些配置会干扰Vue单文件组件的正常编译:// my-vue-app/babel.config.js module.exports = { extends: '../.babelrc.json', presets: [ '@vue/cli-plugin-babel/preset' ] } - 第四步:清理根目录tsconfig的干扰
根目录下的tsconfig.json存在两个问题:一是把@/*的映射路径写为不存在的vue-platform-app/src/*,二是因为已经通过ts-loader指定了读取my-vue-app下的tsconfig,这个根目录的配置对Server端打包是多余的。可以选择直接删除这个根目录的tsconfig,或者把里面的paths配置修正和my-vue-app/tsconfig.json保持一致,避免ts-loader读取到错误的路径映射。
原绝对路径写法可正常运行的原因
绝对路径的写法绕过了Webpack所有的相对路径解析、别名匹配的规则,直接定位到文件实体,自然不会出现解析错位。当上述配置补全后,所有相对路径、@别名的导入写法都可以正常生效,不需要再依赖硬编码的绝对路径,也不会因为导入TS文件触发额外的报错。
内容的提问来源于stack exchange,提问作者Geza Kerecsenyi
相关产品推荐
相关产品推荐

