Skip to content

Commit

Permalink
feat: support specify env mode (vitejs#235)
Browse files Browse the repository at this point in the history
  • Loading branch information
daychongyang committed May 25, 2020
1 parent 8f7ee38 commit db8b6b2
Show file tree
Hide file tree
Showing 11 changed files with 91 additions and 39 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ TODOs.md
temp
explorations
.idea
*.local
1 change: 1 addition & 0 deletions playground/.env
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
CUSTOM_ENV_VARIABLE=9527
EFFECTIVE_MODE_FILE_NAME=.env
1 change: 1 addition & 0 deletions playground/.env.development
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
EFFECTIVE_MODE_FILE_NAME=.env.development
1 change: 1 addition & 0 deletions playground/.env.production
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
EFFECTIVE_MODE_FILE_NAME=.env.production
8 changes: 6 additions & 2 deletions playground/TestEnv.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,21 @@
<p class="node-env">
<code>process.env.NODE_ENV: {{ NODE_ENV }}</code>
</p>
<p class="customize-env-variable">
<p class="custom-env-variable">
<code>process.env.CUSTOM_ENV_VARIABLE: {{ CUSTOM_ENV_VARIABLE }}</code>
</p>
<p class="effective-mode-file-name">
<code>process.env.EFFECTIVE_MODE_FILE_NAME: {{ EFFECTIVE_MODE_FILE_NAME }}</code>
</p>
</template>

<script>
export default {
data() {
return {
NODE_ENV: process.env.NODE_ENV,
CUSTOM_ENV_VARIABLE: process.env.CUSTOM_ENV_VARIABLE
CUSTOM_ENV_VARIABLE: process.env.CUSTOM_ENV_VARIABLE,
EFFECTIVE_MODE_FILE_NAME: process.env.EFFECTIVE_MODE_FILE_NAME
}
}
}
Expand Down
19 changes: 9 additions & 10 deletions src/node/build/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,18 +143,14 @@ export async function createBaseRollupPlugins(
* Bundles the app for production.
* Returns a Promise containing the build result.
*/
export async function build(options: BuildConfig = {}): Promise<BuildResult> {
export async function build(options: BuildConfig): Promise<BuildResult> {
if (options.ssr) {
return ssrBuild({
...options,
ssr: false // since ssrBuild calls build, this avoids an infinite loop.
})
}

const isTest = process.env.NODE_ENV === 'test'
process.env.NODE_ENV = 'production'
const start = Date.now()

const {
root = process.cwd(),
base = '/',
Expand All @@ -173,9 +169,14 @@ export async function build(options: BuildConfig = {}): Promise<BuildResult> {
silent = false,
sourcemap = false,
shouldPreload = null,
env = {}
env = {},
mode
} = options

const isTest = process.env.NODE_ENV === 'test'
process.env.NODE_ENV = mode
const start = Date.now()

let spinner: Ora | undefined
const msg = 'Building for production...'
if (!silent) {
Expand Down Expand Up @@ -204,7 +205,7 @@ export async function build(options: BuildConfig = {}): Promise<BuildResult> {

const basePlugins = await createBaseRollupPlugins(root, resolver, options)

env.NODE_ENV = 'production'
env.NODE_ENV = mode!
const envReplacements = Object.keys(env).reduce((replacements, key) => {
replacements[`process.env.${key}`] = JSON.stringify(env[key])
return replacements
Expand Down Expand Up @@ -380,9 +381,7 @@ export async function build(options: BuildConfig = {}): Promise<BuildResult> {
* - Imports to dependencies are compiled into require() calls
* - Templates are compiled with SSR specific optimizations.
*/
export async function ssrBuild(
options: BuildConfig = {}
): Promise<BuildResult> {
export async function ssrBuild(options: BuildConfig): Promise<BuildResult> {
const {
rollupInputOptions,
rollupOutputOptions,
Expand Down
27 changes: 20 additions & 7 deletions src/node/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ import path from 'path'
import chalk from 'chalk'
import { UserConfig, resolveConfig } from './config'

const command = argv._[0]
const defaultMode = command === 'build' ? 'production' : 'development'

function logHelp() {
console.log(`
Usage: vite [command] [args] [--options]
Expand All @@ -37,6 +40,7 @@ Options:
--sourcemap [boolean] output source maps for build (default: false)
--minify [boolean | 'terser' | 'esbuild'] enable/disable minification, or specify
minifier to use. (default: 'terser')
--mode, -m [string] specify env mode (default: 'development' for dev, 'production' for build)
--ssr [boolean] build for server-side rendering
--jsx ['vue' | 'preact' | 'react'] choose jsx preset (default: 'vue')
--jsx-factory [string] (default: React.createElement)
Expand All @@ -46,15 +50,18 @@ Options:

console.log(chalk.cyan(`vite v${require('../package.json').version}`))
;(async () => {
if (argv.help || argv.h) {
const { help, h, mode, m, version, v } = argv

if (help || h) {
logHelp()
return
} else if (argv.version || argv.v) {
} else if (version || v) {
// noop, already logged
return
}

const options = await resolveOptions()
const envMode = mode || m || defaultMode
const options = await resolveOptions(envMode)
if (!options.command || options.command === 'serve') {
runServe(options)
} else if (options.command === 'build') {
Expand All @@ -67,7 +74,9 @@ console.log(chalk.cyan(`vite v${require('../package.json').version}`))
}
})()

async function resolveOptions() {
async function resolveOptions(mode: string) {
// specify env mode
argv.mode = mode
// shorthand for serviceWorker option
if (argv['sw']) {
argv.serviceWorker = argv['sw']
Expand All @@ -94,11 +103,15 @@ async function resolveOptions() {
}
// normalize root
// assumes all commands are in the form of `vite [command] [root]`
if (argv._[1] && !argv.root) {
argv.root = path.isAbsolute(argv._[1]) ? argv._[1] : path.resolve(argv._[1])
if (!argv.root && argv._[1]) {
argv.root = argv._[1]
}

if (argv.root) {
argv.root = path.isAbsolute(argv.root) ? argv.root : path.resolve(argv.root)
}

const userConfig = await resolveConfig(argv.config || argv.c)
const userConfig = await resolveConfig(mode, argv.config || argv.c)
if (userConfig) {
return {
...userConfig,
Expand Down
63 changes: 47 additions & 16 deletions src/node/config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import path from 'path'
import fs from 'fs-extra'
import chalk from 'chalk'
import { DotenvParseOutput } from 'dotenv'
import dotenv, { DotenvParseOutput } from 'dotenv'
import { Options as RollupPluginVueOptions } from 'rollup-plugin-vue'
import { CompilerOptions } from '@vue/compiler-sfc'
import Rollup, {
Expand Down Expand Up @@ -84,9 +84,13 @@ export interface SharedConfig {
fragment?: string
}
/**
* Environment variables .
* Environment variables
*/
env?: DotenvParseOutput
/**
* Environment mode
*/
mode?: string
}

export interface ServerConfig extends SharedConfig {
Expand Down Expand Up @@ -252,10 +256,18 @@ export interface Plugin
| 'rollupOutputOptions'
> {}

export type ResolvedConfig = UserConfig & { __path?: string }
export type ResolvedConfig = UserConfig & {
/**
* Path of config file.
*/
__path?: string
}

const debug = require('debug')('vite:config')

export async function resolveConfig(
configPath: string | undefined
mode: string,
configPath?: string
): Promise<ResolvedConfig | undefined> {
const start = Date.now()
const cwd = process.cwd()
Expand Down Expand Up @@ -333,19 +345,11 @@ export async function resolveConfig(
}

// load environment variables
const envConfigPath = path.resolve(cwd, '.env')
if (fs.existsSync(envConfigPath) && fs.statSync(envConfigPath).isFile()) {
const env = require('dotenv').config()
if (env.error) {
throw env.error
}

config.env = env.parsed
}
const env = loadEnv(mode, cwd)
debug(`env: %O`, env)
config.env = env

require('debug')('vite:config')(
`config resolved in ${Date.now() - start}ms`
)
debug(`config resolved in ${Date.now() - start}ms`)

config.__path = resolvedPath
return config
Expand Down Expand Up @@ -409,3 +413,30 @@ function resolvePlugin(config: UserConfig, plugin: Plugin): UserConfig {
}
}
}

function loadEnv(mode: string, cwd: string): Record<string, string> {
debug(`env mode: ${mode}`)
const { resolve } = path
const envFiles = [
/** default file */ resolve(cwd, '.env'),
/** local file */ resolve(cwd, `.env.local`),
/** mode file */ resolve(cwd, `.env.${mode}`),
/** mode local file */ resolve(cwd, `.env.${mode}.local`)
]

const env: Record<string, string> = {}
for (const file of envFiles) {
if (fs.existsSync(file) && fs.statSync(file).isFile()) {
const result = dotenv.config({
debug: !!process.env.DEBUG,
path: file
})
if (result.error) {
throw result.error
}
Object.assign(env, result.parsed)
}
}

return env
}
2 changes: 1 addition & 1 deletion src/node/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export interface ServerPluginContext {
config: ServerConfig & { __path?: string }
}

export function createServer(config: ServerConfig = {}): Server {
export function createServer(config: ServerConfig): Server {
const {
root = process.cwd(),
configureServer = [],
Expand Down
5 changes: 3 additions & 2 deletions src/node/server/serverPluginHtml.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,16 @@ export const htmlRewritePlugin: ServerPlugin = ({
}) => {
// inject __DEV__ and process.env.NODE_ENV flags
// since some ESM builds expect these to be replaced by the bundler
const { env = {} } = config
const { env = {}, mode } = config

const devInjectionCode =
`\n<script type="module">\n` +
`import "${hmrClientPublicPath}"\n` +
`window.__DEV__ = true\n` +
`window.__BASE__ = '/'\n` +
`window.process = { env: ${JSON.stringify({
...env,
NODE_ENV: 'development'
NODE_ENV: mode
})}}\n` +
`</script>\n`

Expand Down
2 changes: 1 addition & 1 deletion test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ describe('vite', () => {
expect(await getText('.node-env')).toMatch(
`process.env.NODE_ENV: ${isBuild ? 'production' : 'development'}`
)
expect(await getText('.customize-env-variable')).toMatch(
expect(await getText('.custom-env-variable')).toMatch(
'process.env.CUSTOM_ENV_VARIABLE: 9527'
)
})
Expand Down

0 comments on commit db8b6b2

Please sign in to comment.