本文介绍了Webpack:如何在客户端(浏览器)端注入 process.env 运行时,使构建独立于环境的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

简短问题

我正在寻找某种方法来告诉 Webpack,不要对 process 变量做任何事情,就像对待任何其他全局变量一样(所以它指的是客户端包中的 window.process).如果不可能,那么一种在客户端运行时在 Webpack 的 process.env 中注入变量的方法.

I'm looking some way to tell Webpack that, do not do anything with process variable, just treat as like any other global variable (so it refers to window.process in client bundle). If not possible, then a way to inject variables in process.env of Webpack during runtime on client.

详细解释

目前,我使用 Webpack 来打包我的 React (SSR) 应用程序.我有 5 个环境,例如 dev1、dev2... staging 和 production.我想重复使用相同的构建并保持可配置性,例如每个环境中的 Google Analytics ID 都不同.

At the moment, I use Webpack to pack my React (SSR) application. I have 5 environments like dev1, dev2... staging and production. I want to re-use the same build and keep things configurable like say Google Analytics ID on each environment is different.

后端点 ENV 模块完成这项工作.我可以在 .env 文件中将所有常量定义为 KEY=value 对并加载它们运行时并用作 process.env.KEY 在代码.

Backend Dot ENV module does the job. I can define all constants as KEY=value pair in .env file and load them run time and use as process.env.KEY in the code.

我试图为前端(或共享文件)复制相同的行为.假设我有一个调用 fetchbaseService.js.它也可以从节点 + 客户端使用.它使用像 process.env.HOST 这样的变量.到目前为止,我正在为每个环境创建单独的构建,因此使用 webpack.DefinePlugin 插件在 Webpack 中定义了它,以便能够在客户端包上使用它.

I was trying to replicate same behaviour for the front end side (or shared files). Say I have a baseService.js which makes call to fetch. It can be used from node + client as well. It uses variables like process.env.HOST. Until now I was creating separate build for each environment, therefore had this defined in Webpack using webpack.DefinePlugin plugin to be able to use this on client side bundle.

现在因为我想重用构建,我捕获 process.env 中的所有常量,通过将它们与 PUBLIC_(.*) (它将匹配 PUBLIC_KEY),如果是,则打包然后在数组中并作为对象添加到主 html 文件中,如下所示:-

Now as I want to re-use the builds, I capture all constants in process.env see if any of them is usable on client side by matching them with PUBLIC_(.*) (It would match PUBLIC_KEY), if yes pack then in array and add in main html file as object as shown below:-

window.process = {ENV: { PUBLIC_GA_ID: '1235', PUBLIC_FOO: 'bar' }}

当我使用 webpack 捆绑我的客户端并执行 process.env.PUBLIC_GA_ID 时未定义(尽管它在 head html 中作为全局 window.process 变量).这是因为 webpack 仍然从 Node 向前端注入流程变量,前端有 env 对象作为空白的 {} 对象.下面是我调试过的截图.

When I bundle my client using webpack and execute process.env.PUBLIC_GA_ID is undefined (although it is there in head html as global window.process variable). It is because webpack still injecting process variable from Node to the front end which has env object as blank {} object. I had it debugged below is the screenshot.

以上是baseService.js 文件中process 变量的控制台日志.显然我不能在这里使用 window.process 因为那样在 Node.js 中使用文件时它会失败

Above is console log of process variable in a baseService.js file. Obviously I cannot use window.process here because then it would fail when file is being used in Node.js

我正在寻找某种方法来告诉 Webpack,不要对 process 变量做任何事情,就像对待任何其他全局变量一样(所以它指的是客户端包中的 window.process).如果不可能,那么一种在客户端运行时在 Webpack 的 process.env 中注入变量的方法.

I'm looking some way to tell Webpack that, do not do anything with process variable, just treat as like any other global variable (so it refers to window.process in client bundle). If not possible, then a way to inject variables in process.env of Webpack during runtime on client.

推荐答案

我认为与其使用 Webpack 来完成这项工作,我已经解决了最简单的解决方案.如果有人有更好的答案,请留言.

I think instead playing with Webpack to do this job, I have settled with for the simplest solution. If anyone has any better answer, please do post.

我创建了一个效用函数如下:-

I created a utility function as follows:-

export const getEnv = key => {
  if (typeof window === 'undefined') {
    // node
    return process.env[key]
  }
  // browser
  return window.process.env[key]
}

现在我在节点和浏览器中调用 getEnv('PUBLIC_KEY')getEnv('NODE_ENV') 并且工作得很好.

Now I call getEnv('PUBLIC_KEY') or getEnv('NODE_ENV') both in node and in browser and works perfectly fine.

虽然我仍然更喜欢 Webpack 支持选项的更好方式,以获取 process.env 运行时或为浏览器注入 API

Although I'd still prefer the better way Webpack supports option to take process.env run time or inject API for browser

这篇关于Webpack:如何在客户端(浏览器)端注入 process.env 运行时,使构建独立于环境的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-25 00:15