使用$uibModal的Angular控制器经gulp-uglify与gulp-concat后崩溃问题
解决Angular项目经gulp-uglify/concat后因$uibModal崩溃的问题
这问题我太熟了——本质就是Angular的依赖注入机制在代码压缩时被破坏了,刚好你已经引入了gulp-ng-annotate,只是没把它用在正确的构建流程里,导致$uibModal这类服务无法被正确识别。
为啥会崩溃?
gulp-uglify在压缩代码时会把函数参数名缩短,比如你原来的控制器代码:
angular.module('myApp').controller('ModalCtrl', function($uibModal) { // 这里用$uibModal做逻辑 });
压缩后会变成这样:
angular.module('myApp').controller('ModalCtrl',function(a){/*你的逻辑*/});
Angular是靠参数名来做依赖注入的,现在它根本不知道a对应哪个服务,自然就会抛出注入错误,导致应用崩溃。
怎么修复?
核心就是在uglify压缩之前,用ngAnnotate给代码加上依赖注入注解,把参数名转换成Angular压缩后也能识别的数组格式。下面是调整后的完整JS处理任务:
调整后的gulp脚本任务
gulp.task('scripts', function() { return gulp.src('public/angular/**/*.js') // 替换成你实际的JS文件路径 .pipe(sourcemaps.init()) // 先合并所有JS文件 .pipe(concat('app.js')) // 关键步骤:用ngAnnotate自动添加依赖注入注解 .pipe(ngAnnotate({ add: true, // 自动给没有注解的代码添加数组式注入 single_quotes: true // 可选:用单引号代替双引号,看你代码风格 })) // 先输出未压缩的版本(方便调试) .pipe(gulp.dest('dist/js')) // 再压缩代码 .pipe(uglify()) .pipe(rename({suffix: '.min'})) .pipe(sourcemaps.write('.')) .pipe(gulp.dest('dist/js')) .pipe(livereload()); });
重点说明
- 顺序不能乱:必须先合并文件,再用
ngAnnotate处理,最后执行uglify。这样ngAnnotate能扫描到所有控制器、服务里的依赖,不会遗漏。 - ngAnnotate做了什么? 它会把你原来的控制器代码自动转换成这种格式:
这种数组式注入不受参数名压缩的影响,Angular能通过数组里的字符串angular.module('myApp').controller('ModalCtrl', ['$uibModal', function($uibModal) { // 你的逻辑 }]);$uibModal找到对应的服务。
额外要检查的点
- 确保你的
build任务是按正确顺序执行的,比如先清理旧文件,再处理JS、CSS、HTML:gulp.task('build', ['clean'], function() { gulp.start('scripts', 'styles', 'html'); }); - 如果你的代码里已经手动写了数组式注入(比如
['$uibModal', function($uibModal){...}]),ngAnnotate会自动保留它,不会重复添加注解,不用担心冲突。
内容的提问来源于stack exchange,提问作者Rohit Dhore
相关产品推荐
相关产品推荐

