2015-04-07 18 views
8

Tôi đang sử dụng Grunt và thi hành cmd "grunt build" để tạo thư mục phân phối chứa ứng dụng AngularJS.Xây dựng Grunt khiến ứng dụng Angular gặp sự cố trên

Là ứng dụng độc lập của tôi hoạt động tốt. Khi tôi tạo bản phân phối cho ứng dụng, ứng dụng sẽ bắt đầu gặp sự cố khá nhanh.

tôi nhìn thấy trong Công cụ F12 Console là:

10 $ digest() lặp đạt được. Hủy bỏ!

Tôi nghi ngờ một tệp trong thư mục .tmp của tôi có tên vendor.js và không thể rút gọn, làm xấu và ghép chính xác tệp này vì các biến tiêm phụ thuộc của trình điều khiển mangling đối số điều khiển được nhúng như "$ scope" tới " một ví dụ, mặc dù tôi đang sử dụng ngAnnotate.

Xem Tôi đang sử dụng UglifyJs và gọi ngAnnotate trước khi làm xấu đi và concat nhưng tôi không thể loại bỏ UglifyJs từ useMinPrepare hoặc tôi có lỗi khác như thư mục script thậm chí không được tạo ra trong thư mục TP của tôi:

useminPrepare: { 
    html: '<%= yeoman.app %>/index.html', 
    options: { 
    dest: '<%= yeoman.dist %>', 
    flow: { 
     html: { 
     steps: { 
      js: ['concat', 'uglifyjs'], 
      css: ['cssmin'] 
     }, 
     post: {} 
     } 
    } 
    } 
}, 

tôi đang thiết lập mangle = false trong tập tin GruntJs của tôi nhưng tôi nghi ngờ sử dụngMinPrepare js: ['concat', 'uglifyjs'] thay đổi trình tự thực hiện và chạy uglify trước khi ẩn Chú thích có thể chạy khi useMin được gọi, mặc dù tôi gọi useMin sau ngAnnotate.

Tôi mới sử dụng Grunt và ứng dụng này đã được chuyển cho tôi từ một nhà phát triển khác.

tôi tìm thấy bài viết này sẽ không chính xác có ý nghĩa với tôi và cũng không phải là một sự thay đổi mã mà dường như áp dụng đối với Gruntfile.js của tôi, nhưng tôi nghĩ có lẽ tôi đã vào một cái gì đó:

https://github.com/DaftMonk/generator-angular-fullstack/issues/164

Tôi đã đặt tùy chọn xoài Uglify thành false nhưng không khắc phục được sự cố của tôi.

Đây là mã Gruntfile.js tôi:

module.exports = function (grunt) { 

    // Load grunt tasks automatically 
    require('load-grunt-tasks')(grunt); 

    // Time how long tasks take. Can help when optimizing build times 
    require('time-grunt')(grunt); 

    grunt.loadNpmTasks('grunt-connect-proxy'); 

    // Define the configuration for all the tasks 
    grunt.initConfig({ 

    // Project settings 
    yeoman: { 
     // configurable paths 
     app: require('./bower.json').appPath || 'app', 
     dist: 'dist' 
    }, 

    // Watches files for changes and runs tasks based on the changed files 
    watch: { 
     bower: { 
     files: ['bower.json'], 
     tasks: ['bowerInstall'] 
     }, 
     js: { 
     files: ['<%= yeoman.app %>/scripts/**/*.js'], 
     //  tasks: ['newer:jshint:all'], 
     options: { 
      livereload: true 
     } 
     }, 
     html: { 
      files: ['**/*.html'], 
      options: { 
       livereload: true 
      } 
     }, 
     jsTest: { 
     files: ['test/spec/{,*/}*.js'], 
     tasks: ['newer:jshint:test', 'karma'] 
     }, 
     compass: { 
     files: ['<%= yeoman.app %>/styles/{,*/}*.{scss,sass}'], 
     tasks: ['compass:server', 'autoprefixer'] 
     }, 
     gruntfile: { 
     files: ['Gruntfile.js'] 
     }, 
     livereload: { 
     options: { 
      livereload: '<%= connect.options.livereload %>' 
     }, 
     files: [ 
      '<%= yeoman.app %>/{,*/}*.html', 
      '.tmp/styles/{,*/}*.css', 
      '<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}' 
     ] 
     } 
    }, 

    // The actual grunt server settings 
    connect: { 
     options: { 
     port: 9000, 
     // Change this to '0.0.0.0' to access the server from outside. 
     hostname: '0.0.0.0', 
     //hostname: 'localhost', 
     livereload: 35729 
     }, 
     proxies: [{ 
     context: ['/api', '/images'], 
     host: '127.0.0.1', 
     port: 60878, 
     changeOrigin: true 
     }], 
     livereload: { 
     options: { 
      open: true, 
      base: [ 
      '.tmp', 
      '<%= yeoman.app %>' 
      ], 
      middleware: function (connect, options) { 
      var middlewares = []; 

      if (!Array.isArray(options.base)) { 
       options.base = [options.base]; 
      } 

      // Setup the proxy 
      middlewares.push(require('grunt-connect-proxy/lib/utils').proxyRequest); 

      // setup push state 
      middlewares.push(require('grunt-connect-pushstate/lib/utils').pushState()); 


      // Serve static files 
      options.base.forEach(function(base) { 
       middlewares.push(connect.static(base)); 
      }); 

      return middlewares; 
      } 
     } 
     }, 
     test: { 
     options: { 
      port: 9001, 
      base: [ 
      '.tmp', 
      'test', 
      '<%= yeoman.app %>' 
      ] 
     } 
     }, 
     dist: { 
     options: { 
      base: '<%= yeoman.dist %>', 
      middleware: function (connect, options) { 
      var middlewares = []; 

      if (!Array.isArray(options.base)) { 
       options.base = [options.base]; 
      } 

      // Setup the proxy 
      middlewares.push(require('grunt-connect-proxy/lib/utils').proxyRequest); 

      // setup push state 
      middlewares.push(require('grunt-connect-pushstate/lib/utils').pushState()); 

      // Serve static files 
      options.base.forEach(function(base) { 
       middlewares.push(connect.static(base)); 
      }); 

      return middlewares; 
      } 
     } 
     } 
    }, 

    // Make sure code styles are up to par and there are no obvious mistakes 
    jshint: { 
     options: { 
     jshintrc: '.jshintrc', 
     reporter: require('jshint-stylish') 
     }, 
     all: [ 
     'Gruntfile.js', 
     '<%= yeoman.app %>/scripts/{,*/}*.js' 
     ], 
     test: { 
     options: { 
      jshintrc: 'test/.jshintrc' 
     }, 
     src: ['test/spec/{,*/}*.js'] 
     } 
    }, 

    // Empties folders to start fresh 
    clean: { 
     dist: { 
     files: [{ 
      dot: true, 
      src: [ 
      '.tmp', 
      '<%= yeoman.dist %>/*', 
      '!<%= yeoman.dist %>/.git*' 
      ] 
     }] 
     }, 
     server: '.tmp' 
    }, 

    // Add vendor prefixed styles 
    autoprefixer: { 
     options: { 
     browsers: ['last 1 version'] 
     }, 
     dist: { 
     files: [{ 
      expand: true, 
      cwd: '.tmp/styles/', 
      src: '{,*/}*.css', 
      dest: '.tmp/styles/' 
     }] 
     } 
    }, 

    // Automatically inject Bower components into the app 
    bowerInstall: { 
     app: { 
     src: ['<%= yeoman.app %>/index.html'], 
     ignorePath: '<%= yeoman.app %>/' 
    //  ,exclude : ["bower_components/angular-snap/angular-snap.css"] 
     }, 
     sass: { 
     src: ['<%= yeoman.app %>/styles/{,*/}*.{scss,sass}'], 
     ignorePath: '<%= yeoman.app %>/bower_components/' 
     } 
    }, 

    // Compiles Sass to CSS and generates necessary files if requested 
    compass: { 
     options: { 
     sassDir: '<%= yeoman.app %>/styles', 
     cssDir: '.tmp/styles', 
     generatedImagesDir: '.tmp/images/generated', 
     imagesDir: '<%= yeoman.app %>/images', 
     javascriptsDir: '<%= yeoman.app %>/scripts', 
     fontsDir: '<%= yeoman.app %>/styles/fonts', 
     importPath: '<%= yeoman.app %>/bower_components', 
     httpImagesPath: '/images', 
     httpGeneratedImagesPath: '/images/generated', 
     httpFontsPath: '/styles/fonts', 
     relativeAssets: false, 
     assetCacheBuster: false, 
     raw: 'Sass::Script::Number.precision = 10\n' 
     }, 
     dist: { 
     options: { 
      generatedImagesDir: '<%= yeoman.dist %>/images/generated', 
      fontsDir: '<%= yeoman.dist %>/styles/fonts' 
     } 
     }, 
     server: { 
     options: { 
      debugInfo: false 
     } 
     } 
    }, 

    // Renames files for browser caching purposes 
    rev: { 
     dist: { 
     files: { 
      src: [ 
      '<%= yeoman.dist %>/scripts/{,*/}*.js', 
      '<%= yeoman.dist %>/styles/{,*/}*.css', 
      '<%= yeoman.dist %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}' 
    //   ,'<%= yeoman.dist %>/styles/fonts/*' 
      ] 
     } 
     } 
    }, 

    // Reads HTML for usemin blocks to enable smart builds that automatically 
    // concat, minify and revision files. Creates configurations in memory so 
    // additional tasks can operate on them 
    useminPrepare: { 
     html: '<%= yeoman.app %>/index.html', 
     options: { 
     dest: '<%= yeoman.dist %>', 
     flow: { 
      html: { 
      steps: { 
       js: ['concat', 'uglifyjs'], 
       css: ['cssmin'] 
      }, 
      post: {} 
      } 
     } 
     } 
    }, 

    uglify: { 
     dist: { 
      options : { 
      report: 'min', 
      mangle : false 
      // compress: false, 
      // beautify : true 
     } 
    } 
    }, 

    // Performs rewrites based on rev and the useminPrepare configuration 
    usemin: { 
     html: ['<%= yeoman.dist %>/{,*/}*.html'], 
     css: ['<%= yeoman.dist %>/styles/{,*/}*.css'], 
     options: { 
     assetsDirs: ['<%= yeoman.dist %>', '<%= yeoman.dist %>/styles/fonts', '<%= yeoman.dist %>/images' ] 
     } 
    }, 

    concat: { 
     options: { 
     separator: grunt.util.linefeed + ";" + grunt.util.linefeed 
     } 
    }, 

    // The following *-min tasks produce minified files in the dist folder 
    // cssmin: { 
    //  options: { 
    //  root: '<%= yeoman.dist %>' 
    //  } 
    // }, 

    imagemin: { 
     dist: { 
     files: [{ 
      expand: true, 
      cwd: '<%= yeoman.app %>/images', 
      src: '{,*/}*.{png,jpg,jpeg,gif}', 
      dest: '<%= yeoman.dist %>/images' 
     }] 
     } 
    }, 

    svgmin: { 
     dist: { 
     files: [{ 
      expand: true, 
      cwd: '<%= yeoman.app %>/images', 
      src: '{,*/}*.svg', 
      dest: '<%= yeoman.dist %>/images' 
     }] 
     } 
    }, 

    htmlmin: { 
     dist: { 
     options: { 
      collapseWhitespace: true, 
      collapseBooleanAttributes: true, 
      removeCommentsFromCDATA: true, 
      removeOptionalTags: true 
     }, 
     files: [{ 
      expand: true, 
      cwd: '<%= yeoman.dist %>', 
      src: ['*.html', 'scripts/{,*/}*.html'], 
      dest: '<%= yeoman.dist %>' 
     }] 
     } 
    }, 

    // ngmin tries to make the code safe for minification automatically by 
    // using the Angular long form for dependency injection. It doesn't work on 
    // things like resolve or inject so those have to be done manually. 
    ngAnnotate: { 
     dist: { 
     files: [{ 
      expand: true, 
      cwd: '.tmp/concat/scripts', 
      src: '*.js', 
      dest: '.tmp/concat/scripts' 
     }] 
     } 
    }, 

    ngtemplates: { 
     fctrs: { 
     cwd: "<%= yeoman.app %>", 
     src: ['scripts/**/*.html'], 
     dest: '.tmp/concat/scripts/templates.js' 
     } 
    }, 

    // Replace Google CDN references 
    cdnify: { 
     dist: { 
     html: ['<%= yeoman.dist %>/*.html'] 
     } 
    }, 

    // Copies remaining files to places other tasks can use 
    copy: { 
     dist: { 
     files: [{ 
      expand: true, 
      dot: true, 
      cwd: '<%= yeoman.app %>', 
      dest: '<%= yeoman.dist %>', 
      src: [ 
      '*.{ico,png,txt}', 
      '.htaccess', 
      '*.html', 
      'views/{,*/}*.html', 
      'images/{,*/}*.{webp}', 
      'styles/fonts/*', 
      'statics/**', 
      'test_data/**/*.json' 
      ] 
     }, 
     { 
      expand: true, 
      cwd: '.tmp/images', 
      dest: '<%= yeoman.dist %>/images', 
      src: ['generated/*'] 
     }] 
     }, 
     styles: { 
     expand: true, 
     cwd: '<%= yeoman.app %>/styles', 
     dest: '.tmp/styles/', 
     src: '{,*/}*.css' 
     } 
    }, 

    processhtml: { 
     options : { 
      commentMarker : "process" 
     }, 
     dist: { 
      files: { 
       '<%= yeoman.dist %>/index.html':['<%= yeoman.dist %>/index.html'] 
      } 
     } 
    }, 

    // Run some tasks in parallel to speed up the build process 
    concurrent: { 
     server: [ 
     'compass:server' 
     ], 
     test: [ 
     'compass' 
     ], 
     dist: [ 
     'compass:dist', 
     'imagemin', 
     'svgmin' 
     ] 
    }, 

    // Test settings 
    karma: { 
     unit: { 
     configFile: 'karma.conf.js', 
     singleRun: true 
     } 
    } 
    }); 


    grunt.registerTask('serve', function (target) { 
    if (target === 'dist') { 
     return grunt.task.run(['build', 'configureProxies:server',  'connect:dist:keepalive']); 
    } 

    grunt.task.run([ 
     'clean:server', 
     'bowerInstall', 
     'concurrent:server', 
     'autoprefixer', 
     'configureProxies:server', 
     'connect:livereload', 
     'watch' 
    ]); 
    }); 

    grunt.registerTask('server', function (target) { 
    grunt.log.warn('The `server` task has been deprecated. Use `grunt serve` to start a server.'); 
    grunt.task.run(['serve:' + target]); 
    }); 

    grunt.registerTask('test', [ 
    'clean:server', 
    'concurrent:test', 
    'autoprefixer', 
    'connect:test', 
    'karma' 
    ]); 

    grunt.registerTask('build', [ 
    'clean:dist', 
    'bowerInstall', 
    'useminPrepare', 
    'concurrent:dist', 
    'autoprefixer', 
    'concat', 
    'ngAnnotate', 
    'ngtemplates', 
    'copy:dist', 
    'cdnify', 
    'cssmin', 
    'uglify', 
    'rev', 
    'usemin', 
    'processhtml', 
    'htmlmin' 

    ]); 

    grunt.registerTask('default', [ 
    'newer:jshint', 
    'test', 
    'build' 
    ]); 
}; 
+0

[Góc yêu cầu khi bạn rút gọn, không "mangle"] (http://google.com/search?q=angular+mangle) – laggingreflex

+1

Chạy 'grunt serve: dist', thao tác này sẽ quay lên máy chủ thử nghiệm từ thư mục dist để bạn có thể thấy lỗi xảy ra bên ngoài ứng dụng bạn đang di chuyển đến. – Terry

+0

Có Tôi đang gặp lỗi tương tự với dịch vụ grunt: dist –

Trả lời

2

Vì vậy, tôi đã đi xuống con đường sai suy nghĩ làm mịn đã sai với làm xấu đi hoặc concat hoặc việc rút gọn.

Các lỗi đã không xảy ra với grunt serve nhưng chỉ xảy ra sau khi một gói quận đã được tạo ra với grunt build:dist

Vì vậy, nó đã lừa dối trong một cảm giác rằng ứng dụng của Angular tôi DID làm việc tốt cho đến khi tôi đã tạo ra một gói dist.

Vấn đề là đối với tôi, rằng ban đầu tôi có phần tử <ng-include src="'scripts/navigation/navigationMobile.html'"></ng-include> trong tệp Index.html của mình.

Tại một thời điểm nào đó, tôi đã tạo chỉ thị phần tử tùy chỉnh <my-nav></my-nav> sử dụng cùng một templateUrl = scripts/navigation/navigationMobile.html nhưng tôi quên xóa phần tử <ng-include src="'scripts/navigation/navigationMobile.html'"></ng-include> khỏi chỉ mục của mình.html <my-nav></my-nav> được dự định thay thế.

Vì lý do gì, các lần lặp lại 10 $ digest() đã đạt được. Hủy bỏ! chỉ xảy ra sau khi chạy grunt build và tạo nhà cung cấp đã được rút gọn, được tối ưu hóa.js tập tin, nó đã không xảy ra khi chỉ phát triển và thử nghiệm bằng cách sử dụng grunt serve nhưng tôi không biết lý do chính xác mà lỗi chỉ trình bày chính nó sau grunt build.

Có thể ai đó có thể trả lời câu hỏi đó.

1

tôi nhận thấy chúng ta cần phải đưa ra một gợi ý để ng-chú thích trong hai trường hợp:

  • subclassing (ES6 lớp) khi siêu lớp có thuốc chích vào constructor và lớp phụ không có constructor;
  • $ có được phương pháp của một nhà cung cấp

Lỗi trong tiêu hóa kiểm tra đang diễn ra từ một nhiệm vụ đó chỉ chạy trong grunt build, hoặc có liên quan đến bạn tạo ra một chỉ thị từ một ng-bao gồm.

Khi bạn thay đổi từ ng-include thành mẫu làm chỉ thị của bạn, góc sẽ tạm ngừng biên dịch cho đến lần phân tích tiếp theo, khi mẫu được tải xong, ngay cả khi mẫu đã có trong templateCache $.

tham khảo: https://docs.angularjs.org/api/ng/service/ $ biên dịch (xem templateUrl)

Là một lưu ý cuối cùng, tôi sẽ phải có một cái nhìn vào ngtemplates vì ​​nó tránh được các yêu cầu trên dây, và góc biên dịch mẫu out-of-trật tự khi họ đến từ một tài nguyên bên ngoài, nó có thể là một lỗi về việc bạn triển khai chỉ thị đó hoặc bất kỳ cha mẹ nào của nó, mà không phải là việc gọi $ compile một cách chính xác.

Các vấn đề liên quan