こんにちは。
デザイン部でフロントエンドエンジニアをしているkitoです。
弊社は、転職ナビというドメインの異なるサイトを300サイト以上運営しています。レアケースであるとは思いますが、運営上のノウハウの一部をご紹介したいと思います。
今回はスタイルシートを量産するフローを書かせて頂きます。
jsonファイルから複数のcssを作成する
転職ナビは数百サイトありますが、ひとつのアプリケーションでほぼ同じテンプレートが使われ、静的なアセットは原則として共有されています。
しかし、それぞれのサイトに固有のスタイルシートを適用しなければならない場面がどうしてもあります。
弊社では、サイト固有のスタイルシートをjsonファイルのデータから量産することでその問題に対処していますが、そのjsonの元ファイルはコミュニケーション上使い勝手のよいcsvファイルでデータが管理されています。
従って、まずcsvファイルをjsonに変換します。
下記のようなcsvファイル、prefecture.csvがあったとします。これをprefecture.jsonに変換します。
domainは文字通りサイトドメインで、R,G,BはそれぞれサイトカラーのRGBの値です。
domain |
R |
G |
B |
name |
hokkaido |
0 |
11 |
111 |
北海道 |
aomori |
32 |
66 |
66 |
青森 |
iwate |
4 |
15 |
43 |
岩手 |
miyagi |
55 |
180 |
8 |
宮城 |
akita |
10 |
20 |
30 |
秋田 |
yamagata |
90 |
0 |
0 |
山形 |
fukushima |
10 |
10 |
10 |
福島 |
ibaraki |
40 |
30 |
12 |
茨城 |
tochigi |
68 |
11 |
54 |
栃木 |
gunma |
250 |
100 |
40 |
群馬 |
csvtojsonというモジュールを使いたいので下記コマンドでインストールしてください。
npm install --save csvtojson
以下作成していくディレクトリは以下のようになります。
├── package.json
├── converter.js
├── template.js
├── prefecture.json
├── Gruntfile.js
├── dev
│ └── unique
│ ├── akita
│ │ └── styles
│ │ ├── sp_unique.scss
│ │ └── unique.scss
│ ├── aomori
│ │ └── styles
│ │ ├── sp_unique.scss
│ │ └── unique.scss
│ 以下略
├── tasks
│ └── prefecture_styles.js
├── unique
│ ├── akita
│ │ └── styles
│ │ ├── sp_unique.css
│ │ └── unique.css
│ ├── aomori
│ │ └── styles
│ │ ├── sp_unique.css
│ │ └── unique.css
│ 以下略
└── node_modules
converter.jsを作成して下記のコードを実行してください。csvファイルをjsonに変換します。
var fs = require('fs');
var csv = require("csvtojson");
var converter = csv({});
var csvFile = './prefecture.csv';
var jsonFile = './prefecture.json';
fs.createReadStream(csvFile).pipe(converter);
converter.on("end_parsed", function (jsonArray) {
fs.writeFile( jsonFile, JSON.stringify( jsonArray, null, ' ' ),'utf8');
console.log('csv to json is complete !');
});
下記のようなprefecture.jsonが作成されたと思います。
[
{
"domain": "hokkaido",
"R": 0,
"G": 11,
"B": 111,
"name": "北海道"
},
{
"domain": "aomori",
"R": 32,
"G": 66,
"B": 66,
"name": "青森"
},
以下略
]
弊社はsassを導入しているのでprefecture.jsonからgruntを通じてsassを作成し、それを元にcssを作成するフローになります。
二度手間のように感じるかもしれませんが、他のsassをimportしたり、ユニークなカラーを変数に設定できたりと、使い勝手がよいからです。
sassを量産するprefecture_styles.jsというGruntプラグインを作成します。
tasksディレクトリに、prefecture_styles.jsを作成して下記コードを記入してください。prefecture.jsonと後で作成するテンプレートを元にsassを量産します。
module.exports = function(grunt) {
var fs = require('fs');
var json = grunt.config('prefecture_styles').json;
var data = JSON.parse(fs.readFileSync(json, 'utf8'));
grunt.registerTask('prefecture_styles', 'task', function() {
var dir = grunt.config('prefecture_styles').dir;
var stylesDir = grunt.config('prefecture_styles').stylesDir;
var name = grunt.config('prefecture_styles').name;
var template = grunt.config('prefecture_styles').template;
var sasstmp = require(template);
Object.keys(data).forEach(function(key, index) {
var domain = data[key]["domain"]
var R = data[key]["R"]
var G = data[key]["G"]
var B = data[key]["B"]
var sassObj = new sasstmp(R,G,B);
name.forEach(function(val, index) {
grunt.file.write(dir + domain + stylesDir + name[0],sassObj.pc , function(err) {});
grunt.file.write(dir + domain + stylesDir + name[1],sassObj.sp , function(err) {});
});
});
console.log('generated sass!')
});
};
grunt.config('prefecture_styles').〇〇で、Gruntfile.jsから設定を読み込んでいます。
jsonはスタイルシートの値が入ったjsonファイル(ここではprefecture.json)、dirはベースとなるディレクトリ、stylesDirはsassが入るディレクトリ名、nameはsassの名前、templateは量産するsassのテンプレートになります。
Object.keys(data).forEachでprefecture.jsonから値を取り出して、それぞれ変数に代入し、grunt.file.writeでpc用とsp用のsassを作成&記述しています。
元となるテンプレート、template.jsを作成します。
var sasstmp = function(R,G,B) {
this.pc = '@charset "utf-8";\n' + '$uniqueSiteColor:rgb(' + R + ',' + G + ',' + B + ');\n' + '.siteColor{ background-color:rgb(' + R + ',' + G + ',' + B + ')};\n';
this.sp = '@charset "utf-8";\n' + '$uniqueSiteColor:rgb(' + R + ',' + G + ',' + B + ');\n' + '.siteColor{ background-color:rgb(' + R + ',' + G + ',' + B + ')};\n';
}
module.exports = sasstmp;
次にGruntfile.jsの設定に移ります。
(gruntをインストールについては割愛します。)
下記gruntプラグインをインストールしてください。
npm install grunt-contrib-compass --save-dev
npm install grunt-contrib-clean --save-dev
grunt-contrib-compassはsassをcssにコンパイルするプラグイン、grunt-contrib-cleanはファイルを削除をするプラグインです。
Gruntfile.jsを下記のように記述してください。
実際に業務で使うときのGruntfile.jsは、sassの変更をwatchしたりwebpackを使ってjsをバンドルしたりと他のタスクを追加することになりますが、今回は必要最小限の構成にしてあります。
var grunt = require('grunt');
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
clean: {
build: {
src: [
'.sass-cache',
'./dev/build/unique/'
]
},
release: {
src: [
'.sass-cache',
'./unique/**/styles/*.css'
]
}
},
prefecture_styles: {
dir: './dev/unique/',
json: './prefecture.json',
template: '../template.js',
stylesDir: '/styles/',
name: [
'unique.scss',
'sp_unique.scss'
]
},
compass: {
prod: {
options: {
sassDir: './dev/unique',
cssDir: './unique',
environment: 'production'
}
}
}
});
grunt.task.loadTasks('tasks');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-compass');
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.registerTask('build', ['clean:release', ' prefecture_styles', 'compass:prod']);
};
grunt.initConfig({})の中に prefecture_styles.jsの設定を記述します。
compass:{}には prefecture_styles.js作成したsassをcssにコンパイルする設定を行っています。
grunt.task.loadTasks('tasks')は、コメントにあるように先程作成したprefecture_styles.jsをロードしています。
Nodeモジュールとして公開しておけば、grunt.loadNpmTasks(' prefecture_styles')で読み込めるでしょう。
下記でGruntを実行してください。
grunt build
uniqueディレクトリが作成され、それぞれのドメイン名以下に、unique.css、sp_unique.cssが作成されていれば成功です。
cssを量産するタスクを実施する際に、本稿を参考にして頂ければ幸いです。今回は以上になります。
アスタミューゼでは、エンジニア・デザイナーを募集中です。ご興味のある方は遠慮なく採用サイトからご応募ください。お待ちしています。