Webpack:process.env 使用 DefinePlugin 和 DotEnv 未定义
Webpack: process.env undefined using DefinePlugin and DotEnv
我想从我的 .env 文件中获取我的变量,但我总是得到 undefined
这是我的js代码:
require('dotenv').config();
class Header extends React.Component{
constructor(props){...}
render(){
console.log("NODE ENV", process.env.NODE_ENV);
console.log("REACT_APP_MYAPP", process.env.REACT_APP_MYAPP);
...
}
}
这会打印:
NODE_ENV development
REACT_APP_MYAPP undefined
在我的 package.json 中有:
"scripts":{
"start" : "webpack-dev-server --config webpack.dev.js",
"build" : "webpack --config webpack.prod.js"
}
在我的 webpack.dev.js 中:
const webpack = require("webpack");
const merge = require("webpack-merge");
const path = require("path");
const common = require("./webpack.common.js");
module.exports = merge.smart(common, {
devServer: {
contentBase: path.resolve(__dirname, "dist"),
hot: true,
overlay: {
warnings: true,
errors: true
},
inline :true,
historyApiFallback: true,
port: 8085
},
devtool: "inline-sourcemap",
optimization: {
namedModules: true
},
plugins: [
new webpack.HotModulReplacementPlugin(),
new webpack.DefinePlugin({
"process.env.NODE_ENV": JSON.stringify("development"),
"process.env.REACT_APP_MYAPP": JSON.stringify(process.env.REACT_APP_MYAPP)
})
],
mode: "development"
});
然后我将 .env 文件放在项目的根目录下,在 webpack.dev.js 和 package.json 旁边:
REACT_APP_MYAPP=http://localhost:8080/
所以我认为,获取文件中的变量并没有成功。
请问如何在代码中获取 REACT_APP_MYAPP 值?
有几种方法可以完成这项工作。
最简单的测试方法是将 "start" : "webpack-dev-server --config webpack.dev.js",
更改为 "start" : "REACT_APP_MYAPP=http://localhost:8080/ node webpack-dev-server --config webpack.dev.js",
这将注入环境变量,它将在 webpack 构建过程中可用。每当使用 npm
或 node
到 运行 命令时,您都可以使用此技术。例如,NODE_ENV='development REACT_MY_APP=http://localhost:8080/ node myapp.js
两者都将在 process.env
.
上可用
您也可以在 webpack.dev.js
中调用 require('dotenv').config()
文件。然后它将在您使用 DefinePlugin 期间设置。
通常,您不会使用 npm start
命令来 运行 您的开发服务器。
随着应用程序的增长,您应该查看 Webpack Environment Plugin。然后您可以将 .env 用于 "production" 构建设置,在生产环境中需要它 webpack.prod.js,同时使用插件设置您的 default/fallback 环境变量。
在开始时添加 REACT_APP_MYAPP 的第一个解决方案无效。
但第二种解决方案有效。
解决方案:
在我的 webpack.dev.js
中添加 require('dotenv').config()
文件并替换:
new webpack.DefinePlugin({
"process.env.NODE_ENV": JSON.stringify("development"),
"process.env.REACT_APP_MYAPP": JSON.stringify(process.env.REACT_APP_MYAPP)
})
与
new webpack.EnvironmentPlugin(['NODE_ENV', 'REACT_APP_MYAPP']);
谢谢!
它在我的自定义 React 应用程序模型中对我有用,前提是我不在变量名称中包含 'REACT_APP_':
在webpack.config.js中:
// Node import
const path = require('path');
const webpack = require('webpack');
require('dotenv').config();
module.exports = [
plugins: [
new webpack.EnvironmentPlugin(['NODE_ENV', 'API'])
],
]
在 .env 中:
NODE_ENV=development
API=http://localhost:5000
当我部署应用程序时(例如在 Netlify 上),我从生产环境变量中排除了 NODE_ENV。
穿越这个又深又黑的兔子洞,你会发现以下事实:
- Webpack 5 不再提供
process
或 other Node.js variables.
DefinePlugin
的角色需要重新定义。
- 传递给
DefinePlugin
的值必须是 stringified,即使它们是字符串。
EnvironmentPlugin
给定 Webpack 5 让事情变得更加混乱。
process.env
并不是您真正应该在前端使用的东西。
- 您可以使用 polyfills to re-add
process
and others back in, but there is a reason it's no longer available.
- dotenv-wepack 既不是必需的,也不是可行的方法。
- 使用
process.env
的原因是全局访问变量。但这是错误航班上的乘客。我们可以放弃它,而是直接访问预期的变量:
plugins: [
new DefinePlugin({
// With dotenv (values must be stringified)
...Object.entries(dotenv.config().parsed).reduce((acc, curr) => ({...acc, [`${curr[0]}`]: JSON.stringify(curr[1]) }), {}),
// Without dotenv
'myString': JSON.stringify('IAmAString')
})
]
在前端:
declare var myString: string;
console.log(myString); // 'IAmAString'
如果你有多个带有变量的对象,那么抽象字符串化是有意义的:
// Create a function to stringify values
function stringifyValues(object: {[key: string]: any;}){
return Object.entries(object).reduce((acc, curr) => ({...acc, [`${curr[0]}`]: JSON.stringify(curr[1]) }), {} as { [key: string]: string; });
}
// use with DefinePlugin
plugins: [
new DefinePlugin({
...stringifyValues(dotenv.config().parsed),
...stringifyValues(dotenv.config({ path: '/.env.special' }).parsed),
'myObject': stringifyValues({
name: 'Object',
description: 'to be an object'
})
})
]
如果您真的想要访问process.env
:
plugins: [
new DefinePlugin({
// this might expose confidential data about your environment
'process.env': JSON.stringify(process.env),
// the correct way
'process.env.USERNAME': JSON.stringify('Donald Hump')
})
]
在前端:
declare var process: any;
console.log(process) // will NOT work, because process hasn't been injected
console.log(process.env); // will work but risky
console.log(process.env.USERNAME); // correct: 'Donald Hump'
我想从我的 .env 文件中获取我的变量,但我总是得到 undefined
这是我的js代码:
require('dotenv').config();
class Header extends React.Component{
constructor(props){...}
render(){
console.log("NODE ENV", process.env.NODE_ENV);
console.log("REACT_APP_MYAPP", process.env.REACT_APP_MYAPP);
...
}
}
这会打印:
NODE_ENV development
REACT_APP_MYAPP
undefined
在我的 package.json 中有:
"scripts":{
"start" : "webpack-dev-server --config webpack.dev.js",
"build" : "webpack --config webpack.prod.js"
}
在我的 webpack.dev.js 中:
const webpack = require("webpack");
const merge = require("webpack-merge");
const path = require("path");
const common = require("./webpack.common.js");
module.exports = merge.smart(common, {
devServer: {
contentBase: path.resolve(__dirname, "dist"),
hot: true,
overlay: {
warnings: true,
errors: true
},
inline :true,
historyApiFallback: true,
port: 8085
},
devtool: "inline-sourcemap",
optimization: {
namedModules: true
},
plugins: [
new webpack.HotModulReplacementPlugin(),
new webpack.DefinePlugin({
"process.env.NODE_ENV": JSON.stringify("development"),
"process.env.REACT_APP_MYAPP": JSON.stringify(process.env.REACT_APP_MYAPP)
})
],
mode: "development"
});
然后我将 .env 文件放在项目的根目录下,在 webpack.dev.js 和 package.json 旁边:
REACT_APP_MYAPP=http://localhost:8080/
所以我认为,获取文件中的变量并没有成功。
请问如何在代码中获取 REACT_APP_MYAPP 值?
有几种方法可以完成这项工作。
最简单的测试方法是将 "start" : "webpack-dev-server --config webpack.dev.js",
更改为 "start" : "REACT_APP_MYAPP=http://localhost:8080/ node webpack-dev-server --config webpack.dev.js",
这将注入环境变量,它将在 webpack 构建过程中可用。每当使用 npm
或 node
到 运行 命令时,您都可以使用此技术。例如,NODE_ENV='development REACT_MY_APP=http://localhost:8080/ node myapp.js
两者都将在 process.env
.
您也可以在 webpack.dev.js
中调用 require('dotenv').config()
文件。然后它将在您使用 DefinePlugin 期间设置。
通常,您不会使用 npm start
命令来 运行 您的开发服务器。
随着应用程序的增长,您应该查看 Webpack Environment Plugin。然后您可以将 .env 用于 "production" 构建设置,在生产环境中需要它 webpack.prod.js,同时使用插件设置您的 default/fallback 环境变量。
在开始时添加 REACT_APP_MYAPP 的第一个解决方案无效。 但第二种解决方案有效。
解决方案:
在我的 webpack.dev.js
中添加 require('dotenv').config()
文件并替换:
new webpack.DefinePlugin({
"process.env.NODE_ENV": JSON.stringify("development"),
"process.env.REACT_APP_MYAPP": JSON.stringify(process.env.REACT_APP_MYAPP)
})
与
new webpack.EnvironmentPlugin(['NODE_ENV', 'REACT_APP_MYAPP']);
谢谢!
它在我的自定义 React 应用程序模型中对我有用,前提是我不在变量名称中包含 'REACT_APP_':
在webpack.config.js中:
// Node import
const path = require('path');
const webpack = require('webpack');
require('dotenv').config();
module.exports = [
plugins: [
new webpack.EnvironmentPlugin(['NODE_ENV', 'API'])
],
]
在 .env 中:
NODE_ENV=development
API=http://localhost:5000
当我部署应用程序时(例如在 Netlify 上),我从生产环境变量中排除了 NODE_ENV。
穿越这个又深又黑的兔子洞,你会发现以下事实:
- Webpack 5 不再提供
process
或 other Node.js variables. DefinePlugin
的角色需要重新定义。- 传递给
DefinePlugin
的值必须是 stringified,即使它们是字符串。 EnvironmentPlugin
给定 Webpack 5 让事情变得更加混乱。process.env
并不是您真正应该在前端使用的东西。- 您可以使用 polyfills to re-add
process
and others back in, but there is a reason it's no longer available. - dotenv-wepack 既不是必需的,也不是可行的方法。
- 使用
process.env
的原因是全局访问变量。但这是错误航班上的乘客。我们可以放弃它,而是直接访问预期的变量:
plugins: [
new DefinePlugin({
// With dotenv (values must be stringified)
...Object.entries(dotenv.config().parsed).reduce((acc, curr) => ({...acc, [`${curr[0]}`]: JSON.stringify(curr[1]) }), {}),
// Without dotenv
'myString': JSON.stringify('IAmAString')
})
]
在前端:
declare var myString: string;
console.log(myString); // 'IAmAString'
如果你有多个带有变量的对象,那么抽象字符串化是有意义的:
// Create a function to stringify values
function stringifyValues(object: {[key: string]: any;}){
return Object.entries(object).reduce((acc, curr) => ({...acc, [`${curr[0]}`]: JSON.stringify(curr[1]) }), {} as { [key: string]: string; });
}
// use with DefinePlugin
plugins: [
new DefinePlugin({
...stringifyValues(dotenv.config().parsed),
...stringifyValues(dotenv.config({ path: '/.env.special' }).parsed),
'myObject': stringifyValues({
name: 'Object',
description: 'to be an object'
})
})
]
如果您真的想要访问process.env
:
plugins: [
new DefinePlugin({
// this might expose confidential data about your environment
'process.env': JSON.stringify(process.env),
// the correct way
'process.env.USERNAME': JSON.stringify('Donald Hump')
})
]
在前端:
declare var process: any;
console.log(process) // will NOT work, because process hasn't been injected
console.log(process.env); // will work but risky
console.log(process.env.USERNAME); // correct: 'Donald Hump'