最初的html
来自后端。服务器具有已定义的process.env.NODE_ENV
(以及其他环境变量)。浏览器化代码构建一次并且在多个环境中运行(staging
,production
等),因此不可能将环境变量内联到浏览器化的脚本中(例如,通过envify
)。我希望能够在渲染的html中编写环境变量,并使用浏览器化的代码来使用这些变量。这可能吗?
以下是我想象的事情:
<html>
<head>
<script>window.process = {env: {NODE_ENV: 'production'}};</script>
<script src="/build/browserified_app.js"></script>
</head>
</html>
答案 0 :(得分:9)
不要在环境中对环境变量进行硬编码,而是使用envify插件。
npm install envify
此插件会自动修改process.env.VARIABLE_HERE
,并将您作为参数传递给envify。
例如:
browserify index.js -t [ envify --DEBUG app:* --NODE_ENV production --FOO bar ] > bundle.js
在您的申请中,process.env.DEBUG
将替换为app:*
,process.env.NODE_ENV
将替换为production
,依此类推。这是一个干净的&amp;&amp;在我看来,优雅的方式来处理这个问题。
答案 1 :(得分:2)
您可以更改入口点文件,基本上可以进行此类设置,然后需要原始主文件。
process.env.NODE_ENV = 'production';
require('app.js');
其他方式(非常清晰)是使用envify之类的转换,它会直接用字符串值替换代码中的NODE_ENV。
我认为你的方法通常应该有效,但是我不会直接写到process.env
,因为我非常确定它会在包中被覆盖。相反,您可以创建像__env
这样的全局变量,然后在实际的捆绑代码中将其设置为条目文件中的process.env
。这是未经测试的解决方案,但我相信它应该可行。
使用localStorage并让主脚本在初始化时从那里读取变量。您可以手动将变量设置为localStorage,或者如果您有变量,您甚至可以让服务器提供它们。开发人员只需打开控制台并键入类似loadEnv('production')
的内容,它就会执行XHR并将结果存储在localStorage中。即使使用手动方法,仍然有一个优点,即这些不需要在html中进行硬编码。
如果手动听起来不够好并且服务器也是死路一条,你可以在捆绑包中包含所有环境中的所有变量(如果你有它们),然后使用switch
语句来选择正确的基于某些条件的(例如localhost,生产主机)。
考虑到这一点,根据您的需求,您绝对不在Browserify的范围之内。它可以为您制作捆绑包,但如果您不想在捆绑包中使用这些信息,那么您就是自己的。
答案 2 :(得分:1)
所以我决定插入环境变量是Web服务器的工作。我的场景需要每个环境使用不同的记录器(例如'local','test','prod')。
代码:
var express = require('express')
, replace = require('replace');
...
var app = express();
var fileToReplace = <your browserified js here>;
replace({
regex: 'ENV_ENVIRONMENT'
, replacement: process.env.ENVIRONMENT
, paths: [fileToReplace]
});
...
app.listen(process.env.PORT);
我硬编码'ENV_ENVIRONMENT',但您可以在package.json中创建一个对象并使其可配置。
这当然有效,因为它可能是您拥有的唯一服务器入口点。
答案 3 :(得分:1)
我首先成功写入json文件,然后将该json文件导入需要读取环境的任何地方。
所以在我的gulp文件中:
import settings from './settings';
import fs from 'fs';
...
fs.writeFileSync('./settings.json', JSON.stringify(settings));
在settings.js文件中:
if(process.env.NODE_ENV) {
console.log('Starting ' + process.env.NODE_ENV + ' environment...');
} else {
console.log('No environment variable set.');
process.exit();
}
export default (() => {
let settings;
switch(process.env.NODE_ENV) {
case 'development':
settings = {
baseUrl: '...'
};
break;
case 'production':
settings = {
baseUrl: 'some other url...'
};
break;
}
return settings;
})();
然后你可以在任何其他文件中导入settings.json文件,它将是静态的,但包含你当前的环境:
import settings from './settings.json';
...
console.log(settings.baseUrl);
我来这里寻找更清洁的解决方案......祝你好运!
答案 4 :(得分:1)
我遇到了这个问题构建同构反应应用程序。我使用以下(好吧,它有点hacky)解决方案:
我将env
分配给window
对象,当然我没有公开所有env
个变种,只有那些可能是公开的变量(没有密码的秘密密钥和这样)。
// code...
const expose = ["ROOT_PATH", "ENDPOINT"];
const exposeEnv = expose.reduce(
(exposeEnv, key) => Object.assign(exposeEnv, { [key]: env[key] }), {}
);
// code...
res.send(`<DOCTYPE html>
// html...
<script>window.env = ${JSON.stringify(exposeEnv)}</script>
// html...
`);
// code...
然后,在我的应用程序客户端入口点(哦,是的,你必须有一个入口点)我这样做:
process.env = window.env;
YMMV AKA WFM!