簡體   English   中英

grunt usemin和concat:首先在dist中已經有一個文件而不是app

[英]grunt usemin and concat: take a file already in dist first instead of app

使用grunt構建時,我有兩個任務:

第一個任務preprocess:distapp/scripts/config.js復制到dist/scripts/config.js並將// @echo FOO替換為BAR

然后,usemin,將所有app/scripts/**/*.js 。js連接到dist/scripts/application.js

在Gruntfile中構建任務:

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

我的include腳本在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 -->

一切工作正常,除了在串聯文件dist / scripts / application.js中,我有來自app/scriptsconfig.js ,而不是dist/scriptsconfig.js

我堅信build:js之后的({.tmp,dist,app})用於指定級聯時將文件放置在何處,但是config.js仍然是從錯誤的目錄(應用而非dist)中獲取的。

因此,我最終得到了config.js,其中// @echo VAR沒有被替換。

如何在連接時告訴concat / usemin從dist而不是app中獲取config.js?


注意:一種解決方案是進行預處理,將config.processed.js放入app/scripts ,然后包括該文件而不是config.js ,這樣我就不必更改usemin的工作方式。

但是然后我必須將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');

};

我遇到了同樣的問題,並通過以下步驟解決了問題:

1)為您的腳本使用不同於“ js”的構建類型 ,因此usemin插件將在構建過程中忽略它。 例如,“ dev”。

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

注意,由於usemin的錯誤( 問題128 ),沒有空格。 我正在運行Usemin版本2.1.1

這樣, grunt服務器將使用源代碼中的config.js。

2)修改預處理任務,以將預處理文件放在一個臨時文件夾 (如.tmp)中。 例如:

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

3)現在,你需要創建一個咕嚕任務與通過usemin動態生成的腳本/在你的DIST文件夾中的application.js到CONCAT您config.processed.js中的.tmp文件夾中。

例如:

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

使用此軟件包:

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

您可以將生成的文件附加到串聯的臨時文件中。

您應該從html中完全刪除config js的引用,並在構建任務列表中的concat任務之后添加file-append任務,以將生成的配置文件追加到串聯的js中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM