Files
bedrock/webpack.config.js
2016-03-30 10:03:18 -04:00

232 lines
5.9 KiB
JavaScript

// External dependencies
var webpack = require('webpack'),
path = require('path'),
argv = require('minimist')(process.argv.slice(2)),
qs = require('qs'),
autoprefixer = require('autoprefixer'),
Clean = require("clean-webpack-plugin"),
AssetsPlugin = require('assets-webpack-plugin'),
ExtractTextPlugin = require('extract-text-webpack-plugin'),
OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin'),
cssnano = require('cssnano');
// Internal dependencies
var config = require('./assets/config');
// Internal variables
var scriptsFilename = (argv.release) ? 'scripts/[name]_[hash].js' : 'scripts/[name].js',
stylesFilename = (argv.release) ? 'styles/[name]_[hash].css' : 'styles/[name].css',
sourceMapQueryStr = (argv.release) ? '-sourceMap' : '+sourceMap',
jsLoader,
webpackConfig;
jsLoader = {
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
loaders: [ 'babel?presets[]=es2015&cacheDirectory' ]
};
if (argv.watch) { // '--watch' to add monkey-hot
jsLoader.loaders.unshift('monkey-hot');
}
/**
* Process AssetsPlugin output and format it
* for Sage: {"[name].[ext]":"[name]_[hash].[ext]"}
* @param {Object} assets passed by processOutput
* @return {String} JSON
*/
var assetsPluginProcessOutput = function (assets) {
var name,
ext,
filename,
results = {};
for (name in assets) {
if (assets.hasOwnProperty(name)) {
if (path.extname(assets[name]) === '') {
for (ext in assets[name]) {
if (assets[name].hasOwnProperty(ext)) {
filename = name + '.' + ext;
results[filename] = path.basename(assets[name][ext]);
}
}
}
}
}
return JSON.stringify(results);
}
/**
* Loop through webpack entry
* and add the hot middleware
* @param {Object} entry webpack entry
* @return {Object} entry with hot middleware
*/
var addHotMiddleware = function (entry) {
var name,
results = {},
hotMiddlewareScript = 'webpack-hot-middleware/client?' + qs.stringify({
timeout: 20000,
reload: true
});
for (name in entry) {
if (entry.hasOwnProperty(name)) {
if (entry[name] instanceof Array !== true) {
results[name] = [entry[name]];
} else {
results[name] = entry[name].slice(0);
}
results[name].push(hotMiddlewareScript);
}
}
return results;
}
webpackConfig = {
context: path.resolve(config.context),
entry: config.entry,
output: {
path: path.join(__dirname, config.output.path),
publicPath: config.output.publicPath,
filename: scriptsFilename
},
module: {
preLoaders: [
{
test: /\.js?$/,
exclude: /(node_modules|bower_components)/,
loader: 'eslint'
}
],
loaders: [
jsLoader,
{
test: /\.css$/,
loader: ExtractTextPlugin.extract('style', [
'css?' + sourceMapQueryStr,
'postcss'
])
},
{
test: /\.scss$/,
loader: ExtractTextPlugin.extract('style', [
'css?' + sourceMapQueryStr,
'postcss',
'resolve-url?' + sourceMapQueryStr,
'sass?' + sourceMapQueryStr
])
},
{
test: /\.(png|jpg|jpeg|gif)(\?.*)?$/,
loaders: [
'file?' + qs.stringify({
name: '[path][name].[ext]'
}),
'image-webpack?' + JSON.stringify({
bypassOnDebug:true,
progressive: true,
optimizationLevel: 7,
interlaced: true,
pngquant: {
quality: "65-90",
speed: 4
},
svgo: {
removeUnknownsAndDefaults: false,
cleanupIDs: false
}
})
]
},
{
test: /\.(ttf|eot|svg)(\?.*)?$/,
loader: 'file?' + qs.stringify({
name: '[path][name].[ext]'
})
},
{
test: /\.woff(2)?(\?.*)?$/,
loader: 'url?' + qs.stringify({
limit: 10000,
mimetype: "application/font-woff",
name: "[path][name].[ext]"
})
}
]
},
resolve: {
extensions: [ '', '.js', '.json' ],
modulesDirectories: [
'node_modules',
'bower_components'
]
},
externals: {
jquery: 'jQuery'
},
plugins: [
new Clean([config.output.path]),
new ExtractTextPlugin(stylesFilename, {
allChunks: true,
disable: (argv.watch === true) // '--watch' disable ExtractTextPlugin
}),
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery',
'window.Tether': 'tether'
})
],
postcss: [
autoprefixer({
browsers: [
'last 2 versions',
'android 4',
'opera 12'
]
})
],
eslint: {
failOnWarning: false,
failOnError: true
},
stats: {
colors: true
}
};
// '--watch' to push additional plugins to webpackConfig
if (argv.watch) {
webpackConfig.entry = addHotMiddleware(webpackConfig.entry);
webpackConfig.output.pathinfo = true;
webpackConfig.debug = true;
webpackConfig.devtool = '#cheap-module-source-map';
webpackConfig.plugins.push(new webpack.optimize.OccurenceOrderPlugin());
webpackConfig.plugins.push(new webpack.HotModuleReplacementPlugin());
webpackConfig.plugins.push(new webpack.NoErrorsPlugin());
}
// '--release' to push additional plugins to webpackConfig
if (argv.release) {
webpackConfig.plugins.push(new AssetsPlugin({
path: path.join(__dirname, config.output.path),
filename: 'assets.json',
fullPath: false,
processOutput: assetsPluginProcessOutput
}));
webpackConfig.plugins.push(new webpack.optimize.UglifyJsPlugin({
compress: {
'drop_debugger': true
}
}));
webpackConfig.plugins.push(new OptimizeCssAssetsPlugin({
cssProcessor: cssnano,
cssProcessorOptions: { discardComments: { removeAll: true } },
canPrint: true
}));
}
module.exports = webpackConfig;