背景
项目本地可以正常运行,但是打包发布生产后,点击所有菜单均报错打不开:比如Error: Cannot find module '@/views/system/role/index'
原因分析
报错 Error: Cannot find module '@/views/system/role/index' 的核心原因是:缺少文件后缀名 .vue。
- 生产环境 (Production) 的行为:
- 代码使用了
import('@/views/' + view)进行动态导入。 - Webpack 在打包时,会扫描 views 目录,生成一张映射表(Context Map)。这张表里的键(Key)通常是包含文件后缀的完整相对路径,例如
./system/role/index.vue。 - 当代码运行时,传入的 view 变量是
system/role/index(来自后端数据库)。 - Webpack 尝试用
system/role/index去匹配映射表中的./system/role/index.vue。由于字符串不完全一致(缺少.vue),匹配失败,从而抛出Cannot find module错误。
- 代码使用了
- 本地开发环境 (Development) 为什么正常?
babel.config.js中配置了dynamic-import-node插件,且仅在 development 模式下生效。- 这个插件会将 import() 语法转换为 Node.js 风格的 require()。
- require() 机制非常宽容,它会自动尝试补全
.js,.vue,.json等后缀,所以即使路径里没有写.vue,它也能找到文件。
解决方案
这是一个纯粹的路径匹配问题。可以在 import 路径中显式补全 .vue 后缀。
export const loadView = (view) => {
if (process.env.NODE_ENV === 'development') {
return (resolve) => require([`@/views/${view}`], resolve)
} else {
// 修改前:return () => import(`@/views/${view}`)
// 修改后:显式添加 .vue 后缀
return () => import(`@/views/${view}.vue`)
}
}
或者参考官方方案:如何手动配置路由传参