[grunt] grunt-usemin 介绍
发布于 4 年前 作者 qjzd 4092 次浏览 来自 码农

git地址

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

Notice 提示

grunt-usemin is going under some major developments to tackle the long list of issues. As they might break with master they are merged into dev branch.

grunt-usemin 使用一些主要的开发来解决一系列的问题。

Currently what has been merged:

  • support for a resolveSource function option
  • warning for any missing files instead of silent errors
  • migrate from regexps to HTML parser
  • (current) support for multiple target
当前已经被合并的
支持resolveSource方法选项
有缺失的文件,会警告
从regexp迁移到HTML解析器
现在支持多任务

Getting Started 入门指南

If you haven’t used grunt before, be sure to check out the Getting Started guide, as it explains how to create a gruntfile as well as install and use grunt plugins. Once you’re familiar with that process, install this plugin with this command:

如果你之前还没有接触过grunt,务必县阅读Grunt的入门指南,他会解释创建gruntfile以及安装和使用grunt插件。一旦你熟悉了grunt,就可以使用安装usemin插件。
npm install grunt-usemin --save-dev

Tasks 任务们

usemin replaces the references of scripts, stylesheets and other assets within HTML files dynamically with optimized versions of them. To do this usemin exports 2 built-in tasks called useminPrepare and usemin and utilizes a couple of other Grunt plugins for the optimization process. usemin does this by generating the subtasks for these Grunt plugins dynamically.

“usemin”取代了引用的脚本、样式表和其他资源文件在HTML文件动态优化的版本。为此“usemin”内置了两个任务,分别为“useminPrepare”和“usemin”和利用其他几个Grunt插件的优化过程。“usemin”通过动态地生成这些Grunt的子任务插件。

The built-in tasks of usemin:

  • useminPrepare prepares the configuration to transform specific blocks in the scrutinized file into a single line, targeting an optimized version of the files. This is done by generating subtasks called generated for each of the optimization steps handled by the Grunt plugins listed below.
  • usemin replaces the blocks by the file they reference, and replaces all references to assets by their revisioned version if it is found on the disk. This target modifies the files it is working on.
“usemin”内置的任务:
*“useminPrepare”有一些配置项,针对一个优化版本的文件,可以转换文件中的特定的块转换成一行。这样做是通过生成子任务称为“generated”的可选优化步骤,这些步骤由下面列出的Grunt的插件。
*“usemin”取代了块的文件引用, 并使用修订版本(如果在磁盘上找到)替换所有引用资源。 任务工作的时候文件会被修改。

Grunt plugins which usemin can use to optimize files:

  • concat concatenates files (usually JS or CSS).
  • uglify minifies JS files.
  • cssmin minifies CSS files.
  • filerev revisions static assets through a file content hash.

To install these plugins, run:

安装这些插件,运行一下命令
npm install grunt-contrib-concat grunt-contrib-uglify grunt-contrib-cssmin grunt-filerev --save-dev

Important: You still need to manually install and load these dependencies.

重要:你仍然需要手动安装和加载这些依赖项。

In a typical usemin setup you launch useminPrepare first, then call every optimization step you want through their generated subtask and call usemin in the end. It could look like this:

一个经典的“usemin”设置,首先要启用“useminPrepare”,然后依次调用每一个优化步骤你想通过他们生成的子任务,最后调用“usemin”它可能看起来像这样:
// simple build task
grunt.registerTask('build', [
  'useminPrepare',
  'concat:generated',
  'cssmin:generated',
  'uglify:generated',
  'filerev',
  'usemin'
]);

The useminPrepare task

useminPrepare task updates the grunt configuration to apply a configured transformation flow to tagged files (i.e. blocks). By default the transformation flow is composed of concat and uglify for JS files, but it can be configured.

“useminPrepare”任务更新grunt的配置,去应用一个已经配置的转向流程用于被标记的文件。(比如块)
默认情况下转换流是由“concat”和“uglify”JS文件,但它可以配置。

Blocks

Blocks are expressed as:

<!-- build:<type>(alternate search path) <path> -->
... HTML Markup, list of script / link tags.
<!-- endbuild -->
  • type: can be js, css or a custom type with a block replacement function defined
  • If another type, the block will be ignored. Useful for “development only” blocks that won’t appear in your build
  • alternate search path: (optional) By default the input files are relative to the treated file. Alternate search path allows one to change that
  • path: the file path of the optimized file, the target output
type:可以“js”,的css或一个自定义类型(块替换函数), 如果另一种类型,块将被忽略。开发时,块不应该出现在您的构建中。
alternate search path: 默认输入文件相对于处理文件。 交替搜索路径允许改变这种状况。
path: 优化文件的文件路径,目标输出

An example of this in completed form can be seen below:

一个例子
<!-- build:js js/app.js -->
<script src="js/app.js"></script>
<script src="js/controllers/thing-controller.js"></script>
<script src="js/models/thing-model.js"></script>
<script src="js/views/thing-view.js"></script>
<!-- endbuild -->

Transformation flow 转换流程

The transformation flow is made of sequential steps: each of the steps transform the file, and useminPrepare will modify the configuration in order for the described steps to be correctly performed. By default the flow is: concat -> uglify. Additionally to the flow, at the end, some postprocessors can be launched to further alter the configuration. Let’s have an example, using the default flow (we’re just going to look at the steps), app for input dir, dist for output dir, and the following block:

转换流是由连续的步骤:每个步骤转换文件,“useminPrepare”将修改的配置以描述步骤正确执行。
默认情况下,流:concat - >uglify。
此外,最后,可以启动一些后处理程序进一步改变配置。
我们有一个例子,使用默认流(我们只是去看看步骤),“app”输入目录,“dist”输出目录,和下面的块:
<!-- build:js js/app.js -->
<script src="js/app.js"></script>
<script src="js/controllers/thing-controller.js"></script>
<script src="js/models/thing-model.js"></script>
<script src="js/views/thing-view.js"></script>
<!-- endbuild -->

The produced configuration will look like:

生成的配置像这样
{
  concat: {
    generated: {
      files: [
        {
          dest: '.tmp/concat/js/app.js',
          src: [
            'app/js/app.js',
            'app/js/controllers/thing-controller.js',
            'app/js/models/thing-model.js',
            'app/js/views/thing-view.js'
          ]
        }
      ]
    }
  },
  uglify: {
    generated: {
      files: [
        {
          dest: 'dist/js/app.js',
          src: [ '.tmp/concat/js/app.js' ]
        }
      ]
    }
  }
}

Directories 目录

Internally, the task parses your HTML markup to find each of these blocks, and initializes the corresponding Grunt config for the concat / uglify tasks when type=js, the concat / cssmin tasks when type=css. One doesn’t need to specify a concat/uglify/cssmin configuration anymore. It uses only one target: html, with a list of the concerned files. For example, in your Gruntfile.js: By default, it will consider the directory where the looked-at file is located as the ‘root’ filesystem. Each relative path (for example to a javascript file) will be resolved from this path. Same goes for the absolute ones. If you need to change the ‘root’ dir, use the root option (see below).

在内部,任务解析HTML标记找到每一个块,并初始化相应的Grunt任务配置concat /uglify“ 当 type= js”时,concat / cssmin任务,当type=css。一个不需要指定一个concat /uglify/ cssmin配置了。
它使用只有一个目标:“html”,有关文件的列表。例如,在你的“Gruntfile.js”:
在默认情况下,它将考虑html目标列表文件的所在目录的根文件系统。每一个相对路径(例如一个javascript文件)将从这条路得到解决。绝对的也一样。
如果你需要更改根目录,使用“root”选项(见下文)。
useminPrepare: {
  html: 'index.html'
}

Targets can also be configured using the grunt src-dest files syntax http://gruntjs.com/configuring-tasks#files, e.g.

目标们还可以利用grunt src-dest配置文件的语法
useminPrepare: {
  foo: {
    src: ['index.html', 'another.html']
  },
  bar: {
    src: 'index.html'
  }
}

Options 选项

dest

Type: 'string’
Default: nil Base directory where the transformed files should be output.

转换后的文件的输出目录

staging

Type: 'string’
Default: .tmp Base directory where the temporary files should be output (e.g. concatenated files).

临时文件的输入路径,默认时.tmp目录

root

Type: ‘string’ or 'Array’
Default: nil The root directory from which your files will be resolved.

文件所在的根路径

flow 流程

Type: 'object’
Default: { steps: { js: ['concat', 'uglify'], css: ['concat', 'cssmin'] }, post: {} } This allow you to configure the workflow, either on a per-target basis, or for all the targets. You can change the steps or the post-processors (post) separately.

这允许您配置工作流, 可以是单独一个目标,或者时所有目标。
你可以改变后处理器的“steps”或单独(“post”)。

For example:

  • to change the js steps and post for the target html:
useminPrepare: {
  html: 'index.html',
  options: {
    flow: {
      html: {
        steps: {
          js: ['uglify']
        },
        post: {}
      }
    }
  }
}
  • to change the js steps and post for all targets:
useminPrepare: {
  html: 'index.html',
  options: {
    flow: {
      steps: {
        js: ['uglify']
      },
      post: {}
    }
  }
}
  • to customize the generated configuration via post-processors:
useminPrepare: {
  html: 'index.html',
  options: {
    flow: {
      steps: {
        js: ['uglify']
      },
      post: {
        js: [{
          name: 'uglify',
          createConfig: function (context, block) {
            var generated = context.options.generated;
            generated.options = {
              foo: 'bar'
            };
          }
        }]
      }
    }
  }
}

The given steps or post-processors may be specified as strings (for the default steps and post-processors), or as an object (for the user-defined ones).

给定的步骤或后处理器可能指定为字符串(默认步骤和后处理器),或作为一个对象(用户定义的)。

User-defined steps and post-processors 用户自定义steps和post-processors

User-defined steps and post-processors must have 2 attributes:

用户定义的步骤和后处理器必须有两个属性:
  • name: name of the Gruntfile attribute that holds the corresponding config
  • createConfig which is a 2 arguments function ( a context and the treated block) For an example of steps/post-processors, you can have a look at concat and uglify in the lib/config directory of this repository.
*“name”:“Gruntfile”属性持有相应的配置
*“createConfig”具有一个2参数的函数(“context”和“block”)
steps/post-processors的一个例子,你可以看看“concat”和“uglify”的lib / config目录。
createConfig

The createConfig function is responsible for creating (or updating) the configuration associated to the current step/post-processor. It takes 2 arguments ( a context and the treated block), and returns a configuration object.

“createConfig”方法是负责创建(或更新)的当前 step/post-processor相关的配置。
需要2个参数(“context”和“block”),并返回一个配置对象。
context

The context object represent the current context the step/post-processor is running in. As the step/post-processor is a step of a flow, it must be listed in the input files and directory it must write a configuration for, potentially the already existing configuration. It must also indicate to the other steps/post-processor which files it will output in which directory. All this information is held by the context object.

“context”对象代表当前上下文的step/post-processor中运行。step/post-processor是一个步骤的流程, 必须输入文件和目录中列出必须写一个配置,可能已经存在的配置。它还必须显示的其他step/post-processor文件,它将输出目录。所有这些信息都被“context”对象。

Attributes:

  • inDir: the directory where the input file for the step/post-processors will be
  • inFiles: the list of input file to take care of
  • outDir: where the files created by the step/post-processors will be
  • outFiles: the files that are going to be created
  • last: whether or not we’re the last step of the flow
  • options: options of the Gruntfile.js for this step (e.g. if the step is named foo, holds configuration of the Gruntfile.js associated to the attribute foo)
属性:
*“inDir”:“输入”的目录文件的 step/post-processors
*“inFiles”:输入文件的列表
*“outDir”:在文件创建的步骤/后处理器
*“outFiles”:将创建的文件
*“last”:是否我们流的最后一步
*“options”:“Gruntfile选项。js”这一步(例如,如果一步是名为“foo”,拥有“Gruntfile的配置。js的相关属性“foo”)
block

The actual looked-at block, parsed and put in a structure. Example: The following block

<!-- build:js scripts/site.js -->',
<script src="foo.js"></script>',
<script src="bar.js"></script>',
<script src="baz.js"></script>',
<!-- endbuild -->'

is parsed as, and given to createConfig as:

var block = {
  type: 'js',
  dest: 'scripts/site.js',
  src: [
    'foo.js',
    'bar.js',
    'baz.js'
  ],
  raw: [
    '    <!-- build:js scripts/site.js -->',
    '    <script src="foo.js"></script>',
    '    <script src="bar.js"></script>',
    '    <script src="baz.js"></script>',
    '    <!-- endbuild -->'
  ]
};

The usemin task usemin任务

The usemin task has 2 actions:

  • First it replaces all the blocks with a single “summary” line, pointing to a file creating by the transformation flow.
  • Then it looks for references to assets (i.e. images, scripts, …), and tries to replace them with their revved version if it can find one on disk
usemin的任务有两个动作:
*首先它仅用一“总结”行替换所有的快, 该文件时使用转换流程生产出来的。
*然后查找引用资源(如图像、脚本…),  如果能找到一个在磁盘上, 并试图用他们的转换后的版本。

Finding assets 发现资源

By default usemin will look for a map object created by grunt-filerev, located in grunt.filerev.summary. If it does not find it it will revert to disk lookup which is longer. Note that by using the options.revmap (see below), you can furnish a map object.

默认情况下“usemin”将寻找一个由位于“grunt.filerev.summary”的[grunt-filerev]的map对象由,。如果不找到它将到磁盘再查找。
注意,通过使用“options.revmap”(见下文),您可以提供一个映射对象。

On directories 在目录上

When usemin tries to replace referenced assets with their revved version it has to look at a collection of directories (asset search paths): for each of the directories of this collection it will look at the below tree, and try to find the revved version. This asset search directories collection is by default set to the location of the file that is scrutinized but can be modified (see Options below).

Example 1: file dist/html/index.html has the following content:

<link rel="stylesheet" href="styles/main.css">
<img src="../images/test.png">

By default usemin will look under dist/html for revved versions of:

  • styles/main.css: a revved version of main.css will be looked at under the dist/html/styles directory. For example a file dist/html/styles/main.1234.css will match (although dist/html/main.1234.css won’t: the path of the referenced file is important)
  • ../images/test.png: it basically means that a revved version of test.png will be looked for under the dist/images directory
默认情况下“usemin”将查看dist/html中的文件,并对其中的文件进行转换。
* styles/main.css: 一个转换 cha的main.css将被在dist/htm文件l/styles目录下找到,举个例子:文件dist/html/styles/main.1234.css将匹配(虽然dist/html/main.1234.css不会匹配,引用路径是重要的)
*“../images/test.png”:它基本上意味着转换的版本test.png将会在dist/images目录中

Example 2: file dist/html/index.html has the following content:

<link rel="stylesheet" href="/styles/main.css">
<img src="/images/test.png">

By default usemin will look under dist/html for revved versions of styles/main.css and images/test.png. Now let’s suppose our assets are scattered in dist/assets. By changing the asset search path list to ['dist/assets'], the revved versions of the files will be searched for under dist/assets (and thus, for example, dist/assets/images/test.875487.png and dist/assets/styles/main.98090.css) will be found.

默认情况下“usemin”将会查看dist/html为了styles/main.css和images/test.png的转换后版本。
现在,让我们假设我们的资资源散在dist/assets”。通过改变资源搜索路径列表(dist/assets”), 转换版本的文件将会寻找在dist/assets的(例如, dist/assets/images/test.875487.png”和“dist/assets/styles/main.98090.css”)将被发现。

Options 选项

assetsDirs 资源目录们

Type: 'Array’
Default: Single item array set to the value of the directory where the currently looked at file is. List of directories where we should start to look for revved version of the assets referenced in the currently looked at file.

Default: 只有一个项的数组,这个项的值,是当前被查找文件所在的目录。
我么查找revved version资源的目录列表

Example:

usemin: {
  html: 'build/index.html',
  options: {
    assetsDirs: ['foo/bar', 'bar']
  }
}

Suppose in index.html you have a reference to /images/foo.png, usemin will search for the revved version of /images/foo.png, say /images/foo.12345678.png in any directories in assetsDirs options.

In others words, given the configuration above, usemin will search for the existence of one of these files:

  • foo/bar/images/foo.12345678.png
  • bar/images/foo.12345678.png

patterns

Type: 'Object’
Default: Empty

Allows for user defined pattern to replace reference to files. For example, let’s suppose that you want to replace all references to 'image.png' in your Javascript files by the revved version of image.png found below the directory images. By specifying something along the lines of:

允许用户定义的模式来取代参考文件。例如,让我们假设您想要使用下面的images目录下找到转换后的'image.png’,来替换Javascript文件中所有'image.png’引用
通过指定的路线:
usemin: {
  js: '*.js',
  options: {
    assetsDirs: 'images',
    patterns: {
      js: [
        [/(image\.png)/, 'Replacing reference to image.png']
      ]
    }
  }
}

So in short:

  • key in pattern should match the target (e.g js key for the target js)
  • Each pattern is an array of arrays. These arrays are composed of 4 items (last 2 are optional):
    • First one if the regexp to use. The first group is the one that is supposed to represent the file reference to replace
    • Second one is a logging string
    • A function which behaves like a filter-in. Receives the matched group and must return the file path of the asset. Great functionality when you have a compiled file by a template engine.
    • A function which behaves like a filter-out. It receives the revved path of the asset and must return it as an url from it will be reached from web server.
所以简而言之:
*pattern应该匹配目标(e.g  `js` key for the target `js`)
*每个pattern是一个数组的数组。这些数组是由4项(最后2是可选的):
*第一个如果要使用的regexp。第一组是一个代表该文件引用来取代
*第二个是一个日志的字符串
*函数的行为像一个过滤器。接收匹配组和必须返回该文件路径的资源。当你有一个伟大的功能编译文件模板引擎。
*函数的行为像一个过滤掉。它接收的资源,必须返回它 就像一个url从web服务器。

blockReplacements 块替换元素们

Type: 'Object’
Default: { css: function (block) { ... }, js: function (block) { ... } }

This lets you define how blocks get their content replaced. Useful to have block types other that css and js.

  • Object key matches a block type
  • Value is the replacement function for that block type.
    • The replacement function gets called with a single argument: a block object.
    • Must return a String, the “summary” line that will replace the block content.
这允许您定义块内容替换。有用的块类型其他“css”和“js”。
*类型匹配块的重要对象
*值的替代功能块类型。
*替换函数会调用一个参数:一个(块)(#块)对象。
*必须返回一个字符串,将取代的“summary”行块内容。

For example, to create a less block you could define its replacement function like this:

usemin: {
  html: 'index.html',
  options: {
    blockReplacements: {
      less: function (block) {
          return '<link rel="stylesheet" href="' + block.dest + '">';
      }
    }
  }
}

revmap

Type: 'String’
Default: Empty

Indicate the location of a map file, as produced by grunt-filerev for example. This map file is a simple JSON file, holding an object which attributes are the original file and associated value is the transformed file. For example:

显示地图文件的位置,由“grunt-filerev”为例。这个地图文件是一个简单的JSON文件,持有一个对象
他的属性值转换后的原始文件和相关文件。例如:
{
  "foo.png": "foo.1234.png"
}

This map will be used instead of looking for file on the disk.

map将使用, 而不是在磁盘上寻找文件。

On directories

The main difference to be kept in mind, regarding directories and tasks, is that for useminPrepare, the directories needs to indicate the input, transient and output path needed to output the right configuration for the processors pipeline, whereas in the case of usemin it only reflects the output paths, as all the needed assets should have been output to the destination dir (either transformed or just copied)

主要的区别要牢记,对于目录和任务,是“useminPrepare”, 需要指定输入的目录
瞬态和输出路径需要输出正确的管道配置的处理器,
而对于“usemin”它只反映了输出路径,应该为所有需要的资源输出到指定的目录(转换或仅仅拷贝)

useminPrepare

useminPrepare is trying to prepare the right configuration for the pipeline of actions that are going to be applied on the blocks (for example concatenation and uglify-cation). As such it needs to have the input directory, temporary directories (staging) and destination directory. The files referenced in the block are either absolute or relative (/images/foo.png or ../../images/foo.png). Absolute files references are looked in a given set of search path (input), which by default is set to the directory where the html/css file examined is located (can be overridden per block, or more generally through root option). Relative files references are also looked at from location of the examined file, unless stated otherwise.

“useminPrepare”时尝试准备正确的配置将管道的操作应用于块(例如连接和uglify-cation)。因此它需要输入目录,临时目录(分期)和目标目录。块中引用的文件要么时绝对或者是相对(' /images/foo.png”或“../../images/foo.png”)。
绝对文件引用了在给定的搜索路径(输入), 默认设置待检查html / css文件所在目录(可以覆盖每个块或更多一般通过“root”选项)。
相对文件引用也从检查文件的位置,除非注明。

usemin

usemin target replaces references to images, scripts, css, … in the furnished files (html, css, …). These references may be either absolute (i.e. /images/foo.png) or relative (i.e. image/foo.png or ../images/foo.png). When the reference is absolute a set of asset search paths should be looked at under the destination directory (for example, using the previous example, and searchpath equal to ['assets'], usemin would try to find either a revved version of the image of the image below the assets directory: for example dest/assets/images/foo.1223443.png). When the reference is relative, by default the referenced item is looked in the path relative to the current file location in the destination directory (e.g. with the preceding example, if the file is build/bar/index.html, then transformed index.html will be in dist/bar, and usemin will look for dist/bar/../images/foo.32323.png).

“usemin”目标取代引用图片,脚本、css,……在配置文件(html、css、…)
这些引用可以是绝对的(i.e. `/images/foo.png`)也可以是相对(i.e. `image/foo.png`or `../images/foo.png`)。
当引用资源的路径是绝对的,(例如,使用前面的例子,“searchpath”相当于 ['assets'], “usemin”将试图找到一个版本的图像
下图的“assets”目录: 例如`dest/assets/images/foo.1223443.png`)。
这是引用是相对时, 默认情况下,引用项将被在当前文件的位置所在的目录下查找
(例如, 前面的例子中,如果文件是build/bar/index.html,然后改变了“index.html”
将在“dist/bar”,和“usemin”寻找“dist/bar/../images/foo.32323.png”)。

Use cases

Simple one

|
+- app
|   +- index.html
|   +- assets
|       +- js
|          +- foo.js
|          +- bar.js
+- dist

We want to optimize foo.js and bar.js into optimized.js, referenced using relative path. index.html should contain the following block:

<!-- build:js assets/js/optimized.js -->
<script src="assets/js/foo.js"></script>
<script src="assets/js/bar.js"></script>
<!-- endbuild -->

We want our files to be generated in the dist directory.

By using the following useminPrepare config:

{
  useminPrepare: {
    html: 'app/index.html',
    options: {
      dest: 'dist'
    }
  }
}

This will, on the fly, generate the following configuration:

{
  concat:
  {
    '.tmp/concat/assets/js/optimized.js': [
      'app/assets/js/foo.js',
      'app/assets/js/bar.js'
    ]
  },

  uglify:
  {
    'dist/assets/js/optimized.js': ['.tmp/concat/assets/js/optimized.js']
  }
}

HTML file and asset files in sibling directories

app
|
+- html
|   +- index.html
+- assets
|   +- js
|      +- foo.js
|      +- bar.js
+- dist

We want to optimize foo.js and bar.js into optimized.js, referenced using absolute path. index.html should contain the following block:

<!-- build:js /assets/js/optimized.js -->
<script src="/assets/js/foo.js"></script>
<script src="/assets/js/bar.js"></script>
<!-- endbuild -->

We want our files to be generated in the dist directory.

By using the following useminPrepare config:

{
  useminPrepare: {
    html: 'html/index.html',
    options: {
      root: 'app',
      dest: 'dist'
    }
  }
}

This will, on the fly, generate the following configuration:

{
  concat:
  {
    '.tmp/concat/assets/js/optimized.js': [
      'app/assets/js/foo.js',
      'app/assets/js/bar.js'
    ]
  },

  uglify:
  {
    'dist/assets/js/optimized.js': ['.tmp/concat/assets/js/optimized.js']
  }
}

License

BSD license and copyright Google

回到顶部