Grunt使用usemin和useminPrepare多个目标

28

根据usemin issues,最新版本的useminuseminPrepare支持多个目标:

useminPrepare支持多个目标:

usemin支持:

我尝试使用以下配置来使用多个目标:

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是两个单页面应用程序的主要页面。

感谢您的帮助!


你解决过这个问题吗? - Sean Anderson
1
@SeanAnderson:我最终使用了两个Grunt配置文件,作为一种暂时的解决方案。 - Răzvan Flavius Panda
2
正如@sorich87在此线程的末尾指出的那样(https://github.com/yeoman/grunt-usemin/pull/206),目前支持多个目标,但尚不支持多个目的地。请参见https://github.com/yeoman/grunt-usemin/issues/157。 - svassr
6个回答

5

默认情况下,usemin 会尝试从目标名称中检测解析器类型(html、css)。当您使用的目标名称不是有效的解析器类型时,应使用 type 选项手动指定解析器类型。这将导致每个目标都有两个目标,一个用于 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
@user1828780,还要考虑直接通过js引用资源是一种不好的做法,有时候在不执行js代码的情况下很难找到所有的引用。最好通过保持关注点分离来避免这种情况,将行为放在js中,表示放在css中,语义放在html中,js可以通过css类和数据属性来操作这些层。 - smbeiragh
当与filerev一起使用时,usemin不会用其修订后的文件名替换已构建的js文件。有人知道解决方法吗? - Alex King

0

你需要让两个项目都在同一个代码库和同一个Gruntfile下吗?

你自己说过它们是“两个单页应用的主页面”。如果有能力将其分为两个不同的项目,你可能会避免一些麻烦。

或者,你可以将两个索引文件放在一个公共目录下。这就是我如何使用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版本吗? - James Gardiner

0

不确定这是否有帮助,但我能够通过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 文件夹中,并设置其他开关。


0

尽管 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"
        }

0
作為一種解決方法(經過一段時間的努力),我們決定兩次運行整個grunt任務,並添加了一個grunt選項來切換目標文件的值。 雖然不太優雅,但卻簡單明了。

0
我曾尝试过类似的事情,其中我有多个具有不同依赖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 -->

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接