gpt4 book ai didi

reactjs - 构建一次并在多个环境中部署构建文件,只需对 React 和 Webpack 进行最少的更改

转载 作者:行者123 更新时间:2023-12-05 09:16:50 26 4
gpt4 key购买 nike

在 webpack.config 文件中声明一个变量以在应用程序中读取。

let BASEURL = "http://127.0.0.1:8090";

使用这种方法,我无法在 npm run build 之后更新 BASEURL。如果 BASEURL 发生变化,每次我想为每个环境生成一个新的构建。

有没有什么方法可以构建一次并在多个环境中以最少的更改部署构建文件?

最佳答案

Tl;dr:使用 AJAX 并在 React 上下文或全局变量中进行配置。


详细答案:

确实如您所说,在使用 npm run build 构建应用程序之后, 环境变量变为硬连接且无法更改。

官方声明create-react-app它是否支持一次部署多次原则。来自 https://create-react-app.dev/docs/adding-custom-environment-variables/ :

The environment variables are embedded during the build time. Since Create React App produces a static HTML/CSS/JS bundle, it can’t possibly read them at runtime.

不过实现原理还是有方法的,只是稍微复杂一点。这个想法是,您需要在运行时从外部源获取变量的值,例如 Ajax 。更详细地说,可能的解决方案可能(但不限于)如下:

1。服务器端占位符替换

这是create-react-app提出的解决方案在 https://create-react-app.dev/docs/title-and-meta-tags/#injecting-data-from-the-server-into-the-page ,在将其呈现给客户端之前,引入自定义占位符并将其替换为服务器上的数据。

<!doctype html>
<html lang="en">
<head>
<script>
window.SERVER_DATA = __SERVER_DATA__;
</script>

虽然这行得通,但它带来了很大的开销,因为它将整个后端实现留给了您。根据您的技术堆栈,这可能非常容易实现,也可能非常复杂。

2。动态<script>分配变量值

https://www.cotyhamilton.com/build-once-deploy-anywhere-for-react-applications/ 中提出的解决方案利用javascript的动态特性。在动态下载config.js文件,一个值被分配给变量。在 React 代码的其余部分,变量被读取和使用。您可以更改 config.js随时归档,无需重新编译 React 应用程序。

// public/config.js

const apiUrl = 'localhost:1337';
const env = 'development';
<!-- public/index.html -->

<script src="%PUBLIC_URL%/config.js"></script>
<script>
window.config = { apiUrl, env };
</script>

主要缺点是它不支持 TypeScript,您的 IDE 或 linter 可能会提示 apiUrlenv没有定义。尤其是在较大的项目中,这种方法可能难以维护。

3。使用 AJAX 进行动态配置,支持 TypeScript

本文基于第2种方案https://profinit.eu/en/blog/build-once-deploy-many-in-react-dynamic-configuration-properties/ create-react-app 详细描述了如何最好地实现构建一次部署多次原则什么是优点和缺点。

它建议使用 AJAX 将动态配置下载为 JSON。主要警告是确保在某些代码厌倦使用它之前下载动态配置。在 React 生命周期的上下文中,有两种方法可以实现这一点。

3.1 全局变量

globalConfigUrl 下载动态配置 JSON ,将其存储在一个全局变量中,然后才渲染 React 应用程序。 TypeScript 中的示例:

// index.tsx:
import axios from "axios";
import React, {ReactElement} from "react";
import App from "./App";
import {globalConfig, globalConfigUrl} from "./configuration/config";

axios.get(globalConfigUrl)
.then((response) => {
globalConfig.config = response.data; // THIS IS THE IMPORTANT LINE
return <App />;
})
.catch(e => {
return <p style={{color: "red", textAlign: "center"}}>Error while fetching global config</p>;
})
.then((reactElement: ReactElement) => {
ReactDOM.render(
reactElement,
document.getElementById("root")
);
});

完整的工作示例:https://codesandbox.io/s/build-once-deploy-many-global-config-object-dvpzr

3.2。 react 上下文

包装你的 <App>具有包含配置的 react 上下文提供程序的组件(使用 undefined 或一些默认值)。第一次获取配置 App被呈现,然后将其值保存到上下文中。 React 会处理剩下的事情并传播值的变化!

完整的工作示例:https://codesandbox.io/s/build-once-deploy-many-react-context-7lk7g

基本思路是这样的。查看上面的文章/工作示例以了解所有详细信息:

// App.tsx
import {useConfig} from "./configuration/useConfig";

// ... in the method:
const { setConfig } = useConfig(); // the `useConfig` is a custom hook, wrapping a React context. See the full working example for all details
useEffect(() => {
axios
.get(dynamicConfigUrl)
.then((response) => {
setConfig(response.data);
})
}, [setConfig]);

关于reactjs - 构建一次并在多个环境中部署构建文件,只需对 React 和 Webpack 进行最少的更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49649924/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com