Grunt usemin: связанный файл JavaScript не заменен в файле index.html

Я начал с пустого проекта, созданного yeoman, и попытался отредактировать Gruntfile.js в соответствии с моими потребностями.

Задача сборки grunt считывает мой файл index.html и объединяет зависимости байеров и генерирует файл .vendor.js.

Я сломал что-то в рабочем процессе, и теперь usemin не заменяет разметки в моем файле index.html, даже если создан файл .vendor.js.

Вот мой Gruntfile.js

    'use strict';

    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);

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

        // Project settings
        yeoman: {
          // configurable paths
          app: require('./bower.json').appPath || 'app',
          dist: 'dist',
        },
        express: {
          options: {
            port: process.env.PORT || 9000
          },
          dev: {
            options: {
              script: 'server.js',
              debug: true
            }
          },
          prod: {
            options: {
              script: 'dist/server.js',
              node_env: 'production'
            }
          }
        },
        open: {
          server: {
            url: 'http://localhost:<%= express.options.port %>'
          }
        },

        // Watches files for changes and runs tasks based on the changed files
        watch: {
          js: {
            files: ['<%= yeoman.app %>/scripts/{,*/}*.js'],
            tasks: ['newer:jshint:all'],
            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: {
            files: [
              '<%= yeoman.app %>/views/{,*//*}*.{html,handlebars}',
              '{.tmp,<%= yeoman.app %>}/styles/{,*//*}*.css',
              '{.tmp,<%= yeoman.app %>}/scripts/{,*//*}*.js',
              '<%= yeoman.app %>/images/{,*//*}*.{png,jpg,jpeg,gif,webp,svg}',
              '<%= yeoman.app %>/data/{,*/}*.{png,jpg,jpeg,gif,webp,svg,json,pdf}'
            ],

            options: {
              livereload: true
            }
          },
          express: {
            files: [
              'server.js',
              'lib/**/*.{js,json}'
            ],
            tasks: ['newer:jshint:server', 'express:dev'],
            options: {
              livereload: true,
              nospawn: true //Without this option specified express won't be reloaded
            }
          }
        },

        // Make sure code styles are up to par and there are no obvious mistakes
        jshint: {
          options: {
            jshintrc: '.jshintrc',
            reporter: require('jshint-stylish')
          },
          server: {
            options: {
              jshintrc: 'lib/.jshintrc'
            },
            src: [ 'lib/{,*/}*.js']
          },
          all: [
            '<%= 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 %>/views/*',
                '<%= yeoman.dist %>/public/*',
                '!<%= yeoman.dist %>/public/.git*',
              ]
            }]
          },
          heroku: {
            files: [{
              dot: true,
              src: [
                'heroku/*',
                '!heroku/.git*',
                '!heroku/Procfile'
              ]
            }]
          },
          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
        'bower-install': {
          app: {
            html: '<%= yeoman.app %>/views/edit/index.html',
            ignorePath: '<%= yeoman.app %>/'
          }
        },

        // 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 %>/public/images/generated'
            }
          },
          server: {
            options: {
              debugInfo: true
            }
          }
        },

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

        // The following *-min tasks produce minified files in the dist folder
        imagemin: {
          dist: {
            files: [{
              expand: true,
              cwd: '<%= yeoman.app %>/images',
              src: '{,*/}*.{png,jpg,jpeg,gif}',
              dest: '<%= yeoman.dist %>/public/images'
            }]
          }
        },


        // 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 %>/views/edit/index.html'
                 //'<%= yeoman.app %>/../views/index.handlebars'
            ],
          options: {
            dest: '<%= yeoman.dist %>/public'
          }
        },

        // Performs rewrites based on rev and the useminPrepare configuration
        usemin: {
          html: ['<%= yeoman.dist %>/views/edit/index.html',
                 '<%= yeoman.dist %>/views/{,*/}*.handlebars'],
          css: ['<%= yeoman.dist %>/styles/{,*/}*.css'],
          options: {
            assetsDirs: ['<%= yeoman.dist %>/public', '<%= yeoman.dist %>/public/images']
          }
        },
        svgmin: {
          dist: {
            files: [{
              expand: true,
              cwd: '<%= yeoman.app %>/images',
              src: '{,*/}*.svg',
              dest: '<%= yeoman.dist %>/public/images'
            }]
          }
        },
        htmlmin: {
          dist: {
            options: {
              //collapseWhitespace: true,
              //collapseBooleanAttributes: true,
              //removeCommentsFromCDATA: true,
              //removeOptionalTags: true
            },
            files: {
              '<%= yeoman.dist %>/public/views/edit/index.html': '<%= yeoman.app %>/views/edit/index.html'
            }
            //files: [{
            //  expand: true,
            //  cwd: '<%= yeoman.app %>/views/edit',
            //  src: ['*.html', 'partials/*.html'],
            //  dest: '<%= yeoman.dist %>/public/views/edit'
            //}]
          }
        },

        // Allow the use of non-minsafe AngularJS files. Automatically makes it
        // minsafe compatible so Uglify does not destroy the ng references
        ngmin: {
          dist: {
            files: [{
              expand: true,
              cwd: '.tmp/concat/scripts',
              src: '*.js',
              dest: '.tmp/concat/scripts'
            }]
          }
        },

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

        // Copies remaining files to places other tasks can use
        copy: {
          dist: {
            files: [{
              expand: true,
              dot: true,
              cwd: '<%= yeoman.app %>',
              dest: '<%= yeoman.dist %>/public',
              src: [
                '*.{ico,png,txt}',
                '.htaccess',
                '*.html',
                //'views/edit/{,*/}*.html',
                //'templates/{,*/}*.html',
                'bower_components/**/*',
                'images/{,*/}*.{webp}',
                'data/{,*/}*.*',
                'fonts/**/*'
              ]
            },
            //{
            //  expand: true,
            //  dot: true,
            //  cwd: '<%= yeoman.app %>/views',
            //  dest: '<%= yeoman.dist %>/views',
            //  src: '**/*.handlebars'
            //},
            {
              expand: true,
              cwd: '.tmp/images',
              dest: '<%= yeoman.dist %>/public/images',
              src: ['generated/*']
      }, {
              expand: true,
              dest: '<%= yeoman.dist %>',
              src: [
                'package.json',
                'server.js',
                'lib/**/*'
              ]
            }]
          },
          styles: {
            expand: true,
            cwd: '<%= yeoman.app %>/styles',
            dest: '.tmp/styles/',
            src: '{,*/}*.css'
          }
        },

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

        // By default, your `index.html` <!-- Usemin block --> will take care of
        // minification. These next options are pre-configured if you do not wish
        // to use the Usemin blocks.
        // cssmin: {
        //   dist: {
        //     files: {
        //       '<%= yeoman.dist %>/styles/main.css': [
        //         '.tmp/styles/{,*/}*.css',
        //         '<%= yeoman.app %>/styles/{,*/}*.css'
        //       ]
        //     }
        //   }
        // },
        // uglify: {
        //   dist: {
        //     files: {
        //       '<%= yeoman.dist %>/scripts/scripts.js': [
        //         '<%= yeoman.dist %>/scripts/scripts.js'
        //       ]
        //     }
        //   }
        // },
        //concat: {
        //   dist: {}
        //},

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

      grunt.registerTask('express-keepalive', 'Keep grunt running', function() {
        this.async();
      });

      grunt.registerTask('serve', function (target) {
        if (target === 'dist') {
          return grunt.task.run(['build', 'express:prod', 'open', 'express-keepalive']);
        }

        grunt.task.run([
          'clean:server',
          'bower-install',
          'concurrent:server',
          'autoprefixer',
          'express:dev',
          'open',
          'watch'
        ]);
      });

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

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

      grunt.registerTask('build', [
        'clean:dist',
        'bower-install',
        'useminPrepare',
        'concurrent:dist',
        'autoprefixer',
        'concat',
        'ngmin',
        'copy:dist',
        'cdnify',
        'cssmin',
        'uglify',
        'rev',
        'usemin'
      ]);


      grunt.registerTask('heroku', function () {
        grunt.log.warn('The `heroku` task has been deprecated. Use `grunt build` to build for deployment.');
        grunt.task.run(['build']);
      });

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

И вот что генерируется, когда я запускаю grunt:

    tree dist/public/scripts/
    dist/public/scripts/
    ├── 434e7b5e.scripts-edit.js
    └── ad5d9b7c.vendor-edit.js

index.html

    <!-- build:js(app) scripts/vendor-edit.js -->
    <!-- bower:js-->
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
    <script src="bower_components/angular/angular.js"></script>
    <script src="bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap.js"></script>
    <script src="bower_components/angular-resource/angular-resource.js"></script>
    <script src="bower_components/angular-cookies/angular-cookies.js"></script>
    <script src="bower_components/angular-sanitize/angular-sanitize.js"></script>
    <script src="bower_components/angular-route/angular-route.js"></script>
    <script src="bower_components/angular-animate/angular-animate.js"></script>
    <script src="bower_components/angular-http-auth/src/http-auth-interceptor.js"></script>
    <script src="bower_components/angular-translate/angular-translate.js"></script>
    <script src="bower_components/angular-translate-storage-cookie/angular-translate-storage-cookie.js"></script>
    <script src="bower_components/angular-translate-storage-local/angular-translate-storage-local.js"></script>
    <script src="bower_components/angular-ui-router/release/angular-ui-router.js"></script>
    <script src="bower_components/moment/moment.js"></script>
    <script src="bower_components/angular-moment/angular-moment.js"></script>
    <script src="bower_components/bootstrap/dist/js/bootstrap.js"></script>
    <script src="bower_components/AngularJS-Toaster/toaster.js"></script>
    <!-- endbower -->
    <!-- endbuild -->

И наконец, вот выход grunt

        Running "compass:dist" (compass) task
        directory .tmp/styles/
           create .tmp/styles/edit.css (16.644s)
           create .tmp/styles/webicons.css (0.156s)
           create .tmp/styles/main.css (10.947s)
        Compilation took 27.77s

        Done, without errors.


        Execution Time (2014-03-19 13:47:21 UTC)
        compass:dist  29.1s  ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 100%
        Total 29.2s

        Running "htmlmin:dist" (htmlmin) task
        File dist/public/views/edit/index.html created.

        Done, without errors.


        Execution Time (2014-03-19 13:47:51 UTC)
        loading tasks  13ms  ▇▇▇▇▇▇▇▇▇▇▇▇ 25%
        htmlmin         2ms  ▇▇ 4%
        htmlmin:dist   35ms  ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 67%
        Total 52ms

    Running "autoprefixer:dist" (autoprefixer) task
    Prefixed file ".tmp/styles/edit.css" created.
    Prefixed file ".tmp/styles/main.css" created.
    Prefixed file ".tmp/styles/webicons.css" created.

    Running "concat:generated" (concat) task
    File ".tmp/concat/styles/edit.css" created.
    File ".tmp/concat/scripts/vendor-edit.js" created.
    File ".tmp/concat/scripts/scripts-edit.js" created.

    Running "ngmin:dist" (ngmin) task
    ngminifying .tmp/concat/scripts/scripts-edit.js, .tmp/concat/scripts/vendor-edit.js

    Running "copy:dist" (copy) task
    Created 125 directories, copied 907 files

    Running "cdnify:dist" (cdnify) task
    Going through dist/public/views/edit/index.html to update script refs

    Running "cssmin:generated" (cssmin) task
    File dist/public/styles/edit.css created.

    Running "uglify:generated" (uglify) task
    File "dist/public/scripts/vendor-edit.js" created.
    File "dist/public/scripts/scripts-edit.js" created.

    Running "rev:dist" (rev) task
    dist/public/scripts/scripts-edit.js >> 434e7b5e.scripts-edit.js
    dist/public/scripts/vendor-edit.js >> ad5d9b7c.vendor-edit.js
    dist/public/styles/edit.css >> 9d137efe.edit.css

    Running "usemin:html" (usemin) task

    Running "usemin:css" (usemin) task


    Execution Time (2014-03-19 13:46:43 UTC)
    concurrent:test   20.7s  ▇▇▇▇▇▇▇ 15%
    karma:unit         3.8s  ▇▇ 3%
    concurrent:dist   41.9s  ▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 31%
    ngmin:dist        44.5s  ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 33%
    copy:dist          2.2s  ▇ 2%
    uglify:generated  18.1s  ▇▇▇▇▇▇ 14%
    Total 133.9s

Любая помощь в понимании этого будет оценена.

Ответ 1

Я отвечу на свой вопрос:

У меня была разница между моей конфигурацией useminprepare и моей настройкой usemin.

useminprepare писал <%= yeoman.dist %>/public/views/edit/index.html

и usemin читал от <%= yeoman.dist %>/views/edit/index.html

Ответ 2

По какой-то причине у меня была такая же проблема. Во время grunt build мой index.html не был обновлен (но main.css и main.js были отображены просто отлично). Я пробовал grunt usemin:html И ЧТО РАБОТАЛ.

Итак, я переместил usemin:html на последнее место в моем списке задач grunt build.

Пока не знаю, почему это было, но это поможет мне, где я должен быть. В случае, если кто-то может найти это полезным.

Ответ 3

У меня аналогичная проблема. В моем случае все заменяется так, как ожидалось, кроме содержимого внутри bower: css или bower: js tags. Похоже, что usemin не может заменить то, что окружено комментариями сабли.

Ответ 4

В качестве стандарта убедитесь, что вы выбрали Unix как Line Endings в возвышенном виде или в вашей среде IDE. Это может произойти из-за использования платформы Cross.

введите описание изображения здесь

Ответ 5

У меня была такая же проблема, хрюкать было создание файлов vendor.js и scripts.js, но он не вставлял их в index.html, и в конце он не заменял старые ссылки script. Он исправил это, сделав то, что tk120404 предлагал и исправил процесс сборки.