Gruntfile.js に何を書くか?sails.jsでの利用方法を参考に ヽ(゚ー゚*ヽ)(ノ*゚ー゚)ノわぁい


この記事では以下の絵文字を大事な個所で使用中

  • 注意点
  • 予期せぬ例外やエラーメッセージ
  • 解決方法・お役立ち情報

みなさん、こんにちはでス。sails.js、javascript関連でこんな

記事を書いているものです プロ管したり、開発環境整えたり、実際にコード書いたり、デザインしたりといろいろやってます。いろいろやっているので、できるだけみんながハッピーになるような仕組みをつくっていけたらいいと思う次第。デスマでお疲れの皆さんもこれを読んだら少し休んで 横になってみましょう

この記事の概要

  • grunt の定義ファイル Gruntfile.js が巨大化する問題
  • sails.js ではどのように解決しているか

の二つ

前提になる知識

grunt

gruntはビルドに使ったり、もろもろのタスクを連続的に実行できる便利なツール http://gruntjs.com/

sails.js

railsっぽいNode.jsのフルスタックフレームワーク http://sailsjs.org

grunt の定義ファイル Gruntfile.js が巨大化する問題

便利なタスクの定義をGruntfile.jsというファイルに書くことができるものの、気づくと巨大化しているなんてことも。まぁ、「お前が書いたんだろ」と言われればそれまでですが ファイルが巨大化すると

  • 可読性が落ちる
  • メンテナンスしにくい

という欠点ばかりが目立ち

  • ファイル数が少ない

というけっこうどうでも良い利点がますます価値を失います。

他のウェブサイトでは

シンプルなタスクであれば分かりやすいのですが、多くの拡張機能(プラグイン)を使用したり、タスクの制御を細かく行う必要が生じたたりした場合、Gruntfileの記述量が増えて冗長になり、タスク同士の関連やタスク実行結果も分かりにくくなってしまいます。

と断言されていたり

Grunt を使おうと思っていたら、最近は gulp の方が主流との話を目にする。どうやら gulp の方が記述を簡潔にできて可読性がよいそうな。というわけで、一度 Grunt で書いたものを gulp で書き直してみた。

といった感じの噂がまことしやかに

無駄に長くなると、「あれ、やっべぇ、必要なところまで消しちゃった、まぢぃ」といったことが発生します。私はときどき、不要な個所を消したり、整理してもろもろの調整でたまったストレスを解消するために気分転換するのですが、全然気分転換になりません。

sails.js ではどのように解決しているか

  • 設定とタスクの登録を分けている
  • ファイルをできるだけ分割

といった感じ。具体的には

  • tasks/configtasks/register というディレクトリを用意し、それぞれ設定とタスクの登録といった感じで整理しています。
  • tasks/config 内はタスク名毎の設定ファイルで作成
  • tasks/register 内はエイリアス毎にファイルを作成

このGruntfile.js自体は汎用的に使えるものなので、とても参考になると思います。

それでは良いgruntライフをお送りください ヽ(゚ー゚ヽ)(ノ゚ー゚)ノわぁい

uglify.js の例

こんな感じで uglify の設定をして

tasks/config/uglify.js
/**
 * Minify files with UglifyJS.
 *
 * ---------------------------------------------------------------
 *
 * Minifies client-side javascript `assets`.
 *
 * For usage docs see:
 *      https://github.com/gruntjs/grunt-contrib-uglify
 *
 */
module.exports = function(grunt) {

    grunt.config.set('uglify', {
        dist: {
            src: ['.tmp/public/concat/production.js'],
            dest: '.tmp/public/min/production.js'
        }
    });

    grunt.loadNpmTasks('grunt-contrib-uglify');
};

こんな感じでprodとして登録されます。

tasks/register/prod.js
module.exports = function (grunt) {
    grunt.registerTask('prod', [
        'compileAssets',
        'concat',
        'uglify',
        'cssmin',
        'sails-linker:prodJs',
        'sails-linker:prodStyles',
        'sails-linker:devTpl'
    ]);
};

sails.js の Gruntfile.js

最新版はこっちかも⇒ https://github.com/balderdashy/sails/

Gruntfile.js
/**
 * Gruntfile FTW!
 *
 * This Node script is executed when you run `grunt` or `sails lift`.
 * It's purpose is to load the Grunt tasks in your project's `tasks`
 * folder, and allow you to add and remove tasks as you see fit.
 * For more information on how this works, check out the `README.md`
 * file that was generated in your `tasks` folder.
 *
 * WARNING:
 * Unless you know what you're doing, you shouldn't change this file.
 * Check out the `tasks` directory instead.
 */

module.exports = function(grunt) {


    // Load the include-all library in order to require all of our grunt
    // configurations and task registrations dynamically.
    var includeAll;
    try {
        includeAll = require('include-all');
    } catch (e0) {
        try {
            includeAll = require('sails/node_modules/include-all');
        }
        catch(e1) {
            console.error('Could not find `include-all` module.');
            console.error('Skipping grunt tasks...');
            console.error('To fix this, please run:');
            console.error('npm install include-all --save`');
            console.error();

            grunt.registerTask('default', []);
            return;
        }
    }


    /**
     * Loads Grunt configuration modules from the specified
     * relative path. These modules should export a function
     * that, when run, should either load/configure or register
     * a Grunt task.
     */
    function loadTasks(relPath) {
        return includeAll({
            dirname: require('path').resolve(__dirname, relPath),
            filter: /(.+)\.js$/
        }) || {};
    }

    /**
     * Invokes the function from a Grunt configuration module with
     * a single argument - the `grunt` object.
     */
    function invokeConfigFn(tasks) {
        for (var taskName in tasks) {
            if (tasks.hasOwnProperty(taskName)) {
                tasks[taskName](grunt);
            }
        }
    }




    // Load task functions
    var taskConfigurations = loadTasks('./tasks/config'),
        registerDefinitions = loadTasks('./tasks/register');

    // (ensure that a default task exists)
    if (!registerDefinitions.default) {
        registerDefinitions.default = function (grunt) { grunt.registerTask('default', []); };
    }

    // Run task functions to configure Grunt.
    invokeConfigFn(taskConfigurations);
    invokeConfigFn(registerDefinitions);

};