Vite + React + InversifyJS
InversifyJS をインストールする
| $ npm i inversify reflect-metadata
|
tsconfig.jsonを設定する
以下をマージする。
| tsconfig.app.json |
|---|
| {
"compilerOptions": {
"isolatedModules": false, // コンストラクタインジェクションする時に必要
"experimentalDecorators": true,
"emitDecoratorMetadata": true
}
}
|
vite.config.tsを設定する
Babel の場合
Note
コンストラクタインジェクションするときに動かない。
| $ npm i -D @babel/plugin-proposal-decorators
|
| vite.config.ts |
|---|
1
2
3
4
5
6
7
8
9
10
11
12
13 | import react from "@vitejs/plugin-react";
import { defineConfig } from "vite";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
react({
babel: {
plugins: [["@babel/plugin-proposal-decorators", { legacy: true }]],
},
}),
],
});
|
SWC の場合
| vite.config.ts |
|---|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | import react from "@vitejs/plugin-react-swc";
import { defineConfig } from "vite";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react({ tsDecorators: true })],
optimizeDeps: {
// 意味不明だがコンストラクタインジェクションする時に必要
esbuildOptions: {
tsconfigRaw: {
compilerOptions: {
experimentalDecorators: true,
},
},
},
},
});
|
コードを書く
1
2
3
4
5
6
7
8
9
10
11
12
13
14 | .
├── README.md
├── eslint.config.js
├── index.html
├── package-lock.json
├── package.json
├── src
│ ├── App.tsx
│ ├── main.tsx
│ └── vite-env.d.ts
├── tsconfig.app.json
├── tsconfig.json
├── tsconfig.node.json
└── vite.config.ts
|
| src/main.tsx |
|---|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 | import { Container, injectable } from "inversify";
import { createContext, StrictMode } from "react";
import { createRoot } from "react-dom/client";
import "reflect-metadata";
import App from "./App.tsx";
export interface ISampleService {
hi(): string;
}
@injectable()
export class SampleService implements ISampleService {
hi(): string {
return "Hi!";
}
}
export const types = {
SampleService: Symbol.for("SampleService"),
};
export const container = new Container();
container
.bind<ISampleService>(types.SampleService)
.to(SampleService)
.inSingletonScope();
export const ContainerContext = createContext(container);
createRoot(document.getElementById("root")!).render(
<StrictMode>
<ContainerContext.Provider value={container}>
<App />
</ContainerContext.Provider>
</StrictMode>
);
|
| src/App.tsx |
|---|
1
2
3
4
5
6
7
8
9
10
11
12 | import { useContext, useRef } from "react";
import { ContainerContext, ISampleService, types } from "./main";
function App() {
const container = useContext(ContainerContext);
const sampleServiceRef = useRef<ISampleService>(
container.get<ISampleService>(types.SampleService)
);
return <p>{sampleServiceRef.current.hi()}</p>;
}
export default App;
|