👋

Vue3時代にviteでvue2をビルドする

2022/08/01に公開

もうSvelteでええやn

------------------- ↓ 前書きはここから ↓-------------------

Svelteを使うようになってから、
すっかりご無沙汰のvue
vue3の考え方にあまり賛同できず、
世間もReact一色になりつつある

vue2が急に必要になったので、
じゃあ、ビルドを整理するかと思ったら、
気がついたらvueのバージョン3がstableになっていて、
世の中全部がvue3になっていた。

そこでvue3の時代にvue2をビルドする方法を残しておく。
ビルドツールはvite
rollupesbuildベースのの高速ビルドツールでvue公式がサポートしている。

ヾ(・ω<)ノ" 三三三● ⅱⅲ コロコロ♪

------------------- ↓ 本題はここから ↓-------------------

プロジェクト作成

この手のビルドツールは
テンプレートプロジェクトからアプリを作っていく流れの説明は多いが、
仕事でそんな場面はほぼない。
なので、普通にインストールしていくパターンも用意。

viteコマンドでプロジェクト作成する場合

適当なディレクトリでnpm initを実行
プロジェクトディレクトリを用意してくれる。
フレームワークは vue ではなく vanilla を選択。
typescriptかどうかはお任せで。

npm init vite
✔ Project name: … vite-project
✔ Select a framework: › vanilla
✔ Select a variant: › vanilla

Scaffolding project in /home/dozo/work/vite-project...

Done. Now run:

その後下記を実行

cd vite-project
npm install
npm run dev

\http://localhost:5173/


viteランディングページ

(・∀・) Yeah!

ここからゴニョゴニョやるんですが、
単純ディレクトリと同じなので省略

単純にディレクトリ用意する場合

次にプロジェクト作成コマンドを使わずに環境を整備
既存のプロジェクトに加える場合は大体これだと思う。

インストール

適当なプロジェクト用ディレクトリを用意。
既存のプロジェクトのルートディレクトリと思ってもらえば良い。

mkdir vite-project
cd vite-project
npm init -f

viteとvue2に関する各種バッケージをインストール。

npm i vue@2.6.14
npm i -D vite vite-plugin-vue2 vue-template-compiler@2.6.14
touch vite.config.js
touch main.mjs
touch index.html

vueバージョンとvite-pluginパッケージの関係以下を参照のこと。
\https://vitejs.dev/guide/features.html#vue

設定ファイル作成

viteに関する設定ファイルを作成
内容は一端最小限にしておく

vite.config.js
import { createVuePlugin } from 'vite-plugin-vue2'

export default {
  plugins: [
    createVuePlugin()
  ],
}

フロントhtmlとjsを用意

main.mjs
import Vue from 'vue/dist/vue.esm';

new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue.js2'
  },
  template: `<div>{{message}}</div>`,
})
index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vite App</title>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/main.mjs"></script>
  </body>
</html>

以下のコマンドでページを表示する

npx vite

\http://localhost:5173/

(・ω・) CSSないからこんなもんよ

設定ファイル調整

ここからは細かい調整

入出力ファイル、ディレクトリ調整

各ファイル構成の基本になるhtmlファイルを指定するにはrollupOptionsを設定

vite.config.js
import { resolve } from 'path'
import { defineConfig } from 'vite'

export default defineConfig({
  build: {
    rollupOptions: {
      input: {
        main: resolve(__dirname, 'index.html'),
        nested: resolve(__dirname, 'nested/index.html')
      }
    }
  }
})

詳しくはここ
https://vitejs.dev/guide/build.html

複数モジュール化

viteではinputにhtmlファイルを指定するのが通常なのだが、
javascriptファイルを直接指定できる。
その場合、モジュール化されたファイルが一つ出来上がる。
また、一つではなく複数指定もできるので、
ベースが一つ、ページ単位で一つなどの切り分け方もできる。

出力ファイル名はentryFileNamesで指定。
inputで複数指定したときに、
共通するモジュールはchunkFileNamesで指定。

export default defineConfig({
  build: {
    rollupOptions: {
      input: {
        "front": path.resolve('./front.mjs'),
        "manage": path.resolve('./manage.mjs'),
      },
      output: {
        chunkFileNames: 'chunk-[name].[format].mjs',  
        entryFileNames: 'prefix-[name].[format].mjs',  
      },
    }
  }
})

ライブラリ化

importでの使用やnpmパッケージにするなどライブラリ化することもできる。
専用の設定があるのでこれについてはそちらを参照。

Library Mode
https://vitejs.dev/guide/build.html#library-mode

------------------- ↓ 後書きはここから ↓-------------------

ただ動かすのに異常にハマった。
トラブルシューティングも残しておこう

runtime-only build of Vue エラー

index.htmlに直接コードを記述しているときは問題ないが、
jsだけ切り出すとconsole.logに途端に以下のエラーがでる

[Vue warn]: You are using the runtime-only build of Vue where the template compiler is not available. 
Either pre-compile the templates into render functions, or use the compiler-included build.

(found in <Root>)

理由はわからないが、
使うモジュールが間違っているらしい。
ロードするモジュールを vue から vue.esm に変える

./main.mjs
- import Vue from 'vue';
+ import Vue from 'vue/dist/vue.esm';

Vue packages version mismatch エラー

vueとvue-template-compilerのバージョンが一致していないと発生
バージョンを揃えるようにインストールを調整する

> npm run dev

> vite-vue2-project@0.0.0 dev
> vite

failed to load config from /home/dozo/work/vite-vue2-project/vite.config.js
error when starting dev server:
Error:

Vue packages version mismatch:

- vue@2.6.14 (/home/dozo/work/vite-vue2-project/node_modules/vue/dist/vue.runtime.common.js)
- vue-template-compiler@2.7.7 (/home/dozo/work/vite-vue2-project/node_modules/vue-template-compiler/package.json)

This may cause things to work incorrectly. Make sure to use the same version for both.
If you are using vue-loader@>=10.0, simply update vue-template-compiler.
If you are using vue-loader@<10.0 or vueify, re-installing vue-loader/vueify should bump vue-template-compiler to the latest.

同じバージョン番号のモジュールをインストールする

npm i vue@2.6.14
npm i -D vue-template-compiler@2.6.14

The "fileName" or "name" properties of emitted files must be strings エラー

普通の状態では発生しないが、
ビルド環境とソースが別のディレクトリとかにあると発生。

(-_-;) これが一番ハマったな。

npx vite build
vite v3.0.0 building for production...
✓ 3 modules transformed.
rendering chunks (1)...[vite:build-html] The "fileName" or "name" properties of emitted files must be strings that are neither absolute nor relative paths, received "../front.html".
error during build:
Error: The "fileName" or "name" properties of emitted files must be strings that are neither absolute nor relative paths, received "../front.html".
    at error (file:///home/dozo/work/vite-project/minify/node_modules/rollup/dist/es/shared/rollup.js:1858:30)
    at FileEmitter.emitFile (file:///home/dozo/work/vite-project/minify/node_modules/rollup/dist/es/shared/rollup.js:15471:24)
    at Object.generateBundle (file:///home/dozo/work/vite-project/minify/node_modules/vite/dist/node/chunks/dep-561c5231.js:41453:22)
    at async Bundle.generate (file:///home/dozo/work/vite-project/minify/node_modules/rollup/dist/es/shared/rollup.js:15972:9)
    at async file:///home/dozo/work/vite-project/minify/node_modules/rollup/dist/es/shared/rollup.js:23708:27
    at async catchUnfinishedHookActions (file:///home/dozo/work/vite-project/minify/node_modules/rollup/dist/es/shared/rollup.js:23040:20)
    at async doBuild (file:///home/dozo/work/vite-project/minify/node_modules/vite/dist/node/chunks/dep-561c5231.js:43432:26)
    at async build (file:///home/dozo/work/vite-project/minify/node_modules/vite/dist/node/chunks/dep-561c5231.js:43261:16)
    at async CAC.<anonymous> (file:///home/dozo/work/vite-project/minify/node_modules/vite/dist/node/cli.js:747:9)

課程をすっ飛ばして結論を言うと、
プロジェクトルート未設定が原因。

(ノ-_-)ノ ====┻━┻

プロジェクトルートとコンパイル環境の場所が異なる場合は、
root値にプロジェクトルートを設定しておく。
親ディレクトリ ../ がプロジェクトルートになっている場合

vite.config.js
export default {
+  root: '../',
  ・・・
}

筆者は特殊な現場にいることが多く、
今回もそれによるもの。

legacy対応

いよいよIEがサポート終了で歓喜してる人も大勢いることでしょう。
ただ、公式サポートを止めたからと言って利用者がゼロになったわけではないので、
念のため対応しておく。

以下のモジュールを追加

npm i -D @vitejs/plugin-legacy terser

設定を調整する

vite.config.js
import legacy from '@vitejs/plugin-legacy'
import { createVuePlugin } from 'vite-plugin-vue2';

export default {
  plugins: [
    legacy({
      targets: ['defaults', "last 5 versions", "ie 11"],
      additionalLegacyPolyfills: ["regenerator-runtime/runtime"],
      polyfills: ["es.array.iterator", "es.promise"],      
    }),
    createVuePlugin(),
  ],
};

(・ω・) もういらんか。

コンパイル遅くなるしな。

Discussion