《JavaScript開發框架權威指南》——2.3 將Grunt添加到項目中
本節書摘來自異步社區《JavaScript開發框架權威指南》一書中的第2章,第2.3節,作者:【美】Tim Ambler , Nicholas Cloud著,更多章節內容可以訪問雲棲社區“異步社區”公眾號查看
2.3 將Grunt添加到項目中
在本章前麵,為了添加Grunt命令行工具,我們將npm包grunt-cli作為全局模塊進行了安裝。現在我們應該已經可以在命令行中使用Grunt命令,但是對於每個要使用Grunt的工程,仍然需要為其配置Grunt本地依賴。為此,隻需在工程根目錄下運行以下命令即可。本例假設npm已經針對示例所用項目進行了初始化,package.json文件也已經存在。
$ npm install grunt --save-dev
現在,我們項目的package.json文件應該已經包含與清單中的示例代碼相仿的Grunt條目。
清單2-5 更新後的package.json文件
// example-tasks/package.json
{
"name": "example-tasks",
"version": "1.0.0",
"devDependencies": {
"grunt": "0.4.5"
}
}
將Grunt與項目進行整合的最後一個步驟是創建Gruntfile(見清單),並保存在工程根目錄下。我們的Gruntfile隻調用了一個函數loadTasks(),其作用將在接下來的小節進行討論。
清單2-6 我們的Gruntfile
// example-tasks/Gruntfile.js
module.exports = function(grunt) {
grunt.loadTasks('tasks');
};
保持合理的Grunt模式
我們希望你在讀完本章之後發現,Grunt的確是一件處理日常工作流程中遇到的乏味的重複性工作的利器。但是即便如此,還是不得不承認我們對Grunt的第一反應絕對算不上積極。事實上,剛開始我們對它興趣不大。為了了解其中的原因,我們看一下放在Grunt官方文檔顯著位置的Gruntfile示例(見清單)。
清單2-7 Grunt官方文檔提供的Gruntfile示例
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
concat: {
options: {
separator: ';'
},
dist: {
src: ['src/**/*.js'],
dest: 'dist/<%= pkg.name %>.js'
}
},
uglify: {
options: {
banner: '/*! <%= grunt.template.today("dd-mm-yyyy") %> */\n'
},
dist: {
files: {
'dist/<%= pkg.name %>.min.js': ['<%= concat.dist.dest %>']
}
}
},
qunit: {
files: ['test/**/*.html']
},
jshint: {
files: ['Gruntfile.js', 'src/* */*.js', 'test/**/*.js'],
options: {
// options here to override JSHint defaults
globals: {
jQuery: true,
console: true,
module: true,
document: true
}
}
},
watch: {
files: ['<%= jshint.files %>'],
tasks: ['jshint', 'qunit']
}
});
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-qunit');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.registerTask('test', ['jshint', 'qunit']);
grunt.registerTask('default', ['jshint', 'qunit', 'concat', 'uglify']);
};
清單中略顯臃腫的Gruntfile還是為相對簡單的項目準備的。對於規模更大的項目,Gruntfile會像吹氣球一樣膨脹好幾倍,最終結果就是一大堆根本無法閱讀又難以維護的東西。有經驗的開發者絕不會在寫代碼的時候,將不相關的功能模塊揉在一起。否則,我們為什麼還要在任務運行器上搞點兒花樣出來呢?
正如清單中的代碼所示,使Grunt模式保持合理的秘密就藏在Grunt的loadTasks()方法上。該例中task參數指向task文件夾,其路徑以工程的Gruntfile為參考位置。loadTask()方法一被調用,Grunt就會加載並執行在該文件夾下發現的所有Node模塊,並且每次都將Grunt對象的引用作為參數傳進去。這樣的行為使我們可以將項目的Grunt配置劃分為一係列相互獨立的模塊,每個模塊負責一個單獨的任務或插件的加載及配置工作。清單展示了其中一個小型模塊,模塊中定義的任務可以通過在命令行中執行grunt uglify來運行。
清單2-8 task文件夾中的示例模塊(uglify.js)
// example-tasks/tasks/uglify.js
module.exports = function(grunt) {
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.config('uglify', {
'options': {
'banner': '/*! <%= grunt.template.today("dd-mm-yyyy") %> */\n'
},
'dist': {
'files': {
'dist/app.min.js': ['src/index.js']
}
}
});
};
最後更新:2017-06-05 14:32:20