これはなに?なにがうれしい?
public
配下にあるJavaScriptの設定ファイルをReactで読む必要があった。
この記事ではグローバルオブジェクトwindow
を使用した方法をメインに紹介する。
この方法は、提供されたJSファイルなどを型定義して読み込みたい場合に使用できる。
試したけどダメだった方法
-
public
に定義した変数をsrc
内の.d.ts
でアンビエント宣言(declare)-
public
に定義した変数と同名の変数をアンビエント宣言したからといって読み込めるわけではない
-
- ES Modulesの
import/export
を使用-
src
からsrc
の外をimport
できない - CommonJSの
module.exports/require
はそもそもダメ
-
参考記事
コード
/index.html
Viteの場合はルート直下にindex.html
がある。
対象JSは/public/js/configs.js
とする。
index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React + TS</title>
</head>
<body>
<div id="root"></div>
+++ <script type="module" src="/public/js/configs.js"></script>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
Create React Appの場合はpublic
直下にある。
/public/index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>React Create App</title>
</head>
<body>
<div id="root"></div>
+++ <script type="module" src="%PUBLIC_URL%/js/configs.js"></script>
</body>
</html>
/public/js/config.js
オブジェクトとして定義してみる。
/public/config.js
window.configs = {
windowConfig1: { keyString: 'windowConfigString1' },
windowConfig2: { keyString: 'windowConfigString2' },
};
/src/@types/index.d.ts
config.js
にあるオブジェクトの形に沿って型を定義する。
TypeScriptがWindow
インターフェースにwindow
オブジェクトの持つべきプロパティやメソッドの型を定義している。
Window
インターフェースにアンビエント宣言することで宣言マージされ、Window
インターフェースが拡張される。
/src/@types/index.d.ts
interface Config {
keyString: string;
}
interface Configs {
[id: string]: Config;
}
// ここが本題
declare global {
interface Window {
configs: Configs;
}
}
/src/*.*.tsx
読み込めていない場合を想定したほうがよい。
/src/pages/public/Js.tsx
import { type FC, memo } from 'react';
import { EXPORT_CONFIGS } from '/public/js/configs.js';
const Component: FC = () => {
const windowConfigs = window.configs;
return (
<>
{windowConfigs &&
Object.keys(windowConfigs).map(key => (
<div key={key}>{windowConfigs?.[key]?.keyString}</div>
))}
</>
);
};
export const Js = memo(Component);
出力の抜粋
<div id="root">
<div>windowConfigString1</div>
<div>windowConfigString2</div>
</div>