如何在后端应用程序等前端 js 应用程序中使用变量替换?

Posted

技术标签:

【中文标题】如何在后端应用程序等前端 js 应用程序中使用变量替换?【英文标题】:How to use variable substitution in Frontend js applications like backend applications? 【发布时间】:2019-06-10 18:12:40 【问题描述】:

我正在尝试为应该非常简单的事情找到一个优雅的解决方案。我正在使用 create-react-app 开发 React 应用程序,并且在将代码部署到不同环境(例如在 Azure 中)时,我试图找到一种简单的方法来替换变量(例如 API 地址)。

到目前为止,我一直在使用 .env 和 .env.production 文件来存储变量,只要我们只有一个环境,它们就可以很好地工作。但由于我计划总共拥有三个环境(测试、质量保证和生产),我必须找到更好的解决方案。

一种方法是在 CI 构建的 npm 构建阶段替换变量。这种方法可行,但变量会被注入到 bundle 中,因此此构建不适用于其他环境,我们对为每个环境创建一个构建不感兴趣。

我尝试在 Azure 中使用应用程序设置,并创建自己的环境变量,但这些变量在我的 React 代码中使用 process.env 根本不可用。

有没有办法在发布网络时轻松注入这些变量?或者,我们可以在 Azure 或其他提供商中以某种方式配置这些吗? 还是有其他解决方案?

【问题讨论】:

【参考方案1】:

使用 react、vue、angular 或其他基于 javascript 的框架开发的复杂应用程序与后端应用程序(java、nodejs、python 等)存在相同的问题或要求:如何读取配置?

在这里,我将列出一些处理 javascritpt 框架配置的方法,从简单到管理的解决方案。其中一些用于后端应用程序。

#1 全局变量

当我们谈论 javascript 框架时,只需在您的应用程序启动时创建全局变量,这将可用于您的所有脚本:

<html>
  <header>
    <meta charset="utf-8">
    <title>This is title</title>
    <script>
        var myVar = "global value"; // Declare a global variable
    </script>
    <script>
        console.log("from another script:"+myVar);
    </script>
  </header>
  <body>
    Hello world
  </body>
</html>

当然,源代码中的硬编码 url 不是一个选项,但请理解这是下一个方法的入口点。几乎都是基于这种方法或者做类似的事情。

#2 网络包

Webpack 为我们提供了多种机制,例如 DefinePlugin

new webpack.DefinePlugin(
  API_BASE_URL: JSON.stringify(process.env.API_BASE_URL)
)

DefinePlugin直接文本替换。 Webpack 将查找标识符并将其替换为给定的字符串。以下示例说明了它是如何工作的。

你可以像使用全局变量一样使用这个变量:

$.ajax(
    type: "GET",
    url: API_BASE_URL+'/odds?date=2019-01-19',
    dataType: 'json',
    success: function (data) 
      ...
    
  );

这里有更多的 webpack 机制:https://***.com/a/40416826/3957754

优点:

设置或定义多个变量并在整个应用程序中使用它们的简单方法。 使用像 jenkins 这样的 C.I 服务器,您可以设置所有配置并构建您的工件,然后部署它:

export API_BASE_URL=http://awesome.api.com
export ENDPOINT_DETAIL=/detail
export ENDPOINT_FAVOURITE=/favourite
export MODULES=user,guest,admin,configure

npm run build

缺点

在构建阶段注入变量。更改您的配置将需要重新构建和重新部署您的应用程序。

#3 来自 SCM、数据库或文件系统的属性

检查这个答案:

What is the best way to change application configurations in a CI environment

#4 集中和可管理的配置

主要思想是将您的所有配置、设置或属性放在一个站点中,并且您的所有应用程序都必须以安全的方式检索这些值。如今,从最终应用程序中检索此配置的最常用技术是对平台发布的 api rest 执行 http 请求。

这类平台是微服务架构的完美搭档。我还可以将它用于微前端。

这里有一些平台:

configurator 这是一个 nodejs 应用程序,可让您集中和管理所有应用程序的配置。 zookeeper http://www.therore.net/java/2015/05/03/distributed-configuration-with-zookeeper-curator-and-spring-cloud-config.html Spring Cloud https://www.baeldung.com/spring-cloud-configuration 这是一个 java spring 框架功能,您可以在其中创建带有配置的属性文件并配置您的应用程序以读取它们。 Consul Consul 是一种服务网格解决方案,提供具有服务发现、配置和分段功能的全功能控制平面。 doozerd、etcd

您可以将这些平台之一与 webpack 方法结合使用。因此,您可以在 webpack 的构建阶段或使用您的 C.I 服务器(如 jenkins)使用 api rest,而不是手动导出环境变量。

优势

上面的所有评论。

缺点

与在与应用程序不同的另一台服务器上进行配置相比,配置独特的属性文件或手动环境导出更简单快捷。

#5 /你的网络设置

假设您的网络在 http://myapp.com 提供服务,您可以发布另一个端点,例如 http://myapp.com/settings。此端点将使用 AJAXCLIENT SIDE 返回您的微前端或 Web 应用程序所需的所有设置。

在您的 javascript 应用程序中,在 入口点(通常是 React、vue 等中的 App.js)中,我的意思是在渲染机制之前,您可以使用 http://myapp.com/settings 并作为全局变量公开给你的申请。您还可以将其保存在可用的存储之一中,例如 localStorage、sessionStorage 等

优势

配置中的更改无需重新构建应用程序即可使用。只需执行页面刷新以在您的 javascript 中再次执行 入口点。 您可以在 /settings 的后端控制器中使用方法 #3

缺点

与 ajax http 请求相比,预硬编码变量会立即加载。

【讨论】:

这是一个很好的答案。 +1 从终端端点获取您的设置! 谢谢哥们:D。检查此页面timberazo.com,您可以在初始 ajax 请求中看到 /conf.json 具有相同的想法。你也可以查看我的 repo github.com/utec/geofrontend-server 这个 repo 为你在 angular、vue、react、aurelia 等中构建的资产注入了一个 /settings.json

以上是关于如何在后端应用程序等前端 js 应用程序中使用变量替换?的主要内容,如果未能解决你的问题,请参考以下文章

后端让前端执行某个函数怎么操作

如何在后端和前端具有不同子文件夹的代码沙盒中运行应用程序

Nodemon:是不是可以仅在后端文件中而不是在静态前端文件中重新启动 Node js 服务器?

在后端(.Net)和前端(角度)之间共享 JWT 令牌

JSON 仅在后端和前端之间

角度如何与 Ionic 应用程序中的节点一起工作?