0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

なぜRsbuidスタックなのか?

0
Last updated at Posted at 2026-05-25

vue-vrmで、なぜRsbuildスタックを採用したのか?

現在、Viteスタックはコアエンジンこそ高速化しているものの、周辺を取り巻くeslintやstylelintなどは、古のwebpackの時代から使われてきた技術が使われており、依存関係がぐちゃぐちゃになっています。事実、eslintが9になったときは、設定ファイルの仕様が大幅に変わりトラブルが多発しました。今でもeslint8から移行できないプロジェクトも多いんじゃないでしょうか?

一応、自分でもol-slmapのような、vueのようなライブラリを含まない純粋なJavaScriptの新規プロジェクトでも部分的に使用していましたが、先月(2026/04/22)にRspack2.0がリリースされたことを受け、改めて調べてみると整形ツールのrslintやテストツールのrstest、ライブラリ向けビルドができるrslibなど独自にエコシステムが出来上がっているのを確認したため、使ってみることにしました。

特筆するべき点として、公式のRsbuildのスターターテンプレートは、最初からAI駆動設計のためのスキルや指示書が含まれており、バイブコーディング時のガードレールが予め備わっているところがあります。

ここが決め手となりました。

何でもできるということは「自由度が高い」ではなく、「どうとでもなってしまう」ことですしね。

RsbuildとViteの違い

RsbuildとViteの違いをざっと箇条書きにしました。

1. 根本的な設計思想の違い

項目 Vite Rsbuild
コアエンジン esbuild (Dev) + Rollup (Build)Rspack(全フェーズで統一)言語Go (esbuild) + JavaScript (Rollup) Rust(Rspack) + TypeScript
Dev / Prodの一貫性 低い(DevはESM、ProdはBundling) 非常に高い(両方Rspack)
哲学 「可能な限りバンドルしない」 高速Dev体験「Rustで全部高速化」+Webpack互換

2. 開発モード(Dev Server)の違い

Vite:

  • Native ESM + on-demand compilation が最大の特徴
  • ブラウザが直接ESMを読み込む(<script type="module">
  • 依存関係のPre-bundlingにesbuildを使用(非常に高速)
  • ソースコードの変換は必要最小限のみesbuildで行い、残りはブラウザに任せる
  • HMRは非常に速いが、DevとProdの出力に差が出やすい(特にコード分割や最適化)

Rsbuild (Rspack):

  • Devでもフルバンドリングに近いアプローチ(Rspackが処理)
  • Rust並列処理により、大規模プロジェクトでもHMRが極めて高速
  • DevとProdで同じエンジンを使うため、動作の一貫性が非常に高い
  • プラグインやLoaderもWebpack/Rspack互換で動く

3. 本番ビルド(Production Build)の違い

Vite:

  • Rollupをベースにバンドリング
  • Rollupの優れたTree-shaking、コード分割、チャンク制御が強み。1

Rsbuild:

  • Rspackで一貫して処理
  • RspackはWebpackのAPIをRustで再実装したもの
  • Webpackエコシステム(Loader/Plugin)の多くがそのまま使える
  • 並列処理とRustの速度で、特に大規模プロジェクトでViteを上回るビルド速度を出すケースが多い

4. プラグイン・エコシステムの違い

Vite:

  • Rollup互換プラグイン + Vite独自拡張。エコシステムが非常に成熟

Rsbuild:

  • Webpack/Rspack互換(ほとんどのwebpack pluginが動く) + Rsbuild独自のシンプルなPlugin API
  • 既存のWebpackプロジェクトからの移行が比較的楽

5. 内部的な処理の流れ(簡略化)

Vite:

  1. Devサーバー起動
  2. 依存Pre-bundling(esbuild)
  3. ブラウザからリクエスト → 必要なファイルだけesbuildでtransform
  4. Production: Rollupでフルバンドル

Rsbuild:

  1. RspackがDev/Prod両方で動作
  2. Rust並列処理でLoader/Pluginを実行
  3. 統一されたPipelineで処理(Transformer → Optimizer → Bundler)

まとめ:どちらが優れているか?

  • 開発体験・シンプルさ → Viteがまだ優勢(エコシステムの成熟度)
  • パフォーマンス(特に大規模)・一貫性 → Rsbuild(Rspack)が優勢
  • Webpack資産の活用 → Rsbuildが圧倒的に有利
  • 将来的 → ViteはRolldownでRust統一方向、RsbuildはすでにRust中心

実際の設定

vue-vrmのリポジトリのソースコードは、デモプログラムと、ライブラリのコード両方がsrc/ディレクトリに入っているあたり、あまりいいディレクトリ構造ではありません。ここはおいおい直すとします。

rsbuildでデモプログラムのビルドを行い、rslibでライブラリのビルドを行っています。

デモプログラム部分の設定です。こちらは、rsbuildを用いてビルドします。出力されるコードは圧縮済みでwebpackの出力した圧縮コードに酷似したコードが出力されます。src/meta.tsにビルド日時とバージョン情報を書き込むための定数はここで定義しています。

rsbuild.config.ts
import { readFileSync } from 'node:fs';
import { resolve } from 'node:path';

const packageJson = JSON.parse(readFileSync('./package.json', 'utf-8'));
const buildDate = new Date().toISOString();

console.log('Injected version:', packageJson.version);
console.log('Injected build date:', buildDate);

import { defineConfig } from '@rsbuild/core';
import { pluginVue } from '@rsbuild/plugin-vue';

// Docs: https://rsbuild.rs/config/
// Demo build configuration - for library build, see rslib.config.ts
export default defineConfig({
  plugins: [pluginVue()],
  source: {
    define: {
      __DEMO_BUILD__: JSON.stringify(true),
      __APP_VERSION__: JSON.stringify(packageJson.version),
      __BUILD_DATE__: JSON.stringify(buildDate)
    },
    entry: {
      index: './src/index.ts'
    }
  },
  output: {
    distPath: 'docs',
    assetPrefix: './',
    filenameHash: true,
    copy: [
      {
        from: './src/assets',
        to: 'assets'
      }
    ]
  },
  html: {
    template: './src/index.html',
    title: 'VRM Viewer Demo - Vue VRM'
  },
  tools: {
    htmlPlugin: undefined
  },
  resolve: {
    alias: {
      '@': resolve(__dirname, 'src')
    }
  }
});

ライブラリ部分の設定です。こちらはrslibを使ってビルドしています。出力されるコードは圧縮済みのコードとなります。

rslib.config.ts
import { readFileSync } from 'node:fs';

import { pluginVue } from '@rsbuild/plugin-vue';
import { defineConfig } from '@rslib/core';

const pkg = JSON.parse(readFileSync('./package.json', 'utf-8')) as {
  name: string;
  description: string;
  author: {
    name: string;
    email: string;
  };
  license: string;
  version: string;
  homepage: string;
};

const buildDate = new Date().toISOString();

export default defineConfig({
  lib: [
    {
      // Modern ESM build for modern bundlers and environments
      format: 'esm',
      dts: false,
      syntax: 'esnext',
    },
    {
      // Legacy CommonJS build for Node.js and older bundlers
      format: 'cjs',
      dts: false,
      syntax: 'es2015',
    },
    {
      banner: {
        js: `/**
 * ${pkg.name}
 *
 * @description ${pkg.description}
 * @author ${pkg.author.name} <${pkg.author.email}>
 * @copyright 2026 By Masashi Yoshikawa All rights reserved.
 * @license ${pkg.license}
 * @version ${pkg.version}
 * @see {@link ${pkg.homepage}}
 */
`,
      },
    },
  ],
  plugins: [pluginVue()],
  source: {
    entry: {
      index: './src/lib.ts',
    },
    define: {
      __APP_VERSION__: JSON.stringify(pkg.version),
      __BUILD_DATE__: JSON.stringify(buildDate),
    },
  },
  output: {
    target: 'web',
    minify: true,
    distPath: {
      root: './dist',
    },
  },
});

実際のテンプレート

Vue向けにRsbuildを使用したスターターテンプレートを作成しました。これで色々テストしてみてください。

https://github.com/logue/rsbuild-vue3-ts-starter

日本語ドキュメントはこちらになります。

  1. (2026年現在)Rolldown(Rust版Rollup)への移行が進んでおり、徐々にRust統一されつつある。

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?