Wepback - include script tag if environment is set up for production
My problem is this
https://github.com/petehunt/webpack-howto/issues/46
or - how do I get webpack to include a script tag in HTML based on my environment? I only need a script tag to be included if I'm running in production.
This is what my current webpack file looks like (I am using webpack 2).
const webpack = require('webpack');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const VENDOR_LIBS = [
'axios', 'react', 'react-dom', 'react-router', 'react-apollo', 'prop-types'
];
module.exports = {
entry: {
bundle: './client/src/index.js',
vendor: VENDOR_LIBS
},
output: {
path: path.join(__dirname, 'dist'),
publicPath: '/',
filename: '[name].[chunkhash].js'
},
module: {
rules: [
{
use: 'babel-loader',
test: /\.js$/,
exclude: /node_modules/
},
{
test: /\.scss$/,
use: [{
loader: "style-loader"
}, {
loader: "css-loader"
}, {
loader: "sass-loader"
}]
},
{
test: /\.(jpe?g|png|gif|svg|)$/,
use: [
{
loader: 'url-loader',
options: {limit: 40000}
},
'image-webpack-loader'
]
}
]
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
names: ['vendor', 'manifest']
}),
new HtmlWebpackPlugin({
template: './client/src/index.html'
})
]
};
source to share
Webpack always looks for a file webpack.config.js
, so you have to do the following configurations to make it dynamic:
package.json
"dev": "webpack-dev-server --env=dev",
"prod": webpack -p --env=prod
webpack.config.js
module.exports = function(env) {
return require(`./webpack.${env}.js`)
}
Setting the flag --env=[env]
is the key.
Then I had two different webpack files. One is called wepback.dev.js
and one is called webpack.prod.js
. Based on the team package.json
, it will always work. Then I created two different index.html files - index.prod.html
and index.dev.html
. Inside these, I have included any scripts I need for each environment.
I am using webpack 2. In each of the files, my scope plugins
looks like this:
webpack.dev.js
plugins: [
new webpack.optimize.CommonsChunkPlugin({
names: ['vendor', 'manifest']
}),
new HtmlWebpackPlugin({
template: './client/src/index.dev.html'
})
]
As you can see in this example mine webpack.dev.js
outputs everything to my file index.dev.html
. The prod version will look the same except for using prod
. To see the complete file webpack
, see the original post.
source to share
Since the Webpack config file returns a JS object , you can add a conditional statement (based on your environment or webpack variables) to add further element to the propertyentry
before returning / exporting the config object.
const myWebpackConfig = {
entry: {
bundle: './client/src/index.js',
vendor: VENDOR_LIBS
}
};
if( /* production env, it depends on your */) {
myWebpackConfig.entry.productionScript = './my-production-script.js',
}
// Return config object
module.exports = myWebpackConfig;
An even more flexible approach consists of exporting a config function instead of an object and specifying a custom runtime key using an argument --env
, for example --env.production
when your command is webpack
:
//my-webpack-config.js
// Configuration stuff...
module.exports = function(env) {
// env is the "--env" argument your specified with webpack command
if(env.production) {
// Add your production scripts
}
return myWebpackConfig;
}
And then, when running webpack:
webpack --config ./my-webpack-config.js --env.production
A few tips for customizing your webpack configuration:
- Webpack-merge : merge webpack config objects
- Webpack: Build for Production
source to share