## 経緯
[[esbuild]]のメリット/デメリットを比較して、メリットが勝ると感じた。
### メリット
- **ビルド速度が速い**
- 1~2秒程度だが積み重なったり[[Svelte]]が入るとこれが割とストレス
- 依存関係が少ない
- 将来性がある
### デメリット
- 開発用ビルドでは型チェックができない
- [[IDE]]でも開いているファイルはチェックできるので、コミット時に[[husky]]でチェックさせればOK
## 対象プロジェクト
今回は[[🦉Another Quick Switcher]]。[[Obsidian Sample Plugin]]を参考に。
## 不要packageのアンインストール
### [[Rollup]]
```console
npm uninstall rollup @rollup/plugin-commonjs @rollup/plugin-node-resolve @rollup/plugin-typescript
```
> [!hint]- [[Svelte]]を使っている場合
> [[rollup-plugin-svelte]]もアンインストールする。
> ```console
> $ npm uninstall rollup-plugin-svelte
> ```
### その他
なぜかインストールされていたやつ
```console
npm uninstall @types/node
```
## [[esbuild]]のインストール
```console
npm i -D esbuild builtin-modules
```
> [!hint]- [[Svelte]]を使っている場合
> [[esbuild-svelte]]もインストールする。
> ```console
> $ npm i -D esbuild-svelte
> ```
## 設定変更
> [!hint]- [[Svelte]]を使っている場合
> https://marcus.se.net/obsidian-plugin-docs/getting-started/svelte#configure-your-plugin を参考に適宜追記する
### `esbuild.config.mjs`
以下を追加。
```js
import esbuild from "esbuild";
import process from "process";
import builtins from 'builtin-modules'
const banner =
`/*
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
if you want to view the source, please visit the github repository of this plugin
*/
`;
const prod = (process.argv[2] === 'production');
esbuild.build({
banner: {
js: banner,
},
entryPoints: ['src/main.ts'],
bundle: true,
external: [
'obsidian',
'electron',
'@codemirror/autocomplete',
'@codemirror/collab',
'@codemirror/commands',
'@codemirror/language',
'@codemirror/lint',
'@codemirror/search',
'@codemirror/state',
'@codemirror/view',
'@lezer/common',
'@lezer/highlight',
'@lezer/lr',
...builtins],
format: 'cjs',
watch: !prod,
target: 'es2018',
logLevel: "info",
sourcemap: prod ? false : 'inline',
treeShaking: true,
outfile: 'main.js',
}).catch(() => process.exit(1));
```
### [[package.json]]
```diff
"scripts": {
- "dev": "rollup --config rollup.config.js -w",
+ "dev": "node esbuild.config.mjs",
- "build": "rollup --config rollup.config.js --environment BUILD:production",
+ "build": "tsc -noEmit -skipLibCheck && node esbuild.config.mjs production",
"test": "jest"
},
```
### [[tsconfig.json]]
```diff
{
"compilerOptions": {
"strict": true,
"baseUrl": ".",
"inlineSourceMap": true,
"inlineSources": true,
"module": "ESNext",
"target": "es6",
"allowJs": true,
"noImplicitAny": true,
"strictPropertyInitialization": false,
"moduleResolution": "node",
"importHelpers": true,
+ "isolatedModules": true,
"allowSyntheticDefaultImports": true,
- "lib": ["dom", "es5", "scripthost", "es2020"]
+ "lib": ["dom", "es5", "es6", "es7"]
},
"include": ["**/*.ts"]
}
```
### `rollup.config.js`削除
削除前の設定。
```js
export default {
input: "src/main.ts",
output: {
dir: ".",
sourcemap: "inline",
sourcemapExcludeSources: isProd,
format: "cjs",
exports: "default",
banner,
},
external: ["obsidian"],
plugins: [typescript(), nodeResolve({ browser: true }), commonjs()],
};
```
## 実行確認
以下のコマンドで動作することを確認。
```console
npm run dev
npm run build
task dev
```
### 参考コミット
- [Rollup \-> esbuild · tadashi\-aikawa/obsidian\-another\-quick\-switcher@033bdb4](https://github.com/tadashi-aikawa/obsidian-another-quick-switcher/commit/033bdb4a54839605a2ad09ff7aaee7d0bfb0142c)
- [Use esbuild instead of Rollup · tadashi\-aikawa/obsidian\-various\-complements\-plugin@d733256](https://github.com/tadashi-aikawa/obsidian-various-complements-plugin/commit/d7332569377b5aa4b8a61d0b38543b414514603f) ([[Svelte]])
## テストでも[[esbuild]]を使う
[[Jest]]で[[Babelを使ってTypeScript対応 (Jest)|Babelを使ってTypeScript対応]]をしていたが、こちらも[[esbuild]]を使う。
### [[Babel]]に関するpackageと設定を削除
```console
npm uninstall @babel/preset-env @babel/preset-typescript @types/jest @babel/core babel-jest
rm babel.config.js
```
### [[esbuild-jest]]のインストール
```console
npm i -D esbuild-jest
```
`jest.config.js`
```js
module.exports = {
"transform": {
"^.+\\.tsx?
quot;: "esbuild-jest"
}
}
```
### コード修正
`@types/jest`をアンインストールしたので、`@jest/globals`からインストールするようテストコードを書きなおす必要がある。
```ts
import { describe, expect, test } from "@jest/globals";
```
> [!error]
> [[Parameterized Test]]がエラーになる場合は、[[📝Jestでdescribe.eachを使ったParameterized Testの型が推論されない]] も参照。
### 参考コミット
- [babel\-jest\(ts\) \-> esbuild\-jest · tadashi\-aikawa/obsidian\-another\-quick\-switcher@b887638](https://github.com/tadashi-aikawa/obsidian-another-quick-switcher/commit/b887638847f040bfd3f604ad4361acac25b72934)
- [babel\-jest\(ts\) \-> esbuild\-jest · tadashi\-aikawa/obsidian\-various\-complements\-plugin@80e1cb0](https://github.com/tadashi-aikawa/obsidian-various-complements-plugin/commit/80e1cb06a127498271c281c5608c13ca7bab3f0d) ([[Svelte]])
## コミット前に型チェックとテストを行う
[[esbuildはTypeScriptの型チェックをしない]]ので、[[📕huskyでコミット前に自動でTypeScriptの型チェックとテスト実行]]する。
```console
npm i husky -D
npm set-script prepare "husky install"
npm set-script pre:commit "tsc -noEmit -skipLibCheck && npm run test"
npm run prepare
npx husky add .husky/pre-commit "npm run pre:commit"
git add .husky/pre-commit package.json
```
コミットついでに型チェックとテストが行われることを確認する。
```console
git commit -m "Add husky"
```
もちろん、型チェックかテストのどちらかが失敗すればコミットできない。
### 参考コミット
- [Add husky and a pre\-commit hook · tadashi\-aikawa/obsidian\-another\-quick\-switcher@f1481f8](https://github.com/tadashi-aikawa/obsidian-another-quick-switcher/commit/f1481f83fb762d3e35c53e5e67f497bb31f5159c)