我正在为一个项目构建一个Web(带有reactwebpackbabel)和一个移动应用程序(带有react-nativeexpo)的移动应用程序。因此,我为业务逻辑和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 。

10-06 14:16
查看更多