Skip to content

Commit

Permalink
feat: support loading customize env variables from .env file (#223)
Browse files Browse the repository at this point in the history
close #213
  • Loading branch information
daychongyang authored May 22, 2020
1 parent 029de6b commit 89fe0a9
Show file tree
Hide file tree
Showing 9 changed files with 78 additions and 17 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
"chokidar": "^3.3.1",
"cssnano": "^4.1.10",
"debug": "^4.1.1",
"dotenv": "^8.2.0",
"es-module-lexer": "^0.3.18",
"esbuild": "^0.3.2",
"etag": "^1.8.1",
Expand Down
1 change: 1 addition & 0 deletions playground/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
CUSTOMIZE_ENV_VARIABLE=9527
9 changes: 4 additions & 5 deletions playground/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@
<p class="base">
<code>__BASE__: {{ base }}</code>
</p>
<p class="node_env">
<code>process.env.NODE_ENV: {{ env }}</code>
</p>
<TestEnv />
<h2>Async Component</h2>
<TestAsync />
<TestModuleResolve />
Expand All @@ -28,6 +26,7 @@

<script>
import { defineAsyncComponent } from 'vue'
import TestEnv from './TestEnv.vue'
import TestModuleResolve from './TestModuleResolve.vue'
import TestHmr from './TestHmr.vue'
import TestPostCss from './TestPostCss.vue'
Expand All @@ -45,10 +44,10 @@ import TestTransform from './TestTransform.vue'
export default {
data: () => ({
dev: __DEV__,
base: __BASE__,
env: process.env.NODE_ENV
base: __BASE__
}),
components: {
TestEnv,
TestModuleResolve,
TestHmr,
TestPostCss,
Expand Down
24 changes: 24 additions & 0 deletions playground/TestEnv.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<template>
<h2>Environment Variables</h2>
<p class="node-env">
<code>process.env.NODE_ENV: {{ NODE_ENV }}</code>
</p>
<p class="customize-env-variable">
<code>process.env.CUSTOMIZE_ENV_VARIABLE: {{ CUSTOMIZE_ENV_VARIABLE }}</code>
</p>
<p class="defined-variable-names">
<code>Defined environment variable names: {{ variableNames }}</code>
</p>
</template>

<script>
export default {
data() {
return {
NODE_ENV: process.env['NODE_ENV'],
CUSTOMIZE_ENV_VARIABLE: process.env.CUSTOMIZE_ENV_VARIABLE,
variableNames: Object.keys(process.env).join(",")
}
}
}
</script>
9 changes: 6 additions & 3 deletions src/node/build/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,8 @@ export async function build(options: BuildConfig = {}): Promise<BuildResult> {
minify = true,
silent = false,
sourcemap = false,
shouldPreload = null
shouldPreload = null,
env = {}
} = options

let spinner: Ora | undefined
Expand Down Expand Up @@ -213,8 +214,10 @@ export async function build(options: BuildConfig = {}): Promise<BuildResult> {
// Vue templates are compiled into js and included in chunks.
createReplacePlugin(
{
'process.env.NODE_ENV': '"production"',
'process.env.': `({}).`,
'process.env': `(${JSON.stringify({
...env,
NODE_ENV: 'production'
})})`,
__DEV__: 'false',
__BASE__: JSON.stringify(publicBasePath)
},
Expand Down
29 changes: 23 additions & 6 deletions src/node/config.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import path from 'path'
import fs from 'fs-extra'
import chalk from 'chalk'
import { createEsbuildPlugin } from './build/buildPluginEsbuild'
import { ServerPlugin } from './server'
import { Resolver } from './resolver'
import { DotenvParseOutput } from 'dotenv'
import { Options as RollupPluginVueOptions } from 'rollup-plugin-vue'
import { CompilerOptions } from '@vue/compiler-sfc'
import Rollup, {
InputOptions as RollupInputOptions,
OutputOptions as RollupOutputOptions,
OutputChunk
} from 'rollup'
import { createEsbuildPlugin } from './build/buildPluginEsbuild'
import { ServerPlugin } from './server'
import { Resolver } from './resolver'
import { Transform } from './transform'
import { DepOptimizationOptions } from './depOptimizer'
import { IKoaProxiesOptions } from 'koa-proxies'
Expand Down Expand Up @@ -82,6 +83,10 @@ export interface SharedConfig {
factory?: string
fragment?: string
}
/**
* Environment variables .
*/
env?: DotenvParseOutput
}

export interface ServerConfig extends SharedConfig {
Expand Down Expand Up @@ -253,17 +258,18 @@ export async function resolveConfig(
configPath: string | undefined
): Promise<ResolvedConfig | undefined> {
const start = Date.now()
const cwd = process.cwd()
let config: ResolvedConfig | undefined
let resolvedPath: string | undefined
let isTS = false
if (configPath) {
resolvedPath = path.resolve(process.cwd(), configPath)
resolvedPath = path.resolve(cwd, configPath)
} else {
const jsConfigPath = path.resolve(process.cwd(), 'vite.config.js')
const jsConfigPath = path.resolve(cwd, 'vite.config.js')
if (fs.existsSync(jsConfigPath)) {
resolvedPath = jsConfigPath
} else {
const tsConfigPath = path.resolve(process.cwd(), 'vite.config.ts')
const tsConfigPath = path.resolve(cwd, 'vite.config.ts')
if (fs.existsSync(tsConfigPath)) {
isTS = true
resolvedPath = tsConfigPath
Expand Down Expand Up @@ -326,6 +332,17 @@ 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
}

require('debug')('vite:config')(
`config resolved in ${Date.now() - start}ms`
)
Expand Down
9 changes: 7 additions & 2 deletions src/node/server/serverPluginHtml.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,21 @@ export const htmlRewritePlugin: ServerPlugin = ({
root,
app,
watcher,
resolver
resolver,
config
}) => {
// inject __DEV__ and process.env.NODE_ENV flags
// since some ESM builds expect these to be replaced by the bundler
const { env = {} } = config
const devInjectionCode =
`\n<script type="module">\n` +
`import "${hmrClientPublicPath}"\n` +
`window.__DEV__ = true\n` +
`window.__BASE__ = '/'\n` +
`window.process = { env: { NODE_ENV: 'development' }}\n` +
`window.process = { env: ${JSON.stringify({
...env,
NODE_ENV: 'development'
})}}\n` +
`</script>\n`

const scriptRE = /(<script\b[^>]*>)([\s\S]*?)<\/script>/gm
Expand Down
8 changes: 7 additions & 1 deletion test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,15 @@ describe('vite', () => {
test('env variables', async () => {
expect(await getText('.dev')).toMatch(`__DEV__: ${!isBuild}`)
expect(await getText('.base')).toMatch(`__BASE__: /`)
expect(await getText('.node_env')).toMatch(
expect(await getText('.node-env')).toMatch(
`process.env.NODE_ENV: ${isBuild ? 'production' : 'development'}`
)
expect(await getText('.customize-env-variable')).toMatch(
'process.env.CUSTOMIZE_ENV_VARIABLE: 9527'
)
expect(await getText('.defined-variable-names')).toMatch(
'Defined environment variable names: CUSTOMIZE_ENV_VARIABLE,NODE_ENV'
)
})

test('module resolving', async () => {
Expand Down
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2432,6 +2432,11 @@ dot-prop@^5.2.0:
dependencies:
is-obj "^2.0.0"

dotenv@^8.2.0:
version "8.2.0"
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a"
integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==

duplexer@0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1"
Expand Down

0 comments on commit 89fe0a9

Please sign in to comment.