没有使用uglifyjs,但是打包报UglifyJs错误;Unexpected token: name (raf) [main_25188b.js:121200,4]

背景:

公司老项目,使用的是webpack 3.X 构建项目。没有升级的打算。这个项目在本地 build 的时候,打包成功。但是到了GitLab CI/CD 或 Docker 中,却 build 失败。失败原因是:

ERROR in main_25188b.js from UglifyJs
Unexpected token: name (raf) [main_25188b.js:121200,4]

本地排查错误原因

不知道是什么原因,本地环境能够正常 build,但是一到了 linux 环境就会 build 失败。尝试了很多方法,没能够拿到 GitLab 或 Docker build 后的代码,拿不到 main_25188b.js 文件,就一直无法从这个文件里查看是哪里的代码出现问题。

本地项目package.json没有安装 UglifyJs 依赖

报错很明显提示是UglifyJs出了问题,由于 uglifyjs 无法处理 es6 语法,导致报错,但是我的项目package.json里没有安装 UglifyJs 依赖包。本地的部分 package.json 配置如下:

{
	// ... ... 省略部分代码
	"devDependencies": {
	    "autoprefixer": "^7.1.6",
	    "babel-core": "^6.26.0",
	    "babel-loader": "^7.1.2",
	    "babel-polyfill": "^6.0.16",
	    "babel-preset-env": "^1.6.1",
	    "babel-preset-es2015": "^6.0.15",
	    "babel-preset-latest": "^6.24.1",
	    "babel-preset-stage-0": "^6.0.15",
	    "copy-webpack-plugin": "^4.6.0",
	    "copy-webpack-plugin-advanced": "^2.0.0",
	    "css-loader": "^0.28.7",
	    "extract-text-webpack-plugin": "^3.0.2",
	    "file-loader": "^1.1.5",
	    "html-loader": "^0.5.5",
	    "html-webpack-plugin": "^2.30.1",
	    "postcss-import": "^11.0.0",
	    "postcss-loader": "^2.0.8",
	    "sass": "1.53.0",
	    "sass-loader": "^7.3.1",
	    "style-loader": "^0.19.0",
	    "url-loader": "^0.6.2",
	    "vue-loader": "^13.5.0",
	    "vue-style-loader": "^3.0.3",
	    "vue-template-compiler": "^2.5.3",
	    "webpack": "^3.8.1",
	    "webpack-md5-hash": "^0.0.5"
 	},
  	"dependencies": {
	    "archiver": "^5.3.1",
	    "cross-env": "^7.0.3",
	    "echarts": "^4.1.0",
	    "js-base64": "^2.3.2",
	    "lodash.merge": "^4.6.2",
	    "qrcode": "^1.5.3",
	    "qs": "^6.11.2",
	    "ts-md5": "^1.2.7",
	    "vue": "^2.5.3",
	    "vue-echarts": "^4.0.1",
	    "vue-i18n": "^8.24.4",
	    "vue-resource": "^1.3.4",
	    "vue-router": "^3.0.1",
	    "vue-touch": "^2.0.0-beta.4"
  	}
}

推测是某个插件自身的依赖中有 UglifyJs

通过vscode的全局搜索发现有不少依赖包里使用了 UglifyJs 。
在这里插入图片描述
这种情况,就没法通过将 UglifyJs 替换为 babili-webpack-plugin 插件来解决。

UglifyJs报错,可以通过 babel 编译,将 es6 转为 es5,来解决。

检查项目的 webpack.config.js 文件,找到 babel-loader 处理的部分。

// 省略大量代码
var path = require('path');
function resolve (dir) {
  return path.join(__dirname,dir);
}
module.exports={
	module:{
		rules:[
            // 处理.js文件(把ES6语法转义)
            {
                test:/\.js$/,
                loader:'babel-loader',
                exclude:__dirname+'/node_modules/',
                query:{
                    presets:['es2015', "stage-0"]
                },
            },
        ],
    }
}

看到这里,发现 babel-loader 在编译代码的时候,exclude:__dirname+'/node_modules/',排除了node_modules文件的编译。当我把这个 exclude 删掉后,使用 GitLab 或 Docker 的环境去 build ,结果 build 成功。
由此可见,是node_modules中某个 js 文件使用了 es6 语法,没有编译成 es5 ,导致 UglifyJS 编译出错。
将node_modules所有文件都丢进 babel-loader 编译一遍是不现实的,大大浪费编译时间。所以我们是哪个依赖包出了问题。
只需要找出是哪个依赖包的 js 文件没有编译为 es5 ,将这个依赖包 include 进 babel-loader 中,就可以解决这个问题。
那么要如何找呢?

将 babel-loader 的配置从 exclude 变更为 include,来排查报错

我们将 exclude 排除 node_modules 编译,改为 include 仅包含 xxx 文件编译。

// 省略大量代码
var path = require('path');
function resolve (dir) {
  return path.join(__dirname,dir);
}
module.exports={
	module:{
		rules:[
            // 处理.js文件(把ES6语法转义)
            {
                test:/\.js$/,
                loader:'babel-loader',
                include:[
                	resolve('dist/'),
                ],
                query:{
                    presets:['es2015', "stage-0"]
                },
            },
        ],
    }
}

执行 npm run build后,复现了 GitLab CI/CD 或者 Docker 中 build 出现的错误。
在这里插入图片描述
借助VScode 的跳转功能,按住 Ctrl + 鼠标移动到报错位置,报错的地方就会出现下划线,在按住 Ctrl 的同时,鼠标左键点击报错的地方,就可以跳转到报错的代码处。
在这里插入图片描述
在这里插入图片描述

使用 VS Code 全局搜索功能,查找报错代码出自何处

VS Code 搜索配置:
第一行 搜索内容:取消 Aa ab .* 的筛选
第三行 包含的文件:清空,不要有任何字符或空格,如果有很明确的报错地方,也可以将该文件夹的名称写上去,如果确定就是node_modules报错,可以写上./node_modules
第四行 排除的文件:不要点亮这个排除按钮,不使用“排除设置与忽略文件”
在这里插入图片描述
做好上述的配置后,搜索在 main_25188b.js 找到的导致报错的代码:
在这里插入图片描述
搜索的结果是:在 node_modules\resize-detector 中,有es6代码没有被编译为 es5。
注意:如果搜索的代码是 let name = null; 烂大街到处都有的那种代码,可以在 main_25188b.js 的错误代码附近,一个自己看起来 变量名比较独特的代码进行搜索

在这里插入图片描述

将报错的node_modules 文件添加到 babel-loader 的include中

// 省略大量代码
var path = require('path');
function resolve (dir) {
  return path.join(__dirname,dir);
}
module.exports={
	module:{
		rules:[
            // 处理.js文件(把ES6语法转义)
            {
                test:/\.js$/,
                loader:'babel-loader',
                include:[
                	resolve('dist/'),
                	resolve('node_modules/resize-detector/esm/')
                ],
                query:{
                    presets:['es2015', "stage-0"]
                },
            },
        ],
    }
}

ok,重新 npm run build 下。噢!天哪!又报错了!
在这里插入图片描述

还是UglifyJS 报错,好的,按照上述方法定位查找是哪个node_modules又搞事情。
在这里插入图片描述
哦,是node_modules/qrcode/lib/这个小妖精,把它加到 include 里

// 省略大量代码
var path = require('path');
function resolve (dir) {
  return path.join(__dirname,dir);
}
module.exports={
	module:{
		rules:[
            // 处理.js文件(把ES6语法转义)
            {
                test:/\.js$/,
                loader:'babel-loader',
                include:[
                	resolve('dist/'),
                	resolve('node_modules/resize-detector/esm/'),
                	resolve('node_modules/qrcode/lib/'),
                ],
                query:{
                    presets:['es2015', "stage-0"]
                },
            },
        ],
    }
}

重新 npm run build 下,OK,这次终于没有报下面这种错误了。
ERROR in main_96f20a.js from UglifyJs
Unexpected token: name (toSJISFunction) [main_96f20a.js:35061,4]
可喜可贺。

include:[]里,要加上需要将 es6 转为 es5 的所有文件,可以使用目录,也可以写具体某个js文件

最后发现,原来是 package.json 中添加的 qrcode 这个插件导致的错误。
在这里插入图片描述
如果项目之前能够正常npm run build,但是加了某个依赖后,npm run build 失败了。可以猜测是那个依赖本身有问题,或是这个依赖的依赖有问题。快速定位到问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值