4
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?

More than 1 year has passed since last update.

Vue3 + Storybook の Vite 移行

Last updated at Posted at 2022-10-27

はじめに

我々ユニークビジョン株式会社では、フロントエンドは Vue3 + Storybook を使用しています。
メインのアプリも Storybook も Webpack でビルドしていました。
昨今の vite の普及に伴い、Webpack から vite への移行を行いました。
この記事では、その手順やハマりポイントをまとめたいと思います。

メインアプリの vite 移行

package の置き換え

vue-cli 関連の package を全てアンインストールします。以下が削除対象となりました。

  • @vue/cli-plugin-babel
  • @vue/cli-plugin-eslint
  • @vue/cli-plugin-router
  • @vue/cli-plugin-typescript
  • @vue/cli-plugin-unit-jest
  • @vue/cli-service
  • vue-cli-plugin-storybook
  • vue-cli-plugin-tailwind

vite 関連の package をインストールします。

npm install -D @vitejs/plugin-vue vite

index.html の移動と修正

vite ルート直下にある index.html をエントリーポイントとするのでディレクトリを移動します。

my-app/public/index.html → my-app/index.html

index.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
-    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
+    <link rel="icon" href="/favicon.ico">
    <title>My App</title>
  </head>
  <body>
    <noscript>
-      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
+      <strong>We're sorry but MyApp doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id="app"></div>
+    <!-- main.js ではなく main.ts であることに注意 -->
+    <script type="module" src="/src/main.ts"></script>
    <!-- built files will be auto injected -->
  </body>
</html>

html loader を使用している処理の書き換え

我々のプロジェクトでは、SVG ファイルを文字列として読み込んで html としてレンダリングするという処理があります。
Webpack のプラグイン html-loader を使って実現していました。

const icon = require(`!!html-loader!./assets/icon.svg`);

vite では次のように書けます。

import icon from '../assets/icon.svg?raw'

[参考]アセットを文字列としてインポートする

複数ファイルをまとめて取得したい時は以下のように書けます。

const modules = import.meta.glob('./dir/*.js')

ただし、この方法は実行時に動的に非同期に行われる処理なので、取得したデータにアクセスするには下記のようにしなくてはいけません。

for (const path in modules) {
  modules[path]().then((mod) => {
    console.log(path, mod)
  })
}

ビルド時に取得しておきたい場合はeager: true オプションを付けます。

const modules = import.meta.glob('./dir/*.js', { eager: true })

ビルド時に以下のように変換されます。

import * as __glob__0_0 from './dir/foo.js'
import * as __glob__0_1 from './dir/bar.js'
const modules = {
  './dir/foo.js': __glob__0_0,
  './dir/bar.js': __glob__0_1
}

この方法ならコードの中では module はテキストを値に持つオブジェクトとして扱うことができます。

[参考]Glob のインポート

Storybook の vite 移行

plugin のインストール

npm install -D @vitejs/plugin-vue

main.js の修正

.storybook/header.html
const path = require('path');

module.exports = {
  core: {
-    builder: "webpack5"
+    builder: '@storybook/builder-vite',
  },
  stories: ['../src/**/*.stories.ts'],
  addons: [
    '@storybook/addon-essentials',
    '@storybook/addon-interactions',
    '@storybook/addon-links',
    '@storybook/addon-postcss',
  ],
  framework: '@storybook/vue3',
  staticDirs: [
    { from: '../src/assets', to: 'assets' }
  ],
-  webpackFinal: async config => {
-    config.resolve.alias['@'] = path.resolve(__dirname, '../src');
-    config.resolve.fallback['path'] = require.resolve('path-browserify');
-    return config;
-  },
+  async viteFinal(config) {
+    config.resolve.alias['@'] = path.resolve(__dirname, "../src");
+    
+    return {
+      ...config,
+      build: {
+        ...config.build,
+        sourcemap: false,
+        minify: false,
+      },
+    };
+  },
};

config.build.sourcemap = false; config.build.minify = false; の設定を追加しました。
ユニークビジョン株式会社では Storybook を Gitlab CI でビルドし、Chromatic に publish して VRT を行っています。
Webpack よりも Vite でのビルドサイズが大きく、 Gitlab CI メモリ制限 4GB に引っ掛かってしまいました。
回避策として、前述の設定を追加しました。

header.html の追加

ここまでの状態で storybook を起動すると、

global is not defined

のようなエラーが表示されたので、下記のファイルを追加することで回避しました。

.storybook/header.html
<script>
  window.global = window;
</script>

下記を参考にしました。
https://github.com/storybookjs/storybook/issues/15391

Vite に移行してみた感想

もう Webpack には戻れないなというのが正直な感想です。
コードの修正の確認がリアルタイムでできるようになりました。
移行して 2 カ月ほど運用しましたが、特に困ったことも無いので社内標準にしていきたいと考えています。

と言っている側からさらに速い Turbopack なるものが出てきたりしていますが...

おしらせ

フロントエンド周りのことをよく呟いています。よければフォローお願いします。

4
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
4
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?