프론트엔드 기술의 발전은 정말 빠릅니다. Grunt는 15년 동안 여전히 인기가 있었지만 이제 gulp의 광범위한 사용과 webpack의 인기가 높아짐에 따라 grunt는 기본적으로 사라질 것입니다. 학습의 발전이 기술 발전의 발전을 따라잡을 수 없다는 것은 정말 말로 표현할 수 없는 느낌입니다. 이번 글에서는 오래되었을 수 있는 grunt 설치에 대해 소개하겠습니다.
Grunt 및 Grunt 플러그인은 npm을 통해 설치 및 관리됩니다. Grunt를 배우기 전에 Grunt 명령줄(CLI)을 글로벌 환경에 설치해야 합니다. 설치하는 동안 sudo(OSX, *nix, BSD 등 시스템의 경우) 권한을 사용하거나 관리자(Windows 환경의 경우)로 다음 명령을 실행해야 할 수 있습니다
npm install -g grunt-cli
위 명령이 실행된 후 실행되면 grunt
명령이 시스템 경로에 추가되며, 향후 어떤 디렉터리에서든 이 명령을 실행할 수 있습니다. [참고] grunt-cli
를 설치한다고 해서 설치되는 것은 아닙니다. 꿀꿀 거리는 소리. Grunt CLI의 작업은 간단합니다. Gruntfile
과 동일한 디렉터리에서 Grunt를 호출하면 됩니다. 이것의 장점은 동일한 시스템에 여러 버전의 Grunt를 동시에 설치할 수 있다는 것입니다. grunt
를 실행할 때마다 제공된 require()
를 사용하세요. 시스템은 로컬에 설치된 Grunt를 찾습니다. 이 메커니즘 덕분에 grunt
는 프로젝트의 모든 하위 디렉터리에서 실행될 수 있습니다. 로컬에 설치된 Grunt가 발견되면 CLI는 이를 로드하고 Gruntfile
에 구성 정보를 전달한 다음 지정된 작업grunt
命令就被加入到系统路径中了,以后就可以在任何目录下执行此命令了
[注意]安装grunt-cli
并不等于安装了Grunt。Grunt CLI的任务很简单:调用与Gruntfile
在同一目录中的Grunt。这样带来的好处是,允许在同一个系统上同时安装多个版本的Grunt
每次运行grunt
时,就利用node提供的require()
系统查找本地安装的Grunt。正是由于这一机制,可以在项目的任意子目录中运行grunt
。如果找到一份本地安装的Grunt,CLI就将其加载,并传递Gruntfile
中的配置信息,然后执行所指定的任务
一般需要在项目中添加两份文件:package.json
和 Gruntfile
package.json: 此文件被npm用于存储项目的元数据,以便将此项目发布为npm模块。可以在此文件中列出项目依赖的grunt和Grunt插件,放置于devDependencies配置段内
Gruntfile: 此文件被命名为 Gruntfile.js
或 Gruntfile.coffee
,用来配置或定义任务(task)并加载Grunt插件
【package.json】
package.json
应当放置于项目的根目录中,与Gruntfile
在同一目录中,并且应该与项目的源代码一起被提交。在上述目录(package.json
所在目录)中运行npm install
将依据package.json
文件中所列出的每个依赖来自动安装适当版本的依赖
常用的package.json配置如下
{ "name": "my-project-name", "version": "0.1.0", "devDependencies": {"grunt": "~0.4.5","grunt-contrib-jshint": "~0.10.0","grunt-contrib-nodeunit": "~0.4.1","grunt-contrib-uglify": "~0.5.0" } }
向已经存在的package.json
文件中添加Grunt和grunt插件的最简单方式是通过npm install <module> --save-dev
命令。此命令不光安装了<module>
,还会自动将其添加到devDependencies 配置段中,如下所示
npm install grunt-contrib-jshint --save-dev
【Gruntfile】
Gruntfile.js
或 Gruntfile.coffee
文件是有效的 JavaScript 或 CoffeeScript 文件,应当放在项目根目录中,和package.json
文件在同一目录层级,并和项目源码一起加入源码管理器
Gruntfile由以下几部分构成:
"wrapper" 函数
项目与任务配置
加载grunt插件和任务
自定义任务
在下面列出的这个 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']); };
1、wrapper函数
每一份 Gruntfile
(和grunt插件)都遵循同样的格式,所书写的Grunt代码必须放在wrapper函数内
module.exports = function(grunt) { // Do grunt-related things in here};
2、项目和任务配置
大部分的Grunt任务都依赖某些配置数据,这些数据被定义在一个object内,并传递给grunt.initConfig 方法
Grunt的task配置都是在 Gruntfile
中的grunt.initConfig
package.json
및 Gruntfile
🎜🎜 package.json: 이 파일은 npm에서 프로젝트의 메타데이터를 저장하는 데 사용됩니다. 프로젝트가 npm 모듈로 게시될 수 있습니다. 이 파일에 프로젝트가 의존하는 grunt 및 Grunt 플러그인을 나열하고 devDependency 구성 섹션🎜🎜Gruntfile에 배치할 수 있습니다. 이 파일의 이름은 Gruntfile.js
입니다. 또는 작업을 구성 또는 정의하고 Grunt 플러그인을 로드하는 데 사용되는 Gruntfile.coffee
🎜🎜【package.json】🎜🎜 package.json
은 루트 디렉터리에 있어야 합니다. Gruntfile
과 동일한 디렉터리에 있으며 프로젝트 소스 코드와 함께 제출해야 합니다. 위 디렉터리(package.json
가 있는 디렉터리)에서 npm install
을 실행하면 package.json
파일에 나열된 각 종속성에 따라 달라집니다. . 적절한 버전의 종속성을 자동으로 설치합니다. 🎜🎜 일반적으로 사용되는 package.json 구성은 다음과 같습니다. 🎜🎜grunt.initConfig({ concat: {// 这里是concat任务的配置信息。 }, uglify: {// 这里是uglify任务的配置信息 }, // 任意数据。 my_property: 'whatever', my_src_files: ['foo/*.js', 'bar/*.js'], });🎜🎜 기존
package.json
파일에 Grunt 및 grunt 플러그인을 추가하는 가장 쉬운 방법은 다음과 같습니다. npm install <module> --save-dev
명령. 이 명령은 <module>
을 설치할 뿐만 아니라 아래와 같이 devDependency 구성 섹션에 자동으로 추가합니다🎜🎜grunt.initConfig({ concat: { options: { // 这里是任务级的Options,覆盖默认值 }, foo: { options: {// "foo" target options may go here, overriding task-level options. }, }, bar: { // No options specified; this target will use task-level options. }, }, });🎜🎜【Gruntfile】🎜🎜
Gruntfile.js code > 또는 <code>Gruntfile.coffee
파일은 유효한 JavaScript 또는 CoffeeScript 파일이며 package.json
파일과 동일한 디렉터리 수준의 프로젝트 루트 디렉터리에 배치되어야 합니다. 프로젝트와 함께 소스 코드는 소스 코드 관리자에 추가됩니다🎜🎜 Gruntfile은 다음 부분으로 구성됩니다:🎜Gruntfile code> 아래 나열된 경우 <code>package.json
파일의 프로젝트 메타데이터를 Grunt 구성으로 가져오고 grunt-contrib-uglify 플러그인의 uglify
작업은 다음과 같습니다. 소스 코드 파일을 압축(축소)하고 위의 메타데이터를 기반으로 파일 헤더 주석을 동적으로 생성하도록 구성됩니다. 명령줄에서 grunt
명령을 실행하면 기본적으로 uglify
작업이 실행됩니다🎜🎜// 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'} } });🎜🎜 1.wrapper function🎜🎜
의 각 복사본 Gruntfile code> (및 grunt 플러그인)은 모두 동일한 형식을 따릅니다. 작성된 Grunt 코드는 래퍼 함수🎜🎜<pre class="brush:php;toolbar:false">// 加载能够提供"uglify"任务的插件。grunt.loadNpmTasks('grunt-contrib-uglify');</pre>🎜🎜 2. 프로젝트 및 작업 구성🎜🎜대부분의 Grunt 작업은 특정 구성 데이터에 의존합니다. , 이러한 데이터는 객체에 정의되어 grunt.initConfig 메소드로 전달됩니다. 🎜🎜 Grunt의 작업 구성은 <code>Gruntfile
의 grunt.initConfig
메소드에 지정됩니다. 이 구성은 주로 작업 이름을 따라 명명된 속성이며 기타 임의의 데이터를 포함할 수도 있습니다. 임의의 데이터를 나타내는 이러한 속성이 작업에 필요한 속성과 충돌하면 무시됩니다🎜🎜// Default task(s).grunt.registerTask('default', ['uglify']);🎜
在一个任务配置中,options
属性可以用来指定覆盖内置属性的默认值。此外,每一个目标(target)中还可以拥有一个专门针对此目标(target)的options
属性。目标(target)级的平options将会覆盖任务级的options。options
对象是可选的,如果不需要,可以忽略
grunt.initConfig({ concat: { options: { // 这里是任务级的Options,覆盖默认值 }, foo: { options: {// "foo" target options may go here, overriding task-level options. }, }, bar: { // No options specified; this target will use task-level options. }, }, });
在下面的案例中,grunt.file.readJSON('package.json')
将存储在package.json
文件中的JSON元数据引入到grunt config中。 由于<% %>
模板字符串可以引用任意的配置属性,因此可以通过这种方式来指定诸如文件路径和文件列表类型的配置数据,从而减少一些重复的工作
与大多数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'} } });
3、加载grunt插件和任务
像 concatenation、[minification]、grunt-contrib-uglify 和 linting这些常用的任务(task)都已经以grunt插件的形式被开发出来了。只要在 package.json
文件中被列为dependency(依赖)的包,并通过npm install
安装之后,都可以在Gruntfile
中以简单命令的形式使用:
// 加载能够提供"uglify"任务的插件。grunt.loadNpmTasks('grunt-contrib-uglify');
[注意] grunt --help
命令将列出所有可用的任务
4、自定义任务
通过定义 default
任务,可以让Grunt默认执行一个或多个任务。在下面的这个案例中,执行 grunt
命令时如果不指定一个任务的话,将会执行uglify
任务。这和执行grunt uglify
或者 grunt default
的效果一样。default
任务列表数组中可以指定任意数目的任务(可以带参数)
// Default task(s).grunt.registerTask('default', ['uglify']);
本节将介绍合并插件grunt-contrib-concat的实例应用
1、首先,建立项目结构。 根目录为'project',存在一个'src'的文件夹,该文件夹下又包含'css'和'js'这两个文件夹。其中,'css'文件夹有一个空的'concat'文件夹,一个'style1.css'文件,以及一个'style2.css'文件;类似地,'js'文件夹有一个空的'concat'文件夹,一个'script1.js'文件,以及一个'script2.js'文件
由于需要用到grunt来实现合并,所以需要在项目根目录下,新建'package.json'和'Gruntfile.js'文件
最终的目录结构如下所示
2、填充文件内容
合并的目的是把'style1.css'和'style2.css'的内容合并到'css/src/concat'文件夹下,把'script1.js'和'script2.js'的内容合并到'js/src/concat'文件夹下
style1.css的文件内容如下
body{margin: 0;}
style2.css的文件内容如下
ul{margin: 0;padding: 0;list-style:none; }
script1.js的文件内容如下
console.log('a');
script2.js的文件内容如下
console.log('b');
3、设置Grunt的package.json及Gruntfile.js文件
由于需要用到grunt及grunt-contrib-concat插件,所以package.json的文件内容如下
{ "name": "project", "version": "1.0.0", "devDependencies": {"grunt": "^1.0.1","grunt-contrib-concat": "^1.0.1" } }
Gruntfile.js的配置文件如下
module.exports = function(grunt) { grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), concat: { options: {stripBanners: true, banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' +'<%= grunt.template.today("yyyy-mm-dd") %> */' }, myCSSDist: { src: ['src/css/*.css'], dest: 'src/css/concat/<%= pkg.name %>-<%= pkg.version %>.css' }, myJSDist: { src: ['src/js/*.js'], dest: 'src/js/concat/<%= pkg.name %>-<%= pkg.version %>.js' }, }, }); grunt.loadNpmTasks('grunt-contrib-concat'); grunt.registerTask('default', ['concat']); };
4、效果演示
通过在命令行中使用npm install命令来安装插件
npm install
然后执行命令grunt
在'css/concat'文件夹下生成一个'project-1.0.0.css'的文件,内容如下
body{margin: 000-
在'js/concat'文件夹下生成一个'project-1.0.0.js'的文件,内容如下
/*! project - v1.0.0 - 2017-05-27 */console.log('a');console.log('b');
接下来,我们对合并后的project-1.0.0.css和project-1.0.0.js文件进行压缩,压缩名称加一个'.min'前缀,并分别保存到'project'目录下的'dist'目录下'css'文件夹和'js'文件夹
由于需要用到grunt-contrib-cssmin和grunt-contrib-uglify插件,所以package.json的文件内容如下
{ "name": "project", "version": "1.0.0", "devDependencies": {"grunt": "^1.0.1","grunt-contrib-concat": "^1.0.1","grunt-contrib-cssmin": "^2.2.0","grunt-contrib-uglify": "^3.0.1" } }
Gruntfile.js的配置文件如下
module.exports = function(grunt) { grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), concat: { options: { stripBanners: true, banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' +'<%= grunt.template.today("yyyy-mm-dd") %> */' }, myCSSDist: { src: ['src/css/*.css'], dest: 'src/css/concat/<%= pkg.name %>-<%= pkg.version %>.css' }, myJSDist: { src: ['src/js/*.js'], dest: 'src/js/concat/<%= pkg.name %>-<%= pkg.version %>.js' }, }, cssmin:{ options: { stripBanners: true, banner: '/* <%= grunt.template.today("yyyy-mm-dd") %> */' }, build:{ src: 'src/css/concat/<%= pkg.name %>-<%= pkg.version %>.css', dest: 'dist/css/<%= pkg.name %>-<%= pkg.version %>.min.css' } }, uglify:{ options: { stripBanners: true, banner: '/* <%= grunt.template.today("yyyy-mm-dd") %> */' }, build:{ src: 'src/js/concat/<%= pkg.name %>-<%= pkg.version %>.js', dest: 'dist/js/<%= pkg.name %>-<%= pkg.version %>.min.js' } } }); grunt.loadNpmTasks('grunt-contrib-concat'); grunt.loadNpmTasks('grunt-contrib-cssmin'); grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.registerTask('default', ['concat','cssmin','uglify']); };
通过在命令行中使用npm install命令来安装插件
然后执行命令grunt
在'dist/css/'文件夹下生成一个'project-1.0.0.min.css'的文件,内容如下
/*! project - v1.0.0 - 2017-05-27 */body{margin:0}ul{margin:0;padding:0;list-style:none}
在'dist/js/'文件夹下生成一个'project-1.0.0.min.js'的文件,内容如下
/* 2017-05-27 */console.log("a"),console.log("b");
前面的博文已经介绍过jshint和csslint。如果要使用grunt中的插件,则需要在根目录下建立 .csslintrc 和 .jshintrc 文件,并设置它们的内容如下
//.csslintrc{"adjoining-classes":false,"box-sizing":false,"box-model":false,"compatible-vendor-prefixes": false,"floats":false,"font-sizes":false,"grandients":false,"important":false,"known-properties":false,"outline-none":false,"qualified-headings":false,"regex-selectors":false,"shorthand":false,"text-indent":false,"unique-headings":false,"universal-selector":false,"unqualified-attributes":false}//.jshintrc{"boss": false,"curly": true,"eqeqeq": true,"eqnull": true,"expr": true,"immed":true,"newcap":true,"noempty":true,"noarg":true,"undef":true,"regexp":true,"browser":false,"devel":true,"node":true}
由于需要用到grunt-contrib-csslint和grunt-contrib-jshint插件,所以package.json的文件内容如下
{ "name": "project", "version": "1.0.0", "devDependencies": {"grunt": "^1.0.1","grunt-contrib-concat": "^1.0.1","grunt-contrib-cssmin": "^2.2.0","grunt-contrib-uglify": "^3.0.1","grunt-contrib-csslint": "^2.0.0","grunt-contrib-jshint": "^1.1.0" } }
Gruntfile.js的配置文件如下
module.exports = function(grunt) { grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), concat: { options: { stripBanners: true, banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' +'<%= grunt.template.today("yyyy-mm-dd") %> */' }, myCSSDist: { src: ['src/css/*.css'], dest: 'src/css/concat/<%= pkg.name %>-<%= pkg.version %>.css' }, myJSDist: { src: ['src/js/*.js'], dest: 'src/js/concat/<%= pkg.name %>-<%= pkg.version %>.js' }, }, cssmin:{ options: { stripBanners: true, banner: '/* <%= grunt.template.today("yyyy-mm-dd") %> */' }, build:{ src: 'src/css/concat/<%= pkg.name %>-<%= pkg.version %>.css', dest: 'dist/css/<%= pkg.name %>-<%= pkg.version %>.min.css' } }, uglify:{ options: { stripBanners: true, banner: '/* <%= grunt.template.today("yyyy-mm-dd") %> */' }, build:{ src: 'src/js/concat/<%= pkg.name %>-<%= pkg.version %>.js', dest: 'dist/js/<%= pkg.name %>-<%= pkg.version %>.min.js' } }, jshint:{ options:{ jshintrc:'.jshintrc' }, build:['Gruntfile.js','src/js/*.js'] }, csslint:{ options:{ csslintrc:'.csslintrc' }, build:['src/css/*.css'] } }); grunt.loadNpmTasks('grunt-contrib-concat'); grunt.loadNpmTasks('grunt-contrib-cssmin'); grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.loadNpmTasks('grunt-contrib-csslint'); grunt.registerTask('default', ['jshint','csslint','concat','cssmin','uglify']); };
通过在命令行中使用npm install命令来安装插件
然后执行命令grunt
可以看到'script1.js'文件中第1行缺少分号,修改后再执行命令grunt
grunt构建工具的自动化主要体现在grunt-contrib-watch插件上,该插件主要用于监听并执行对应的任务
package.json的文件内容如下
{ "name": "project", "version": "1.0.0", "devDependencies": {"grunt": "^1.0.1","grunt-contrib-concat": "^1.0.1","grunt-contrib-csslint": "^2.0.0","grunt-contrib-cssmin": "^2.2.0","grunt-contrib-jshint": "^1.1.0","grunt-contrib-uglify": "^3.0.1","grunt-contrib-watch": "^1.0.0" } }
Gruntfile.js的配置文件如下
module.exports = function(grunt) { grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), concat: { options: { stripBanners: true, banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' +'<%= grunt.template.today("yyyy-mm-dd") %> */' }, myCSSDist: { src: ['src/css/*.css'], dest: 'src/css/concat/<%= pkg.name %>-<%= pkg.version %>.css' }, myJSDist: { src: ['src/js/*.js'], dest: 'src/js/concat/<%= pkg.name %>-<%= pkg.version %>.js' }, }, cssmin:{ options: { stripBanners: true, banner: '/* <%= grunt.template.today("yyyy-mm-dd") %> */' }, build:{ src: 'src/css/concat/<%= pkg.name %>-<%= pkg.version %>.css', dest: 'dist/css/<%= pkg.name %>-<%= pkg.version %>.min.css' } }, uglify:{ options: { stripBanners: true, banner: '/* <%= grunt.template.today("yyyy-mm-dd") %> */' }, build:{ src: 'src/js/concat/<%= pkg.name %>-<%= pkg.version %>.js', dest: 'dist/js/<%= pkg.name %>-<%= pkg.version %>.min.js' } }, jshint:{ options:{ jshintrc:'.jshintrc' }, build:['Gruntfile.js','src/js/*.js'] }, csslint:{ options:{ csslintrc:'.csslintrc' }, build:['src/css/*.css'] }, watch:{ build:{ files: ['src/js/*.js','src/css/*.css'], tasks: ['jshint','csslint','concat','cssmin','uglify'], options:{spawn:false} } } }); grunt.loadNpmTasks('grunt-contrib-concat'); grunt.loadNpmTasks('grunt-contrib-cssmin'); grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.loadNpmTasks('grunt-contrib-csslint'); grunt.loadNpmTasks('grunt-contrib-watch'); grunt.registerTask('default', ['jshint','csslint','concat','cssmin','uglify','watch']); };
通过在命令行中使用npm install命令来安装插件
然后执行命令grunt
修改'scrpt1.js'文件内容后,命令行自动显示如下
contrib-watch插件会监听需要处理的文件的变动,一旦有变动就会自动执行相应处理。但是它有一个问题,就是每当监听到一处变动时,就会大费周章地把所有被监听的文件都处理一遍
而newer插件的作用是处理contrib-watch插件的毛病,让watch在监听到某个文件变动时,仅仅对变动的文件进行事务处理
package.json的文件内容如下
{ "name": "project", "version": "1.0.0", "devDependencies": {"grunt": "^1.0.1","grunt-contrib-concat": "^1.0.1","grunt-contrib-csslint": "^2.0.0","grunt-contrib-cssmin": "^2.2.0","grunt-contrib-jshint": "^1.1.0","grunt-contrib-uglify": "^3.0.1","grunt-contrib-watch": "^1.0.0","grunt-contrib-requirejs": "^1.0.0","grunt-newer":"^1.3.0" } }
Gruntfile.js的配置文件如下
module.exports = function(grunt) { grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), concat: { options: { stripBanners: true, banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' +'<%= grunt.template.today("yyyy-mm-dd") %> */' }, myCSSDist: { src: ['src/css/*.css'], dest: 'src/css/concat/<%= pkg.name %>-<%= pkg.version %>.css' }, myJSDist: { src: ['src/js/*.js'], dest: 'src/js/concat/<%= pkg.name %>-<%= pkg.version %>.js' }, }, cssmin:{ options: { stripBanners: true, banner: '/* <%= grunt.template.today("yyyy-mm-dd") %> */' }, build:{ src: 'src/css/concat/<%= pkg.name %>-<%= pkg.version %>.css', dest: 'dist/css/<%= pkg.name %>-<%= pkg.version %>.min.css' } }, uglify:{ options: { stripBanners: true, banner: '/* <%= grunt.template.today("yyyy-mm-dd") %> */' }, build:{ src: 'src/js/concat/<%= pkg.name %>-<%= pkg.version %>.js', dest: 'dist/js/<%= pkg.name %>-<%= pkg.version %>.min.js' } }, jshint:{ options:{ jshintrc:'.jshintrc' }, build:['Gruntfile.js','src/js/*.js'] }, csslint:{ options:{ csslintrc:'.csslintrc' }, build:['src/css/*.css'] }, watch:{ build:{ files: ['src/js/*.js','src/css/*.css'], tasks: ['newer:jshint','newer:csslint','newer:concat','newer:cssmin','newer:uglify'], options:{spawn:false} } } }); grunt.loadNpmTasks('grunt-contrib-concat'); grunt.loadNpmTasks('grunt-contrib-cssmin'); grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.loadNpmTasks('grunt-contrib-csslint'); grunt.loadNpmTasks('grunt-contrib-watch'); grunt.loadNpmTasks('grunt-newer'); grunt.registerTask('default', ['newer:jshint','newer:csslint','newer:concat','newer:cssmin','newer:uglify','watch']); };
执行命令grunt
grunt
由于'script1.js'的内容发生了变化,所以重新合并了js文件,project-1.0.0.min.js的内容如下
/* 2017-06-09 */console.log("a"),console.log("b");
由于css的内容没有发生变化,所以project-1.0.0.min.css的内容如下
/*! project - v1.0.0 - 2017-05-29 */body{margin:0}ul{list-style:none;margin:0;padding:0}
下面说明grunt如何与requireJS配合使用,需要使用contrib-requirejs插件
npm install grunt-contrib-requirejs
该插件的使用与r.js的使用类似,不需要建立单独的build.js文件,而是在Gruntfile.js中配置
设置如下项目结构,src为开发环境,dist为上线环境
在r.js中,可以使用'dir'配置项,将项目目录复制到一个新的地方。但是,在实际项目开发中,有许多文件与requirejs无关,也会被复制。所以,不应该使用'dir',而应该使用'out'配置项,只是将入口文件main.js打包到一个新的地方
一般地,jQuery并不打包到main.js文件中。如果使用相对路径,打包前的main.js(开发环境)与jQuery存在路径依赖关系。打包后的main.js已经处于新的环境(上线环境),但此时仍然与开发环境的jQuery存在路径依赖关系,不符合逻辑
所以,jQuery应该是上线环境的地址。由于打包后,main.js的config也会打包进行,新的main.js的位置发生变化,jQuery的相对路径也会变化。所以config应该写在index.html页面中。这样,在jQuery或main.js的路径发生变化时,可以进行改动
因此,script1.js和script2.js这两个文件的内容如下
//script.jsdefine(['jquery'],function (){return $('div').height(); })//s2.jsdefine(['jquery'],function (){return $('div').width(); })
main.js的内容如下
//main.jsrequire(['module/script1','module/script2'], function(a,b){ console.log(a); console.log(b); });
index.html代码如下
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <div></div> <script data-main="main" src="dist/js/require.js?1.1.11"></script> <script>require.config({ baseUrl:'src/js', paths:{'jquery':'../../dist/js/jquery'} });</script> </body> </html>
package.json的文件内容如下
{ "name": "project", "version": "1.0.0", "devDependencies": {"grunt": "^1.0.1","grunt-contrib-concat": "^1.0.1","grunt-contrib-csslint": "^2.0.0","grunt-contrib-cssmin": "^2.2.0","grunt-contrib-jshint": "^1.1.0","grunt-contrib-uglify": "^3.0.1","grunt-contrib-watch": "^1.0.0","grunt-contrib-requirejs": "^1.0.0","grunt-newer":"^1.3.0" } }
【contrib-requirejs插件配置】
由于该插件打包后的文件,内容还是使用原来的路径关系。但是,开发和线上的路径并不一致。所以,要把可能会变化的路径设置为'baseUrl',其他的路径保持一致
[注意]contrib-requirejs插件不能与newer插件混用
requirejs: { compile: { options: { baseUrl: 'src/js', paths:{ jquery:'../../dist/js/jquery' }, name: 'main', out:'dist/js/main.js', exclude: ['jquery'] } } }
Gruntfile.js的配置文件如下
module.exports = function(grunt) { grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), concat: { options: { stripBanners: true, banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' +'<%= grunt.template.today("yyyy-mm-dd") %> */' }, myCSSDist: { src: ['src/css/*.css'], dest: 'src/css/concat/<%= pkg.name %>-<%= pkg.version %>.css' } }, cssmin:{ options: { stripBanners: true, banner: '/* <%= grunt.template.today("yyyy-mm-dd") %> */' }, build:{ src: 'src/css/concat/<%= pkg.name %>-<%= pkg.version %>.css', dest: 'dist/css/<%= pkg.name %>-<%= pkg.version %>.min.css' } }, jshint:{ options:{ jshintrc:'.jshintrc' }, build:['Gruntfile.js','src/js/*.js'] }, csslint:{ options:{ csslintrc:'.csslintrc' }, build:['src/css/*.css'] }, requirejs: { compile: { options: { baseUrl: 'src/js', paths:{ jquery:'../../dist/js/jquery' }, name: 'main', out:'dist/js/main.js', exclude: ['jquery'] } } }, watch:{ build:{ files: ['src/js/*.js','src/css/*.css'], tasks: ['newer:jshint','newer:csslint','newer:concat','newer:cssmin','newer:uglify','requirejs'], options:{spawn:false} } } }); grunt.loadNpmTasks('grunt-contrib-concat'); grunt.loadNpmTasks('grunt-contrib-cssmin'); grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.loadNpmTasks('grunt-contrib-csslint'); grunt.loadNpmTasks('grunt-contrib-requirejs'); grunt.loadNpmTasks('grunt-contrib-watch'); grunt.loadNpmTasks('grunt-newer'); grunt.registerTask('default', ['newer:jshint','newer:csslint','newer:concat','newer:cssmin','requirejs','watch']); };
执行命令grunt
更改index.html页面如下,依然能正常显示
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Document</title></head><body><div></div><script data-main="main" src="dist/js/require.js?1.1.11"></script><script>require.config({ baseUrl:'dist/js', paths:{'jquery':'../../dist/js/jquery'} });</script></body></html>
위 내용은 그런트 란 무엇입니까? 그에 대한 자세한 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!