Open rtsao opened 9 years ago
zero-config
is currently a node only module.
A certain subset of the features could be made to work in the browser.
config/x.json
folder.config/NODE_ENV.json
patternThe following will not work in the browser.
--config
There are two approaches to make this work.
"browser"
field in package.json to point to a browser.js file."browser"
key to the config files, this is to support the same
config folder in both the browser & the server for one application.So one way to implement this is to author and use browserify transforms that can read NODE_ENV and datacenter information at compile time and bundle the correct files into the browserify artifact.
I'm not sure whether we would have to write our own transforms or could re-use some.
You can use something like json-globals
to inject
the server loaded configuration into the browser.
The browser config loader can then just read the correct config from global scope.
This means the disk reading, NODE_ENV resolution, etc will be done on the server as part of rendering the html.
I recommend the server-side help solution as browserify transforms are pretty complicated.
I do not have the bandwidth to implement it this week.
cc @lxe for suggestings on how to implement this in bedrock
cc @orbiteleven for suggestions on how this fits into toolshed
Are you trying to load the server configuration on the client side? If so, you can export it either as a route:
app.get('/config.json', function (req, res) {
res.json(config);
});
Or as template variables:
app.get('/config', function (req, res) {
res.render('my_template', {
config: config
});
});
Are you trying to have client-specific configuration variables available to the client scripts?
You can possibly run zero-config as one of your gulp steps that generates a config.js prior to browserifying, then bundle the config.js, and use it via require('config.js')?
We want require('zero-config')
to work in the browser without thinking about it.
Ideally it would read all the "browser"
keys in the config files at the entire config object.
Having it be an async HTTP request or having it be baked into some kind of gulp step would not be acceptable. It needs to have a subset of the interface with require('zero-config')
and #justwork.
We need to define "#justwork". What exactly should this code do on the client?:
var fetchConfig = require('zero-config');
var config = fetchConfig(__dirname, {
dc: NODE_ENV === 'production' ?
'/etc/playdoh/datacenter' : null
});
We can't read config from "file" or "directory" on the client side (well.. technically we can, but I'm not sure this is useful for our usecase), requiring either a route requesting which returns the config, or somehow pre-populating the config before browserifying.
@mlmorg I think browserifying our secrets files and serving that to browsers is a BAD IDEA (TM).
@mlmorg @Raynos I've been playing around with brfs transform. One limitation/feature of brfs, is that it only overrides the fs.readFileSyncs
in the current project, and not in the nested modules.
Also config-chain is very difficult to browserify (browserify actually ends up failing on index.js due to lack of semicolons).
Also, there's no clean way that I know of to conditionally detect whether brfs needs to be loaded at all. It's kind of wasteful to load brfs for projects that don't need client-side loading.
Nonetheless, there's a way to make zero-config browserifiable by directly fs.readFile
ing things in config/browser/env.json
and appending that to the config chain object.
Reference PR pending.
It should be noted that browser code probably wants a seperate entry point.
Namely a browser.js
entry point.
We will have to refactor this code to break out the shared / browser / node modules.
Conveniently, config-chain is unable to load anything at all after browserifying (if no changes are made to zero-config and config-chain).
Something like this works:
var zeroConfig = require('zero-config');
var fs = require('fs');
// This always loads an empty config object
var config = zeroConfig(__dirname);
// Add stuff to it
config.set(JSON.parse(fs.readFileSync(__dirname + '/config/browser/common.json')));
console.log(config.get());
Let's not "conveniently" rely config-chain not loading anything.
Let's duplicate some more of the implementation to make the browser implementation leaner and less "works on my machine (tm)".
Let's not "conveniently" rely config-chain not loading anything.
I completely agree with this. I'm just exploring options and reporting what I find. Just notifying that "there is a way"
Ping. Did you come up with anything for this?
As far as I know it's not implemented.
zero-config doesn't work in browserified files
I was hoping to use zero-config on a SPA that will live on web-toolshed.
cc @orbiteleven @lxe @sh1mmer @Raynos