こんにちは。
デザイン部でフロントエンドエンジニアをしている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' } } } }); //ローカルにあるprefecture_styles.jsを読み込んでいる。 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を量産するタスクを実施する際に、本稿を参考にして頂ければ幸いです。今回は以上になります。
アスタミューゼでは、エンジニア・デザイナーを募集中です。ご興味のある方は遠慮なく採用サイトからご応募ください。お待ちしています。