2

grunt でビルドするときは、次の 2 つのタスクがあります。

preprocess:distにコピーapp/scripts/config.jsdist/scripts/config.jsて置き換える最初// @echo FOOのタスクBAR

app/scripts/**/*.js次に、すべてを に連結する usemindist/scripts/application.jsです。

Gruntfile でタスクをビルドします。

grunt.registerTask('build', [
    'clean:dist',
    'preprocess:dist',
    'useminPrepare',
    ...
    'htmlmin'
    'concat',
    'usemin'
]

私のインクルードスクリプトは次のindex.htmlとおりです。

<!-- build:js({.tmp,dist,app}) scripts/application.js -->
<script src="/scripts/config.js"></script>
<script src="/scripts/other_file.js"></script>
<script src="/scripts/yet_another_file.js"></script>
<!-- endbuild -->

config.js連結されたファイル dist/scripts/application.js にfromapp/scriptsではなくfromがあることを除いて、すべて正常に動作しますdist/scripts

({.tmp,dist,app})後は連結時にファイルをどこに取るかを指定するためだと思いましbuild:jsたが、それでも config.js は間違ったディレクトリ (アプリであり、dist ではありません) から取得されます。

したがって、// @echo VAR が置き換えられていない config.js になります。

連結時に app ではなく dist から config.js を取得するように concat/usemin に指示するにはどうすればよいですか?


注: 1 つの解決策は、usemin の動作方法を変更する必要がないように、前処理で を に入れ、 のconfig.processed.js代わりapp/scriptsにこのファイルを含めることです。config.js

しかし、次にconfig.processed.jsを.gitignoreに配置する必要があり、ソースファイル内に生成されたファイルがあります...

このファイルを .tmp または dist で生成することをお勧めします。


編集:私のGruntfile全体:

// Generated on 2013-10-31 using generator-angular 0.5.1
'use strict';

// # Globbing
// for performance reasons we're only matching one level down:
// 'test/spec/{,*/}*.js'
// use this if you want to recursively match all subfolders:
// 'test/spec/**/*.js'

module.exports = function (grunt) {
  require('time-grunt')(grunt);
  require('load-grunt-tasks')(grunt);
  require('time-grunt')(grunt);

  grunt.loadNpmTasks('grunt-preprocess');
  grunt.loadNpmTasks('grunt-include-source');

  grunt.initConfig({
    yeoman: {
      // configurable paths
      app: require('./bower.json').appPath || 'app',
      dist: 'dist'
    },
    watch: {
      coffee: {
        files: ['<%= yeoman.app %>/scripts/{,*/}*.coffee'],
        tasks: ['coffee:dist']
      },
      coffeeTest: {
        files: ['test/spec/{,*/}*.coffee'],
        tasks: ['coffee:test']
      },
      compass: {
        files: ['<%= yeoman.app %>/styles/{,*/}*.{scss,sass}'],
        tasks: ['compass:server', 'autoprefixer']
      },
      styles: {
        files: ['<%= yeoman.app %>/styles/{,*/}*.css'],
        tasks: ['copy:styles', 'autoprefixer']
      },
      livereload: {
        options: {
          livereload: '<%= connect.options.livereload %>'
        },
        files: [
          '<%= yeoman.app %>/{,*/}*.html',
          '.tmp/styles/{,*/}*.css',
          '{.tmp,<%= yeoman.app %>}/scripts/{,*/}*.js',
          '<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
        ]
      },
      includeSource: {
        files: ['<%= yeoman.app %>/index.html'],
        tasks: ['includeSource:server']
      }
    },
    autoprefixer: {
      options: ['last 1 version'],
      dist: {
        files: [
          {
            expand: true,
            cwd: '.tmp/styles/',
            src: '{,*/}*.css',
            dest: '.tmp/styles/'
          }
        ]
      }
    },
    connect: {
      options: {
        port: 8080,
        // Change this to '0.0.0.0' to access the server from outside.
        hostname: '0.0.0.0',
        livereload: 35729,
        // Modrewrite rule, connect.static(path) for each path in target's base
        middleware: function (connect, options) {
          var optBase = (typeof options.base === 'string') ? [options.base] : options.base;
          return [require('connect-modrewrite')(['!(\\..+)$ / [L]'])].concat(
            optBase.map(function (path) {
              return connect.static(path);
            }));
        }
      },
      livereload: {
        options: {
          open: true,
          base: [
            '.tmp',
            '<%= yeoman.app %>'
          ]
        }
      },
      test: {
        options: {
          port: 9001,
          base: [
            '.tmp',
            'test',
            '<%= yeoman.app %>'
          ]
        }
      },
      dist: {
        options: {
          base: '<%= yeoman.dist %>'
        }
      }
    },
    clean: {
      dist: {
        files: [
          {
            dot: true,
            src: [
              '.tmp',
              '<%= yeoman.dist %>/*',
              '!<%= yeoman.dist %>/.git*'
            ]
          }
        ]
      },
      server: '.tmp'
    },
    jshint: {
      options: {
        jshintrc: '.jshintrc'
      },
      all: [
        'Gruntfile.js',
        '<%= yeoman.app %>/scripts/{,*/}*.js'
      ]
    },
    coffee: {
      options: {
        sourceMap: true,
        sourceRoot: ''
      },
      dist: {
        files: [
          {
            expand: true,
            cwd: '<%= yeoman.app %>/scripts',
            src: '{,*/}*.coffee',
            dest: '.tmp/scripts',
            ext: '.js'
          }
        ]
      },
      test: {
        files: [
          {
            expand: true,
            cwd: 'test/spec',
            src: '{,*/}*.coffee',
            dest: '.tmp/spec',
            ext: '.js'
          }
        ]
      }
    },
    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
      },
      dist: {},
      server: {
        options: {
          debugInfo: true
        }
      }
    },
    // not used since Uglify task does concat,
    // but still available if needed
    /*concat: {
     dist: {}
     },*/
    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/*'
          ]
        }
      }
    },
    useminPrepare: {
      // changed from app to dist, to take index.html processed by includeSource in dist
      html: '<%= yeoman.dist %>/index.html',
      options: {
        dest: '<%= yeoman.dist %>'
      }
    },
    usemin: {
      //html: ['<%= yeoman.dist %>/{,*/}*.html'],
      html: ['<%= yeoman.dist %>/index.html'],
      //css: ['<%= yeoman.dist %>/styles/{,*/}*.css'],
      //js: ['<%= yeoman.dist %>/scripts/**/*.js'],
      options: {
        dirs: ['<%= yeoman.dist %>']
      }
    },
    imagemin: {
      dist: {
        files: [
          {
            expand: true,
            cwd: '<%= yeoman.app %>/images',
            src: '{,*/}*.{png,jpg,jpeg}',
            dest: '<%= yeoman.dist %>/images'
          }
        ]
      }
    },
    svgmin: {
      dist: {
        files: [
          {
            expand: true,
            cwd: '<%= yeoman.app %>/images',
            src: '{,*/}*.svg',
            dest: '<%= yeoman.dist %>/images'
          }
        ]
      }
    },
    cssmin: {
      // By default, your `index.html` <!-- Usemin Block --> will take care of
      // minification. This option is pre-configured if you do not wish to use
      // Usemin blocks.
      // dist: {
      //   files: {
      //     '<%= yeoman.dist %>/styles/main.css': [
      //       '.tmp/styles/{,*/}*.css',
      //       '<%= yeoman.app %>/styles/{,*/}*.css'
      //     ]
      //   }
      // }
    },
    htmlmin: {
      dist: {
        options: {
          /*removeCommentsFromCDATA: true,
           // https://github.com/yeoman/grunt-usemin/issues/44
           //collapseWhitespace: true,
           collapseBooleanAttributes: true,
           removeAttributeQuotes: true,
           removeRedundantAttributes: true,
           useShortDoctype: true,
           removeEmptyAttributes: true,
           removeOptionalTags: true*/
        },
        files: [
          {
            expand: true,
            cwd: '<%= yeoman.app %>',
            src: ['*.html', 'views/**/*.html', 'blocs/**/*.html'],
            dest: '<%= yeoman.dist %>'
          }
        ]
      }
    },
    // Put files not handled in other tasks here
    copy: {
      dist: {
        files: [
          {
            expand: true,
            dot: true,
            cwd: '<%= yeoman.app %>',
            dest: '<%= yeoman.dist %>',
            src: [
              '*.{ico,png,txt}',
              '.htaccess',
              'bower_components/**/*',
              'images/{,*/}*.{gif,webp}',
              'assets/**/*',
              'fonts/**/*',
              'styles/fonts/*'
            ]
          },
          {
            expand: true,
            cwd: '.tmp/images',
            dest: '<%= yeoman.dist %>/images',
            src: [
              'generated/*'
            ]
          }
        ]
      },
      styles: {
        expand: true,
        cwd: '<%= yeoman.app %>/styles',
        dest: '.tmp/styles/',
        src: '{,*/}*.css'
      }
    },
    concurrent: {
      server: [
        'coffee:dist',
        'compass:server',
        'copy:styles'
      ],
      test: [
        'coffee',
        'compass',
        'copy:styles'
      ],
      dist: [
        'coffee',
        'compass:dist',
        'copy:styles',
        'imagemin',
        'svgmin',
        'htmlmin'
      ]
    },
    //karma: {
    //  unit: {
    //    configFile: 'karma.conf.js',
    //    singleRun: true
    //  }
    //},
    cdnify: {
      dist: {
        html: ['<%= yeoman.dist %>/*.html']
      }
    },
    ngmin: {
      dist: {
        files: [
          {
            expand: true,
            cwd: '<%= yeoman.dist %>/scripts',
            src: '*.js',
            dest: '<%= yeoman.dist %>/scripts'
          }
        ]
      }
    },
    uglify: {
      dist: {
        files: {
          '<%= yeoman.dist %>/scripts/scripts.js': [
            '<%= yeoman.dist %>/scripts/scripts.js'
          ]
        }
      }
    },

    preprocess: {
      options: {
        context: {
          // /!\ Security warning:
          // On heroku, process.env might contain sensitive information. (such as DATABASE_URL)
          // To make sure what fields we pass, we specify every field explicitly.
          // So DON'T do this: ENV: JSON.stringify(process.env)

          ENV: JSON.stringify({
            FIRST_VAR: process.env.FIRST_VAR || '',
            SECOND_VAR: process.env.SECOND_VAR || '',
            NODE_ENV: process.env.NODE_ENV || 'production'
          })
        }
      },
      server: {
        src: 'app/scripts/config.js', dest: 'app/scripts/config.processed.js'//dest: '.tmp/scripts/config.js'
      },
      dist: {
        src: 'app/scripts/config.js', dest: 'app/scripts/config.processed.js'//dest: 'dist/scripts/config.js'
      }
    },
    includeSource: {
      options: {
        basePath: 'app',
        baseUrl: '/',
      },
      server: {
        files: {
          '.tmp/index.html': 'app/index.html'
        }
      },
      dist: {
        files: {
          'dist/index.html': 'app/index.html'
        }
      }
    }
  });

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

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

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

  grunt.registerTask('build', [
    'clean:dist',
    'includeSource:dist',
    'preprocess:dist',
    'useminPrepare',

    'concurrent:dist',
    'autoprefixer',
    'concat',
    'copy:dist',
    'cdnify',
    'ngmin',
    'cssmin',
    //'uglify',
    'rev',
    'usemin'
  ]);

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

  // building the app on heroku
  grunt.registerTask('heroku', 'build');

};
4

2 に答える 2

3

私は同じ問題を抱えていましたが、次の手順で解決しました。

1)スクリプトに「js」とは異なるビルド タイプを使用すると、usemin プラグインはビルド プロセスでそれを無視します。たとえば、「開発者」。

<!-- build:dev({.tmp,dist,app}) --><script src="/scripts/config.js"></script><!-- endbuild -->

usemin のバグのため、スペースがないことに注意してください ( Issue 128 )。私はuseminバージョン2.1.1を実行しています

これにより、grunt サーバーはソース コードの config.js を使用します。

2) 前処理タスクを変更して、前処理済みファイルを.tmp などの一時フォルダーに配置します。例えば:

dist: {
        src: 'app/scripts/config.js', dest: '.tmp/scripts/config.processed.js'
      }

3) 次に、.tmp フォルダーの config.processed.js と、usemin によって動的に生成された dist フォルダーの scripts/application.jsを連結する Grunt タスクを作成する必要があります。

例えば:

concat: {
          environment: {
              dest: 'dist/scripts/application.js',
              src: ['dist/scripts/application.js', '.tmp/scripts/config.processed.js']
          }
        },

Windows を使用している場合は、/ の代わりに \\ を使用する必要があります。

4) 最後に、すべてをまとめる必要があります。ビルド タスクは次のようになります。

 grunt.registerTask('build', [
    'clean:dist',
    'includeSource:dist',
    'preprocess:dist',
    'useminPrepare',
    'concurrent:dist',
    'autoprefixer',
    'concat',
    'copy:dist',
    'cdnify',
    'ngmin',
    'cssmin',
    'concat:environment',
    'uglify',
    'rev',
    'usemin'
  ]);
于 2014-06-02T15:58:02.980 に答える
0

このパッケージで:

https://www.npmjs.org/package/grunt-file-append

生成されたファイルを連結された一時ファイルに追加できます。

構成 js の参照を html から完全に削除し、ビルド タスクリストの concat タスクの後に file-append タスクを追加して、生成された構成ファイルを連結された js に追加する必要があります。

于 2014-03-23T20:23:56.883 に答える