问题及原因
前几天项目出现了一个问题,在某些客户的机器上前端网页直接白屏什么都不显示。远程过去 f12 后控制台报错如下:
unpkg.com/vue@2.6.10/dist/vue.min.js Failed to load resource: net::ERR_TIMED_OUT
unpkg.com/lodash@4.17.11/lodash.js Failed to load resource: net::ERR_CONNECTION_TIMED_OUT
pro.vendor.0717c650.js:12 Uncaught ReferenceError: Vue is not defined
at Object.<anonymous> (.vendor.0717c650.js:12)
at c (pro.manifest.ab17da1a.js:1)
at Object.<anonymous> (pro.vendor.0717c650.js:434)
at e (pro.vendor.0717c650.js:434)
at Object.<anonymous> (pro.vendor.0717c650.js:434)
at e (pro.vend
一看到这个 unpkg 就大致猜到了估计是网络原因导致了 unpkg.com 被墙了,从而下不下来依赖,自然就白屏了。然后直接把上面依赖链接复制到浏览器地址栏里回车,果然打不开。
解决方案
接下来解决就简单了,只需要在源码里找到用到unpkg
的地方,然后批量替换成国内 cdn 即可,然后全局搜了一下发现,裂开了,啥都没找到。

既然生产环境用到了,那肯定是在这个项目里不假,而源码里没有,自然先去编译过程里看一看。打开 package.json
,找到了编译都写在 build.js
里。

打开看了一下,果不其然,找到了罪魁祸首:
const cdn = new WebpackCdnPlugin({
modules: [
{ name: 'vue', var: 'Vue', path: 'vue.min.js' },
{ name: 'lodash', var: '_', path: 'lodash.js' }
]
})
原来,在编译的时候使用了webpackCdnPlugin
把 npm 安装的依赖转化为了 cdn 加载,这样在编译时就可以减少包体积并提高首屏加载速度。这个拓展的文档看这里:npmjs - webpack-cdn-plugin。而我这里的配置并没有指定下载源,自动的使用了默认的unpkg.com
,导致了问题的出现。
根据文档,添加了prodUrl
来指定下载源,最后修改结果如下:
const cdn = new WebpackCdnPlugin({
modules: [
{ name: 'vue', var: 'Vue', path: 'vue/2.6.11/vue.min.js' },
{ name: 'lodash', var: '_', path: 'lodash.js/4.17.15/lodash.js' }
],
prodUrl: '//cdn.bootcdn.net/ajax/libs/:path'
})
实际上更推荐在prodUrl
中使用:name
、:version
等占位符,但是 bootcdn 里的 lodash 下载地址和想象中的有些出入,如果使用//cdn.bootcdn.net/ajax/libs/:name/:version/:path
组装依赖地址的话就会出现下面的问题:
- 正确地址:
https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.15/lodash.js
- 拼接地址:
https://cdn.bootcdn.net/ajax/libs/lodash/4.17.15/lodash.js
而 modules 属性中的 name 字段则代表着要外部化的模块名称,如果改成lodash.js
的话会在编译的时候报错找不到 lodash.js 模块。并且我在文档里没找到哪里可以配置具体的版本号,无奈之下只能把这些信息都写在path
里一并组装,倒也不影响可读性。
网友评论