Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/436.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Webpack:如何在客户端(浏览器)注入process.env运行时,使构建独立于环境_Javascript_Node.js_Webpack_Webpack 4 - Fatal编程技术网

Javascript Webpack:如何在客户端(浏览器)注入process.env运行时,使构建独立于环境

Javascript Webpack:如何在客户端(浏览器)注入process.env运行时,使构建独立于环境,javascript,node.js,webpack,webpack-4,Javascript,Node.js,Webpack,Webpack 4,简短问题 我想用某种方式告诉Webpack,不要使用process变量做任何事情,只需像对待任何其他全局变量一样对待它(因此它指的是客户端包中的window.process)。如果不可能,则提供一种在客户端运行期间在Webpack的process.env中注入变量的方法 详细解释 目前,我使用Webpack打包我的React(SSR)应用程序。我有5个环境,如dev1、dev2。。。舞台和制作。我想重复使用相同的构建并保持可配置性,比如说谷歌分析ID在每个环境中都是不同的 后端点环境模块执行此任

简短问题

我想用某种方式告诉Webpack,不要使用
process
变量做任何事情,只需像对待任何其他全局变量一样对待它(因此它指的是客户端包中的window.process)。如果不可能,则提供一种在客户端运行期间在Webpack的
process.env
中注入变量的方法

详细解释

目前,我使用Webpack打包我的React(SSR)应用程序。我有5个环境,如dev1、dev2。。。舞台和制作。我想重复使用相同的构建并保持可配置性,比如说谷歌分析ID在每个环境中都是不同的

后端点环境模块执行此任务。我可以在
.env
文件中将所有常量定义为
KEY=value
对,并在运行时加载它们,并在代码中用作
process.env.KEY

我试图在前端(或共享文件)复制相同的行为。假设我有一个
baseService.js
,它调用
fetch
。它也可以从节点+客户端使用。它使用诸如
process.env.HOST
之类的变量。到目前为止,我一直在为每个环境创建单独的构建,因此在Webpack中使用
Webpack.DefinePlugin
plugin来定义它,以便能够在客户端包中使用它

现在,由于我想重复使用构建,我捕获了
process.env
中的所有常量,通过将它们与
PUBLIC_(.*)
(它将匹配PUBLIC_键)匹配,查看它们中是否有任何常量在客户端可用,如果是,则将它们打包在数组中,并将其作为对象添加到主html文件中,如下所示:-

window.process = {ENV: { PUBLIC_GA_ID: '1235', PUBLIC_FOO: 'bar' }}
当我使用webpack捆绑我的客户端并执行
process时,env.PUBLIC\u GA\u ID
是未定义的(尽管它作为全局
window.process
变量存在于head html中)。这是因为webpack仍然将流程变量从节点注入前端,前端的
env
对象为空
{}
对象。我已经调试过了,下面是截图

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


我想用某种方式告诉Webpack,不要使用
process
变量做任何事情,只需像对待任何其他全局变量一样对待它(因此它指的是客户端包中的window.process)。如果不可能,那么在客户端上运行期间,在Webpack的
process.env
中插入变量的方法。

我想,与其玩Webpack来完成这项工作,我已经找到了最简单的解决方案。如果有人有更好的答案,请发帖子

我创建了一个实用函数,如下所示:-

export const getEnv = key => {
  if (typeof window === 'undefined') {
    // node
    return process.env[key]
  }
  // browser
  return window.process.env[key]
}
现在我在NODE和浏览器中调用
getEnv('PUBLIC_KEY')
getEnv('NODE_ENV')
,效果非常好


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

,但在编译时,我遇到了一个类似的问题,即Webpack内联
process.env.NODE\u env
的内容

通过将以下内容添加到我的服务器网页包配置中,我可以关闭该功能:

  optimization: {
    nodeEnv: 'production'
  }

要了解更多相关信息,webpack预设了2个环境来构建不同的应用程序。 考虑这个配置:

// package.json
"scripts": {
    "build:development": "cross-env NODE_ENV=development webpack",
    "build:production": "cross-env NODE_ENV=production  webpack",
 }
//webpack.config.js
const ENVIRONMENT=process.env.NODE\u env;
module.exports={
条目:{/…},
输出:{/…},
//typeof mode=“开发”|“生产”|“无”;
模式:环境
}
$npm运行构建:开发

构建之后,打开浏览器,同时输出您设置的
当前环境为:development

祝你好运

在代码中用“”代替“窗口”,用“.process”代替“process”。

我最后做的是:

  • 使用webpack生成捆绑包,该捆绑包将在开发、生产和阶段中重用
  • 在执行时使用自己的代码访问.env文件,不使用dotenv,也不使用webpack dotenv
  • 创建一个函数getEnv(),该函数使用
    const rawFile=new XMLHttpRequest()并读取.env文件
  • 您不使用dotenv包,也不需要它。您只需导入{getEnv}并在运行时的代码中使用它
当然,这不是最安全的,但dotenv或webpack dotenv都是,因为密钥以任何方式注入到客户端并可访问


您可以重用您的包,并在docker或任何地方创建函数读取的文件。

您签出EnvironmentPlugin了吗@ben在编译时编写值示例process.env。PUBLIC_FOO将成为编译时本身的
bar
。所以这是不可重用的构建,因为对于其他环境,此值可能不同。我在找运行时option@UmakantPatil让我们来回答,试着做你想做的事。它就是这样工作的。