我正在为一个项目构建一个Web(带有react
和webpack
的babel
)和一个移动应用程序(带有react-native
的expo
)的移动应用程序。因此,我为业务逻辑和redux/api库创建了一个公共(public)库。
网络和移动设备之间的某些代码会稍有不同。就我而言,它是localStorage与AsyncStorage,我用于身份验证等...
我正在尝试为构建阶段传递一个环境变量,以切换某些文件的导入,以便为每个构建加载正确的文件,这些文件只是路径链接(即,我的库没有预构建,我只是做import '../mylib'
) 前任:
if(PLATFORM === 'mobile'){
import StorageModule from './mobile-storage-module`
} else {
import StorageModule from './mobile-storage-module`
}
export default StorageModule
尝试1个
@babel/preset-env
来说明它是移动设备还是网络设备,以便根据构建方式导入不同的库,如下所示:我的
.babelrc
有这个:{
"presets": [
[
"@babel/preset-env",
{
"platform": "mobile"
}
]
]
}
然后在本地存储文件中执行以下操作:
export default () => {
const platform = process.env.platform
if (platform === 'mobile') {
return import './storage-modules/storage-mobile'
}
return import './storage-modules/storage-web'
}
那没有用,这对我也没有用。
尝试2
我安装了react-native-dotenv并使用以下命令创建了一个
.env
文件:PLATFORM=mobile
并在我的.babelrc
中设置插件:{
"presets": [
"babel-preset-expo",
"react-native-dotenv"
]
}
在示例文件中,我尝试了以下操作:
import { PLATFORM } from 'react-native-dotenv'
export default PLATFORM === 'mobile' ? import './storage-modules/storage-mobile' : import './storage-modules/storage-web'
但是现在我的构建不起作用。知道我如何在适用于react-native应用程序和Webpack构建(也使用babel)的babel的构建过程中进行动态导入吗?
最佳答案
首先,@babel/preset-env
不会执行您认为的操作。这不是用于指定您自己的变量,而是一个插件,用于为您要支持的浏览器自动使用正确的目标和pollyfills。
获取环境变量的最简单方法是使用webpack define插件(它是webpack的一部分,因此无需安装任何额外的东西)
只需将其添加到您的webpack配置中即可。
plugins: [
new webpack.DefinePlugin({
'process.env': {
platform: 'mobile',
},
}),
],
接下来,您不能在ifs内使用普通的
import
语句。在通过Webpack构建或在脚本加载受支持的环境中运行任何代码之前,
import
都会得到解析。要在运行时导入某些内容,您需要使用动态导入。
这是一个看起来像这样的例子。
export default new Promise(async resolve => {
resolve(
process.env.platform === 'mobile'
? (await import('./mobile.js')).default
: (await import('./desktop.js')).default
);
});
现在,您可以像平常一样从此文件导入,但是请注意,默认导出是一个 promise 。