From 50de97fb1239b7079f36c3897fe0c0c5f2e39070 Mon Sep 17 00:00:00 2001 From: gongpeione Date: Wed, 3 Jan 2018 11:46:13 +0800 Subject: [PATCH] Add basic .env support. (#258) * Add .env support. * Handle promise rejection. * Use process.env.DOTENV * Use dotenv * Use dotenv module * Move env loading to a util, copy to workers, add tests --- package.json | 1 + src/Bundler.js | 3 +++ src/utils/env.js | 26 ++++++++++++++++++++++++++ src/worker.js | 1 + test/integration/env-file/.env | 2 ++ test/integration/env-file/index.js | 1 + test/javascript.js | 7 +++++++ yarn.lock | 4 ++++ 8 files changed, 45 insertions(+) create mode 100644 src/utils/env.js create mode 100644 test/integration/env-file/.env create mode 100644 test/integration/env-file/index.js diff --git a/package.json b/package.json index a5a17b97eea..8e7e191792f 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "commander": "^2.11.0", "cross-spawn": "^5.1.0", "cssnano": "^3.10.0", + "dotenv": "^4.0.0", "get-port": "^3.2.0", "glob": "^7.1.2", "htmlnano": "^0.1.6", diff --git a/src/Bundler.js b/src/Bundler.js index 08ee747ee88..7260a21f17b 100644 --- a/src/Bundler.js +++ b/src/Bundler.js @@ -14,6 +14,7 @@ const PackagerRegistry = require('./packagers'); const localRequire = require('./utils/localRequire'); const config = require('./utils/config'); const emoji = require('./utils/emoji'); +const loadEnv = require('./utils/env'); /** * The Bundler is the main entry point. It resolves and loads assets, @@ -176,8 +177,10 @@ class Bundler extends EventEmitter { } await this.loadPlugins(); + await loadEnv(this.mainFile); this.options.extensions = Object.assign({}, this.parser.extensions); + this.options.env = process.env; this.farm = WorkerFarm.getShared(this.options); if (this.options.watch) { diff --git a/src/utils/env.js b/src/utils/env.js new file mode 100644 index 00000000000..1bf1e8a4824 --- /dev/null +++ b/src/utils/env.js @@ -0,0 +1,26 @@ +const config = require('./config'); +const dotenv = require('dotenv'); + +async function loadEnv(filepath) { + const NODE_ENV = process.env.NODE_ENV || 'development'; + const dotenvFiles = [ + `.env.${NODE_ENV}.local`, + `.env.${NODE_ENV}`, + // Don't include `.env.local` for `test` environment + // since normally you expect tests to produce the same + // results for everyone + NODE_ENV !== 'test' && '.env.local', + '.env' + ].filter(Boolean); + + await Promise.all( + dotenvFiles.map(async dotenvFile => { + const envPath = await config.resolve(filepath, [dotenvFile]); + if (envPath) { + dotenv.config({path: envPath}); + } + }) + ); +} + +module.exports = loadEnv; diff --git a/src/worker.js b/src/worker.js index a988a2161bc..f6ed40eb7ed 100644 --- a/src/worker.js +++ b/src/worker.js @@ -5,6 +5,7 @@ let parser; exports.init = function(options, callback) { parser = new Parser(options || {}); + Object.assign(process.env, options.env || {}); callback(); }; diff --git a/test/integration/env-file/.env b/test/integration/env-file/.env new file mode 100644 index 00000000000..3552f1442f9 --- /dev/null +++ b/test/integration/env-file/.env @@ -0,0 +1,2 @@ +FOO=bar +BAR=test diff --git a/test/integration/env-file/index.js b/test/integration/env-file/index.js new file mode 100644 index 00000000000..e81b72112b6 --- /dev/null +++ b/test/integration/env-file/index.js @@ -0,0 +1 @@ +module.exports = process.env.FOO + process.env.BAR; diff --git a/test/javascript.js b/test/javascript.js index 5f7d0f3b4a1..b91b527c369 100644 --- a/test/javascript.js +++ b/test/javascript.js @@ -222,6 +222,13 @@ describe('javascript', function() { assert.equal(output(), 'test:test'); }); + it('should insert environment variables from a file', async function() { + let b = await bundle(__dirname + '/integration/env-file/index.js'); + + let output = run(b); + assert.equal(output, 'bartest'); + }); + it('should support adding implicit dependencies', async function() { let b = await bundle(__dirname + '/integration/json/index.js', { delegate: { diff --git a/yarn.lock b/yarn.lock index 489ebff024a..ec9bd34ccf3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1621,6 +1621,10 @@ domutils@^1.5.1: dom-serializer "0" domelementtype "1" +dotenv@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-4.0.0.tgz#864ef1379aced55ce6f95debecdce179f7a0cd1d" + ecc-jsbn@~0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505"