当uullified与gulp一起使用时,Angular-ui-router会中断

时间:2014-07-25 21:25:04

标签: javascript angularjs angular-ui-router gulp

我有以下简单的angular.js应用,遵循概述here的最佳做法。

angular
  .module('myApp', ['ui.router']);

(function() {
    function routes($stateProvider, $urlRouterProvider) {
        $urlRouterProvider.otherwise("/404");

        $stateProvider
            .state('createCluster', {
                url: '/create-cluster',
                templateUrl: 'templates/create-cluster.html'
            })
    }

    angular
        .module('myApp')
        .config(routes);
})();

我正在使用 gulp 来连接所有JavaScript文件,包括angular-ui-router.js,然后通过uglify运行所有内容。当我丑化的时候,我得到了:

  

未捕获错误:[$ injector:modulerr]由于以下原因无法实例化myApp模块:
  错误:[$ injector:unpr]未知提供者:e

当我删除uglification时,一切正常。如何才能解决 ui-router

这是我的gulp任务:

gulp.task('uglify-js', function () {
  gulp.src(['client/js/libraries/**/*.js', 'client/js/source/**/*.js'])
    .pipe(concat('app'))
    .pipe(ngAnnotate())
    .pipe(uglify())
    .pipe(rename({ extname: ".min.js" }))
    .pipe(gulp.dest('client/js'))'
});

6 个答案:

答案 0 :(得分:16)

在不更改所有代码的情况下实现此功能的一个简单方法是将mangle uglify选项设置为false,如下所示:

gulp.task('uglify-js', function() {
  gulp.src(['client/js/libraries/**/*.js', 'client/js/source/**/*.js'])
    .pipe(concat('app'))
    .pipe(ngAnnotate())
    .pipe(uglify({ mangle: false }))
    .pipe(rename({ extname: '.min.js' }))
    .pipe(gulp.dest('client/js'));
});

保留名称,这样就不会出现注射问题。

答案 1 :(得分:4)

您应该使用ngannotate。这同时预处理你的角度代码,使其对uglify / minification安全。 Ngannotate添加了依赖注释,因此minifier不会破坏您的依赖注入。

angular documentation提供了相关说明:

  

由于Angular将控制器的依赖关系从参数名称推断到控制器的构造函数,如果你要缩小PhoneListCtrl控制器的JavaScript代码,它的所有函数参数都会被缩小。 ,依赖注入器将无法正确识别服务。我们可以通过使用依赖项的名称来注释函数来克服这个问题,这些依赖项的名称是字符串,不会被缩小。

Ngannotate为您完成此过程,使您的代码更加清晰。

Ngmin现已弃用,github建议使用nnotnotate。它也比ngmin快。

答案 2 :(得分:1)

查看正在生成的代码。缩小AngularJS时的一个问题是依赖注入是基于参数名称的,因此在缩小时会中断。

例如,这一行

function routes($stateProvider, $urlRouterProvider) {

可能最终看起来像

function routes(a, b) {

然后Angular不知道要注入哪个依赖项,您将收到Unknown provider错误。

要解决此问题,您可以使用array syntax(请参阅:内联数组注释)。

['$dependencyA', '$dependencyB', function($dependencyA, $dependencyB)

因为缩小了看起来像

['$dependencyA', '$dependencyB', function(a, b)

然后Angular知道该怎么做。

在你的情况下,它会像

.config(['$stateProvider', '$urlRouterProvider', routes]);

答案 3 :(得分:1)

尝试这样做,以便缩小注意事项:

var routes = function ($stateProvider, $urlRouterProvider) {
    $urlRouterProvider.otherwise("/404");

    $stateProvider
        .state('createCluster', {
            url: '/create-cluster',
            templateUrl: 'templates/create-cluster.html'
        })
};

routes.$inject = ['$stateProvider','$urlRouterProvider'];

angular
    .module('myApp')
    .config(routes);

答案 4 :(得分:0)

刚刚找到解决方案。

或者,甚至比使用$inject手动指定依赖项更好,请使用 gulp @ngInject中的内置ngAnnotate帮助程序。

angular
    .module('myApp', [
        'ui.router'
    ]);

(function() {
    /**
     * @ngInject
     */
    function routes($stateProvider, $urlRouterProvider) {
        $urlRouterProvider.otherwise("/404");

        $stateProvider
            .state('createCluster', {
                url: '/create-cluster',
                templateUrl: 'templates/create-cluster.html'
            })
    }

    angular
        .module('myApp')
        .config(routes);
})();

答案 5 :(得分:0)

不要忘记你在功能上方的@ngInject评论,我正在努力让自动功能参考在ng-annotate的未来版本中登陆,如果你可以加入并在这里+1,那就是太棒了:https://github.com/olov/ng-annotate/issues/57