Home > ブログ > Vue3をrollupでバンドルする

ブログ

Vue3をrollupでバンドルする

最近、電子カタログ/漫画ビューアのWebアプリケーションで使っていたVue2をVue3に切り替える作業をしていました。また、今までは<script>タグで読み込んでいたので、ついでにバンドルするように修正しました。

Vue2からVue3に対応するためのコードの修正はそれほど手間ではなかったのですが、バンドルの設定に(あいかわらず)手こずりました。

以下にVue3をrollupでバンドルする時のconfig例を載せておきます。あくまで、Vue3のバンドルにだけ注目し、typescriptとかBabelの設定は入れていません。

なお、使用したNodeのバージョンはv16.14.0になります。

まずはpackage.jsonの例です。必要なモジュールは以下のとおりです。モジュールはplugin-node-resolveとかrollup-plugin-replaceではなく、@rollup/plugin-node-resolve、@rollup/plugin-replace等の@rollupの方にある最新のものを使いましょう。

package.jsonの例

{
  "name": "vue3-rollback",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "type": "module",
  "scripts": {
    "build": "rollup -c rollup-config.js"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@rollup/plugin-alias": "^4.0.2",
    "@rollup/plugin-node-resolve": "^15.0.1",
    "@rollup/plugin-replace": "^5.0.1",
    "@rollup/plugin-terser": "^0.1.0",
    "rollup": "^3.3.0",
    "rollup-plugin-vue": "^6.0.0"
  },
  "dependencies": {
    "vue": "^3.2.45"
  }
}

あと、Vueというよりrollup v3の話になりますが、package.jsonの"type"フィールドに"module"を指定しておく必要があります。この指定がないと、rollup-config.jsをCommonJSとして扱おうとしてimport文を処理できずに以下のようなエラーとなります。

[!] RollupError: Node tried to load your configuration file as CommonJS even though it is likely an ES module. To resolve this, change the extension of your configuration to ".mjs", set "type": "module" in your package.json file or pass the "--bundleConfigAsCjs" flag.

これは、rollup v3からconfigファイルの読み込みにはNodeの仕組みが使われるようになったためです。そこで、"type": "module"を指定して、Nodeが.jsファイルをES Moduleとして扱うように設定しています(*1)。

Unless the --configPlugin or --bundleConfigAsCjs options are used, Rollup will directly use Node to import the file. Note that there are some caveats when using native Node ES modules as Rollup will observe Node ESM semantics.

https://rollupjs.org/guide/en/#configuration-files より

次にrollupのconfig例です。

rollup-config.jsの例

import { nodeResolve } from '@rollup/plugin-node-resolve';
import replace from '@rollup/plugin-replace';
import alias from '@rollup/plugin-alias';
import terser from '@rollup/plugin-terser';
import vue from 'rollup-plugin-vue';

export default {
  input: 'src/index.js',
  output: [
    {
      format: 'iife',
      sourcemap: true,
      file: 'html/main.js',
      plugins: [
        terser(),
      ]
    },
  ],
  plugins: [
    nodeResolve(),
    alias({
      resolve: ['.js', '.vue'],
      entries: [
        {find: 'vue', replacement: './node_modules/vue/dist/vue.esm-bundler.js'},
      ]
    }),
    // for importing vue
    // https://v2.ja.vuejs.org/v2/guide/installation.html
    replace({
      preventAssignment: true,
      "process.env.NODE_ENV": JSON.stringify('production'),
    }),
    vue(),
  ]
};

要点は以下の2点です。

(1) aliasの設定

import { createApp } from 'vue' のようにvueモジュールをインポートした際に、ランタイムのコンパイラを含んだvue.esm-bundler.jsを読み込むように設定しています(*2)。テンプレートを事前にコンパイルしておくならこの設定は不要です。

(2) replaceの設定

このままvueをインポートするだけだと、実行時に以下のエラーが出ます(開発ツールのコンソールで確認)。

Uncaught ReferenceError: process is not defined

これはVueの内部でprocess.env.NODE_ENVを参照しているせいなのですが、processはNode実行環境において存在するもので、ブラウザでの実行だとprocessが存在しないため、このようなエラーになります。そこで、replace()でprocess.env.NODE_ENVを参照している部分を書き換えてやります。

このあたりについては、https://v2.ja.vuejs.org/v2/guide/installation.html を参照してください。

まとめ

これで、Vue3をバンドルできるようになります。

Nodeモジュールやバンドルまわりは少し目を話すと互換性のない変更が加わっていたりするので、毎回、コードの修正よりpackage.jsonやバンドル設定の修正に時間がかかってしまうのが辛い所です。

(*1) https://nodejs.org/api/packages.html#type 参照

(*2) https://v3.ja.vuejs.org/guide/installation.html#%E3%83%8F%E3%82%99%E3%83%B3%E3%83%88%E3%82%99%E3%83%A9%E3%83%BC%E3%82%92%E4%BD%BF%E3%81%86%E5%A0%B4%E5%90%88 参照

投稿日:2022/11/23 12:26

タグ: Webアプリ Vue.js

Top

アーカイブ

タグ

Server (18) プログラミング (15) 作業実績 (15) PHP (11) ネットワーク (9) C (7) C++ (7) Webアプリ (6) EC-CUBE (6) Nginx (5) OpenSSL (5) laravel (4) Linux (4) 書籍 (4) JavaScript (3) AWS (3) Rust (3) Vue.js (3) Golang (2) Symfony (2) Apache (1) デモ (1) お知らせ (1) MySQL (1) CreateJS (1) OSS (1)