我有一个具有以下接口的API(仅出于示例目的)
export type FrogAPI = {
getFrogs(): Promise<Frog[]>
putFrogs(frogs: Frog[]): Promise<void>
}
我有2个版本,其中1个模拟版本可以从localStorage读取和写入:
export class LocalStorageFrogAPI implements FrogAPI {
getFrogs(): Promise<Frog[]> {
return Promise.resolve(JSON.parse(localStorage.getItem('@frogApi/frogs')))
}
// ...
}
以及与远程api配合使用的真实版本:
export class HttpFrogAPI implements FrogAPI {
getFrogs(): Promise<Frog[]> {
return fetch('/frogs').then((res) => res.json())
}
// ...
}
对于开发,我使用的是localStorage,对于HTTP,则用于生产。
问题:如何有条件地导入正确的源代码,因此在 build 时,输出js中仅包含正确的源代码?这很重要,因为两个文件都变得很大。出于安全原因,我也不想在生产中公开localStorage版本。
如果我这样做:
const ApiConstructor = process.env.ENV === 'development'
? require('./LocalStorageFrogAPI')
: require('./HttpFrogAPI')
export const API = new ApiConstructor() as FrogAPI
这两个源仍将包含在生成的输出中。在输出js中只包含正确的方法是什么?某些webpack配置可以吗?
答案 0 :(得分:1)
在我从事的项目中,我有类似的要求。 我发现有2个主要选项。首先-使用异步导入,例如:
const ApiConstructor = await import("./LocalStorageFrogAPI");
这可以有条件地完成。但是这里的比赛条件可能会有问题。特别是在发展中。当所有导入都将被加载和缓存时,除了这一步。可能会导致错误。
我们最终得到的解决方案是创建使用该条件导入的文件的2个版本。因此,在您的情况下,一个文件(供开发人员使用)将使用
const ApiConstructor = require("./LocalStorageFrogAPI");
和产品:
const ApiConstructor = require("./HttpFrogAPI");
其余代码相同。
然后您只需根据构建(dev / prod)使用webpack替换文件即可。
您可以使用NormalModuleReplacementPlugin进行替换。否则,本文将概述如何使用webpack分离开发和生产依赖:Managing Dev and Production Builds with Webpack