独学者Fossa

独学していることなど

Laravel Modulesで、npm Workspaces

以前、Yarnを使っていましたが、YarnWorkspacesがあったなんて、知りませんでした。

npm v7になって、Workspacesが使えるようになりました。

ずっと前から、Laravel Modulesを使って思っていたのが、各モジュール毎に、package.jsonがありますが、共通するものがあります。

例えば、私の場合、UIkit v3というCSS フレームワークは、全てのモジュールで使っています。*1

モジュールが10個あれば、UIkit v3を10回分、インストールしてましたし、アップデートも然りです。

ルートのpackage.jsonに、UIkit v3を書いておくだけで、各モジュールで使えれば便利だなと思いました。

早速、試してみましょう。

使用環境

Name Version
node 14.17.1
npm 7.19.0
UIkit 3.6.22

フォルダ構成

├── app
├── artisan
├── bootstrap
├── composer.json
├── composer.lock
├── config
├── database
├── modules
│   └── A
│      <<省略>>
│       └── package.json
│   └── B
│      <<省略>>
│       └── package.json
├── node_modules
├── package.json
├── phpunit.xml
├── public
├── resources
├── routes
├── server.php
├── storage
├── tests
├── vendor
└── webpack.mix.js

説明に必要な部分だけ、抜き出すと下記の通り。

├── modules
│   └── A
│      <<省略>>
│       └── package.json
│   └── B
│      <<省略>>
│       └── package.json
├── node_modules
├── package.json

ルートのpackage.json

{
    "private": true,
    "scripts": {
        "dev": "npm run development",
        "development": "mix",
        "watch": "mix watch",
        "watch-poll": "mix watch -- --watch-options-poll=1000",
        "hot": "mix watch --hot",
        "prod": "npm run production",
        "production": "mix --production"
    },
    "devDependencies": {
        "laravel-mix": "^6.0.25"
    },
    "dependencies": {
        "uikit": "^3.6.22"
    },
    "workspaces": [
        "modules/*"
    ]
}

workspaces欄を、追記しています。

モジュールAのpackage.json

{
    "name": "module-a",
    "private": true,
    "scripts": {
        "dev": "npm run development",
        "development": "mix",
        "watch": "mix watch",
        "watch-poll": "mix watch -- --watch-options-poll=1000",
        "hot": "mix watch --hot",
        "prod": "npm run production",
        "production": "mix --production"
    },
    "devDependencies": {
        "laravel-mix-merge-manifest": "^2.0.0",
        "postcss": "^8.3.0",
        "sass": "^1.34.0",
        "vue-loader": "^16.1.1"
    },
    "dependencies": {
        "@vue/compiler-sfc": "^3.1.2",
        "axios": "^0.21.1",
        "vue": "^3.1.2",
        "vue-router": "^4.0.1"
    }
}

"name"欄が、ポイントです。
"uikit": "^3.6.22"と、"laravel-mix": "^6.0.25"を、取り除いています。

試してみましょう

npm i
npm run dev --workspace=module-a

結論

これで、何回もUIkit v3をインストールしたり、アップデートしたりする必要は、なくなりました。

全てのモジュールで使うものは、ルートのpackage.jsonに書いておけばいいということですね。

以前なら、cd modules/Aと入力し、フォルダに移動してから、npm run devとか、ncu -uとか、していました。

フォルダに移動する必要がなく、ルートで、全て作業できそうです。*2

Laravel Mixなど、node_modulesの位置が変わるので、設定の変更が必要になる場合もあるかと思います。

npm-check-updates

  • 全てのモジュール
npm exec --workspaces -- ncu -u
  • モジュールAだけの場合
npm exec --workspace=module-a -- ncu -u

dart-sass

モジュールAのpackage.jsonに、追記します。

"scripts": {
    "scss": "sass --quiet --load-path=../../node_modules Resources/scss/style.scss ../../public/css/style.css",
    <<以下省略>>
npm run scss --workspace=module-a

*1:modalとか、vueでimportして使っています

*2:npm-scriptsは、​Visual Studio Codeを使えば、フォルダに移動しなくても、実行できます