2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

WXTをwin11 + WSL2 + Dockerで動かす

Posted at

やりたかったこと、経緯

  • TypeScript + React + Vite で Chrome 拡張機能を作りたい
  • その開発環境を WSL2 上に Docker で構築したい
  • 現行の crxjs はライブラリの更新が滞っているため、wxt を使ってみたい
  • しかし、wxt を Docker コンテナ上で動かす知見がない(技術的には有用でないのかも)

この記事のセールスポイント

  • 現時点のwxtをコンテナで動かすための、コンテナ設定、wxt.config.ts の設定項目を解説

最終成果物とその解説

ディレクトリ構造(抜粋)

.
├── Dockerfile
├── docker-compose.yml
└── host-frontend-root # コンテナの/opt/frontend-container-app-rootにマウントされるディレクトリ
    └── frontend-src-root # wxtで作成したプロジェクト
        ├── .output # chromeから読み込むディレクトリ
        ├── .wxt 
        ├── assets
        ├── entrypoints # 開発で編集するファイル
        ├── package-lock.json
        ├── package.json
        ├── public
        ├── tsconfig.json
        └── wxt.config.ts # docker対応のために編集

各ファイル

# 実際には wxt の初期化を行うため、作業時にいくつかのコードをコメントアウトしている
FROM node:23.0-alpine3.19

WORKDIR /opt/frontend-container-app-root/frontend-src-root

# Chromium のインストール
RUN apk add --no-cache \
  chromium

COPY ./host-frontend-root/frontend-src-root /opt/frontend-container-app-root/frontend-src-root

RUN npm install

docker-compose.yml
services:
  frontend:
    image: frontend-image
    build: .
    restart: always
    tty: true
    volumes:
      - ./host-frontend-root:/opt/frontend-container-app-root/
    environment:
      - HOST=localhost
    network_mode: host
wxt.config.ts
import { defineConfig } from 'wxt';

// See https://wxt.dev/api/config.html
export default defineConfig({
  extensionApi: 'chrome',
  modules: ['@wxt-dev/module-react'],

  dev: {
    server: {
      hostname: 'localhost',
      port: 3000,
    }
  },
  runner: {
    disabled: true,
  },
  vite:() =>  ({
    server: {
      host: 'localhost',
      port: 3000,
      strictPort: true, 
      hmr: {
        port: 3000,
      }
    }
  }),
});

前提

  • Windows 11
  • WSL2
  • 空のリポジトリが作成済み
  • Docker、Docker Compose がインストール済み

やったこと

初期ディレクトリ、ファイル構成

プロジェクトルートにフォルダを作成

WSL on win11
mkdir host-frontend-root

プロジェクトルートに Dockerfile、docker-compose.yml を作成

WSL on win11
echo "FROM node:23.0-alpine3.19" > Dockerfile
echo "services:" > docker-compose.yml

この時点のディレクトリ構造は下記の通り

WSL on win11
tree -I .
.
├── Dockerfile
├── README.md
├── docker-compose.yml
└── host-frontend-root

2 directories, 3 files

初期コンテナ作成

あとで使う箇所をコメントアウトしておく

Dockerfile
FROM node:23.0-alpine3.19

WORKDIR /opt/frontend-container-app-root/frontend-src-root

# Chromium のインストール
RUN apk add --no-cache \
  chromium

# COPY ./host-frontend-root/frontend-src-root /opt/frontend-container-app-root/frontend-src-root

# RUN npm install
docker-compose.yml
services:
  frontend:
    image: frontend-image
    build: .
    restart: always
    tty: true
    volumes:
      - ./host-frontend-root:/opt/frontend-container-app-root/
    environment:
      - HOST=localhost
    network_mode: host

コンテナを起動する

WSL on win11
docker compose build --no-cache && docker compose up -d && docker compose ps

wxtを使ってプロジェクトを作成

VS Code のリモートエクスプローラーで起動したコンテナに接続する

container
pwd
/opt/frontend-container-app-root

wxt を使ってプロジェクトを作成する

container
npx wxt@latest init frontend-src-root

を実行。今回はreact、npmを選んでいるが、目的に応じて変えて良い

container
npx wxt@latest init frontend-src-root
WXT 0.19.23
ℹ Initalizing new project
✔ Choose a template › react
✔ Package Manager › npm
✔ Downloading template

✨ WXT project created with the react template.

Next steps:
  1. cd frontend-src-root
  2. npm install

ログが示してくれた通りコマンドを実行

container
cd frontend-src-root
npm install

> wxt-react-starter@0.0.0 postinstall
> wxt prepare

WXT 0.19.23
types...
✔ Finished in 3.013 s

added 546 packages in 8m

148 packages are looking for funding
  run `npm fund` for details

wxt.config.ts を編集

wxt.config.ts
import { defineConfig } from 'wxt';

// See https://wxt.dev/api/config.html
export default defineConfig({
  extensionApi: 'chrome',
  modules: ['@wxt-dev/module-react'],

  dev: {
    server: {
      hostname: 'localhost',
      port: 3000,
    }
  },
  runner: {
    disabled: true,
  },
  vite: () => ({
    server: {
      host: 'localhost',
      port: 3000,
      strictPort: true, 
      hmr: {
        port: 3000,
      }
    }
  }),
});
container
/opt/frontend-container-app-root/frontend-src-root # npm run dev

> wxt-react-starter@0.0.0 dev
> wxt

WXT 0.19.23

✔ Started dev server @ http://localhost:3000
ℹ Pre-rendering chrome-mv3 for development with Vite 6.0.7
✔ Built extension in 1.747 s
  ├─ .output/chrome-mv3/manifest.json               1.05 kB 
  ├─ .output/chrome-mv3/popup.html                  744 B   
  ├─ .output/chrome-mv3/background.js               19.96 kB
  ├─ .output/chrome-mv3/chunks/popup-BxzUToPe.js    8.24 kB 
  ├─ .output/chrome-mv3/content-scripts/content.js  36.77 kB
  ├─ .output/chrome-mv3/icon/128.png                3.07 kB 
  ├─ .output/chrome-mv3/icon/16.png                 559 B   
  ├─ .output/chrome-mv3/icon/32.png                 916 B   
  ├─ .output/chrome-mv3/icon/48.png                 1.33 kB 
  ├─ .output/chrome-mv3/icon/96.png                 2.37 kB 
  └─ .output/chrome-mv3/wxt.svg                     1.07 kB 
Σ Total size: 76.08 kB                                               
ℹ Load ".output/chrome-mv3" as an unpacked extension manually 

ホスト側でもファイル修正できるように権限を修正

WSL on win11
sudo chown -R (wslユーザー名):(wslユーザー名) frontend-src-root/

chrome-mv3 を手動で読み込む

wxt.config.ts で

wxt.config.ts
  runner: {
    disabled: true,
  },

としているため、chrome-mv3 を手動で読み込む必要がある。

Chrome で下記を開く
chrome://extensions/ > パッケージ化されていない拡張機能を読み込む
\wsl.localhost(Ubuntuのディストリビューション)\home(ユーザー名)(プロジェクトルート)\host-frontend-root\frontend-src-root.output\chrome-mv3

image.png
上記のような初期画面が表示され、カウント機能とホットリロードが正常に動作していることを確認。

リモートエクスプローラーを閉じ、ここまでを一旦コミットする

Dockerfile による永続化

FROM node:23.0-alpine3.19

WORKDIR /opt/frontend-container-app-root/frontend-src-root

# Chromium のインストール
RUN apk add --no-cache \
  chromium

COPY ./host-frontend-root/frontend-src-root /opt/frontend-container-app-root/frontend-src-root

RUN npm install

再ビルド

WSL on win11
docker compose build --no-cache && docker compose up -d && docker compose ps

docker コマンドでコンテナに接続して、npm run dev を実行

WSL on win11
docker compose exec frontend npm run dev

再びポップアップとホットリロードの動作を確認して、環境構築は完了。

解説

今回の設定値の肝

  • wxt.config.tsのdevプロパティとviteプロパティでのhostname、portの値を一致させる必要がある。
  • wxt.config.tsのrunnerプロパティを無効にする。
  • また、hostnameの値はdocker-compose.ymlのenvironmentプロパティのHOSTにも合わせる必要がある。
    • コンテナ内のViteサーバーとホストマシンのChrome拡張機能が通信できるようにするため。
  • 現時点では、docker-compose.ymlのnetwork_modeをhostにしておく必要がある(後述)。

vite.config.tsの内容はwxt.config.tsに記述する

公式ドキュメント
https://wxt.dev/guide/essentials/config/vite.html#change-vite-config
によれば、通常vite.config.tsのdefineConfigに記述する内容を、wxt.config.tsに記述することで、Viteの設定を変更できる。

// wxt.config.ts
import { defineConfig } from 'wxt';

export default defineConfig({
  vite: () => ({
    // Override config here, same as `defineConfig({ ... })`
    // inside vite.config.ts files
  }),
});

未解決事項

network_mode: host について

本来はdocker-compose.ymlでnetwork_modeをhostにしないほうが望ましいが、WebSocket関連のエラーを回避できなかったため、一時的にhostを使用している。

Dockerfileにおけるレイヤーキャッシュの利用

ビルド速度向上のため、ホスト側からのソースコードコピー前にnpm installを実行したい。

# 1. package.json と lockファイルのみコピー
COPY ./host-frontend-root/frontend-src-root/package*.json ./

# 2. 先に依存関係をインストール
RUN npm install

# 3. 全ソースコードをコピー
COPY ./host-frontend-root/frontend-src-root ./

しかし、wxtの場合、npm installを実行すると、npx wxt@latest initコマンド実行時にデフォルトで用意される

package.json
  "postinstall": "wxt prepare"

が実行される。これにより、

ERROR  No entrypoints found in /opt/frontend-container-app-root/frontend-src-root/entrypoints

というエラーが発生するため、 RUN npm install 前にソースコードが存在している必要がある。

回避するにはpackage.jsonからpostinstallを削除し、以下のように書き換える方法がある。

# 1. package.json と lockファイルのみコピー
COPY ./host-frontend-root/frontend-src-root/package*.json ./

# 2. 先に依存関係をインストール (キャッシュが効きやすい)
RUN npm install

# 3. 全ソースコードをコピー
COPY ./host-frontend-root/frontend-src-root ./

# postinstallで指定されているコマンドを実行
RUN npx wxt prepare

これでレイヤーキャッシュを活用できるが、デフォルトのpostinstallを削除する必要があり、対応を検討中。

wxt.config.tsのrunner: { disabled: true } について

wxt.config.ts で

wxt.config.ts
  runner: {
    disabled: true,
  },

と設定しているが、本来はfalseやオプション削除が望ましい。しかし、これを削除すると下記エラーが発生する。

✖ Command failed after 34.1 s

 ERROR  connect ECONNREFUSED 127.0.0.1:32885

  at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1608:16)

chromiumPortなどの設定を試しても改善せず、一時的にrunnerを無効にして手動ロードを行っている。

改善できそうな箇所

  • port等の設定値を.envにまとめる
  • ボイラーテンプレート化
2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?