タスクランナーとして有名なgulpやgruntですが、
学習コストが高い上、gulpで得た知識がgulpでしか使えなかったり、
プラグインを介してモジュールを使うため、プラグインの更新が滞ると、使いたいモジュールが使えなかったりしていました。
それならnpm-scriptsをタスクランナーにしちゃえ
どういうことかと言うと、
まず、gulpやgruntといったタスクランナーは、それらを介して間接的にモジュールを使います。
しかし、上記で挙げたような問題が起こるため、gulpやgruntから脱却し、
直接モジュールを使ってしまおうという考え方です。
準備
cdコマンドで任意のプロジェクトディレクトリに移動しましょう。
移動したら、次のコマンドを実行します。
$ npm init
プロジェクトディレクトリを確認すると、見覚えのあるpackage.jsonがあります。
これで準備ができました。
Sassのコンパイル
sassを使うには、node-sassをインストールします。
次のコマンドを実行してみましょう。
$ npm install node-sass
これでsassを使えるようになりました。
npmでは、npm install ○○で様々な機能をインストールできるので覚えておきましょう。
続いて、package.jsonを編集していきます。
ファイルを開くと、scriptsという配列があるので、
その中に処理を書いていきます。
"scripts": { //ここに処理 }
sassをコンパイルするので、次のコードをscriptsの中に記述します。
"css/sass": "node-sass src/scss/style.scss -o dist/css --output-style expanded"
「node-sassを使い、
src/scss/style.scssを
dist/cssとして書き出す。
圧縮はしない。」
という意味です。
この、「:」(コロン)より左側の「css/sass」の部分をターミナルで打つと実行させることができます。
$ npm run css/sass
ベンダープレフィックスの追加
タスクランナーを使っていた人なら、cssのベンダープレフィックスを自動で追加してくれる機能を入れていた人もいると思いますが、それも可能です。
必要なのは、autoprefixerとpostcss-cliの2つです。
先程のように、コマンドでインストールしてください。
$ npm install autoprefixer postcss-cli
scriptsの中に、次のコードを記述します。
"css/postcss/autoprefix": "postcss dist/css/style.css -o dist/css/style.css -c=postcss.config.js"
「dist/css/style.css」の部分はscssではなく、cssのパスを書いてください。
次に、設定ファイルを用意します。
postcss.config.jsというファイルを、プロジェクトのルートに設置します。
postcss.config.jsの中身は次のとおりです。
module.exports = { plugins: [ require('autoprefixer')({ browsers: ['last 2 version', 'not ie < 11', 'iOS >= 9', 'Android >= 4.4'], cascade: true }) ] }
browsersの部分で対応するブラウザを指定しています。
主に書き換えるのはここだけで良いと思います。
処理をまとめて実行する
ここまでに紹介したsassのコンパイルと、ベンダープレフィックスの自動追加を実行するには、次の2つのコマンドを実行しなければいけません。
$ npm run css/sass
$ npm run css/postcss/autoprefix
しかし、処理が増えると、このようなコマンドを一つ一つ実行していくのは手間なので、一つのコマンドで実行できるようにします。
その前にnpm-run-allが必要なので、インストールしましょう。
$ npm install npm-run-all
scriptsの中に以下のコードを記述します。
"css": "npm run css/clean && npm-run-all -p css/*", "css/clean": "rimraf dist/css && mkdir -p dist/css"
2行目のcss/cleanは、コンパイルする前に、cssフォルダにある不要なファイルを削除する処理です。
1行目で、最初にcss/cleanを実行してから、npm-run-allで「css/」からはじまる処理をすべて実行しています。
ここまでのコードをまとめると次のようになります。
"scripts": { "css": "npm run css/clean && npm-run-all -p css/*", "css/clean": "rimraf dist/css && mkdir -p dist/css", "css/sass": "node-sass src/scss/style.scss -o dist/css --output-style expanded", "css/postcss/autoprefix": "postcss dist/css/style.css -o dist/css/style.css -c=postcss.config.js" }
これで次のコマンドを実行するだけでcssに関する処理がすべて実行できるようになりました。
$ npm run css
package.json内で変数を使う
package.jsonを編集していると、フォルダのパスなど、何度も同じ記述をする場面があります。
そんな時は、変数を使うと便利です。
package.jsonにはconfigという配列が用意されていて、その中に変数を入れることができます。
※configが無い場合は追加してください。
変数を使うと、次のコードのようにスッキリまとめることができます。
"config": { "cssDir": "dist/css", "scssDir": "src/scss" }, "scripts": { "css": "npm run css/clean && npm-run-all -p css/*", "css/clean": "rimraf $npm_package_config_cssDir && mkdir -p $npm_package_config_cssDir", "css/sass": "node-sass $npm_package_config_scssDir/style.scss -o dist/css --output-style expanded", "css/postcss/autoprefix": "postcss $npm_package_config_cssDir/style.css -o $npm_package_config_cssDir/style.css -c=postcss.config.js" }
このコードでは、cssDirという変数にdist/cssを、
scssDirという変数にsrc/scssを代入しています。
変数をscripts内で使う場合は、$npm_package_config_変数名という文字列を使用します。
cssDirという変数を使いたいなら、$npm_package_config_cssDirと書いてください。
画像の圧縮
画像を圧縮するには、次のものが必要になります。
すべてインストールしましょう。
imagemin
imagemin-keep-folder
imagemin-mozjpeg
imagemin-pngquant
imagemin-gifsicle
imagemin-svgo
imagemin-svgo
npm install imagemin imagemin-keep-folder imagemin-mozjpeg imagemin-pngquant imagemin-gifsicle imagemin-svgo
次に、ルートにimagemin.jsというファイルを設置します。
内容は次のとおりです。
const imagemin = require('imagemin-keep-folder'); const imageminMozjpeg = require('imagemin-mozjpeg'); const imageminPngquant = require('imagemin-pngquant'); const imageminGifsicle = require('imagemin-gifsicle'); const imageminSvgo = require('imagemin-svgo'); imagemin(['src/img/**/*.{jpg,png,gif,svg}'], { plugins: [ imageminMozjpeg({ quality: 70, progressive: true }), imageminPngquant({ quality: [.65, .80], speed: 1, floyd: 0 }), imageminGifsicle(), imageminSvgo() ], replaceOutputDir: output => { return output.replace(/src\//, 'dist/') } }).then(() => { console.log('Images optimized'); });
scriptsには次のように記述します。
"img": "npm run img/clean && npm-run-all -p img/*", "img/clean": "rimraf dist/img && mkdir -p dist/img", "img/imagemin": "node imagemin.js"
試しに画像を入れて実行してみましょう。
EJS
EJSも入れちゃいましょう。
ejs-cliをインストールします。
$ npm install ejs-cli
scriptsは以下でOK
"ejs": "ejs-cli --base-dir src/ejs '**/*.ejs' --out dist"
ejsフォルダ内のejsファイルをディレクトリ構造を保持してコンパイルします。
_header.ejsなど、頭に_(アンダーバー)をつければコンパイルしなくなります。
ファイルの監視
必要なものをインストールします。
$ npm install browser-sync onchange watch
scriptsには次のコードを記述。
"s": "npm-run-all -p watch/*", "watch/sass": "watch 'npm run css' src/scss", "watch/img": "onchange src/img -e '**/*.DS_Store' -- npm run img", "watch/ejs": "watch 'npm run ejs' src/ejs", "watch/server": "browser-sync start -s dist -f 'dist, !node_modules/**/*'"
watch/serverではbrowser-syncでサーバーを起動する処理を書いています。
start -s の後のdistは、distディレクトリをルートにしてサーバーを起動するという意味です。
watch/sass、watch/img、watch/ejsはそれぞれのファイルを監視しています。
最後に、watch/で始まる処理をまとめているのが、「s」という処理です。
次のコマンドを実行すれば、サーバーが起動し、watchの処理も走るようになります。
$npm run s