UNPKG

3.12 kBJavaScriptView Raw
1'use strict'
2
3const fs = require('fs')
4const { ensureSlash } = require('@mara/devkit')
5const paths = require('./paths')
6
7const NODE_ENV = process.env.NODE_ENV
8
9if (!NODE_ENV) {
10 throw new Error(
11 'The NODE_ENV environment variable is required but was not specified.'
12 )
13}
14
15function loadDotEnv() {
16 // https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use
17 const dotenvFiles = [
18 `${paths.dotenv}.${NODE_ENV}.local`,
19 `${paths.dotenv}.${NODE_ENV}`,
20 // Don't include `.env.local` for `test` environment
21 // since normally you expect tests to produce the same
22 // results for everyone
23 NODE_ENV !== 'test' && `${paths.dotenv}.local`,
24 paths.dotenv
25 ].filter(Boolean)
26
27 // merge .env* 文件中的环境变量
28 // dotenv 永远不会覆盖已经存在的环境变量
29 // 对于环境中已存在的同名变量,dotenv 会略过设置
30 // https://github.com/motdotla/dotenv
31 // https://github.com/motdotla/dotenv-expand
32 dotenvFiles.forEach(dotenvFile => {
33 if (fs.existsSync(dotenvFile)) {
34 require('dotenv-expand')(
35 require('dotenv').config({
36 // 使用自定义路径
37 path: dotenvFile
38 })
39 )
40 }
41 })
42}
43
44function loadBrowserslist() {
45 const browserslist = require('browserslist')
46
47 // https://github.com/ai/browserslist/blob/master/node.js
48 if (!browserslist.findConfig(paths.app)) {
49 // 默认浏览器配置,移动为先
50 process.env.BROWSERSLIST = [
51 '> 1%',
52 'last 4 versions',
53 'ios >= 8',
54 'android >= 4.1',
55 'not ie < 9'
56 ]
57 }
58}
59
60function getMaraEnv(baseEnv) {
61 // 为防止环境变量混淆,自定义变量需以 MARA_ 作为前缀
62 const maraPrefix = /^MARA_/i
63
64 return (
65 Object.keys(process.env)
66 // 收集当前环境中的自定义环境变量
67 .filter(key => maraPrefix.test(key))
68 .reduce((env, key) => {
69 env[key] = process.env[key]
70
71 return env
72 }, baseEnv)
73 )
74}
75
76function stringify(raw) {
77 return Object.keys(raw).reduce((env, key) => {
78 env[key] = JSON.stringify(raw[key])
79
80 return env
81 }, {})
82}
83
84function getEnv({ publicPath, deployEnv, globalEnv = {}, version }) {
85 // NODE_ENV,PUBLIC_URL 放在 assign 尾部
86 // 防止被用户覆盖
87 const baseEnv = Object.assign({}, globalEnv, {
88 // 标识开发与生产环境
89 // React 内部依赖此变量
90 NODE_ENV: process.env.NODE_ENV || 'development',
91 // 命令行获取的 env 具有最高优先级
92 DEPLOY_ENV: deployEnv,
93 VERSION: version,
94 // 公共资源路径,去除尾 /
95 // 在 js 内,以 process.env.PUBLIC_URL 变量存在
96 // html 中可使用 %PUBLIC_URL% 占位符
97 // 例:<img src="%PUBLIC_URL%/img/logo.png">
98 PUBLIC_URL: ensureSlash(publicPath, false)
99 })
100
101 const raw = getMaraEnv(baseEnv)
102
103 // DefinePlugin 需要传入序列化参数值
104 const stringified = {
105 'process.env': stringify(raw)
106 }
107
108 // raw 给 InterpolateHtmlPlugin 插件使用
109 return { raw, stringified }
110}
111
112loadDotEnv()
113
114// browserslist 供 babel-preset-env,postcss-env 使用
115loadBrowserslist()
116
117module.exports = getEnv