課題
個人で開発しているsharemoreのversion2のbuild時間が少しずつ伸びてきていることで開発の効率が落ちていた.
現在必要なビルドは4つあって,buildを待つのに絶妙に待たないといけない時間であったため、もやもやする開発を行っていた.(実際には並列でbuildしているので一番遅い箇所がボトルネックとなっていた)
厳密にはbuildのみを行っているわけではないのでご参考程度に
project | build時間 |
---|---|
api | 7.90s |
backend | 8.17s |
logging | 12.05s |
frontend | 29.77s |
合計 | 57.89s |
改善方法
webpackでbuildを行っていたため、viteやesbuildというバンドラを使用するとwebpackよりも高速にバンドルが可能ということで試してみることにした.
個人での開発なのでここら辺の開発手法の導入は企業で作業するプロジェクトよりも柔軟に対応することが可能ですし、今後の自身の実績にもなるのでどんどんと有効なものは活用していきたいという考えがあります.
frontendはreactを使用していてviteが使用できるということだったので、viteを導入してみました.
backend側はviteが使用できなかったのでesbuildを使用することにしました.
変更した結果の時間は以下の通りです.ざっと4分の1程度になりました!
project | build時間 |
---|---|
api | 1.38s |
backend | 1.95s |
logging | 1.32s |
frontend | 10.96s |
合計 | 15.61s |
移行方法
webpackからvite/esbuildに移行した方法ですが、結構簡単で3時間程度ですべてのプロジェクトを移行することができました.
webpackからesbuildに移行した方法
該当のプロジェクトでwebpackのモジュールを削除して,esbuildをinstallします.
npm remove webpack webpack-cli webpack-dev-server
npm install esbuild --save-dev
次にbuildするために使用するscriptをjavascriptで作成します.
作成したら該当のプロジェクトに配置します.
私のbuild.jsをサンプルとして載せておきます.
やりたかったのはproductionとdevelopmentのbuildはできるようにしたかったので,外部の変数でbuild方法を決められるようにしています.
output場所はwebpackと同じ場所に出力したかったのでwebpackフォルダにしています.
targetでは自身の使用しているnodeのversionを指定しています.
// esbuild.js
const esbuild = require('esbuild');
const isProduction = process.env.NODE_ENV === 'production';
const options = {
entryPoints: ['./index.ts'],
bundle: true,
outfile: './webpack/sharemore_backend.js',
platform: 'node',
target: 'node17',
sourcemap: !isProduction,
minify: isProduction,
define: {
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
},
};
esbuild.build(options).catch(() => process.exit(1));
そのあとに,package.jsonにbuildコマンドを記述します.
node esbuild.jsを実行するとesbuildされるのでwebpackで使用していたコマンドを少し変更して、下記のようにしました.
"scripts": {
"build": "npm version patch && SET NODE_ENV=production&& node esbuild.js",
"build:dev": "npm version patch && SET NODE_ENV=development&& node esbuild.js",
},
最後にyarn buildコマンドを実行してbuildできるかどうかを確認します.
私の場合は特にエラーが出ずに成果物が生成されました.
yarn build
webpackからviteに移行した方法
該当のプロジェクトでwebpackのモジュールを削除して,viteをinstallします.
自分のプロジェクトの都合によりnpmではなく,yarnでinstallしました.
yarn add vite --save-dev
yarn add @vitejs/plugin-react
次にconfigファイルを作成します.名前をvite.config.tsというように付けました.そしてそれをプロジェクトの直下に配置します.
// vite.config.js
import react from '@vitejs/plugin-react';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [react()],
build: {
outDir: 'build', // 出力先ディレクトリ
},
});
viteはindex.htmlを使用するようなので,同様にindex.htmlをプロジェクト直下に配置します.
webpackの際に出力されたindex.htmlを部分的に修正を行い,そのまま使用しています.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta name="description" content="Web site created using create-react-app" />
<link rel="apple-touch-icon" href="/logo192.png" />
<link rel="manifest" href="/manifest.json" />
<title>Vite App</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="./src/index.tsx"></script>
</body>
</html>
srcが入っているindexファイルと同じ場所にvite-env.d.tsを作成しました.
これはviteを使用していることを明示することでimport.meta.env.VITE_XXXXのエラー出力を抑制します.
これを入れていないと「プロパティ 'env' は型 'ImportMeta' に存在しません」というエラーが表示されます.
/// <reference types="vite/client" />
次にpackage.jsonにコマンドを記述します.
"scripts": {
"dev": "vite",
"build": "npm version patch && set VITE_REACT_APP_VERSION=%npm_package_version% && vite build",
},
最後にbuildできるかを確認します.
yarn build
特にエラーが出なければ,出力されたファイルを動作確認して問題がなければ完了です.