2020年のタスクランナー、【脱gulp】でnpm scriptsを使っていくための導入記事です。sassの環境構築やローカルサーバーの立ち上げもnpm scriptsで対応可能なので説明していきます。
はじめに
以前、
で簡単なnpm scriptsを使用してみました。以下は、その時のnpm scriptの例。
$ "babel": "./node_modules/.bin/babel src --out-dir js"
これで npm run babel を実行することでトランスパイルされるというものでした。
以前までタスクランナーにgulpを使用しているのですが、できれば脱gulp、そしてnpm scriptsに移行していきたいと考えていました。
今回はnpm scriptsについて深く知って、以下を目標に進めていきます。
sassの自動コンパイル&圧縮処理 babelを使用してjavascriptの自動トランスパイル&圧縮処理 browser-syncでブラウザリロード
npm scriptsとは
npmはpackage.jsonの「scripts」箇所に記述することで、シェルスクリプトやaliasコマンドを登録・実行することができます。
Frontend Developer Roadmap 2020版でも推奨
Frontend Developer Roadmap 2020版でもGulpよりnpm scriptsの使用が推奨されています。
Frontend Developer Roadmap 2020版を詳しく見たい方は以下から。
タスクランナー「gulp」との比較
以下、タスクランナーgulpとの比較です。
メリット
・豊富なnode_modulesをそのまま使用できる。 ・npmのパッケージ更新でタスクランナーがエラーになることがない。 ・タスクランナー(gulp,grunt等)を学ぶ必要がなくなる。
デメリット
・package.jsonの記述量が多くなる(肥大化する) ・可読性はタスクランナーの記述の方が高い気がする。 ・タスクランナーに比べて柔軟性・拡張性が低い。
ディレクトリ構成を決める
今回は以下のディレクトリ構成で環境を構築していきます。
dist/cssdist/jsdist/index.htmlsrc/sass/style.scsssrc/js/index.jspackage.jsonnode_modulesbabel.config.json
srcフォルダ内のファイルをコンパイル・トランスパイルしてdistフォルダに生成する流れです。
npm scriptsの準備
以前
で作成した環境をもとにnpm scriptsを使用した環境構築をしたいと思います。軽くおさらいですが、node.jsの準備ができた状態で、以下のコマンドを入力してpackage.jsonが作成します。(作成中の質問は全てenterでOK)
$ npm init
使用するnpmパッケージをインストール
今回の環境構築の目標を再度確認します。
sassの自動コンパイル&圧縮処理 babelを使用してjavascriptの自動トランスパイル&圧縮処理 browser-syncでブラウザリロード
これに必要なnpmパッケージをインストールしていきます。
sassのコンパイル処理
node-sassのパッケージをインストールします。 以下のコマンドを実行します。
$ npm install node-sass --save-dev
npm scriptsの記述
package.jsonのscriptsに以下を記述を追加します。
"css:sass": "node-sass src/sass/style.scss -o dist/css --output-style expanded --source-map dist/css"
ベンダープレフィックス付与と圧縮
node-sassでコンパイルしたCSSに、ベンダープレフィックスを自動的に付与、その後CSSを圧縮させます。 以下のコマンドで必要なパッケージをインストールします。
$ npm install postcss-cli cssnano autoprefixer --save-dev
postcss-cli
postcssの本体です。後述のパッケージを使用するために必要です。
cssnano
CSSファイルをminify(圧縮)してくれます。
autoprefixer
ベンダープレフィックスを自動で付与してくれます。
npm scriptsの記述
package.jsonのscriptsに以下を記述を追加します。
"css/postcss": "postcss dist/css/style.css -o dist/css/style.min.css"
postcss.config.jsの設定
PostCSS用の設定ファイルを作成します。
module.exports = { plugins: [ require("autoprefixer")(), require("cssnano")({ preset: "default", }), ],};
browserslistを設定する
ベンダープレフィックスを付与する範囲を指定します。「browserslist」はpackage.jsonに記述します。
"browserslist": [ ">0.25% in JP", "not ie <= 10", "not op_mini all" ]
browserslistの記述については以下もご参考にください。
sassの処理をまとめる
ここまでのタスクをまとめて1つのスクリプトで実行できるようにします。
流れを確認します。
SCSSファイルをコンパイルする ↓ CSSファイルにベンダープレフィックスを付与する ↓ CSSファイルを圧縮する
実行順序について(補足)
タスク連結の際の補足です。
npm scriptsは「&」や「&&」を使い分けることで実行順序を指定することができます。(今回は次項でnpm-run-allを使用します。)
並列に実行
「&」で繋げるとそれぞれのscriptを並列に実行。
直列に実行
「&&」で繋げるとそれぞれのscriptを直列に実行。
npm-run-allを利用する
今回はタスクをまとめる際に便利な「npm-run-all」を利用します。 以下のコマンドでnpm-run-allをインストールします。
$ npm install npm-run-all --save-dev
npm scriptsの記述
package.jsonのscriptsに以下を記述を追加します。
"css": "npm-run-all -s css:*"
内容の意味としては、
npm-run-allを使用して、「css:」とついたタスク名を記述の順番通りに実行する。
という感じです。
npm-run-allのオプションの説明です。
-p, —parallel | タスクを並行処理 |
-s, —sequential | タスクを順次処理* |
*順次とは、package.jsonのscriptの記述順になります。
Javascriptを圧縮するタスクを作成する
次にJavascriptのタスクを作成していきます。JSを圧縮するため、uglify-jsをインストールします。以下のコマンドでインストールします。
$ npm install uglify-js --save-dev
npm scriptsの記述
package.jsonのscriptsに以下を記述を追加します。
"js/uglifyjs": "uglifyjs dist/js/index.js -o dist/js/index.min.js"
「dist/js/index.js」を圧縮処理して、「dist/js/index.min.js」として書き出すという感じです。
Babelを利用してトランスパイルをする
Babelの設定については以下をご覧ください。
Babelでトランスパイルするタスクを以下のようにscriptsを変更します。
"js:babel": "./node_modules/.bin/babel ./src/js --out-dir ./dist/js"
Javascriptの処理をまとめる
Sassの処理をまとめる同様、Javascriptの処理をnpm-run-allを使用してまとめます。流れの確認です。
BabelでJavascriptコードをトランスパイルする。 ↓ Javascriptファイルを圧縮する。
以下をscriptsに追加します。
"js": "npm-run-all -s js:*"
これで npm run js コマンドで、JSのトランスパイルと圧縮処理ができるようになりました。
ファイルを監視する
ここからは毎回、処理の時にコマンドを打つ必要をなくすため、ファイルをwatch(監視)するようにして、変更がある度に自動的に処理するようにしていきます。
brwser-syncでサーバーを立ち上げる
browser-syncでサーバーを立ち上げます。 以下のコマンドでインストールします。
$ npm install browser-sync --save-dev
npm scriptsの記述
package.jsonのscriptsに以下を記述を追加します。
"watch:server": "browser-sync start --server dist --files 'dist, **/*.html, !node_modules/**/*'"
使用しているオプションです。
—server, -s | ローカルサーバーを実行します。 |
—files, -f | 監視するファイルパス |
その他、browser-syncのオプションについては以下のページをご参考ください。
SASSとJavascriptファイルを監視する
watchパッケージをインストールします。
$ npm install watch --save-dev
npm scriptsの記述
「src/sass」フォルダ内のファイルを監視対象にします。
"watch:css": "watch 'npm run css' ./src/sass"
JSの監視も同様に「src/js」フォルダ内のファイルを監視対象にします。
"watch:js": "watch 'npm run js' ./src/js"
監視用タスクをまとめる
最後に監視用タスクをまとめてしまいます。 以下をscriptsに追加します。
"watch": "npm-run-all -p watch/*"
これで、開発を開始する際に、npm run watch のコマンドで「watch:server」「watch:css」「watch:js」の監視タスクがひとまとめで実行することができます。
補足
npm scriptsの予約語
npm scriptsには予約語があります。予約語は「run」をつけずに実行することができます。
$ npm start$ npm restart$ npm stop$ npm test
例えば、「npm run watch」を→「npm start」にすることでコマンド入力がさらに楽になります。
コードまとめ
ここまでのscriptsをまとめたpackage.jsonが以下になります。
{ "name": "babel_test", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "css:sass": "node-sass src/sass/style.scss -o dist/css --output-style expanded --source-map dist/css", "css:postcss": "postcss dist/css/style.css -o dist/css/style.min.css", "css": "npm-run-all -s css:*", "js:babel": "./node_modules/.bin/babel ./src/js --out-dir ./dist/js", "js:uglifyjs": "uglifyjs dist/js/index.js -o dist/js/index.min.js", "js": "npm-run-all -s js:*", "watch:server": "browser-sync start --server dist --files 'dist, **/*.html, !node_modules/**/*'", "watch:css": "watch 'npm run css' ./src/sass", "watch:js": "watch 'npm run js' ./src/js", "watch": "npm-run-all -p watch:*" }, "author": "", "license": "ISC", "devDependencies": { "@babel/cli": "^7.8.4", "@babel/core": "^7.9.0", "@babel/preset-env": "^7.9.5", "browser-sync": "^2.26.7", "node-sass": "^4.13.1", "npm-run-all": "^4.1.5", "uglify-js": "^3.9.1", "watch": "^1.0.2", "autoprefixer": "^9.7.6", "cssnano": "^4.1.10", "postcss-cli": "^7.1.0" }, "browserslist": [ ">0.25% in JP", "not ie <= 10", "not op_mini all" ]}
最後に
今回は、脱gulpに向けて、npm scriptsを使用して以下の処理をする環境構築を行いました。
sassの自動コンパイル&圧縮処理 babelを使用してjavascriptの自動トランスパイル&圧縮処理 browser-syncでブラウザリロード
前までは、npm scriptsの記述が難しいなと敬遠していたのですが、一つづつ紐解いていくとgulpの変わりに使えそうだなと感じました。
脱gulpを予定されている方は、是非npm scriptsへの移行をご検討ください。