本文へジャンプ

SassとJSの設定ファイルを一元管理する!

Posted by MONSTER DIVE

図 - SassとJSの設定ファイルを一元管理する!

『CSSアニメーションが終わったら、JSでなにかしらの処理を走らせる』といった場合、CSSアニメーションのduration値とJSのsetTimeoutの値を合わせたりするわけですが、それって結局同じ値。

これに限らず、CSS/JS間で共通した値(アニメーション時間やプロパティ)を使うんだったら一元管理したいですよね。

そんなときは...そうだあれだ!
Gruntでやってしまいましょう!

grunt-shared-configを使う

Gruntのモジュール 「grunt-shared-config」 を使います。
CSSプリプロセッサー(SassとかSCSSとかLESSとかStylus)とJSで共通で使えるconfigファイルを生成してくれるモジュールです。

Gruntを使うので、Grunt.jsとNode.jsが必須です。
詳しくはこちら↓

まずは動作環境を用意

※Mac環境で行っています(OSX: 10.8.5)

任意の場所に動作環境用のフォルダを作ります。
フォルダ構成はこんなかんじにしてみます。

test
├bin
│├ css
││ └ style.css (style.scssからコンパイルするCSSファイル)
│├ js
││ ├ config.js (config.jsonから生成されるJSファイル)
││ └ test.js (config.jsの値を使ってスクリプトを記述したJSファイル)
│└ sample.html
├node_modules (インストールしたGruntファイルがいろいろと)
├src
│└ sass
│ ├ config.scss (config.jsonから生成されるSassファイル)
│ └ style.scss (config.scssをインポートしつつ、他のスタイルも設定するSassファイル)
├config.json (一元管理するための設定ファイル)
├Gruntfile.js (Grunt用設定ファイル)
└package.json (node環境のマニフェストファイル)

ターミナルを開いて、作っておいたトップディレクトリのフォルダ(ここでは"test")へ移動したら...

cd [フォルダまでのパス]

以下のコマンドを。

sudo npm init

聞かれるがまま、MacOSのパスワードを入力した後は、こちら↓

name: (test) test
version: (0.0.0) 0.0.1
description: this project is only test that controls propaties of animation of sass and js from one source.
entry point: (index.js) 
test command: 
git repository: 
keywords: sass js
author: monster dive
license: (BSD-2-Clause) MIT

こんなかんじでいろいろ聞かれるので、必要なところを入力&returnしていくと...

Is this ok? (yes)

イエス!ということで「yes」と入力。
フォルダに設定した内容の package.json ができているはずです。

次に、Gruntと例のGruntモジュール grunt-shared-config をインストールします。

sudo npm install grunt --save-dev
sudo npm install grunt-shared-config --save-dev

Gruntの設定ファイルも用意しましょう。

  • Gruntfile.js
module.exports = function(grunt){
    'use strict';
    var _pkg = grunt.file.readJSON('package.json'), _taskName;
    grunt.initConfig({
        pkg: _pkg,
        shared_config: {
            default: {
                options: {
                    name: 'Config',// Sass, JSで吐き出すファイル名
                    cssFormat: 'dash',// Sassのフォーマット
                    jsFormat: 'uppercase',// JSのフォーマット
                    amd: false
                },
                src: 'config.json',// 一元管理するJSON
                dest: [
                    'src/sass/config.scss',//吐き出すSCSSのパス
                    'bin/js/config.js'// 吐き出すJSのパス
                ]
            }
        }
    });
    // package.jsonに記載されているパッケージを自動読み込み
    for(_taskName in _pkg.devDependencies) {
        if(_taskName.substring(0, 6) == 'grunt-') {
            grunt.loadNpmTasks(_taskName);
        }
    }
    grunt.registerTask('default', ['shared_config']);
};

Written by Junichi.Honda

6行目から20行目の記述が、grunt-shared-config用です。
CSSとJSの出力フォーマットも設定できます。

設定ファイルを作る

JSON形式でconfigファイルを作ります。

  • config.json
{
    "speed" : 3,
    "animation_class_name" : "data-execute"
}

gruntコマンドを実行すると、以下のファイルが生成されます。

grunt

config.scss(Sass用の変数セット)

    $speed: 3;
    $animation_class_name: "data-execute";

config.js(JS用の変数セット)

    var Config = {
        "SPEED": 3,
        "ANIMATION_CLASS_NAME": "data-execute"
    };

Gruntfile.jsで設定したフォーマットに沿った変数セットが出力されています。

設定ファイルを使ってみる

出力されたSass/JSの設定ファイルを使って、アニメーションを作ってみます。

  • sample.html

config.js、test.js、style.cssを読み込みます。
また、jQueryを使っているので、jQueryのライブラリも必要です。

  • test.js
jQuery(document).ready(function(){
    'use strict';
    // -------------------------------------------------------------------------
    // function
    // -------------------------------------------------------------------------
    var onClick, onAnimationCompleted;
    onClick = function(){
        // Config.jsに設定したアニメーション用のクラスをaddClassする
        _obj.addClass(Config.ANIMATION_CLASS_NAME);
        setTimeout(onAnimationCompleted, _watingTime);
        return false;
    };
    // CSS側のアニメーションが終ったはず
    onAnimationCompleted = function(){
        alert('css3 animation completed!');
    };

    // -------------------------------------------------------------------------
    // initialize
    // ------------------------------------------------------------------------- 
    // CSSのアニメーションを待たせる時間
    // config.jsに生成される値の単位はJSで使用する"ms"じゃないので1000をかけておく
    var _watingTime = Config.SPEED * 1000,
        _btn = jQuery(document.getElementById('data-btn').getElementsByTagName('a')[0]).on('click', onClick),
        _obj = jQuery(document.getElementById('data-object'));
});

Written by Junichi.Honda

  • style.scss

いろいろ書いていますが重要なのはこの辺↓

// config.scssをインポート
@import "config";
// アニメーションのduration値に共通変数「$speed」を使用(単位をつけて)
.data-execute {
    -webkit-animation: anim $speed + s linear forwards;
    -moz-animation: anim $speed + s linear forwards;
    animation: anim $speed + s linear forwards;

    .count {
        -webkit-animation: count $speed + s ease forwards; 
        -moz-animation: count $speed + s ease forwards;
        animation: count $speed + s ease forwards; 
    }
}

ということでサンプルです。
ボタンをクリックしてから共通変数で設定した3s(秒)間、CSSアニメーションが動作した後、JSでアラートを表示させます。
動作環境)IE10以上、Chrome、Firefox、Safari

CSSアニメーションが終了したタイミングでJSのアラートが!
ちょうどいい具合!

もちろん、config.jsonでアニメーションの時間設定を調整してgruntコマンドを実行すれば、それぞれのファイルを開くことなく修正ができます。便利!

まとめ

今回試した使い方の他にも、アニメーションはJSよりCSSで動かすほうが軽い!ということを活かして、CSSアニメーションが有効なブラウザ(IE10以上、モダンブラウザ)ではCSS、それ以外のブラウザ(IE9以下)ではJSでアニメーションさせる際にも設定を一元管理すれば、あっちを直してこっちは直して...ない!などというケアレスミスも防げるし、とても効率的です。

CSSで出来ることも増えていますが、動的な処理はもちろんJSにおまかせするわけで、今後益々、CSS(Sass)とJSの連携の機会は増えていきそうな気配ですね。

Grunt/JS監修・協力:Kentaro.Otsuka, Junichi.Honda

Recent Entries
MD EVENT REPORT
What's Hot?