概要
フロントエンドの開発中 npm-script を書いたけど、OSのコマンド差異でうまくチーム内で展開できない...
そんな悩みないですか?
その問題、 run-script-os
パッケージを使って解決出来ます!
(簡素なノウハウですが...)
やること
-
run-script-os
とnpm-run-all
(Option) を install
npm install --save-dev run-script-os npm-run-all
# or
yarn add --dev run-script-os npm-run-all
- npm-script を書く
{
...
"scripts": {
...
"echo-os": "run-script-os",
"echo-os:win32": "echo 'echo by Windows'",
"echo-os:darwin": "echo 'echo by macOS'",
"echo-os:linux": "echo 'echo by Linux'",
"test-file": "run-s create-file delete-file",
"create-file": "run-script-os",
"create-file:win32": "type nul > empty.txt",
"create-file:darwin:linux": "touch empty.txt",
"delete-file": "run-script-os",
"delete-file:win32": "del empty.txt",
"delete-file:darwin:linux": "rm -f empty.txt",
...
},
...
}
- npm-scriptを実行する
# "echo by [OS名称]"を出力する
npm run echo-os
# npm-run-allと組み合わせて、空ファイルを作成して削除する
npm run ctrl-file
- 実行OS毎に実行される command が切り替わる npm-script が出来る!
npm-run-os とは
- (簡単に言うと)nodeの実行環境(OS)毎に実行する npm-scriptを変更できるモジュール
- Node.js の node.processに設定されている値に応じてscriptが実行される
メリット
-
このモジュールの真価が発揮されるのは、フロントエンドアプリケーションのnpmエコシステム(と言うのか?)において、OS nativeな操作を実行する必要がある場合
- 反面、
npm module
のみで完結するのであれば不要なモジュール
- 反面、
-
一昔前に流行ったフロントエンドの歴戦のタスクランナー達のように、version依存などの問題回避が期待できる
- 特に npm module の管理と合わせて、タスク管理は非常にやりやすい
- npm modulen のバイナリを実行したいのであれば
npx
使えば良いし、非常に便利 - 歴戦のタスクランナー達:gulp.js, Grunt等
- (一昔前と言っても、gulpなんかは知る限り5年以上前にブームがあった気が... )
デメリット
- 上記の例でもわかる通り、OS nativeな操作に依存する操作が多ければ多いほどscriptが膨れ上がる
- だいたい、課題になる
Windows
とunix/linux系
を分けるだけでも、最低3行(1. npm-run-osの実行, 2.Windows
依存処理, 3.unix/linux系
依存処理)が必要になる - 必然的にpackage.jsonの肥大化に繋がる...
- だいたい、課題になる
- オデ ヘンスウ ツカウホウホウ ワカラナイ...オプション ドウスル...
例
ここでは、適当なビルドの例を想定して例をあげます。
あくまで一例ですし、書けば動作する例を示すわけでもないので参考程度に...
それぞれ、利用する要素技術については解説しないです。
(本記事の本旨からは外れますが、あらかじめnpm-run-scriptについてを読んでいただいた方が良いかもです)
ビルド例
- 想定する実行フロー
- 事前準備のNativeモジュールをビルドするbat/shを叩く
- sassでcssビルド (build:css)
- flowで型チェック (build:check-type)
- prettierでフォーマット整形 (build:format)
- babelでトランスパイル (build:transpile)
{
...
"scripts": {
...
"build": "run-s pre-build build:*",
"pre-build": "run-script-os",
"pre-build:win32": ".¥tools¥build-native.bat",
"pre-build:darwin:linux": "./tools/build-native.sh",
"build:css": "sass sass/*.scss dist/css/test.css --style=compressed",
"build:check-type": "flow check",
"build:format": "prettier src/**/.js --write",
"build:transpile": "babel src/**/ -o dist/main.js",
...
},
...
}
備考
npm-run-scriptについて
- npm-scriptを書くにあたって、関連するコマンドをパイプラインで繋いだりすると問題が...
2. セマンティックにnpm-scriptを定義したい- scriptを駆使して、script実行を繰り返すにしても...
npm script ** && npm script ** && npm script ** ...
< OMG
- 開発中は、developサーバ起動してUI確認しながら開発したい
- サーバー起動でコンソールがロックされる...バックグラウンド実行やxargs, GNU parallelで良いけど windows環境でどうする?
- scriptを駆使して、script実行を繰り返すにしても...
上記のような問題に対して、npm-scriptを逐次/並列に実行できるようにしてくれるのが、npm-run-scriptモジュール
使い方も非常にシンプルで、以下の2つを覚えれば良いだけです。
run-s: タスクを逐次実行
run-p: タスクを並列実行
run-p
は、ロール開発には必須となる webpack-dev-server
などの開発用ローカルサーバを立てたときにLISTEN状態になってしまうタスクと、後続タスクを並列で起動したい場合などで便利です。
{
...
"scripts": {
...
"run-dev": "run-p run-dev-server open-browser",
"run-dev-server": "webpack-dev-server --hot --watch-content-base --content-base dist/ --port 8080",
"open-browser": "run-script-os",
"open-browser:win32": "start microsoft-edge:http://localhost:8080",
"open-browser:darwin": "open http://localhost:8080",
"open-browser:linux": "open http://localhost:8080",
...
},
...
}
npm-script内に、run-s
やrun-p
を書けば、後続の処理を逐次/並列実行してくれる
ね、簡単でしょ?
まとめ
正直、だいたいのことは上記のnpm-scriptでなんとかなると思っている
何か複雑なことをしたければ特化したnpm moduleを利用すればいいし、npm module外のことをするにしても上記のモジュールを導入すればなんとかなる
(ちょっと気になるのは、package.jsonのscriptが肥大化すること... )
この記事が誰かの役に立てれば幸いです!
より良い npm ライフを!