我想在多个模块之间共享一个 api 实例,并能够使用外部配置对其进行初始化。我的代码使用 Webpack 和 Babel 将这些漂亮的 ES6 模块转换为浏览器可用的东西。我正在努力实现这一目标:
// api.js
let api = null;
export default api;
export function initApi(config) {
// use config to configure the shared api instance (e.g. with api base url)
api = ...
}
// ======================
// entry.js
import { initApi } from './api';
import App from './App';
// Initialize the single shared instance before anyone has the chance to use it
const apiConfig = ...
initApi(apiConfig);
// Create the app and run it
// ======================
// App.js
// RootComponent has an import dependency chain that eventually imports DeeplyNestedComponent.js
import RootComponent from './RootComponent';
// Actual App code not important
// ======================
// DeeplyNestedComponent.js
// PROBLEM! This "assignment" to the api var happens before initApi is run!
import api from '../../../../api';
api.getUser(123); // Fails because "api" stays null forever even after the initApi() call
出现“问题”是因为 ES6 模块是静态导入的,并且 import 语句是提升的。换句话说,只需移动import App from './App'
下面一行initApi(apiConfig)
不会使导入发生在initApi
叫做。
解决这个问题的一种方法是从api.js
(或者在另一个globals.js
文件(如果我有多个具有相同模式的此类共享对象)而不是像这样的单个变量:
// api.js
const api = {
api: null,
};
export default api;
export function initApi(config) {
// use config to configure the shared api instance (e.g. with api base url)
api.api = ... // <-- Notice the "api." notation
}
// ======================
// DeeplyNestedComponent.js
// api is now the object with an empty "api" property that will be created when initApi() is called
import api from '../../../../api';
api.api.getUser(123); // <-- Ugh :(
使用ES6模块时有没有办法优雅地实现共享服务实例的初始化?
就我而言,DeeplyNestedComponent.js
还必须import
api 实例以某种方式。换句话说,不幸的是没有上下文对象从App
一直到DeeplyNestedComponent.js
可以提供 api 实例的访问权限。
你的代码的问题是
let api = null;
export default api;
是否导出value null
在默认导出的隐式生成的绑定中。但是,您也可以导出名称下的任意绑定default
通过使用语法
let api = null;
export { api as default };
这将按预期工作。但您仍然需要确保在调用之前没有模块访问此导出initApi
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)