带有node_env的react-native expo预构建命令

问题描述 投票:0回答:1

背景信息

我们没有使用 eas 或 expo go,而是使用我们自己的配置文件以及 app.json 和 babel.config.js 的组合。

我们希望从开发环境过渡到质量保证/临时环境。我们正在使用 azure pipelines 运行 expo 的 ios 和 android 构建预构建命令。例如:

npx expo prebuild --platform ios --clean --npm

我成功设置了开发环境以使用以下命令运行...

npx expo run dev-android
(指向package.json中的以下脚本
"dev-android": "cross-env NODE_ENV=development npx expo run:android --port 8082"

开发环境成功打印出以下内容...

enter image description here

结构

enter image description here

代码...

应用程序.tsx

import React, { useEffect } from 'react';
import * as SplashScreen from 'expo-splash-screen';
import '@app/utils/IgnoreWarnings';
import Toast from 'react-native-toast-message';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import { GlobalContextProvider, useLoadingStore } from '@app/stores';
import { ToastInit } from '@app/components';
import { NavigationConductor } from '@app/navigation';
import { toastFailedProps } from '@app/utils';
import { RANDOM_ENV_DEV, RANDOM_ENV_QA } from '@env';
import type { LoadingStore } from '@app/types';

// Keep the splash screen visible while we fetch resources
SplashScreen.preventAutoHideAsync();

export default function App() {
  // variables
  const { loadInitialAppData } = useLoadingStore((store: LoadingStore) => store);

  // setup
  useEffect(() => {
    console.log('NODE_ENV:', process.env.NODE_ENV);
    console.log('RANDOM_ENV_DEV:', RANDOM_ENV_DEV);
    console.log('RANDOM_ENV_QA:', RANDOM_ENV_QA);
    const loadApp = async () => {
      try {
        await loadInitialAppData();
      } catch (error: any) {
        Toast.show(toastFailedProps(error.message));
      } finally {
        await SplashScreen.hideAsync();
      }
    };
    loadApp();
  }, [loadInitialAppData]);

  // render
  return (
    <GlobalContextProvider>
      <SafeAreaProvider>
        <NavigationConductor />
        <ToastInit />
      </SafeAreaProvider>
    </GlobalContextProvider>
  );
}

.env

RANDOM_ENV_DEV=HelloWorldDev
RANDOM_ENV_QA=HelloWorldQa

babel.config.js

module.exports = function (api) {
  api.cache(true);
  return {
    presets: ['module:metro-react-native-babel-preset', 'babel-preset-expo'],
    plugins: [
      [
        require.resolve('babel-plugin-module-resolver'),
        {
          extensions: ['.js', '.jsx', '.ts', '.tsx', '.android.js', '.android.tsx', '.ios.js', '.ios.tsx'],
          alias: {
            '@': './',
            '@app': './app'
          }
        }
      ],
      [
        'module:react-native-dotenv',
        {
          envName: 'APP_ENV',
          moduleName: '@env',
          path: '.env',
          blocklist: null,
          allowlist: null,
          blacklist: null, // DEPRECATED
          whitelist: null, // DEPRECATED
          safe: false,
          allowUndefined: true,
          verbose: false
        }
      ]
    ]
  };
};

app.json(配置文件)

{
  "expo": {
    "name": "PROJECTNAME",
    "slug": "PROJECTSLUG",
    "version": "1.0.0",
    "scheme": "msauth",
    "orientation": "portrait",
    "icon": "./assets/images/qa-icon-1024.png",
    "userInterfaceStyle": "light",
    "backgroundColor": "#001689",
    "splash": {
      "image": "./assets/images/qa-splash.png",
      "resizeMode": "contain",
      "backgroundColor": "#001689"
    },
    "assetBundlePatterns": ["**/*"],
    "ios": {
      "supportsTablet": true,
      "bundleIdentifier": "com.example.qa",
      "buildNumber": "1.0.0"
    },
    "android": {
      "adaptiveIcon": {
        "foregroundImage": "./assets/images/qa-icon-1024.png",
        "backgroundColor": "#001689"
      },
      "package": "com.example.qa",
      "versionCode": 1
    },
    "web": {
      "favicon": "./assets/favicon.png"
    },
    "plugins": [
      [
        "expo-build-properties",
        {
          "android": {
            "minSdkVersion": 23
          }
        }
      ],
      [
        "expo-image-picker",
        {
          "photosPermission": "Allow $(PRODUCT_NAME) to access your photos",
          "cameraPermissions": "Allow $(PRODUCT_NAME) to access your camera"
        }
      ]
    ]
  }
}

package.json

{
  "name": "Project-Name",
  "version": "1.0.0",
  "main": "node_modules/expo/AppEntry.js",
  "scripts": {
    "ts:check": "tsc",
    "dev-android": "cross-env NODE_ENV=development npx expo run:android --port 8082",
    "dev-ios": "cross-env NODE_ENV=development npx expo run:ios --port 8082",
    "android": "expo run:android",
    "ios": "expo run:ios"
  },
  "dependencies": {
    "@expo/vector-icons": "^13.0.0",
    "@react-native-async-storage/async-storage": "1.18.2",
    "@react-native-community/netinfo": "9.3.10",
    "@react-navigation/native": "^6.1.9",
    "@react-navigation/stack": "^6.3.20",
    "axios": "^1.6.2",
    "core-js": "^3.35.0",
    "expo": "~49.0.15",
    "expo-auth-session": "~5.0.2",
    "expo-build-properties": "^0.8.3",
    "expo-constants": "~14.4.2",
    "expo-file-system": "~15.4.5",
    "expo-image-manipulator": "~11.3.0",
    "expo-image-picker": "~14.3.2",
    "expo-secure-store": "~12.3.1",
    "expo-splash-screen": "~0.20.5",
    "expo-status-bar": "~1.6.0",
    "expo-system-ui": "~2.4.0",
    "expo-web-browser": "~12.3.2",
    "formik": "^2.4.5",
    "jwt-decode": "^4.0.0",
    "lodash": "^4.17.21",
    "react": "18.2.0",
    "react-native": "0.72.10",
    "react-native-device-info": "^11.1.0",
    "react-native-element-dropdown": "^2.10.1",
    "react-native-gesture-handler": "~2.12.0",
    "react-native-get-random-values": "~1.9.0",
    "react-native-safe-area-context": "4.6.3",
    "react-native-screens": "~3.22.0",
    "react-native-toast-message": "^2.1.9",
    "react-query": "^3.39.3",
    "scandit-react-native-datacapture-barcode": "^6.21.3",
    "scandit-react-native-datacapture-core": "^6.21.3",
    "uri-scheme": "^1.1.0",
    "uuid": "^9.0.1",
    "yup": "^1.3.2",
    "zustand": "^4.4.7"
  },
  "devDependencies": {
    "@babel/core": "^7.20.0",
    "@types/lodash": "^4.14.202",
    "@types/react": "~18.2.14",
    "@types/uuid": "^9.0.7",
    "cross-env": "^7.0.3",
    "react-native-dotenv": "^3.4.10",
    "typescript": "^5.1.3"
  },
  "private": true
}

环境.ts

declare module '@env' {
  export const RANDOM_ENV_DEV: string;
  export const RANDOM_ENV_QA: string;
}
declare var process: {
  env: {
    NODE_ENV: string;
  };
};

结果

这是在开发环境中工作的,其中

process.env.NODE_ENV
读作
development

问题

现在,当我们使用 expo

prebuild
命令来打包包含
process.env.NODE_ENV
的构建时,我们该如何使其读取为
uat
qa

react-native expo dotenv
1个回答
0
投票

由于您已经有了react-native-dotenv,您可以创建多个.env文件来满足您对UAT或QA的需求

.env.dev
.env.uat
.env.qa

在您的 package.json 文件中

"scripts": {
     "dev-android": "cross-env NODE_ENV=development npx expo run:android --port 8082",
     "dev-ios": "cross-env NODE_ENV=development npx expo run:ios --port 8082",
     "uat-android": "cross-env NODE_ENV=uat npx expo run:android --port 8082",
     "uat-ios": "cross-env NODE_ENV=uat npx expo run:ios --port 8082",
     "qa-android": "cross-env NODE_ENV=qa npx expo run:android --port 8082",
     "qa-ios": "cross-env NODE_ENV=qa npx expo run:ios --port 8082",
  },
© www.soinside.com 2019 - 2024. All rights reserved.