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.jsonPostBuildイベントを使ってファイルを移動させましょう。

    以下は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')
        );
      }
    };
    
    

    広告ここから
    広告ここまで
    Home
    Search
    Bookmark