NxでNext.jsのMonorepo構成を試す
関連した複数のNext.jsアプリを作成する必要があり、Monorepo構成がドンピシャなのではと思い始めて見る。
ちなみに筆者は業務でMonorepoをやるのは初なので、とりあえずドキュメントに沿ってやってみる。
最初のセットアップ
$ npx create-nx-workspace nx-test-2 --package-manager=yarn
プロジェクト名は nx-test-2
, アプリ名は next-app-01
とする。
Package Managerは Yarn, StylingはEmotionを使う。
するとこんな感じで、apps以下に Next.js アプリができる。e2eもできてる。便利。
起動
yarn start
yarn start
で nx serve
コマンドが実行できる。
アプリを追加してみる
複数のNext.jsアプリを運用する想定なので、新たなappを追加する
$ npx nx g @nrwl/next:app
✔ What name would you like to use for the application? · next-app-02
next-app-02 という新しいNext.jsアプリが追加されたので、起動してみる。
$ yarn start next-app-02
無事起動できた。ちなみに、yarn start だけでは1つめの方 next-app-01
のアプリが起動した。
これは nx.json
の defaultProject
によるものっぽい。
Reactライブラリを追加してみる
複数のNext.jsアプリで共通で使うようなReact UIコンポーネントを、ライブラリという形で追加してみる。
$ npx nx g @nrwl/react:lib shared-ui-components --importPath=@nx-test-2/ui-components
✔ Which stylesheet format would you like to use? · @emotion/styled
すると、./libs 以下に shared-ui-components ディレクトリが生成され、tsconfig.base.json にもpath が追加された。便利。
(要検証)srcディレクトリに対応してない?
Next.js はsrc ディレクトリに対応しているのだが、Nxのapps内のNext.jsでsrcディレクトリを作ってみたら、_app.tsx
を読み込まない。
@nrwl/next
が悪さをしてるような気がするが、要検証。時間がなく一旦後回し。
ESLint, Prettier, Stylelint を導入する
通常のNext.jsアプリでは、 NPM Scriptを通してLinter, Formatterを使用していたが、Nxだと各appにpackage.jsonが無い。そこで、project.json
に targets
として登録してみた。これが最適解なのかはわからないが、今の所問題ない。「こっちのやり方の方が良いぜ!」があれば教えて下さいm(_ _)m
デフォルトの lint
targetは、eslintのみの実行だと思われるので、overrideする。ついでに Format 用の fix
target も作成した。
{
...略
"targets": {
"lint": {
"executor": "@nrwl/workspace:run-commands",
"options": {
"commands": [
"stylelint './**/*.(tsx|ts)'",
"prettier --check .",
"eslint ."
],
"cwd": "apps/app-01",
"parallel": true
}
},
"fix": {
"executor": "@nrwl/workspace:run-commands",
"options": {
"commands": [
"stylelint --fix './**/*.(tsx|ts)'",
"prettier --write .",
"eslint --fix ."
],
"cwd": "apps/app-01",
"parallel": false
}
}
},
}
lint
はparallelに、fix
はシーケンシャルに実行するようにした。
npm-run-all
でいうところの run-p
, run-s
を使う感覚で書ける。
これで
nx run app-01:lint
または
nx lint app-01
でLintを実行できる
Nx + ngrok
Nxで作成したReactアプリケーションをlocalhostで起動する際に、ngrokをかます必要があったのでやり方をメモ。
そのままだと ngrokが生成したURLを叩いても Invalid Host Header
と表示されてしまうので、修正が必要。
今回は "executor": "@nrwl/web:webpack",
なので、カスタムのwebpack設定ファイルを置けばよい。
https://nx.dev/guides/customize-webpack を参考にまんま持ってきて、
// Helper for combining webpack config objects
const { merge } = require('webpack-merge');
module.exports = (config, context) => {
return merge(config, {
devServer: {
allowedHosts: ['.ngrok.io'],
},
});
};
のように allowedHosts
で ngrokを許可し、
{
...略
"targets": {
"build": {
"executor": "@nrwl/web:webpack",
...略
"webpackConfig": "apps/app-01/custom-webpack.config.js"
},
}
とすればよい。production deployの際は非許可にするのを忘れないこと。