【问题标题】:Grunt usemin and useminPrepare multiple targetsgrunt usemin 和 usemin 准备多个目标
【发布时间】:2013-12-29 08:22:06
【问题描述】:

usemin issues 看来useminuseminPrepare 在最新版本中支持多个目标:

在useminPrepare中支持多个目标:

用户支持:

我已经尝试使用具有以下配置的多个目标:

useminPrepare: {
    foo: {
        dest: 'fooDist',
        src: ['foo/index.html']
    },
    bar: {
        dest: 'barDist',
        src: ['bar/index.html']
    }
},
usemin: {
    foo: {
        options: {
            assetsDirs : ['fooDist']
        },
        html: ['fooDist/**/*.html'],
        css: ['fooDist/styles/**/*.css']
    },
    bar: {
        options: {
            assetsDirs : ['barDist']
        },
        html: ['barDist/**/*.html'],
        css: ['barDist/styles/**/*.css']
    }
},

但我收到以下错误:

运行“usemin:foo”(usemin)任务警告:不支持的模式:foo

使用 --force 继续。

使用 grunt-usemin 2.0.2

foo/index.htmlbar/index.html 是 2 个单页应用程序的主页。

感谢您的帮助!

【问题讨论】:

标签: javascript node.js gruntjs npm grunt-usemin


【解决方案1】:

我试图做一些类似的事情,我有多个页面/模板,其中包含不同的依赖 css/js/img 文件,我想通过 usemin 单独处理这些文件。您可以使用单个 Gruntfile.js 并使用多任务通过 usemin 完成多个目标和目的地。这将是您的 gruntfile:

var packageConfig = [];
var gruntConfig = {};
gruntConfig.useminPrepareMulti = {};
gruntConfig.useminPrepare = {};
gruntConfig.usemin = {
  html: [],
  css: [],
  options: {
    assetDirs: []
  }
};

var projectDirs = ['foo', 'bar'];

var src, dist;
projectDirs.forEach(function(dir) {
  src = path1 + dir;
  dist= path2 + dir;
  gruntConfig.useminPrepareMulti[dir] = {
    html: src + '*.html',
    options: {
      dest: dist,
      staging: '.tmp' + dir,
      flow: { html: { steps : { js : ['concat'] } } },
      post: {}
    }
  };
  packageConfig.push(src);
  gruntConfig.usemin.html.push(dist + '*.html');
  gruntConfig.usemin.css.push(dist + '/styles/*.css');
  gruntConfig.usemin.options.assetsDirs.push( dist, dist + '/styles');
});

grunt.initConfig(gruntConfig);

grunt.registerMultiTask('useminPrepareMulti', 'multi-target-usemin', function() {
  grunt.config.set('useminPrepare', this.data);
  grunt.task.run('useminPrepare');
});

注册任务后,您可以运行所有不同的目标/目标配置:

grunt.registerTask('default', ['useminPrepareMulti']);

或者从您创建的 packageConfig 中单独运行它们:

grunt.registerTask('single', ['useminPrepareMulti:' + packageConfig[0]]);

我还必须修改 html 代码中的 usemin 块以包含相对于根的路径,例如:

<!-- build:js(./assets/dir/foo) scripts/vendor.js -->
<script src="scripts/file.js"></script>
<!-- endbuild -->

【讨论】:

    【解决方案2】:

    作为一种解决方法(为此苦苦挣扎了一段时间),我们决定运行整个 grunt 作业两次,并添加了一个 grunt 选项,它将目标文件切换为不同的值。不优雅,但简单。

    【讨论】:

      【解决方案3】:

      默认情况下,usemin 会尝试从目标名称中检测解析器类型(html、css)。当您使用的目标名称不是有效的解析器类型时,您应该使用 type 选项手动指定解析器类型。这将导致每个 dest 有两个目标,一个用于 html,一个用于 css。

      usemin:{
          'foo-html':
          {
             options:
             {
                 assetsDirs : ['fooDist'],
                 type:'html'
             },
             files: {src: ['fooDist/**/*.html']}
          },
          'foo-css':
          {
              options:
              {
                  assetsDirs : ['fooDist'],
                  type:'css'
              },
              files: {src: ['fooDist/styles/**/*.css']}
          },
          'bar-html':
          {
              options:
              {
                  assetsDirs : ['barDist'],
                  type:'html'
              },
              files: {src: ['barDist/**/*.html']}
          },
          'bar-css':
          {
              options:
              {
                  assetsDirs : ['barDist'],
                  type:'css'
              },
              files: {src: ['barDist/styles/**/*.css']}
          }
      }
      

      https://github.com/yeoman/grunt-usemin/issues/255

      【讨论】:

      • 乘以type:'js'怎么样?
      • @user1828780,还认为直接通过 js 引用资产是一种不好的做法,有时不执行 js 代码就不可能找到所有引用。最好通过保持关注点分离来避免这种情况,保持js中的行为和css中的表示以及html中的语义,js可以通过css类和数据属性来操作这些层。
      • 当与 filerev 一起使用时,usemin 不会将构建的 js 文件替换为其修订后的文件名。有谁知道这方面的任何解决方案?
      【解决方案4】:

      虽然目前 usemin 不支持多个目标,但它们确实允许您定义新模式...

      因此,与此同时,您可以使用以下方式定义新目标:

      usemin: {
                  html: ['index.html'],
                  css: ['styles/{,*/}*.css'],
                  options: {
                      assetsDirs: ['src'],
                      patterns: {
                          templates: [[ /<img[^\>]+src=['"]([^"']+)["']/gm,
                              'Update the templates with the new img filenames'
                          ]]
                      }
                  },
                  templates: "scripts/**/*.tpl.html"
              }
      

      【讨论】:

        【解决方案5】:

        不确定这是否会有所帮助,但我能够通过 Grunt-Contrib-Min 和 Grunt-Contr 的组合成功地完成您正在尝试的事情

        'use strict';
        
        module.exports = function(grunt) {
        // Project Configuration
        grunt.initConfig({
            pkg: grunt.file.readJSON('package.json'),
            copy: {
              main: {
                options: {
                    encoding: 'UTF-16'
                  },
                files:[
                {
                  expand: 'true',
                  flatten: 'true',
                  src: 'src/audio/*',
                  dest: 'bin/pro/audio/'
                },
                {
                  expand: 'true',
                  flatten: 'true',
                  src: 'src/fonts/*',
                  dest: 'bin/pro/fonts/'
                },
                {
                  expand: 'true',
                  flatten: 'true',
                  src: 'src/adaptors/*.html',
                  dest: 'bin/pro/adaptors/'
                },
                {
                  expand: 'true',
                  flatten: 'true',
                  src: 'src/lib/*',
                  dest: 'bin/pro/lib/'
                },
                {
                  expand: 'true',
                  flatten: 'true',
                  src: 'src/img/*',
                  dest: 'bin/pro/img/'
                },
                {
                  expand: 'true',
                  flatten: 'true',
                  src: 'src/manifest.json',
                  dest: 'bin/pro/'
                },
                {
                  expand: 'true',
                  flatten: 'true',
                  src: 'src/audio/*',
                  dest: 'bin/lite/audio/'
                },
                {
                  expand: 'true',
                  flatten: 'true',
                  src: 'src/fonts/*',
                  dest: 'bin/lite/fonts/'
                },
                {
                  expand: 'true',
                  flatten: 'true',
                  src: 'src/adaptors/*.html',
                  dest: 'bin/lite/adaptors/'
                },
                {
                  expand: 'true',
                  flatten: 'true',
                  src: 'src/lib/*',
                  dest: 'bin/lite/lib/'
                },
                {
                  expand: 'true',
                  flatten: 'true',
                  src: 'src/img-lite/*',
                  dest: 'bin/lite/img/'
                },
                {
                  expand: 'true',
                  flatten: 'true',
                  src: 'src/lite/manifest.json',
                  dest: 'bin/lite/'
                }
              ]
           },
         },
            uglify: {
                all: {
                    files: {
                      'bin/pro/js/cupid.min.js': ['src/popup.js','src/cupid.js','src/adaptors/*.js'],
                      'bin/pro/background.js': ['src/background.js'],
                      'bin/lite/js/cupid.min.js': ['src/popup.js','src/cupid.js','src/adaptors/*.js'],
                      'bin/lite/background.js': ['src/background.js'],
                      'bin/lite/lite.js': ['src/lite.js'],
                      'bin/pro/pro.js': ['src/pro.js'],
                    },
                    options: {
                        compress: false,
                        mangle:false
                    }
                }
            },
            targethtml: {
              dist: {
                files: {
                  'bin/pro/popup.html': 'src/popup.html'
                }
              },
              lite: {
                files: {
                  'bin/lite/popup.html': 'src/popup.html'
                }
              },
            },
        
            cssmin: {
                all: {
                    files: {
                      'bin/pro/cupid.min.css': ['src/*.css'],
                      'bin/lite/cupid.min.css': ['src/*.css'],
        
                    },
                    options: {
                        compress: true,
                        mangle:true
                    }
                }
            },
        });
        
        
        //Default task(s).
        grunt.loadNpmTasks('grunt-contrib-uglify');
        grunt.loadNpmTasks('grunt-contrib-cssmin');
        grunt.loadNpmTasks('grunt-contrib-copy');
        grunt.loadNpmTasks('grunt-targethtml');
        
        grunt.registerTask('default', ['uglify','cssmin','copy','targethtml']);
        
        };
        

        这个 Grunt 文件将获取我的 App 目录,将其全部输出到 PRO 文件夹并添加一些特殊标签,并将所有内容再次输出到 Lite 文件夹,并设置其他开关。

        【讨论】:

          【解决方案6】:

          您是否需要两个项目都存在于同一个存储库和同一个 Gruntfile 下?

          您自己说过它们是“2 个单页应用程序的主页”。如果你有能力把它分成两个不同的项目,你可能会省去一些痛苦。

          或者,您可以将两个索引分组到一个公共目录下。这就是我将 grunt-usemin 与两个不同的索引文件一起使用的方式:

          useminPrepare:
              html: ['build/<%= relativePath %>/index.html', 'build/<%= relativePath %>/orderPlaced/index.html']
              options:
                  dest: 'build/'
                  root: 'build/'
          
          usemin:
              html: ['build/<%= relativePath %>/index.html', 'build/<%= relativePath %>/orderPlaced/index.html']
          

          【讨论】:

          • 这是我期望它的工作方式,我尝试以这种方式使用它,但在同一目录中有两个索引文件。但由于某种原因,它没有按预期工作,useminPrepare 是不为每个 html 文件制作组合的 js 文件。不知道如何调试它。能否参考一下你使用的usemin版本。
          猜你喜欢
          • 1970-01-01
          • 2013-07-22
          • 1970-01-01
          • 1970-01-01
          • 2017-08-07
          • 1970-01-01
          • 2018-11-27
          • 2012-11-04
          • 1970-01-01
          相关资源
          最近更新 更多