《JavaScript開發框架權威指南》——2.6 創建Grunt插件
本節書摘來自異步社區《JavaScript開發框架權威指南》一書中的第2章,第2.6節,作者:【美】Tim Ambler , Nicholas Cloud著,更多章節內容可以訪問雲棲社區“異步社區”公眾號查看
2.6 創建Grunt插件
社區提供的豐富插件庫是讓Grunt真正變得閃耀的庫,它能使你立即從Grunt中獲益,而不是需要從頭創建複雜的任務。如果你需要在項目中做自動構建,那麼很可能某人已經為你做好這項“Grunt”工作。在這一節中,你可以懂得如何向社區回饋自己創建的Grunt插件。
2.6.1 開始
首先要做的事情之一是情創建一個公共的GitHub倉庫,以存儲你的新插件。下文中將要提及的示例包含在本書附帶的源碼中,本書附帶了源碼。一旦你準備好代碼倉庫,就把它克隆到你的電腦上。下一步,按照本章前麵“將Grunt添加到項目中”一節所概述的步驟,在倉庫目錄中初始化Grunt。然後,你的新Grunt插件的文件模式將會類似清單中的示例。
清單2-31 新Grunt插件的文件模式
.
├── Gruntfile.js
├── README.md
├── package.json
├── tasks
注意:
這裏提到的最重要一點是創建Grunt插件不需要任何額外的模式或知識(拋開本章已經涵蓋的內容不說)。這個過程反映了把Grunt整合進一個現有的項目中,Gruntfile的建立用於加載任務,除此之外是任務本身。一旦插件發布至npm,其他的Grunt項目就能夠像本章中到處提及的方式一樣來加載你的插件。
2.6.2 創建任務
按照示例中的方式,讓我們創建一個Grunt插件,該插件能夠生成一份描述了項目中包含的文件類型、大小和數量的報告。該插件的配置示例如清單所示。
清單2-32 插件配置示例代碼
// example-plugin/Gruntfile.js
module.exports = function(grunt) {
grunt.config('file-report', {
'options': {
},
'public': {
'src': ['public/**/*']
},
'images': {
'src': ['public/**/*.jpg', 'public/* */*.png', 'public/**/*.gif']
}
});
grunt.loadNpmTasks('grunt-file-reporter');
grunt.registerTask('default', ['file-report']);
};
從清單中可以看到插件的源碼,其中Grunt注冊了一個多任務file-report。每當調用這個任務,清單中指定的目標文件會被迭代遍曆。完成這個任務後,插件會編譯得到一個報告展示出它發現的文件類型、數量和大小詳情。
清單2-33 插件的源碼
// example-plugin/node_modules/grunt-file-reporter/Gruntfile.js
var fs = require('fs');
var filesize = require('filesize');
var _ = require('lodash');
_.mixin(require('underscore.string'));
module.exports = function(grunt) {
var mime = require('mime');
var Table = require('cli-table');
grunt.registerMultiTask('file-report', 'Generates a report of file types & sizes used
within a project ', function() {
var report = {
'mimeTypes': {},
'largest': null,
'smallest': null
};
var table = new Table({
'head': ['Content Type', 'Files Found', 'Total Size',
'Average Size', 'Largest', 'Smallest']
});
var addFile = function(file) {
if (grunt.file.isDir(file)) return;
var mimeType = mime.lookup(file);
if (!report.mimeTypes[mimeType]) {
report.mimeTypes[mimeType] = {
'count': 0,
'sizes': [],
'largest': null,
'smallest': null,
'oldest': null,
'newest': null
};
}
var details = report.mimeTypes[mimeType];
details.count++;
var stats = fs.statSync(file);
details.sizes.push(stats.size);
if (!details.largest || stats.size > details.largest.size) {
details.largest = { 'file': file, 'size': stats.size };
}
if (!report.largest || stats.size > report.largest.size) {
report.largest = { 'file': file, 'size': stats.size };
}
if (!details.smallest || stats.size < details.smallest.size) {
details.smallest = { 'file': file, 'size': stats.size };
}
if (!report.smallest || stats.size < report.smallest.size) {
report.smallest = { 'file': file, 'size': stats.size };
}
};
var sum = function(arr) {
return arr.reduce(function(a, b) {
return a + b;
});
};
var displayReport = function() {
var totalSum = 0;
var totalFiles = 0;
var totalSizes = [];
_.each(report.mimeTypes, function(data, mType) {
var fileSum = sum(data.sizes);
totalSum += fileSum;
totalFiles += data.sizes.length;
totalSizes = totalSizes.concat(data.sizes);
table.push([mType, data.count, filesize(fileSum),
filesize(fileSum / data.sizes.length),
_.sprintf('%s (%s)', data.largest.file, filesize(data.largest.size)),
_.sprintf('%s (%s)', data.smallest.file, filesize(data.smallest.size)),
]);
});
table.push(['-', totalFiles, filesize(totalSum),
filesize(totalSum / totalSizes.length),
_.sprintf('%s (%s)', report.largest.file, filesize(report.largest.size)),
_.sprintf('%s (%s)', report.smallest.file, filesize(report.smallest.size)),
]);
console.log(table.toString());
};
this.files.forEach(function(files) {
files.src.forEach(addFile);
});
displayReport();
});
};
由file-report插件生成的輸出如圖所示。
圖2-1 file-report任務所生成的輸出
2.6.3 將任務發布到npm
一旦我們的插件已經就緒並且我們的Git倉庫也更新到最新的代碼,最後一步就是通過npm發布插件使他人也可用。
$ npm publish
注意:
如果這是你第一次向npm發布模塊,你將被要求創建一個賬號。
最後更新:2017-06-06 07:33:03