implement .env loading

This commit is contained in:
Evan You
2017-12-29 16:34:04 -05:00
parent 9c86a8ec8f
commit c8a52f3838
14 changed files with 105 additions and 36 deletions

View File

@@ -1,17 +1,27 @@
.DS_Store
node_modules/
/dist/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
node_modules
/dist
<%_ if (options.coverage) { _%>
# test coverage files
/test/unit/coverage/
<%_ } _%>
<%_ if (options.e2e === 'nightwatch') { _%>
# e2e reports & log
/test/e2e/reports/
selenium-debug.log
<%_ } _%>
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode

View File

@@ -10,9 +10,11 @@ module.exports = class PluginAPI {
return path.resolve(this.service.context, _path)
}
setEnv (env) {
process.env.NODE_ENV = env
process.env.BABEL_ENV = env === 'production' ? env : 'development'
setMode (mode = 'development') {
// by default, NODE_ENV === mode, but this can be overwritten in .env files
process.env.NODE_ENV = mode
// load .env files based on mode
this.service.loadEnv(mode)
}
registerCommand (name, opts, fn) {

View File

@@ -1,6 +1,8 @@
const fs = require('fs')
const path = require('path')
const debug = require('debug')
const chalk = require('chalk')
const dotenv = require('dotenv')
const getPkg = require('read-pkg-up')
const merge = require('webpack-merge')
const Config = require('webpack-chain')
@@ -19,6 +21,10 @@ module.exports = class Service {
this.pkg = pkg.pkg || {}
this.context = path.dirname(pkg.path)
this.projectOptions = this.loadProjectConfig()
debug('vue:project-config')(this.projectOptions)
// load base .env
this.loadEnv()
// install plugins
this.resolvePlugins().forEach(({ id, apply }) => {
@@ -34,6 +40,31 @@ module.exports = class Service {
}
}
loadEnv (mode) {
const basePath = path.resolve(this.context, `.env${mode ? `.${mode}` : ``}`)
const localPath = `${basePath}.local`
const baseRes = dotenv.load({ path: basePath })
const localRes = dotenv.load({ path: localPath })
const checkError = res => {
// only ignore if file is not found
if (res.error && res.error.toString().indexOf('ENOENT') < 0) {
error(res.error)
}
}
checkError(baseRes)
checkError(localRes)
const logger = debug('vue:env')
if (baseRes.parsed) {
logger(basePath, baseRes.parsed)
}
if (localRes.parsed) {
logger(localPath, localRes.parsed)
}
}
resolvePlugins () {
const builtInPlugins = [
'./command-plugins/serve',

View File

@@ -1,11 +1,21 @@
const defaults = {
mode: 'production',
extractCSS: true,
sourceMap: true,
cssSourceMap: false
}
module.exports = (api, options) => {
api.registerCommand('build', {
description: 'build for production',
usage: 'vue-cli-service build',
options: {
'--extractCSS': 'extract component CSS into one file.'
'--mode': `specify env mode (default: ${defaults.mode})`,
'--extractCSS': `extract component CSS into one file. (default: ${defaults.extractCSS})`,
'--sourceMap': `generate source map (default: ${defaults.sourceMap})`,
'--cssSourceMap': `generate source map for CSS (default: ${defaults.cssSourceMap})`
}
}, args => {
// TODO
api.setMode(args.mode || defaults.mode)
})
}

View File

@@ -1,21 +1,28 @@
const { info, error, hasYarn, clearConsole } = require('@vue/cli-shared-utils')
const defaults = {
mode: 'development',
host: '0.0.0.0',
port: 8080,
https: false
}
module.exports = (api, options) => {
api.registerCommand('serve', {
description: 'start development server',
usage: 'vue-cli-service serve',
options: {
'--open': 'open browser on server start',
'--env': 'specify NODE_ENV (default: development)',
'--host': 'specify host (default: 0.0.0.0)',
'--port': 'specify port (default: 8080)',
'--https': 'use https'
'--open': `open browser on server start`,
'--mode': `specify env mode (default: ${defaults.mode})`,
'--host': `specify host (default: ${defaults.host})`,
'--port': `specify port (default: ${defaults.port})`,
'--https': `use https (default: ${defaults.https})`
}
}, args => {
clearConsole()
info('Starting development server...')
api.setEnv(args.env || 'development')
api.setMode(args.mode || defaults.mode)
const chalk = require('chalk')
const webpack = require('webpack')
@@ -27,9 +34,9 @@ module.exports = (api, options) => {
const overlayMiddleware = require('@vue/cli-overlay/middleware')
const projectDevServerOptions = options.devServer || {}
const useHttps = args.https || projectDevServerOptions.https
const host = args.host || process.env.HOST || projectDevServerOptions.host || '0.0.0.0'
portfinder.basePort = args.port || process.env.PORT || projectDevServerOptions.port || 8080
const useHttps = args.https || projectDevServerOptions.https || defaults.https
const host = args.host || process.env.HOST || projectDevServerOptions.host || defaults.host
portfinder.basePort = args.port || process.env.PORT || projectDevServerOptions.port || defaults.port
portfinder.getPort((err, port) => {
if (err) {

View File

@@ -5,7 +5,7 @@ const WatchMissingNodeModulesPlugin = require('../webpack/watchmissingnodemodule
module.exports = api => {
api.chainWebpack(webpackConfig => {
if (process.env.NODE_ENV !== 'production') {
if (process.env.NODE_ENV === 'development') {
webpackConfig
.devtool('cheap-module-source-map')

View File

@@ -1,5 +1,7 @@
module.exports = api => {
api.chainWebpack(webpackConfig => {
// TODO
if (process.env.NODE_ENV === 'production') {
}
})
}

View File

@@ -1,14 +1,9 @@
const prefixRE = /^VUE_APP_/
module.exports = function resolveClientEnv () {
// this should have been set by api.setEnv()
const NODE_ENV = process.env.NODE_ENV || 'development'
// TODO load .env files
const env = { NODE_ENV: JSON.stringify(NODE_ENV) }
const env = {}
Object.keys(process.env).forEach(key => {
if (prefixRE.test(key)) {
if (prefixRE.test(key) || key === 'NODE_ENV') {
env[key] = JSON.stringify(process.env[key])
}
})

View File

@@ -28,6 +28,7 @@
"chalk": "^2.3.0",
"cross-spawn": "^5.1.0",
"css-loader": "^0.28.7",
"dotenv": "^4.0.0",
"express-open-in-editor": "^3.1.1",
"extract-text-webpack-plugin": "^3.0.2",
"file-loader": "^1.1.6",

View File

@@ -1,4 +1,5 @@
const chalk = require('chalk')
const readline = require('readline')
const padStart = require('string.prototype.padstart')
const { logWithSpinner, stopSpinner } = require('./spinner')
@@ -34,9 +35,10 @@ exports.error = (msg) => {
exports.clearConsole = title => {
if (process.stdout.isTTY) {
process.stdout.write(
process.platform === 'win32' ? '\x1Bc' : '\x1B[2J\x1B[3J\x1B[H'
)
const blank = '\n'.repeat(process.stdout.rows)
console.log(blank)
readline.cursorTo(process.stdout, 0, 0)
readline.clearScreenDown(process.stdout)
if (title) {
console.log(title)
}

View File

@@ -21,6 +21,7 @@
"dependencies": {
"chalk": "^2.3.0",
"ora": "^1.3.0",
"readline": "^1.3.0",
"string.prototype.padstart": "^3.0.0"
},
"publishConfig": {

View File

@@ -44,7 +44,7 @@ module.exports = class Creator {
// prompt
clearConsole()
const answers = await inquirer.prompt(this.resolveFinalPrompts())
debug('answers')(answers)
debug('vue:cli-answers')(answers)
let options
if (answers.mode === 'saved') {
@@ -71,7 +71,7 @@ module.exports = class Creator {
projectName: name
}
debug('options')(options)
debug('vue:cli-ptions')(options)
// write base package.json to disk
clearConsole()
@@ -204,7 +204,7 @@ module.exports = class Creator {
this.injectedPrompts,
this.outroPrompts
)
debug('prompts')(prompts)
debug('vue:cli-prompts')(prompts)
return prompts
}

View File

@@ -42,13 +42,13 @@ module.exports = class Generator {
}, {})
this.pkg.dependencies = sortDeps(this.pkg.dependencies)
this.pkg.devDependencies = sortDeps(this.pkg.devDependencies)
debug('pkg')(this.pkg)
debug('vue:cli-pkg')(this.pkg)
}
async resolveFiles () {
for (const middleware of this.fileMiddlewares) {
await middleware(this.files, ejs.render)
}
debug('files')(this.files)
debug('vue:cli-files')(this.files)
}
}

View File

@@ -2140,6 +2140,10 @@ dot-prop@^3.0.0:
dependencies:
is-obj "^1.0.0"
dotenv@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-4.0.0.tgz#864ef1379aced55ce6f95debecdce179f7a0cd1d"
duplexer3@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2"
@@ -5818,6 +5822,10 @@ readdirp@^2.0.0:
readable-stream "^2.0.2"
set-immediate-shim "^1.0.1"
readline@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/readline/-/readline-1.3.0.tgz#c580d77ef2cfc8752b132498060dc9793a7ac01c"
realpath-native@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-1.0.0.tgz#7885721a83b43bd5327609f0ddecb2482305fdf0"