如何在运行browserified脚本之前设置process.env?
最初的html
来自后端。 服务器有一个定义的process.env.NODE_ENV
(以及其他的环境variables)。 browserified代码是一次构build的 , 可以在多个环境 ( staging
, production
等)上运行,所以不可能将环境variablesembedded到envify
脚本中(例如通过envify
)。 我想能够写出所呈现的html中的环境variables,并为browserified代码使用这些variables。 那可能吗?
以下是我所想象的:
<html> <head> <script>window.process = {env: {NODE_ENV: 'production'}};</script> <script src="/build/browserified_app.js"></script> </head> </html>
而不是硬编码环境variables,使用envify插件。
npm install envify
这个插件会自动修改process.env.VARIABLE_HERE
作为parameter passing给envify。
例如:
browserify index.js -t [ envify --DEBUG app:* --NODE_ENV production --FOO bar ] > bundle.js
在您的应用程序中, process.env.DEBUG
将被app:*
, process.env.NODE_ENV
replace为production
等。 在我看来,这是一个干净&&雅致的方式来处理这个问题。
您可以更改您的入口点文件,这基本上会做这样的设置,然后需要原始的主文件。
process.env.NODE_ENV = 'production'; require('app.js');
其他方式(更干净)是使用像envify这样的转换,它直接replace代码中的NODE_ENV和string值。
选项1
我认为你的方法通常应该可以工作,但是我不会直接写入process.env
因为我非常肯定它会被bundle中的内容覆盖。 相反,你可以像__env
那样创build全局variables,然后在实际的bundle代码中将其设置为process.env
。 这是未经testing的解决scheme,但我相信它应该工作。
选项2
使用localStorage并让主脚本在初始化时从那里读取variables。 您可以手动将variables设置为localStorage,或者甚至可以让服务器提供它们,如果有的话。 开发者只需打开控制台并input类似loadEnv('production')
,就可以执行XHR并将结果存储在localStorage中。 即使使用手动方法,仍然有一个优点,这些不需要在html中进行硬编码。
如果手动听起来不够好,服务器也是死胡同,你可以包含所有环境中的所有variables(如果有的话),然后使用switch
语句根据某些条件select正确的variables(例如。localhost,生产主机)。
考虑到这一点,你肯定超出了Browserify的范围与您的需求。 它可以为你打包,但如果你不想把这些信息捆在一起,那么你就是自己的。
我已经成功地写入一个json文件,然后将该json文件导入需要读取环境的任何地方。
所以在我的大文件中:
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);
我来到这里寻找一个更清洁的解决scheme…祝你好运!
我遇到了这个问题build设同构反应的应用程序。 我使用以下(好吧,这是一个有点哈克)解决scheme:
我将env
分配给window
对象,当然我并不公开所有的env
variables,只有那些可能公开的variables(没有密码的密钥等)。
// 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!
所以我决定这是Web服务器的工作来插入环境variables。 我的scheme要求每个环境使用不同的logging器(例如“本地”,“testing”,“产品”)。
码:
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中创build一个对象,并使其可configuration。
这当然有效,它是有道理的,因为它可能是唯一的服务器入口点。