Skip to content

fix: dist ディレクトリに HTML 付き production ビルドを出力する #44

@takaokouji

Description

@takaokouji

概要

smalruby.app (本番環境) へのデプロイ用に、最適化された production ビルドを dist/ ディレクトリに HTML 付きで出力する仕組みを追加する。

背景

現在のビルド構成:

  • build/: 開発ビルド(HTML + JS、圧縮なし、ソースマップあり)
  • dist/: JS ライブラリのみ(HTML なし)

デプロイ先と使用ディレクトリ:

  • smalruby.app (本番): dist/ を使用(最適化されたビルド)
  • smalruby3-editor (develop): build/ を使用(プレビュー用)
  • PR ブランチ: build/ を使用(プレビュー用)

問題

webpack で dist/ に HTML を出力しようとすると、TerserPlugin の段階でビルドが失敗する。

<s> [webpack.Progress] 92% sealing asset processing TerserPlugin
npm error Lifecycle script `build:dist-html` failed with error:
npm error code 1

エラーメッセージの詳細が表示されないため、原因の特定が困難。

調査内容

試したアプローチ

アプローチ 1: buildWithPwaConfig.clone() をベースに作成

const distWithHtmlConfig = buildWithPwaConfig.clone()
    .merge({
        output: {
            path: path.resolve(__dirname, 'dist')
        }
    });

結果: TerserPlugin でビルド失敗

アプローチ 2: buildConfig.clone() をベースに作成

const distWithHtmlConfig = buildConfig.clone()
    .merge({
        output: {
            path: path.resolve(__dirname, 'dist')
        }
    })
    .addPlugin(new WorkboxPlugin.GenerateSW({...}))
    .addPlugin(new WebpackPwaManifest({...}));

結果: TerserPlugin でビルド失敗

考えられる原因

  1. output 設定の競合: distConfig に clean: false が設定されており、継承した設定と競合している可能性
  2. library 設定の干渉: distConfig の output.library 設定が HTML 出力時に干渉している可能性
  3. ScratchWebpackConfigBuilder の .clone() の挙動: 内部状態が正しくコピーされていない可能性
  4. TerserPlugin の設定: 本番モードでの圧縮処理中にエラーが発生している
  5. publicPath の違い: buildConfig ('') と distConfig ('auto') の違いが影響している可能性

次のステップ(デバッグ候補)

1. エラーログの詳細を確認

docker compose run --rm app bash -c "cd packages/scratch-gui && NODE_ENV=production BUILD_TYPE=dist-html npx webpack --stats=errors-only"

2. TerserPlugin を無効化してテスト

webpack.config.js で一時的に TerserPlugin を無効化して、HTML が生成されるか確認。

3. mode を development に変更してテスト

NODE_ENV=production の代わりに development でビルドして、問題を切り分ける。

4. output 設定を明示的に指定

const distWithHtmlConfig = buildConfig.clone()
    .merge({
        mode: 'production',
        output: {
            path: path.resolve(__dirname, 'dist'),
            publicPath: '',
            clean: true,
            library: undefined
        }
    })

5. 別のアプローチ: build/ を dist/ にコピー

webpack の設定を変更せず、CI/CD で build/ を dist/ にコピーする方法:

- name: Prepare deployment files for smalruby.app
  if: github.ref == 'refs/heads/develop'
  run: |
    cp -r packages/scratch-gui/build packages/scratch-gui/dist
    touch packages/scratch-gui/dist/.nojekyll

メリット:

  • webpack の設定を変更しないので、upstream とのマージが容易
  • エラーが発生しない
  • シンプルで理解しやすい

関連ファイル

  • packages/scratch-gui/webpack.config.js
  • packages/scratch-gui/package.json
  • packages/scratch-gui/src/playground/index.jsx
  • packages/scratch-gui/src/playground/render-gui.jsx
  • .github/workflows/ci-cd.yml

詳細調査レポート

詳細な調査内容は別途ドキュメントにまとめてあります。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions