NxでGatsbyサイトを管理する
Nxのプラグイン一覧には載っていないのですが、Gatsbyプラグインも公式でリリースされています。 nx gコマンドがなかなか強力なので、使ってみました。 ワークスペース / アプリの立ち上げ create-nx-wor […]
広告ここから
広告ここまで
目次
Nxのプラグイン一覧には載っていないのですが、Gatsbyプラグインも公式でリリースされています。
nx g
コマンドがなかなか強力なので、使ってみました。
ワークスペース / アプリの立ち上げ
create-nx-workspace
はまだGatsbyをサポートしていません。(2021/1/14時点)そのため作成時にはemptyを指定します。
$ npx create-nx-workspace --cli=nx --preset=empty
その後、手動でアプリを作成しましょう。
$ yarn add -D @nrwl/gatsby
$ npx nx g @nrwl/gatsby:app <app-name>
ディレクトリ構成
ほぼ初期状態だとこのような形です。TypeScriptデフォルトなのが個人的に結構好みでした。
% tree -L 2 apps/gatsby/
apps/gatsby/
├── README.md
├── gatsby-browser.js
├── gatsby-config.js
├── gatsby-node.js
├── gatsby-ssr.js
├── jest.config.js
├── package.json
├── public
│ ├── favicon-32x32.png
│ ├── icons
│ ├── index.html
│ ├── manifest.webmanifest
│ ├── page-data
│ ├── render-page.js
│ ├── render-page.js.map
│ └── static
├── src
│ ├── Layout.tsx
│ ├── images
│ └── pages
├── tsconfig.json
└── tsconfig.spec.json
7 directories, 15 files
workspace.json
に追加されるオブジェクトはこんな感じです。build
/ serve
/ lint
/ test
コマンドが使えるみたいですね。
{
"root": "apps/gatsby",
"sourceRoot": "apps/gatsby/src",
"projectType": "application",
"generators": {},
"targets": {
"build": {
"executor": "@nrwl/gatsby:build",
"options": {
"outputPath": "dist/apps/gatsby",
"uglify": true,
"color": true,
"profile": false
},
"configurations": {
"production": {}
}
},
"serve": {
"executor": "@nrwl/gatsby:server",
"options": {
"buildTarget": "gatsby:build"
},
"configurations": {
"production": {
"buildTarget": "gatsby:build:production"
}
}
},
"lint": {
"executor": "@nrwl/linter:eslint",
"options": {
"lintFilePatterns": ["apps/gatsby/**/*.{ts,tsx,js,jsx}"]
}
},
"test": {
"executor": "@nrwl/jest:jest",
"options": {
"jestConfig": "apps/gatsby/jest.config.js",
"passWithNoTests": true
}
}
}
}
ビルドディレクトリについて
Nxで管理しているものは、だいたいdist/
配下にビルド結果を出力します。が、Gatsbyについてはapp/<app_name>/public
に吐き出されるという違いがあります。
dist
配下に配置したい場合、gatsby-node.js
でonPostBuild
イベントを使ってファイルを移動させましょう。
以下はIssueで見つけたコードをベースにNx向けに手を加えたサンプルです。workspaceJSON.projects[<app_name>].targets.build.options.outputPath
になることに注意しましょう。
const path = require('path');
const fs = require('fs');
const getBuildTarget = () => {
const workspaceJSON = require('../../workspace.json');
if (
workspaceJSON &&
workspaceJSON.projects &&
workspaceJSON.projects.gatsby &&
workspaceJSON.projects.gatsby.targets &&
workspaceJSON.projects.gatsby.targets.build &&
workspaceJSON.projects.gatsby.targets.build.options &&
workspaceJSON.projects.gatsby.targets.build.options.outputPath
) {
return path.join(
process.env.NX_WORKSPACE_ROOT,
workspaceJSON.projects.gatsby.targets.build.options.outputPath
);
}
return path.join(__dirname, 'public');
};
const target = getBuildTarget();
exports.onPreInit = () => {
if (process.argv[2] === 'build') {
if (fs.existsSync(target)) fs.rmdirSync(target, { recursive: true });
if (fs.existsSync(path.join(__dirname, 'public'))) {
fs.renameSync(
path.join(__dirname, 'public'),
path.join(__dirname, 'public_dev')
);
}
}
};
exports.onPostBuild = () => {
if (fs.existsSync(path.join(__dirname, 'public'))) {
fs.renameSync(path.join(__dirname, 'public'), target);
}
if (fs.existsSync(path.join(__dirname, 'public_dev'))) {
fs.renameSync(
path.join(__dirname, 'public_dev'),
path.join(__dirname, 'public')
);
}
};