Grunt构build导致Angular应用程序在dist上崩溃

我正在使用Grunt并执行cmd“grunt build”来创build包含AngularJS应用程序的分发文件夹。

作为一个独立的我的应用程序工作正常。 一旦我创build了应用程序的发行版,应用程序开始很快崩溃。

我看到在F12工具控制台是:

达到10 $ digest()迭代。 中止!

我怀疑我的.tmp目录中的一个文件名为vendor.js,并且由于控制器dependency injectionvariables将注入的控制器参数(例如“$ scope”)注入到“a”中,所以无法正确缩小,uglify和/即使我正在使用ngAnnotate。

请参阅我正在使用UglifyJs和Uglify和Concat之前调用ngAnnotate,但我不能从useMinPrepare中删除UglifyJs,或者我有其他的错误,如脚本目录甚至不是在我的dist目录中创build:

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

我在我的GruntJs文件中设置mangle = false,但我怀疑useMinPrepare js: ['concat', 'uglifyjs']更改执行顺序并运行uglify之前ngAnnotate可以运行时调用useMin ,即使我调用后, ngAnnotate

我是新来的Grunt,这个应用程序已经从另一个开发人员传给我。

我发现这篇文章对我来说并不完全有意义,也不是一个代码更改似乎适用于我的Gruntfile.js,但我想也许我正在做的事情:

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

我已经将Uglify mangle选项设置为false,但是尚未解决我的问题。

这是我的Gruntfile.js代码:

  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' ]); }; 

所以我走错了路,认为Uglify或concat或minification的平滑是错误的。

这个错误不会发生在grunt serve但是只有在使用grunt build:dist创build一个dist包的时候才会发生错误

所以这是骗人的意义,我的Angular应用程序DID工作正常,直到我创build一个dist包。

这个问题对我来说,我最初在我的Index.html文件中有一个<ng-include src="'scripts/navigation/navigationMobile.html'"></ng-include>元素。

在某些时候,我创build了一个自定义元素指令<my-nav></my-nav> ,它使用了相同的templateUrl = scripts/navigation/navigationMobile.html但是我忘记删除<ng-include src="'scripts/navigation/navigationMobile.html'"></ng-include>元素来自我的Index.html, <my-nav></my-nav>旨在replace。

无论出于什么原因,都达到10 $ digest()迭代。 中止! 只发生在运行grunt build和创build缩小的Uglified vendor.js文件之后,在使用grunt serve开发和testing时并没有发生,但是我不知道错误只在grunt build之后才出现的确切原因。

也许有人可以回答。

我注意到我们需要在两种情况下给ng-annotate一个提示:

  • 当超类在构造函数和子类上有注入时,子类化(ES6类)没有构造函数;
  • $ get提供者的方法

摘要检查错误发生在一个只能在grunt build运行的任务,或者与您从ng-include创build指令有关。

当你从ng-include改变成你的指令模板时,angular会暂停编译,直到下一个摘要,当模板被加载,即使它已经在$ templateCache中。

参考: https : //docs.angularjs.org/api/ng/service/ $ compile(请参阅templateUrl)

作为最后一点,我会看看ngtemplates,因为它避免了通过线路的请求,而且当来自外部资源的angular度编译模板乱序时,它可能是你实现该指令的一个错误或者它的任何父母,这不是调用$编译正确。