以前投稿したシンプルだけどシッカリ働く最新のECMAScript開発環境ではクロスプラットフォームなnodeモジュールをいくつか使わせてもらいながらも、Windows環境では動かない構成になっていました。

素晴らしいモジュールたちをしっかり活かすべくWindows対応を行い、その際必要だった対応をまとめます。

対応前のpackage.json

package.json
{
  "private": true,
  "scripts": {
    "start": "npm run mkdist && npm run cpassets -- -w & npm run cphtml -- -w & webpack-dev-server",
    "build": "npm run mkdist && npm run cpassets && npm run cphtml && webpack --optimize-minimize",
    "mkdist": "rimraf dist/ && mkdirp dist/",
    "cpassets": "cpx 'assets/**/*' dist/",
    "cphtml": "cpx src/index.html dist/"
  },
  "dependencies": {
    "babel-polyfill": "^6.26.0"
  },
  "devDependencies": {
    "cpx": "^1.5.0",
    "mkdirp": "^0.5.1",
    "rimraf": "^2.6.2",
    "babel-core": "^6.26.0",
    "babel-loader": "^7.1.2",
    "babel-preset-env": "^1.6.1",
    "webpack": "^3.5.6",
    "webpack-dev-server": "^2.7.1"
  }
}

ダメだった箇所

npmスクリプト内のシングルクオーテーション

cpxでのディレクトリ内再帰的コピーが動きませんでした

Macではコレでいけてましたが

package.jsonより抜粋
"cpassets": "cpx 'assets/**/*' dist/",

Winではこうしないとダメでした

package.jsonより抜粋
"cpassets": "cpx \"assets/**/*\" dist/",

npmスクリプトではシングルクオーテーションでなくエスケープ付きダブルクオーテーションを使った方が良さそうです

npmスクリプトの並列実行

&を使用したnpmスクリプトの並列実行ができませんでした

コマンド Mac Windows
& 並列実行 エラー無視の直列実行
&& 直列実行 直列実行

npmスクリプトを直列・並列実行させるためのクロスプラットフォームなモジュールnpm-run-allを導入し

並列実行を使用しているstartをこのように書き換えました

Before

package.jsonより抜粋
"start": "npm run mkdist && npm run cpassets -- -w & npm run cphtml -- -w & webpack-dev-server",

After

package.jsonより抜粋
"start": "npm-run-all mkdist --parallel \"cpassets -- -w\" \"cphtml -- -w\" webpack-dev",
"webpack-dev": "webpack-dev-server"

mkdistを実行後、cpassets -- -w cphtml -- -w webpack-devを並列実行させています

npm-run-allはオプション無しだと直列実行ですが、オプションを指定すると並列/直列を組み合わせることができます
並列 : --parallel <tasks>
直列 : --serial <tasks>

対応後のpackage.json

package.json
{
  "private": true,
  "scripts": {
    "start": "npm-run-all mkdist --parallel \"cpassets -- -w\" \"cphtml -- -w\" webpack-dev",
    "build": "npm-run-all mkdist cpassets cphtml webpack",
    "mkdist": "rimraf dist/ && mkdirp dist/",
    "cpassets": "cpx \"assets/**/*\" dist/",
    "cphtml": "cpx src/index.html dist/",
    "webpack": "webpack --optimize-minimize",
    "webpack-dev": "webpack-dev-server"
  },
  "dependencies": {
    "babel-polyfill": "^6.26.0"
  },
  "devDependencies": {
    "cpx": "^1.5.0",
    "mkdirp": "^0.5.1",
    "npm-run-all": "^4.1.2",
    "rimraf": "^2.6.2",
    "babel-core": "^6.26.0",
    "babel-loader": "^7.1.2",
    "babel-preset-env": "^1.6.1",
    "webpack": "^3.5.6",
    "webpack-dev-server": "^2.7.1"
  }
}

まとめ

クロスプラットフォーム対応の便利なモジュールを使う

コマンド差分が辛いので、クロスプラットフォームに対応しているモジュールを使いましょう

  • cpx : ファイルコピーをサポート&監視
  • mkdirp : ディレクトリ作成をサポート
  • rimraf : ディレクトリ削除をサポート
  • npm-run-all : npmスクリプトの並列実行をサポート

npmスクリプト内ではシングルクオーテーションを使わない

エスケープ付きダブルクオーテーションを使いましょう

パスの指定にはNodeAPIのpathを使う

今回は対応不要でしたが、ファイルパス系はMacとWindowsで以下のように異なります

Mac

const indexPath = './src/index.js';

Windows

const indexPath = '.\\src\\index.js';

これはNodeAPIのpathを使用することで、下記に統一することができます

const path = require('path');

const indexPath = path.resolve('src', 'index.js');

さいごに

対応後の環境はこちらにあるので、よかったら試してみてください。