Skip to content

Instantly share code, notes, and snippets.

@tadjik1
Created December 25, 2015 14:02
Show Gist options
  • Save tadjik1/daeb32b3d1bf76b23360 to your computer and use it in GitHub Desktop.
Save tadjik1/daeb32b3d1bf76b23360 to your computer and use it in GitHub Desktop.
webpack.config.js
import path from 'path';
import webpack, { DefinePlugin, BannerPlugin } from 'webpack';
import merge from 'lodash/object/merge';
import autoprefixer from 'autoprefixer';
import ExtractTextPlugin from 'extract-text-webpack-plugin';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import minimist from 'minimist';
import { getTemplates } from './html';
const parameters = minimist(process.argv.slice(2))._;
const environment = parameters[0] || 'local';
const API = parameters[1] || 'http://dev-api.spbtv.com';
const DEBUG = environment === 'local';
const WATCH = global.WATCH === undefined ? false : global.WATCH;
const VERBOSE = process.argv.includes('verbose');
const STYLE_LOADER = 'style-loader';
const CSS_LOADER = DEBUG ? 'css-loader' : 'css-loader?minimize';
const SASS_LOADER = `${CSS_LOADER}!postcss-loader!sass-loader?indentedSyntax`;
const AUTOPREFIXER_BROWSERS = [
'Android 2.3',
'Android >= 4',
'Chrome >= 20',
'Firefox >= 24',
'Explorer >= 10',
'iOS >= 6',
'Opera >= 12',
'Safari >= 6'
];
const GLOBALS = {
'process.env.NODE_ENV': DEBUG ? '"development"' : '"production"',
'__DEV__': DEBUG,
'__API__': `"${API}"`,
'__ENV__': `"${environment}"`
};
//
// Common configuration chunk to be used for both
// client-side (app.js) and server-side (server.js) bundles
// -----------------------------------------------------------------------------
const JS_LOADER = {
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader'
};
const config = {
output: {
publicPath: '/',
sourcePrefix: ' '
},
cache: DEBUG,
debug: DEBUG,
stats: {
colors: true,
reasons: DEBUG,
hash: VERBOSE,
version: VERBOSE,
timings: true,
chunks: VERBOSE,
chunkModules: VERBOSE,
cached: VERBOSE,
cachedAssets: VERBOSE
},
plugins: [
new webpack.optimize.OccurenceOrderPlugin()
],
resolve: {
extensions: ['', '.webpack.js', '.web.js', '.js'],
modulesDirectories: ['web_modules', 'node_modules', 'shared']
},
module: {
preLoaders: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'eslint'
}
],
loaders: [
{
test: /\.json$/,
loader: 'json'
}, {
test: /\.(png|jpg|jpeg|gif|svg|woff|woff2)$/,
loader: 'url-loader?limit=10000&name=images/[hash].[ext]'
}, {
test: /\.(eot|ttf|wav|mp3)$/,
loader: 'file-loader'
},
{
test: /\.txt/,
loader: 'file?name=[path][name].[ext]'
}, {
test: /\.html/,
loader: 'html'
}
]
},
postcss: [
autoprefixer(AUTOPREFIXER_BROWSERS)
]
};
//
// Configuration for the client-side bundle (app.js)
// -----------------------------------------------------------------------------
const appConfig = merge({}, config, {
entry: [
...(WATCH ? ['webpack-hot-middleware/client'] : []),
'./src/scripts/client/index.js'
],
output: {
path: path.join(__dirname, '../build/public'),
filename: DEBUG ? 'javascript/client.js' : 'javascript/client.[chunkhash].js'
},
devtool: DEBUG ? 'cheap-module-eval-source-map' : 'source-map',
plugins: [
...config.plugins,
new DefinePlugin(merge({}, GLOBALS, {'__SERVER__': false})),
...(WATCH ? [
] : [
new ExtractTextPlugin('styles/styles.[chunkhash].css')
]),
...(DEBUG ? [] : [
new webpack.optimize.DedupePlugin(),
new webpack.optimize.UglifyJsPlugin({compress: {warnings: VERBOSE}}),
new webpack.optimize.AggressiveMergingPlugin(),
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
filename: 'javascript/vendor.[chunkhash].js',
minChunks: module => {
return module.resource &&
module.resource.indexOf(path.resolve(__dirname, '../node_modules')) === 0;
}
}),
new HtmlWebpackPlugin({
templateContent: () => {
const [indexHtml] = getTemplates();
return indexHtml;
},
filename: '../views/index.html'
}),
new HtmlWebpackPlugin({
templateContent: () => {
const [, nodeIndexHtml] = getTemplates();
return nodeIndexHtml;
},
filename: '../views/index-nodejs.html'
})
]),
...(WATCH ? [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin()
] : [])
],
module: {
loaders: [
...config.module.loaders,
(WATCH ? [{
test: /\.sass/,
loader: `${STYLE_LOADER}!${SASS_LOADER}`
}, {
...JS_LOADER,
query: {
'plugins': ['react-transform'],
'extra': {
'react-transform': {
'transforms': [{
'transform': 'react-transform-hmr',
'imports': ['react'],
'locals': ['module']
}, {
'transform': 'react-transform-catch-errors',
'imports': ['react', 'redbox-react']
}]
}
}
}
}] : [{
test: /\.sass/,
loader: ExtractTextPlugin.extract(SASS_LOADER)
}, JS_LOADER])
]
}
});
//
// Configuration for the server-side bundle (server.js)
// -----------------------------------------------------------------------------
const serverConfig = merge({}, config, {
entry: './src/scripts/server/index.js',
output: {
path: './build',
filename: 'server.js',
libraryTarget: 'commonjs2'
},
target: 'node',
externals: [
(context, request, cb) => {
const isExternal =
request.match(/^[a-z][-0-9a-z\.]*$/);
cb(null, Boolean(isExternal));
}
],
node: {
console: false,
global: false,
process: false,
Buffer: false,
__filename: false,
__dirname: false
},
devtool: DEBUG ? 'eval' : 'source-map',
plugins: [
...config.plugins,
new DefinePlugin(merge({}, GLOBALS, {'__SERVER__': true})),
new BannerPlugin('require("source-map-support").install();',
{raw: true, entryOnly: false})
],
module: {
loaders: [
...config.module.loaders,
{
...JS_LOADER,
query: {
'blacklist': ['regenerator', 'es6.spec.symbols']
}
},
{
test: /\.sass/,
loader: 'null-loader'
}
]
}
});
export default [appConfig, serverConfig];
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment