Reputation: 8404
I'm running a React app with Webpack version 3.6.0, and I'm having trouble using the DefinePlugin
to set global variables - values that are set 'normally', as per the documentation are not available throughout the app... however, if I wrap values in an object named process.env
, the variables are available throughout the app, albeit with the prefix process.env
.
For example, here is what I'd like my DefinePlugin
to look like:
plugins: [
new Webpack.DefinePlugin({
"NODE_ENV": process.env.NODE_ENV ? JSON.stringify(process.env.NODE_ENV) : JSON.stringify("development"),
"SIGNUP_PATH": JSON.stringify("signup")
})
]
This does not work - trying to console.log(NODE_ENV)
or console.log(SIGNUP_PATH)
does nothing, the variables are undefined
.
Surprisingly (or maybe not, maybe there's just something I don't know), this works:
plugins: [
new Webpack.DefinePlugin({
"process.env": {
"NODE_ENV": process.env.NODE_ENV ? JSON.stringify(process.env.NODE_ENV) : JSON.stringify("development"),
"SIGNUP_PATH": JSON.stringify("signup")
}
})
]
and I can access the variables with console.log(process.env.NODE_ENV)
and console.log(process.env.SIGNUP_PATH)
, etc.
Why is it that I have to put everything into an object called process.env
in order to access it as I would a global? Am I doing something wrong here, or is there just something that I don't understand about this?
Upvotes: 0
Views: 1042
Reputation: 8404
Ultimately, this problem was due to the fact that I built my app to make use of server-side rendering - it needs two separate Webpack configs, but initially I was only including the DefinePlugin
settings on the client. Basically, I put everything for the DefinePlugin
into a separate file, imported it into both the client and server configs, and then bundled it into a final webpack.config.prod.js
for production (or a similar webpack.config.dev.js
for development... only production shown below). Here's how it all came together:
webpack_config.define-plugin-config.js
:
module.exports = {
"API_URL": process.env.API_URL ? JSON.stringify(process.env.API_URL) : JSON.stringify("http://localhost:4000/api/v1/"),
"SOME_OTHER_VAR": JSON.stringify("foo")
}
webpack.config.server.js
:
const Webpack = require("webpack"),
path = require("path"),
definePluginConfig = require("./webpack_config/define-plugin-config"),
rule_js = require("./webpack_config/rule"),
resolve = require("./webpack_config/resolve")
module.exports = {
"entry": {
"component": path.join(__dirname, "js/containers/index.jsx")
},
"output": {
"path": path.join(__dirname, "../priv/static/server/js"),
"filename": "app.js",
"library": "dl",
"libraryTarget": "commonjs2"
},
"module": {
"rules": [
rule_js
]
},
"resolve": resolve,
"plugins": [
new Webpack.DefinePlugin(definePluginConfig)
]
}
webpack.config.client.js
:
const Webpack = require("webpack"),
ExtractTextPlugin = require("extract-text-webpack-plugin"),
CopyPlugin = require("copy-webpack-plugin"),
path = require("path"),
definePluginConfig = require("./webpack_config/define-plugin-config"),
rule_js = require("./webpack_config/rule"),
resolve = require("./webpack_config/resolve")
module.exports = {
"entry": [
path.join(__dirname, "js/index.jsx"),
path.join(__dirname, "styles/index.scss")
],
"output": {
"path": path.join(__dirname, "../priv/static"),
"filename": "js/app.js",
"publicPath": "/"
},
"module": {
"rules": [
rule_js,
{
"test": /\.scss$/,
"use": ExtractTextPlugin.extract({
"fallback": "style-loader",
"use": ["css-loader", "sass-loader"]
})
},
{
"test": /\.css$/,
"use": ExtractTextPlugin.extract({
"fallback": "style-loader",
"use": ["css-loader?modules&importLoaders=1&localIdentName=[local]"]
})
}
]
},
"resolve": resolve,
"plugins": [
new Webpack.DefinePlugin(definePluginConfig),
new ExtractTextPlugin({
"filename": "css/app.css",
"allChunks": true
}),
new CopyPlugin([{ "from": path.join(__dirname, "static") }])
]
}
webpack.config.prod.js
:
const clientWebPackConfig = require("./webpack.config.client"),
serverWebPackConfig = require("./webpack.config.server"),
UglifyJsPlugin = require("uglifyjs-webpack-plugin"),
webpackConfig = [clientWebPackConfig, serverWebPackConfig],
uglifyJsPluginOptions = { "sourceMap": true }
webpackConfig[0].plugins = [...webpackConfig[0].plugins, new UglifyJsPlugin(uglifyJsPluginOptions)]
module.exports = webpackConfig
Upvotes: 0
Reputation: 1867
Here is a working example. Anywhere In my code I can reference __ API_URL __
require('dotenv').config({ path: `${__dirname}/src/.dev.env` });
const production = process.env.NODE_ENV === 'production';
const { DefinePlugin, EnvironmentPlugin } = require('webpack');
const HtmlPlugin = require('html-webpack-plugin');
const CleanPlugin = require('clean-webpack-plugin');
const UglifyPlugin = require('uglifyjs-webpack-plugin');
const ExtractPlugin = require('extract-text-webpack-plugin');
let plugins = [
new EnvironmentPlugin(['NODE_ENV']),
new ExtractPlugin('bundle-[hash].css'),
new HtmlPlugin({ template: `${__dirname}/src/index.html` }),
new DefinePlugin({
__DEBUG__: JSON.stringify(!production),
__API_URL__: JSON.stringify(process.env.API_URL),
__GOOGLE_CLIENT_ID__: JSON.stringify(process.env.GOOGLE_CLIENT_ID),
__AWS_ACCESS_KEY_ID__: JSON.stringify(process.env.AWS_ACCESS_KEY_ID),
__AWS_SECRET_ACCESS_KEY__: JSON.stringify(process.env.AWS_SECRET_ACCESS_KEY),
}),
];
Upvotes: 1