Grunt 入门 #5

Open
hahnzhu opened this Issue Aug 12, 2014 · 2 comments

Comments

Projects
None yet
3 participants
@hahnzhu

hahnzhu commented Aug 12, 2014

介绍

Grunt 是 JavaScript 世界的构建工具。对于需要反复重复的任务,例如压缩(minification)、编译、单元测试、linting 等,Grunt 自动化工具可以减轻你的劳动,简化你的工作。当你正确配置好了任务,任务运行器就会自动帮你或你的小组完成大部分无聊的工作。

@hahnzhu

This comment has been minimized.

Show comment
Hide comment
@hahnzhu

hahnzhu Aug 12, 2014

快速入门

Grunt 和 Grunt 插件是通过 npm 安装并管理的,npm 是 Node.js 的包管理器。

1、安装 CLI

在继续学习前,你需要先将 Grunt 命令行(CLI)安装到全局环境中。安装时可能需要使用 sudo(针对OSX、*nix、BSD 等系统中)权限或者作为管理员(对于 Windows 环境)来执行以下命令。

npm install -g grunt-cli

上述命令执行完后,grunt 命令就被加入到你的系统路径中了,以后就可以在任何目录下执行此命令了。

注意,安装 grunt-cli 并不等于安装了 Grunt!Grunt CLI 的任务很简单:调用与 Gruntfile 在同一目录中 Grunt。这样带来的好处是,允许你在同一个系统上同时安装多个版本的 Grunt。这样就能让多个版本的 Grunt 同时安装在同一台机器上。

2、CLI 是如何工作的

每次运行 grunt 时,他就利用 node 提供的 require() 系统查找本地安装的 Grunt。正是由于这一机制,你可以在项目的任意子目录中运行 grunt 。

如果找到一份本地安装的 Grunt,CLI 就将其加载,并传递 Gruntfile 中的配置信息,然后执行你所指定的任务。

3、拿一份现有的 Grunt 项目练手

假定 Grunt CLI 已经正确安装,并且已经有一份配置好 package.json 和 Gruntfile 文件的项目了,接下来就很容易拿 Grunt 练手了:

  1. 将命令行的当前目录转到项目的根目录下。
  2. 执行 npm install 命令安装项目依赖的库。
  3. 执行 grunt 命令。

OK,就是这么简单。还可以通过 grunt --help 命令列出所有已安装的 Grunt 任务(task),但是一般更建议去查看项目的文档以获取帮助信息。

4、准备一份新的 Grunt 项目

一般需要在你的项目中添加两份文件:package.json 和 Gruntfile。

  • package.json:此文件被 npm 用于存储项目的元数据,以便将此项目发布为 npm 模块。你可以在此文件中列出项目依赖的 grunt 和 Grunt 插件,放置于 devDependencies 配置段内。
  • Gruntfile:此文件被命名为 Gruntfile.js 或 Gruntfile.coffee,用来配置或定义任务(task)并加载 Grunt 插件的。

5、package.json

package.json 应当放置于项目的根目录中,与 Gruntfile 在同一目录中,并且应该与项目的源代码一起被提交。在上述目录(package.json 所在目录)中运行 npm install 将依据 package.json 文件中所列出的每个依赖来自动安装适当版本的依赖。

下面列出了几种为你的项目创建 package.json 文件的方式:

大部分 grunt-init 模版都会自动创建特定于项目的 package.json 文件。npm init 命令会创建一个基本的 package.json 文件。
复制下面的案例,并根据需要做扩充,参考此说明.

{
  "name": "my-project-name",
  "version": "0.1.0",
  "devDependencies": {
    "grunt": "~0.4.1",
    "grunt-contrib-jshint": "~0.6.0",
    "grunt-contrib-nodeunit": "~0.2.0",
    "grunt-contrib-uglify": "~0.2.2"
  }
}
5-1:安装 Grunt 和 Grunt 插件

向已经存在的 package.json 文件中添加 Grunt 和 grunt 插件的最简单方式是通过 npm install <module> --save-dev 命令。此命令不光安装了,还会自动将其添加到 devDependencies 配置段中,遵循 tilde version range 格式。

例如,下面这条命令将安装 Grunt 最新版本到项目目录中,并将其添加到 devDependencies 内:
npm install grunt --save-dev

同样,grunt 插件和其它 node 模块都可以按相同的方式安装。安装完成后一定要记得将被修改的package.json 文件提交到源码管理器中。

6、Gruntfile

Gruntfile.js 或 Gruntfile.coffee 文件是有效的 JavaScript 或 CoffeeScript 文件,应当放在你的项目根目录中,和 package.json 文件在同一目录层级,并和项目源码一起加入源码管理器。

Gruntfile由以下几部分构成:

  • "wrapper" 函数
  • 项目与任务配置
  • 加载grunt插件和任务
  • 自定义任务
6-1:Gruntfile 文件案例

在下面列出的这个 Gruntfile 中,package.json 文件中的项目元数据(metadata)被导入到 Grunt 配置中, grunt-contrib-uglify 插件中的 uglify 任务(task)被配置为压缩(minify)源码文件并依据上述元数据动态生成一个文件头注释。当在命令行中执行 grunt 命令时,uglify 任务将被默认执行。

module.exports = function(grunt) {

  // Project configuration.
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    uglify: {
      options: {
        banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
      },
      build: {
        src: 'src/<%= pkg.name %>.js',
        dest: 'build/<%= pkg.name %>.min.js'
      }
    }
  });

  // 加载包含 "uglify" 任务的插件。
  grunt.loadNpmTasks('grunt-contrib-uglify');

  // 默认被执行的任务列表。
  grunt.registerTask('default', ['uglify']);

};

前面已经向你展示了整个 Gruntfile,接下来将详细解释其中的每一部分。

"wrapper" 函数

每一份 Gruntfile (和 grunt 插件)都遵循同样的格式,你所书写的 Grunt 代码必须放在此函数内:

module.exports = function(grunt) {
  // Do grunt-related things in here
};

项目和任务配置

大部分的 Grunt 任务都依赖某些配置数据,这些数据被定义在一个 object 内,并传递给 grunt.initConfig 方法。

在下面的案例中,grunt.file.readJSON('package.json') 将存储在 package.json 文件中的 JSON 元数据引入到 grunt config 中。 由于<% %>模板字符串可以引用任意的配置属性,因此可以通过这种方式来指定诸如文件路径和文件列表类型的配置数据,从而减少一些重复的工作。

你可以在这个配置对象中(传递给 initConfig() 方法的对象)存储任意的数据,只要它不与你任务配置所需的属性冲突,否则会被忽略。此外,由于这本身就是 JavaScript,你不仅限于使用 JSON;你可以在这里使用任意的有效的 JS 代码。如果有必要,你甚至可以以编程的方式生成配置。

与大多数 task 一样,grunt-contrib-uglify 插件中的 uglify 任务要求它的配置被指定在一个同名属性中。在这里有一个例子, 我们指定了一个 banner 选项(用于在文件顶部生成一个注释),紧接着是一个单一的名为 build 的 uglify 目标,用于将一个 JS 文件压缩为一个目标文件。

// Project configuration.
grunt.initConfig({
  pkg: grunt.file.readJSON('package.json'),
  uglify: {
    options: {
      banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
    },
    build: {
      src: 'src/<%= pkg.name %>.js',
      dest: 'build/<%= pkg.name %>.min.js'
    }
  }
});

加载 Grunt 插件和任务

像 concatenation、[minification]、grunt-contrib-uglify 和 linting 这些常用的任务(task)都已经以 grunt 插件的形式被开发出来了。只要在 package.json 文件中被列为 dependency(依赖)的包,并通过 npm install 安装之后,都可以在 Gruntfile 中以简单命令的形式使用:

// 加载能够提供"uglify"任务的插件。
grunt.loadNpmTasks('grunt-contrib-uglify');

注意: grunt --help 命令将列出所有可用的任务。

自定义任务
通过定义 default 任务,可以让 Grunt 默认执行一个或多个任务。在下面的这个案例中,执行 grunt 命令时如果不指定一个任务的话,将会执行 uglify 任务。这和执行 grunt uglify 或者 grunt default 的效果一样。default任务列表数组中可以指定任意数目的任务(可以带参数)。

// Default task(s).
grunt.registerTask('default', ['uglify']);

如果 Grunt 插件中的任务(task)不能满足你的项目需求,你还可以在 Gruntfile 中自定义任务(task)。例如,在下面的 Gruntfile 中自定义了一个 default 任务,并且他甚至不依赖任务配置:

module.exports = function(grunt) {

  // A very basic default task.
  grunt.registerTask('default', 'Log some stuff.', function() {
    grunt.log.write('Logging some stuff...').ok();
  });

};

特定于项目的任务不必在 Gruntfile 中定义。他们可以定义在外部.js 文件中,并通过 grunt.loadTasks 方法加载。

hahnzhu commented Aug 12, 2014

快速入门

Grunt 和 Grunt 插件是通过 npm 安装并管理的,npm 是 Node.js 的包管理器。

1、安装 CLI

在继续学习前,你需要先将 Grunt 命令行(CLI)安装到全局环境中。安装时可能需要使用 sudo(针对OSX、*nix、BSD 等系统中)权限或者作为管理员(对于 Windows 环境)来执行以下命令。

npm install -g grunt-cli

上述命令执行完后,grunt 命令就被加入到你的系统路径中了,以后就可以在任何目录下执行此命令了。

注意,安装 grunt-cli 并不等于安装了 Grunt!Grunt CLI 的任务很简单:调用与 Gruntfile 在同一目录中 Grunt。这样带来的好处是,允许你在同一个系统上同时安装多个版本的 Grunt。这样就能让多个版本的 Grunt 同时安装在同一台机器上。

2、CLI 是如何工作的

每次运行 grunt 时,他就利用 node 提供的 require() 系统查找本地安装的 Grunt。正是由于这一机制,你可以在项目的任意子目录中运行 grunt 。

如果找到一份本地安装的 Grunt,CLI 就将其加载,并传递 Gruntfile 中的配置信息,然后执行你所指定的任务。

3、拿一份现有的 Grunt 项目练手

假定 Grunt CLI 已经正确安装,并且已经有一份配置好 package.json 和 Gruntfile 文件的项目了,接下来就很容易拿 Grunt 练手了:

  1. 将命令行的当前目录转到项目的根目录下。
  2. 执行 npm install 命令安装项目依赖的库。
  3. 执行 grunt 命令。

OK,就是这么简单。还可以通过 grunt --help 命令列出所有已安装的 Grunt 任务(task),但是一般更建议去查看项目的文档以获取帮助信息。

4、准备一份新的 Grunt 项目

一般需要在你的项目中添加两份文件:package.json 和 Gruntfile。

  • package.json:此文件被 npm 用于存储项目的元数据,以便将此项目发布为 npm 模块。你可以在此文件中列出项目依赖的 grunt 和 Grunt 插件,放置于 devDependencies 配置段内。
  • Gruntfile:此文件被命名为 Gruntfile.js 或 Gruntfile.coffee,用来配置或定义任务(task)并加载 Grunt 插件的。

5、package.json

package.json 应当放置于项目的根目录中,与 Gruntfile 在同一目录中,并且应该与项目的源代码一起被提交。在上述目录(package.json 所在目录)中运行 npm install 将依据 package.json 文件中所列出的每个依赖来自动安装适当版本的依赖。

下面列出了几种为你的项目创建 package.json 文件的方式:

大部分 grunt-init 模版都会自动创建特定于项目的 package.json 文件。npm init 命令会创建一个基本的 package.json 文件。
复制下面的案例,并根据需要做扩充,参考此说明.

{
  "name": "my-project-name",
  "version": "0.1.0",
  "devDependencies": {
    "grunt": "~0.4.1",
    "grunt-contrib-jshint": "~0.6.0",
    "grunt-contrib-nodeunit": "~0.2.0",
    "grunt-contrib-uglify": "~0.2.2"
  }
}
5-1:安装 Grunt 和 Grunt 插件

向已经存在的 package.json 文件中添加 Grunt 和 grunt 插件的最简单方式是通过 npm install <module> --save-dev 命令。此命令不光安装了,还会自动将其添加到 devDependencies 配置段中,遵循 tilde version range 格式。

例如,下面这条命令将安装 Grunt 最新版本到项目目录中,并将其添加到 devDependencies 内:
npm install grunt --save-dev

同样,grunt 插件和其它 node 模块都可以按相同的方式安装。安装完成后一定要记得将被修改的package.json 文件提交到源码管理器中。

6、Gruntfile

Gruntfile.js 或 Gruntfile.coffee 文件是有效的 JavaScript 或 CoffeeScript 文件,应当放在你的项目根目录中,和 package.json 文件在同一目录层级,并和项目源码一起加入源码管理器。

Gruntfile由以下几部分构成:

  • "wrapper" 函数
  • 项目与任务配置
  • 加载grunt插件和任务
  • 自定义任务
6-1:Gruntfile 文件案例

在下面列出的这个 Gruntfile 中,package.json 文件中的项目元数据(metadata)被导入到 Grunt 配置中, grunt-contrib-uglify 插件中的 uglify 任务(task)被配置为压缩(minify)源码文件并依据上述元数据动态生成一个文件头注释。当在命令行中执行 grunt 命令时,uglify 任务将被默认执行。

module.exports = function(grunt) {

  // Project configuration.
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    uglify: {
      options: {
        banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
      },
      build: {
        src: 'src/<%= pkg.name %>.js',
        dest: 'build/<%= pkg.name %>.min.js'
      }
    }
  });

  // 加载包含 "uglify" 任务的插件。
  grunt.loadNpmTasks('grunt-contrib-uglify');

  // 默认被执行的任务列表。
  grunt.registerTask('default', ['uglify']);

};

前面已经向你展示了整个 Gruntfile,接下来将详细解释其中的每一部分。

"wrapper" 函数

每一份 Gruntfile (和 grunt 插件)都遵循同样的格式,你所书写的 Grunt 代码必须放在此函数内:

module.exports = function(grunt) {
  // Do grunt-related things in here
};

项目和任务配置

大部分的 Grunt 任务都依赖某些配置数据,这些数据被定义在一个 object 内,并传递给 grunt.initConfig 方法。

在下面的案例中,grunt.file.readJSON('package.json') 将存储在 package.json 文件中的 JSON 元数据引入到 grunt config 中。 由于<% %>模板字符串可以引用任意的配置属性,因此可以通过这种方式来指定诸如文件路径和文件列表类型的配置数据,从而减少一些重复的工作。

你可以在这个配置对象中(传递给 initConfig() 方法的对象)存储任意的数据,只要它不与你任务配置所需的属性冲突,否则会被忽略。此外,由于这本身就是 JavaScript,你不仅限于使用 JSON;你可以在这里使用任意的有效的 JS 代码。如果有必要,你甚至可以以编程的方式生成配置。

与大多数 task 一样,grunt-contrib-uglify 插件中的 uglify 任务要求它的配置被指定在一个同名属性中。在这里有一个例子, 我们指定了一个 banner 选项(用于在文件顶部生成一个注释),紧接着是一个单一的名为 build 的 uglify 目标,用于将一个 JS 文件压缩为一个目标文件。

// Project configuration.
grunt.initConfig({
  pkg: grunt.file.readJSON('package.json'),
  uglify: {
    options: {
      banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
    },
    build: {
      src: 'src/<%= pkg.name %>.js',
      dest: 'build/<%= pkg.name %>.min.js'
    }
  }
});

加载 Grunt 插件和任务

像 concatenation、[minification]、grunt-contrib-uglify 和 linting 这些常用的任务(task)都已经以 grunt 插件的形式被开发出来了。只要在 package.json 文件中被列为 dependency(依赖)的包,并通过 npm install 安装之后,都可以在 Gruntfile 中以简单命令的形式使用:

// 加载能够提供"uglify"任务的插件。
grunt.loadNpmTasks('grunt-contrib-uglify');

注意: grunt --help 命令将列出所有可用的任务。

自定义任务
通过定义 default 任务,可以让 Grunt 默认执行一个或多个任务。在下面的这个案例中,执行 grunt 命令时如果不指定一个任务的话,将会执行 uglify 任务。这和执行 grunt uglify 或者 grunt default 的效果一样。default任务列表数组中可以指定任意数目的任务(可以带参数)。

// Default task(s).
grunt.registerTask('default', ['uglify']);

如果 Grunt 插件中的任务(task)不能满足你的项目需求,你还可以在 Gruntfile 中自定义任务(task)。例如,在下面的 Gruntfile 中自定义了一个 default 任务,并且他甚至不依赖任务配置:

module.exports = function(grunt) {

  // A very basic default task.
  grunt.registerTask('default', 'Log some stuff.', function() {
    grunt.log.write('Logging some stuff...').ok();
  });

};

特定于项目的任务不必在 Gruntfile 中定义。他们可以定义在外部.js 文件中,并通过 grunt.loadTasks 方法加载。

@fayching fayching reopened this Dec 26, 2014

@fayching fayching added the doc label Dec 26, 2014

@oldfu

This comment has been minimized.

Show comment
Hide comment
@oldfu

oldfu Oct 14, 2015

学习了!

oldfu commented Oct 14, 2015

学习了!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment