Skip to content

Instantly share code, notes, and snippets.

@sgentile
Created January 31, 2017 02:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sgentile/c142c08b043f9039037d9d37133df445 to your computer and use it in GitHub Desktop.
Save sgentile/c142c08b043f9039037d9d37133df445 to your computer and use it in GitHub Desktop.
Sample Webpack Config
const webpack = require('webpack');
const path = require('path');
// Webpack extensions
const CleanWebpackPlugin = require('clean-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const validate = require('webpack-validator');
// For production builds, additional steps are necessary.
const TARGET = process.env.npm_lifecycle_event;
const PRODUCTION = process.env.NODE_ENV === 'production';
console.log(PRODUCTION);
const ASSETS_LIMIT = 8192; // Threshold for generating inline base64 URLs
const COPYRIGHT_NOTICE = 'Copyright ' + new Date().getFullYear() + ' Your company name here. ALL RIGHTS RESERVED.';
// Define the source and destinations folders used for bundling.
const PATHS = {
src: path.join(__dirname, 'src'),
build: path.join(__dirname, 'dist')
};
const INDEX_TEMPLATE = path.join(PATHS.src, 'index.html');
const config = {
debug: !PRODUCTION,
devtool: PRODUCTION ? 'source-map' : 'eval-source-map',
entry: {
app: PATHS.src
},
output: {
path: PATHS.build,
filename: '[name]-[hash:5].js'
},
plugins: [
// Generate the index.html page from a template
new HtmlWebpackPlugin({
template: INDEX_TEMPLATE,
favicon: PATHS.src + '/favicon.ico'
})
// , new webpack.ProvidePlugin({
// $: "jquery",
// jQuery: "jquery",
// "window.jQuery": "jquery",
// "window.$": "jquery"
// })
],
module: {
preLoaders: [
// Perform linting prior to compilation.
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'eslint-loader'
}
],
loaders: [
// ES6 Javascript transpiling
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader'
},
// Less to CSS transpiling
{
test: /\.less$/,
include: PATHS.src,
loader: PRODUCTION ?
ExtractTextPlugin.extract('style', 'css!postcss!less')
: 'style!css!postcss!less'
},
// Raw CSS
{
test: /\.css$/,
include: PATHS.src,
loader: PRODUCTION ?
ExtractTextPlugin.extract('style', 'css!postcss')
: 'style!css!postcss'
},
{ test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/,
loader: 'url-loader?limit=10000&mimetype=application/font-woff'
},
{ test: /\.(eot|svg|ttf|jpg|png|gif)(\?v=\d+\.\d+\.\d+)?$/,
loader: 'file'
},
//this resolves where jquery.flot.resize references 'window' - in this context it should be 'this.window'
// {
// test: require.resolve("jquery-flot/jquery.flot.resize"),
// loader: "imports?this=>window"
// },
//used by the tests
{ test: /\.json$/, loader: 'json' }
]
},
postcss: [
// Handle cross-browser CSS prefixing
require('autoprefixer-core')
],
resolve: {
modulesDirectories: ['node_modules', 'src'],
extensions: ['', '.js']
}
};
if (PRODUCTION) {
// Add clean for 'build' directory.
// Development is served from memory and no clean-up needed.
config.plugins.unshift(
new CleanWebpackPlugin(
['dist'],{
verbose: true,
dry: false, // If true, reports intentions but won't delete.
root: __dirname
})
);
// For production builds, extract CSS into seperate file to
// avoid flash of unstyled content (FOUC). Use normal
// javascript loader in development to facilitate hot loading.
// Switch between environments is handled by disable flag.
config.plugins.push(
new ExtractTextPlugin(
'[name]-[hash:5].css',
{ allChunks: true }
)
),
// Add copyright to files.
config.plugins.push(
new webpack.BannerPlugin(COPYRIGHT_NOTICE)
);
// Optimize order of imported modules.
config.plugins.push(
new webpack.optimize.OccurrenceOrderPlugin()
);
// Optimization (reference: https://reactjsnews.com/how-to-make-your-react-apps-10x-faster)
config.plugins.push(
// A common mistake is not stringifying the "production" string.
new webpack.DefinePlugin(
{
'process.env.NODE_ENV': JSON.stringify('production'),
'__DEV__': JSON.stringify(false),
__VERSION__: JSON.stringify(require('./package.json').version)
})
);
// Dedupe code
config.plugins.push(
new webpack.optimize.DedupePlugin()
);
// Minify javascript
config.plugins.push(
new webpack.optimize.UglifyJsPlugin({
compress: {
// TODO: Not sure if this is a good idea. ReactJS has warnings
// but this setting may mask dead-code issues in app code.
warnings: false // turns off warnings when dead-code removed
}
})
);
}
else { /* DEVELOPMENT */
// Enable multi-pass compilation for enhanced performance
// in larger projects. Good default.
config.plugins.push(
new webpack.HotModuleReplacementPlugin({
multiStep: true
})
);
// Hide spurious errors caused during hot reloading.
config.plugins.push(
new webpack.NoErrorsPlugin()
);
config.plugins.push(
// A common mistake is not stringifying the "production" string.
new webpack.DefinePlugin(
{
'__DEV__': JSON.stringify(true),
__VERSION__: JSON.stringify(require('./package.json').version)
})
);
config.output = {
path: PATHS.build,
publicPath: 'http://localhost:8080/',
filename: '[name]-[hash:5].js'
};
config.devtool = 'inline-source-map';
config.devServer = {
// Root folder to server static content. If you copy
// your static content to the build folder, point it there instead.
//contentBase: PATHS.build,
contentBase: path.join(PATHS.src, 'assets'),
// Enable history API fallback so HTML5 History API based
// routing works.
historyApiFallback: true,
// Unlike the cli flag, this doesn't set HotModuleReplacementPlugin
hot: true,
inline: true,
host: process.env.HOST,
port: process.env.PORT,
proxy: {
'/config' : {
target: 'http://localhost:8085',
secure: false
},
'/feedback' : {
target: 'http://localhost:8085',
secure: false
}
},
// Display only errors to reduce the amount of output.
stats: 'errors-only'
};
}
// Always validate webpack configuration.
module.exports = validate(config);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment