Webpack 无法解析 node_modules 个惰性资产
Webpack Cannot Resolve node_modules lazy assets
我正在开发一个 vuejs 项目,我们正在尝试使用外部 vue cli 应用程序作为库。在这些库中,我们希望能够导出一个路由器配置,它可以延迟加载其中一个模块中的组件。然而,当我们使用 vue-cli-service 将它编译成一个库时,它有惰性块资产,我们无法使用 webpack 解析它们。
我感觉它与 public 路径或一些简单的配置有关,但在这个阶段我只是卡住了,用头撞墙。
https://github.com/EvanBurbidge/mono-repo-tester
这是我们正在做的事情的简单概述
App1 -> main app, installs App2, imports { router } from 'app2'
App2 -> library, compiles to common js lib exports router config
app1 的控制台输出
来自 app2 的路由器配置
从 app1 导入 app2 的路由器
/* config.module.rule('js') */
{
test: /\.jsx?$/,
exclude: [
function () { /* omitted long function */ }
],
use: [
/* config.module.rule('js').use('cache-loader') */
{
loader: 'cache-loader',
options: {
cacheDirectory: '/Users/evan/test/node_modules/.cache/babel-loader',
cacheIdentifier: '39e7e586'
}
},
/* config.module.rule('js').use('babel-loader') */
{
loader: 'babel-loader'
}
]
},
我想我知道问题出在哪里了。
看来您正遭受这样一个事实,即与 VueJS 捆绑在一起的 webpack 的默认配置不支持您试图完成的任务。事实上,很可能 Webpack 不支持你想要完成的 #2471 #6818 #7843.
当您将 app2 编译到 UMD 中并尝试通过导入 UMD 在 app1 中使用它时,app2 的动态导入未被解析,因此不会复制到 app1 的 publicPath
。由于它是动态导入,编译成功到可以部署应用程序的程度。但是,当您尝试加载应用程序时,它开始抱怨缺少块。
这是解决此问题的一种方法:
app2/package.json
{
"name": "app2",
...
"main": "src/router.js"
}
app2/src/router.js
const Hey = () => import(/*webpackChunkName: 'app2.Hello.vue' */ './components/HelloWorld.vue')
export default [
{
path: '/app2',
component: Hey,
name: 'app2.hey'
}
]
app1/router.js
import app2Router from 'app2'
import Home from './views/Home.vue'
export default new Router([
mode: 'history',
...
routes: [
{
path: '/',
name: 'home',
component: Home
},
...app2Router
]
])
通过将 app2/package.json
的 main
或 module
标记为 router.js
而不是 UMD 包,您将强制 app1 构建整个依赖关系图并包括检测到的任何动态导入。这反过来又会导致依赖项被正确复制。
您也可以使用
获得完全相同的结果
import app2Router from 'app2/src/router'
据推测,此问题现已在 Webpack 5 中修复https://github.com/webpack/webpack/issues/11127
我正在开发一个 vuejs 项目,我们正在尝试使用外部 vue cli 应用程序作为库。在这些库中,我们希望能够导出一个路由器配置,它可以延迟加载其中一个模块中的组件。然而,当我们使用 vue-cli-service 将它编译成一个库时,它有惰性块资产,我们无法使用 webpack 解析它们。
我感觉它与 public 路径或一些简单的配置有关,但在这个阶段我只是卡住了,用头撞墙。
https://github.com/EvanBurbidge/mono-repo-tester
这是我们正在做的事情的简单概述
App1 -> main app, installs App2, imports { router } from 'app2'
App2 -> library, compiles to common js lib exports router config
app1 的控制台输出
/* config.module.rule('js') */ { test: /\.jsx?$/, exclude: [ function () { /* omitted long function */ } ], use: [ /* config.module.rule('js').use('cache-loader') */ { loader: 'cache-loader', options: { cacheDirectory: '/Users/evan/test/node_modules/.cache/babel-loader', cacheIdentifier: '39e7e586' } }, /* config.module.rule('js').use('babel-loader') */ { loader: 'babel-loader' } ] },
我想我知道问题出在哪里了。
看来您正遭受这样一个事实,即与 VueJS 捆绑在一起的 webpack 的默认配置不支持您试图完成的任务。事实上,很可能 Webpack 不支持你想要完成的 #2471 #6818 #7843.
当您将 app2 编译到 UMD 中并尝试通过导入 UMD 在 app1 中使用它时,app2 的动态导入未被解析,因此不会复制到 app1 的 publicPath
。由于它是动态导入,编译成功到可以部署应用程序的程度。但是,当您尝试加载应用程序时,它开始抱怨缺少块。
这是解决此问题的一种方法:
app2/package.json
{
"name": "app2",
...
"main": "src/router.js"
}
app2/src/router.js
const Hey = () => import(/*webpackChunkName: 'app2.Hello.vue' */ './components/HelloWorld.vue')
export default [
{
path: '/app2',
component: Hey,
name: 'app2.hey'
}
]
app1/router.js
import app2Router from 'app2'
import Home from './views/Home.vue'
export default new Router([
mode: 'history',
...
routes: [
{
path: '/',
name: 'home',
component: Home
},
...app2Router
]
])
通过将 app2/package.json
的 main
或 module
标记为 router.js
而不是 UMD 包,您将强制 app1 构建整个依赖关系图并包括检测到的任何动态导入。这反过来又会导致依赖项被正确复制。
您也可以使用
获得完全相同的结果import app2Router from 'app2/src/router'
据推测,此问题现已在 Webpack 5 中修复https://github.com/webpack/webpack/issues/11127