最近在重新部署基于gulp的开发环境的时候遇到了标题中提到的2个错误,在接下来的内容中我会分享基于我的特征环境而产生的解决方案。
##gulp-jade 报错uglify-js unexpected token:punc {{}}}
这个错误表明在运行 gulp-jade插件的时候 uglify-js 组件解析文本内容失败。首先我们需要明确gulp-jade的功能是将jade文件转化成html文件,所以我们需要从jade文件本身开始排查,但是通过一些初步检查(删除部分编译不通过的jade文件,这里吐槽一点gulp的机制,在它报错的时候没有报出正在解析哪个文件,错误堆栈中只存放着gulp-jade组件内部抛出异常逻辑的位置),我可以确定应该是文件中的某种编码格式导致编译不通过。
但是存在一个悖论,在我之前部署的环境中存在着一套基本相同的代码,并且代码运行正常。而我项目组的另外两个人的环境上能够直接编译通过。
于是我开始确认我与他们环境的不同的地方,最后确认是nodejs版本的问题,我之前nodejs的版本是4.10,而他们的版本是0.12,更换完nodejs版本之后 项目便能正常运行了,根本原因还没有找到,从解决方案逆推得知应该是新项目原有的代码配置或者编码格式与高版本的nodejs不兼容。
总结:对项目可能原来依赖于低版本的nodejs的项目,针对这个问题的一个可行的解决方案:
- 卸载nodejs
- 清空npm缓存(c:/user/{{username}}/AppData/Roaming/npm* 与 c:/user/{{username}}/AppData/local/Temp/npm*)
- 重新安装低版本的nodejs (npm 会附带安装 可以通过 node -v 与 npm -v 检查文件的内容)
- 重启电脑(这个点是在我这发现的一个问题,windows删除的部分东西 还存在于缓冲区中,还可能对系统有影响,通过重启可以清空缓存)
- 重新搭建环境
##ng-annotate报错error parse
ng-annotate是给angularjs 模块自动注入依赖项的,如果我们运行 uglify等工具精简代码的话,我们原来的缩写风格可能不被系统识别
下面是官网上的描述
ng-annotate adds and removes AngularJS dependency injection annotations. It is non-intrusive so your source code stays exactly the same otherwise. No lost comments or moved lines. Annotations are useful because with them you're able to minify your source code using your favorite JS minifier.
You write your code without annotations, like this:
angular.module("MyMod").controller("MyCtrl", function($scope, $timeout) {
});
You then run ng-annotate as a build-step to produce this intermediary, annotated, result (later sent to the minifier):
angular.module("MyMod").controller("MyCtrl", ["$scope", "$timeout", function($scope, $timeout) {
}]);
当然官网上也对这个问题(
虽然在报错的时候会给出出错的行数,但是一般我们都会通过gulp的 concat命令拼接js文件,然后统一引入页面来实现解除依赖,gulp的配置文件大概如下
// JS APP
gulp.task('scripts:app', function() {
// Minify and copy all JavaScript (except vendor scripts)
return gulp.src(source.scripts.app)
.pipe( useSourceMaps ? sourcemaps.init() : gutil.noop())
.pipe(concat(build.scripts.app.main))
.pipe(ngAnnotate())
.on("error", handleError)
.pipe( isProduction ? uglify({preserveComments:'some'}) : gutil.noop() )
.on("error", handleError)
.pipe( useSourceMaps ? sourcemaps.write() : gutil.noop() )
.pipe(gulp.dest(build.scripts.app.dir));
});
于是这就带来了问题,如果我们源文件很多,我们会出现类似 44599 这样的行号,由于中间文件我们看不到,所以我们也无法定位出错的源文件。
参考链接 https://www.npmjs.com/package/ng-annotate
所以我采用了下面的方法来定位出错的位置
- 注释掉ngAnnotate 与之后的处理过程 直接输出到目标文件来获取拼接后的文件 通过报错的行号来定位错误
- (不推荐在定位bug的时候后台运行js文件,报错的指针会跑偏,建议开启gulp定位错位,关掉gulp,调整完错误,然后开启gulp验证错误解决的过程)
最后在朋友的提示下 我们可以在拼接文件之前进行一遍文件验证,这样能提前发现错误,配置文件参考下面的配置
$ = require('gulp-load-plugins')()
gulp.task('scripts:app', function() {
log('Building scripts..');
// Minify and copy all JavaScript (except vendor scripts)
return gulp.src(source.scripts)
.pipe($.jsvalidate())
.on('error', handleError)
.pipe( $.if( useSourceMaps, $.sourcemaps.init() ))
.pipe($.concat( 'app.js' ))
.pipe($.ngAnnotate())
.on('error', handleError)
.pipe( $.if(isProduction, $.uglify({preserveComments:'some'}) ))
.on('error', handleError)
.pipe( $.if( useSourceMaps, $.sourcemaps.write() ))
.pipe(gulp.dest(build.scripts));
});
以上就是我这篇文件分享的内容