閱讀848 返回首頁    go 阿裏雲 go 技術社區[雲棲]


《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插件生成的輸出如圖所示。


screenshot


圖2-1 file-report任務所生成的輸出

2.6.3 將任務發布到npm
一旦我們的插件已經就緒並且我們的Git倉庫也更新到最新的代碼,最後一步就是通過npm發布插件使他人也可用。

$ npm publish
注意:
 

如果這是你第一次向npm發布模塊,你將被要求創建一個賬號。

最後更新:2017-06-06 07:33:03

  上一篇:go  《Cucumber:行為驅動開發指南》——導讀
  下一篇:go  構建你的數據科學作品集:機器學習項目