Grunt是用于Web开发的出色构建系统,但是设置起来可能很棘手。 在本指南中,您将学习配置Grunt来构建现代的Web项目。 完成后,您的Gruntfile将能够:
- 将文件从源目录复制到构建目录
- 删除构建文件
- 编译手写笔文件并为其添加供应商前缀
- 编译CoffeeScript
- 缩小CSS和JavaScript
- 编译玉
- 修改后自动生成源文件
- 运行开发服务器
入门
如果尚未安装Node.js和NPM ,请安装它。 您还需要通过运行npm install -g grunt-cli
来安装Grunt命令行界面。 这使您可以从系统上的任何位置运行grunt
命令。
使用下面的内容创建一个package.json
。
json
{
"name": "grunt_tutorial",
"description": "An example of how to set up Grunt for web development.",
"author": "Landon Schropp (http://landonschropp.com)",
"dependencies": {
"grunt": "0.x.x",
"grunt-autoprefixer": "0.2.x",
"grunt-contrib-clean": "0.5.x",
"grunt-contrib-coffee": "0.7.x",
"grunt-contrib-connect": "0.4.x",
"grunt-contrib-copy": "0.4.x",
"grunt-contrib-cssmin": "0.6.x",
"grunt-contrib-jade": "0.8.x",
"grunt-contrib-jshint": "0.6.x",
"grunt-contrib-stylus": "0.8.x",
"grunt-contrib-uglify": "0.2.x",
"grunt-contrib-watch": "0.5.x"
},
"engine": "node >= 0.10"
}
该文件将您的项目定义为NPM包,并声明您项目的依赖项。 每个依赖项都有一个版本号。 例如, grunt-contrib-copy: "0.4.x"
告诉NPM安装grunt-contrib-copy
软件包的最新0.4版本。 在控制台中运行npm install
以安装依赖项。
复制
一个好的构建脚本总是将源代码与构建文件分开。 这种分离使您可以在不影响源代码的情况下破坏构建,并防止意外编辑构建。
首先,您将使Grunt将文件从source
目录复制到build
目录。 创建一个Gruntfile.js
文件,并将以下内容粘贴到其中:
javascript
module.exports = function(grunt) {
// configure the tasks
grunt.initConfig({
copy: {
build: {
cwd: 'source',
src: [ '**' ],
dest: 'build',
expand: true
},
},
});
// load the tasks
grunt.loadNpmTasks('grunt-contrib-copy');
// define the tasks
};
让我们分解一下。 在Node中,当您require
一个模块时,将调用modules.exports
函数并返回结果。 通过在Gruntfile中设置modules.exports
,您可以告诉Node返回定义Grunt配置的函数。 grunt.initConfig
是一种带有一个参数的方法:一个对象,其属性配置各个Grunt任务。
在Grunt配置中,您已经添加了copy
任务的配置。 该任务有一个子任务,称为build
。 在Grunt中,某些任务(称为多任务 )可以具有多个子任务 ,这些子任务可以分别调用。 对于copy
,您不需要此功能,但是仍然需要至少具有一个子任务。
内部build
子任务是Grunt的文件数组格式 。 这种格式是Grunt允许您为任务提供源文件的方式之一。 cwd
指向源文件相对的目录,并且src
指定源文件。 '**'
是一个通配图案 ,告诉格朗特匹配任何文件。 dest
是Grunt将输出任务结果的位置。 您已将其设置为"build"
以告知grunt将内容复制到build目录。 如果存在source/index.html
文件,则此配置将输出build/index.html
。 最后,将expand
参数设置为true
以启用所有这些选项。
grunt.loadNpmTasks("grunt-contrib-copy");
告诉Grunt从grunt-contrib-copy
包中加载任务。 这给了我们一个copy
命令,您可以通过在控制台中键入grunt copy
来运行它。
清洁
现在您有了build
目录,是时候编写一个将其清除的任务了。 复制配置之后,添加以下内容:
javascript
clean: {
build: {
src: [ 'build' ]
},
},
就像copy
一样,您具有任务配置的clean
目标。 clean
配置的src
设置为"build"
以删除build
目录。
在grunt.loadNpmTasks("grunt-contrib-copy");
,加载clean
任务,这将允许您从控制台运行grunt clean
。
javascript
grunt.loadNpmTasks('grunt-contrib-clean');
建立
如果您有一个在复制新的源文件之前要删除旧版本的build
任务,那不是很好吗? 让我们添加一个!
javascript
// define the tasks
grunt.registerTask(
'build',
'Compiles all of the assets and copies the files to the build directory.',
[ 'clean', 'copy' ]
);
registerTask
方法创建一个新任务。 第一个参数"build"
定义任务的名称。 第二个是任务的描述。 最后是将要运行的一系列任务。 build
任务先运行clean
任务,然后运行copy
任务。
触控笔
手写笔是一种很漂亮的语言,可以编译为CSS。 它以多种方式增强了CSS,包括添加变量,嵌套和函数。
javascript
stylus: {
build: {
options: {
linenos: true,
compress: false
},
files: [{
expand: true,
cwd: 'source',
src: [ '**/*.styl' ],
dest: 'build',
ext: '.css'
}]
}
},
这与其他任务配置略有不同。 仍然有一个build
子任务,但是它现在具有两个属性: options
和files
。 options
指定我们希望任务的行为方式。 我们添加了两个选项: compress
确定是否应压缩CSS输出, linenos
在源手写笔文件中添加选择器的行号。
files
采用与以前相同的文件数组映射格式。 这将在source
目录中所有以.styl
结尾的文件上运行任务。 ext
将输出文件的扩展名更改为.css
。
既然stylus
任务将CSS文件输出到build
目录,就没有理由再将手写笔文件复制到build
目录了。 让我们修改copy
配置以防止这种情况。
javascript
copy: {
build: {
cwd: 'source',
src: [ '**', '!**/*.styl' ],
dest: 'build',
expand: true
},
},
!
在路径的开头,可以防止grunt包含与模式匹配的文件。 不要忘记在build
任务中添加"stylus"
。
javascript
grunt.registerTask(
'build',
'Compiles all of the assets and copies the files to the build directory.',
[ 'clean', 'copy', 'stylus' ]
);
自动前缀
Autoprefixer是一个插件,可在将Stylus文件编译为CSS 之后向CSS3属性添加供应商前缀。 它是Nib和Compass等库的理想替代品。
继续并添加自动autoprefixer
配置。
javascript
autoprefixer: {
build: {
expand: true,
cwd: 'build',
src: [ '**/*.css' ],
dest: 'build'
}
},
注意模式吗? 此配置与其他任务非常相似。 一个显着的区别是cwd
和dest
都设置为"build"
。 这使autoprefixer
将文件输出到从中读取文件的文件夹中,从而替换原始文件。
和以前一样,您还需要加载Autoprefixer任务。
javascript
grunt.loadNpmTasks('grunt-autoprefixer');
与其将所有CSS任务都推入build
,不如为样式表创建一个新任务并将其添加到build中。
javascript
// define the tasks
grunt.registerTask(
'stylesheets',
'Compiles the stylesheets.',
[ 'stylus', 'autoprefixer' ]
);
grunt.registerTask(
'build',
'Compiles all of the assets and copies the files to the build directory.',
[ 'clean', 'copy', 'stylesheets' ]
);
CSS缩小
将一堆笨重的CSS文件传递给客户端确实会减慢网站的加载时间。 幸运的是, grunt-contrib-cssmin
软件包可以最小化CSS文件并将它们组合成一个文件。 再一次,从配置开始。
javascript
cssmin: {
build: {
files: {
'build/application.css': [ 'build/**/*.css' ]
}
}
},
此配置不使用文件数组格式,而是使用Grunt的files对象格式 ,该格式将多个文件映射到单个目标。 build
目录中的所有CSS文件将被缩小,并输出到build/application.css
。
加载程序包,然后将CSS缩小文件添加到stylesheets
任务中。
javascript
grunt.loadNpmTasks('grunt-contrib-cssmin');
javascript
grunt.registerTask(
'stylesheets',
'Compiles the stylesheets.',
[ 'stylus', 'autoprefixer', 'cssmin' ]
);
CoffeeScript
CoffeeScript是一种很棒的语言,可以编译为JavaScript。 它具有干净漂亮的语法,包括类,并且隐藏了许多JavaScript的较丑陋的方面。
将CoffeeScript添加到项目很容易! 首先,添加配置。
javascript
coffee: {
build: {
expand: true,
cwd: 'source',
src: [ '**/*.coffee' ],
dest: 'build',
ext: '.js'
}
},
这将提取源CoffeeScript文件,将其扩展名更改为.js
并将其输出到build
目录。 接下来,加载grunt-contrib-coffee
软件包。
javascript
grunt.loadNpmTasks('grunt-contrib-coffee');
添加一个scripts
任务,并将其添加到build
任务。
javascript
grunt.registerTask(
'scripts',
'Compiles the JavaScript files.',
[ 'coffee' ]
);
grunt.registerTask(
'build',
'Compiles all of the assets and copies the files to the build directory.',
[ 'clean', 'copy', 'stylesheets', 'scripts' ]
);
再一次,您将需要添加一个异常以进行copy
以免将CoffeeScript文件复制到build
目录中。
javascript
copy: {
build: {
cwd: 'source',
src: [ '**', '!**/*.styl', '!**/*.coffee' ],
dest: 'build',
expand: true
},
},
丑化
像cssmin
一样, UglifyJS缩小JavaScript文件并将它们组合成一个文件。 配置如下:
javascript
uglify: {
build: {
options: {
mangle: false
},
files: {
'build/application.js': [ 'build/**/*.js' ]
}
}
},
默认情况下,UglifyJS将用较短的名称替换脚本中的变量和函数的名称。 如果您的项目代码是独立的,这很方便,但是如果与其他项目共享,则可能会导致问题。 将mangle设置为false
将关闭此行为。
与cssmin
任务一样,此任务也使用files对象格式。
加载软件包并将"uglify"
添加到scripts
任务。
javascript
grunt.loadNpmTasks('grunt-contrib-uglify');
javascript
grunt.registerTask(
'scripts',
'Compiles the JavaScript files.',
[ 'coffee', 'uglify' ]
);
打扫干净
当您运行grunt build
,除了build/application.css
和build/application.js
,所有其他CSS和JavaScript文件都在build
目录中徘徊。 由于不需要它们,因此可以添加子任务以将其删除到clean
配置中。
javascript
clean: {
build: {
src: [ 'build' ]
},
stylesheets: {
src: [ 'build/**/*.css', '!build/application.css' ]
},
scripts: {
src: [ 'build/**/*.js', '!build/application.js' ]
},
},
运行任务时,如果不指定子任务,Grunt将全部运行它们。 如果您从控制台运行grunt clean
,它将运行clean:build
, clean:stylesheets
和clean:scripts
。 这不是问题,因为如果clean
任务无法删除文件,它将忽略它。
注意,如何从stylesheets
和scripts
子任务中排除build/application.css
和build/application.js
。 经过所有辛苦的工作,您不想删除这些错误的信息!
更新任务以使用适当的子任务。
javascript
// define the tasks
grunt.registerTask(
'stylesheets',
'Compiles the stylesheets.',
[ 'stylus', 'autoprefixer', 'cssmin', 'clean:stylesheets' ]
);
grunt.registerTask(
'scripts',
'Compiles the JavaScript files.',
[ 'coffee', 'uglify', 'clean:scripts' ]
);
grunt.registerTask(
'build',
'Compiles all of the assets and copies the files to the build directory.',
[ 'clean:build', 'copy', 'stylesheets', 'scripts' ]
);
玉
Jade是一种模板语言,使编写HTML变得有趣。 使用grunt-contrib-jade
软件包将Jade添加到您的项目中。
javascript
jade: {
compile: {
options: {
data: {}
},
files: [{
expand: true,
cwd: 'source',
src: [ '**/*.jade' ],
dest: 'build',
ext: '.html'
}]
}
},
像stylus
和coffee
任务一样, jade
是使用文件数组格式配置的。 注意options
的data
对象吗? 编译Jade文件时,此对象将传递到每个模板。 它对于诸如创建单独的开发和生产版本或生成动态内容之类的操作非常方便。
和以前一样,您需要向copy
任务添加一个例外,以防止Jade文件被复制。
javascript
copy: {
build: {
cwd: 'source',
src: [ '**', '!**/*.styl', '!**/*.coffee', '!**/*.jade' ],
dest: 'build',
expand: true
},
},
不要忘记加载grunt-contrib-jade
并将其添加到`build`中。
javascript
grunt.loadNpmTasks('grunt-contrib-jade');
javascript
grunt.registerTask(
'build',
'Compiles all of the assets and copies the files to the build directory.',
[ 'clean:build', 'copy', 'stylesheets', 'scripts', 'jade' ]
);
看
您的Gruntfile确实开始发光了,但是如果您每次进行更改时都不必运行grunt build
那岂不是很好吗? 使用grunt-contrib-watch
,您不需要! 让我们配置一个任务,该任务将监视源代码中的更改并自动构建它们。
javascript
watch: {
stylesheets: {
files: 'source/**/*.styl',
tasks: [ 'stylesheets' ]
},
scripts: {
files: 'source/**/*.coffee',
tasks: [ 'scripts' ]
},
jade: {
files: 'source/**/*.jade',
tasks: [ 'jade' ]
},
copy: {
files: [ 'source/**', '!source/**/*.styl', '!source/**/*.coffee', '!source/**/*.jade' ],
tasks: [ 'copy' ]
}
},
stylesheets
, scripts
和jade
子任务监视Stylus,CoffeeScript和Jade文件进行更改并运行它们各自的任务。 copy
任务监视应用程序中所有剩余的文件,并将它们复制到构建目录。
同样,您将需要加载grunt任务。
javascipt
grunt.loadNpmTasks('grunt-contrib-watch');
开发服务器
没有开发服务器,Web开发环境是不完整的。 grunt-contrib-connect
软件包是功能齐全的静态文件服务器,非常适合您的项目。
javascript
connect: {
server: {
options: {
port: 4000,
base: 'build',
hostname: '*'
}
}
}
您已将服务器配置为在端口4000上托管build
目录。默认情况下,Connect仅将站点托管在localhost
,这限制了您访问计算机外部的服务器。 将hostname
设置为"*"
可以从任何地方访问服务器。
和以前一样,您还需要加载NPM任务。
javascript
grunt.loadNpmTasks('grunt-contrib-connect');
如果尝试从命令行运行grunt connect
,则服务器将运行,然后立即停止。 这是因为默认情况下,grunt connect任务不会无限期运行。 您将在下一节中学习如何解决此问题。
默认
如果您有一项任务将所有其他任务组合在一起,那不是很好吗? default
任务对此非常适合。
javascript
grunt.registerTask(
'default',
'Watches the project for changes, automatically builds them and runs a server.',
[ 'build', 'connect', 'watch' ]
);
default
任务运行build来创建一个初始构建。 然后,它启动连接服务器。 最后,它运行watch
以监视文件中的更改并构建它们。 由于watch
一直运行到被杀死,因此Connect服务器将无限期运行。 在控制台中运行grunt
并导航到http:// localhost:4000以查看您的项目!
结论
我们在本教程中讨论了很多内容,Grunt可以做的事情还很多。 有关Grunt可用的所有插件的完整列表,请访问Grunt插件站点 。 祝您开心!
From: https://www.sitepoint.com/writing-awesome-build-script-grunt/