一个难题的价值不仅仅是难题本身,更加有收获的是解决它的过程。
这个bug在网上就可以搜索到解决的答案uglify 压缩报错问题及 es5-imcompatible-versions,建议看这篇文字之前可以先看上面的文章,直接看视频比较直观。如果看完上面的还没有解决,可以看我下面的解决过程。
Failed to minify the bundle. Error: index.a0a9eebd.js from UglifyJs
什么是 Error: index.a0a9eebd.js from UglifyJs ?
就是当我们运行roadhog build
完以后进行压缩的时候发生的错误,因为我们在webpack
默认打包的时候,一般都不会对node_modules
里面的包进行babel
的编译,所以业界有一个默认的规定是你发布包之前应该先把发布的包编译成es5
的代码,然后再发布上去。但是就是有一些包并不会遵守这条约定。
所以就造成我们打完包以后,包里有了es6
的代码,从而造成压缩的失败。
怎么解决?
在sorrycc
大佬的文章里已经提供了解决的办法。大家可以直接看视频比较直观。
升级roadhog
或者是Umi
到最新版。
打开下面的设置:
es5ImcompatibleVersions: true,
extraBabelIncludes:[
// "node_modules/chalk",
// "node_modules/ansi-styles",
// "node_modules/ansi-html",
]
es5ImcompatibleVersions
这个开关设置为true
的时候,roadhog
打包的时候会对node_modules
里的包进行检查,检查到有es5ImcompatibleVersions
里设置的 没有打包为es6
代码的包。就会对其进行编译。这样就不会出现上面的错误了。
打开以后还是无法解决怎么办呢?
这个时候你就需要自己找到这个包,然后把它添加到extraBabelIncludes
里,在打包的时候也会对这里设置的目录进行额外的编译。
那么应该怎么找到这个包呢?
我们看这个错误:
PS C:\Users\玉丽\Desktop\company_work\vitark-web-ui> npm run build
> vitark-web-ui@2.0.0-beta.1 build C:\Users\玉丽\Desktop\company_work\vitark-web-ui
> cross-env ESLINT=none roadhog build
Build completed in 33.772s
Failed to compile.
Failed to minify the bundle. Error: index.a0a9eebd.js from UglifyJs
Unexpected token: name (matches) [index.a0a9eebd.js:89727,5]
at doneHandler (C:\Users\玉丽\Desktop\company_work\vitark-web-ui\node_modules\af-webpack\lib\build.js:91:27)
// ...
Read more here: http://bit.ly/2tRViJ9
看上面的错误,在第二行,我们可以看到有标识,写着196155
,这个就是发生错误的地方。
我们通过上面的行数从打包的文件里找到那一行,
/***/ "FnaF":
/***/ (function(module, exports, __webpack_require__) {
"use strict";
const TEMPLATE_REGEX = /(?:\\(u[a-f\d]{4}|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi;
const STYLE_REGEX = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g;
const STRING_REGEX = /^(['"])((?:\\.|(?!\1)[^\\])*)\1$/;
const ESCAPE_REGEX = /\\(u[a-f\d]{4}|x[a-f\d]{2}|.)|([^\\])/gi;
发现这里确实是有es6
的代码。然后通过找到一个比较特别的方法,在node_modules
里搜索。
发现这一段代码是属于prettier
包的,prettier
包是一个工具包。不应该出现在打好的包里呀?
我这里很疑惑,还去请教了sorrycc
大佬。大佬告诉我说这是一个工具包,不应该出现在打包的包里。让我去排查一下。
然后我通过查看package-lock.json
文件,找到了引用它的位置。
发现在react-slick@0.23.2
中,它的dependencies
生产环境配置中居然引用了prettier
代码。我欣喜若狂,以为找到了我想要的答案。
然后我查看了react-slick
在node_modules
里的package.json
中的引用,果然是这样。
大家也可以通过npm view react-slick
这个命令来查看包的情况。
npm view react-slick
react-slick@0.23.2 | MIT | deps: 6 | versions: 89
React port of slick carousel
https://github.com/akiran/react-slick
keywords: slick, carousel, Image slider, orbit, slider, react-component
dist
.tarball: https://registry.npmjs.org/react-slick/-/react-slick-0.23.2.tgz
.shasum: 8d8bdbc77a6678e8ad36f50c32578c7c0f1c54f6
.integrity: sha512-fM6DXX7+22eOcYE9cgaXUfioZL/Zw6fwS6aPMDBt0kLHl4H4fFNEbp4JsJQdEWMLUNFtUytNcvd9KRml22Tp5w==
.unpackedSize: 322.1 kB
dependencies:
classnames: ^2.2.5 json2mq: ^0.2.0 prettier: ^1.14.3
enquire.js: ^2.1.6 lodash.debounce: ^4.0.8 resize-observer-polyfill: ^1.5.0
maintainers:
- akiran <kiran.coder0@gmail.com>
dist-tags:
latest: 0.23.2
published 5 months ago by akiran <kiran@neostack.com>
PS C:\Users\玉丽\Desktop\company_work\vitark-web-ui>
然后这个react-slick
是在antd
下面的引用。
哦哦,原来是因为你的原因。我去检查了react-slick
线上的发布的包,发现只有最新版0.23.2
中有这个问题。而在过去的发布的包中并没有引用prettier
。
我果断降级安装了npm install react-slick@0.23.1 --save dev
这个包。
现在项目里没有了引用prettier
的代码,应该不会报这个错误了。
为了保险起见,我把prettier
添加到了编译的数组里。
es5ImcompatibleVersions: true,
extraBabelIncludes:[
"node_modules/prettier",
]
打包,结果还是发生错误。
开始检查所有的引用连接,通过搜索prettier
发现非常多的包用到了这个prettier
,但是他们基本全都是在devDependencies
中。并没有发现在dependencies
中引用的代码。
我把prettier
这里包都删除掉了,结果还是能发现它的代码在里面,幽灵代码啊。
这个时候我想到了另一种解决思路,在文章中提到的可以通过babel 7
来编译node_modules
,通过升级发现roadhog 2.5
的最新版本是用的babel 7
,然后我设置了
es5ImcompatibleVersions: true,
extraBabelIncludes:[
"node_modules",
]
编译node_modules
下所有的包,顺利通过编译,没有报错。
但是,打出来的包有问题,甚至不能在谷歌浏览器里运行。说明在编译的时候对编译过的代码重新编译出现了错误。
还是绕不开这个问题。
怎么办?我想到了一个办法,手动编译,具体思路是这样。
设置编译所有的代码,也就是编译node_modules
里的代码。
es5ImcompatibleVersions: true,
extraBabelIncludes:[
"node_modules",
]
然后运行下面的命令,它会打包,但是不会压缩。
"builds": "cross-env ESLINT=none COMPRESS=none roadhog build",
运行完成以后拷贝出来,然后把上面的//"node_modules",
注释掉。
重新运行打包命令,然后找到上一次出问题的代码,把里面的es6的代码在我们第一次打包的文件中找到。
/***/ "FnaF":
/***/ (function(module, exports, __webpack_require__) {
"use strict";
可以搜索模块前面的字符串标识,Fnaf
来找到。然后替换。
在ie
浏览器中运行。
既然我们替换了es6
的代码,那么它就可以运行了,但是并没有,从ie
的报错里,我们找到报错的地方,发现又是一处新的es6
代码,按照之前的步骤,我们通过搜索关键字找到它的模块,然后把这个模块添加到
es5ImcompatibleVersions: true,
extraBabelIncludes:[
"node_modules/chalk",
"node_modules/ansi-styles",
"node_modules/ansi-html",
]
重新打包,找到新的错误代码,重复这个过程,直到找到所有的es6
的包。
就是这样,按个找到了这些模块。
这就是折磨了我好几天的这个bug
的解决过程。
还好最后解决了...在解决的过程还是学到很多东西的,也发现了之前自己认识上的不足。
嗯嗯,就这样。
有什么问题可以随时问我,关于这个错误的。
对这个问题的更新 按照这个步骤来就可以了!
发现其他的同事上面居然不能运行,不应该呀,通过上面的步骤按个找:
1.运行 npm run build
,
2.查看错误的行数,例如:119999
,
3.打开打包的.js
文件,
4.通过快捷键ctrl+G
跳转到119999
这一行,可以看到出问题的代码,
5.复制一行特别的代码(特别的代码就是不容易在其他的包里重复的)
6.在node_modules
里搜索这个代码。
7.顺利的话,你会定位到那个包,发现这个包里包含了ES6
的代码。
8.在extraBabelIncludes
里添加。
extraBabelIncludes:[
"node_modules/chalk",
"node_modules/ansi-styles",
"node_modules/ansi-html",
]
9.如果在搜索的时候发现有很多,你可能定位了很多的包,其实有可能是很多包都引用了同样的包,
然后再它们自己下面的node_modules
里维护。
10.解决办法就是用yarn add chalk
来安装这个包,yarn
会对包进行识别,如果很多包使用了同样的包,那么它会只维护一个包,而不是各自引用各自自己的。
11.当然你也可以添加不同的路劲,把它们都放进去就可以了。只要能找到。
2019年10月29日更新:
在最新的Umi
版本下的,改为这样处理:
es5ImcompatibleVersions: true,
extraBabelIncludes: [
require('path').resolve(__dirname, 'node_modules/swiper'),
require('path').resolve(__dirname, 'node_modules/chalk'),
require('path').resolve(__dirname, 'node_modules/ansi-styles'),
require('path').resolve(__dirname, 'node_modules/@babel/highlight'),
require('path').resolve(__dirname, 'node_modules/@babel/code-frame'),
require('path').resolve(__dirname, 'node_modules/eslint-plugin-react'),
require('path').resolve(__dirname, 'node_modules/@bundled-es-modules'),
],
over...
网友评论