Skip to content

Instantly share code, notes, and snippets.

@jasan-s
Created September 28, 2016 23:53
Show Gist options
  • Save jasan-s/1514be3b792cf75a5724292b1fa98951 to your computer and use it in GitHub Desktop.
Save jasan-s/1514be3b792cf75a5724292b1fa98951 to your computer and use it in GitHub Desktop.
import webpack from 'webpack'
import path from 'path'
import HtmlWebpackPlugin from 'html-webpack-plugin'
import autoprefixer from 'autoprefixer'
import ExtractTextPlugin from 'extract-text-webpack-plugin'
import SWPrecacheWebpackPlugin from 'sw-precache-webpack-plugin'
import CopyWebpackPlugin from 'copy-webpack-plugin'
import pkg from './package.json'
import manifest from './app/manifest.json'
import CleanWebpackPlugin from 'clean-webpack-plugin'
import FaviconsWebpackPlugin from 'favicons-webpack-plugin'
import WebpackMd5Hash from 'webpack-md5-hash'
import StatsPlugin from 'stats-webpack-plugin'
const LAUNCH_COMMAND = process.env.npm_lifecycle_event
let SWPrecacheHandleFetch // dynamic variable changed for production and dev
LAUNCH_COMMAND === 'production' ? SWPrecacheHandleFetch = true : SWPrecacheHandleFetch = false
const isProduction = LAUNCH_COMMAND === 'production'
process.env.BABEL_ENV = LAUNCH_COMMAND
const PATHS = {
root: path.join(__dirname),
app: path.join(__dirname, 'app'),
build: path.join(__dirname, 'dist')
}
// inserts link and scripts dependcies in to the generated index.html
const HTMLWebpackPluginConfig = new HtmlWebpackPlugin({
template: PATHS.app + '/index.html',
filename: 'index.html',
inject: 'body'
})
// removed dist directory before run start or run production
const CleanDistPlugin = new CleanWebpackPlugin([PATHS.build], {
root: PATHS.root,
verbose: true,
dry: false
})
// creates favicons and touch icons
const CreateFaviconsPlugin = new FaviconsWebpackPlugin({
// source logo
logo: PATHS.app + '/media/app-logo.png',
// The prefix for all image files (might be a folder or a name)
prefix: '/images/icons/',
// Emit all stats of the generated icons
emitStats: false,
// Generate a cache file with control hashes and
// don't rebuild the favicons until those hashes change
persistentCache: true,
// Inject the html into the html-webpack-plugin
inject: true,
// favicon background color (see https://github.com/haydenbleasel/favicons#usage)
background: manifest.background_color,
// favicon app title (see https://github.com/haydenbleasel/favicons#usage)
title: pkg.name,
// which icons should be generated (see https://github.com/haydenbleasel/favicons#usage)
icons: {
android: true,
appleIcon: true,
appleStartup: false,
coast: false,
favicons: true,
firefox: false,
opengraph: false,
twitter: false,
yandex: false,
windows: false
}
})
const DefineProductionENVPlugin = new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('production')
}
})
const Md5HashPlugin = new WebpackMd5Hash()// required for swprecache hash generation
// copies files at runtime
const CopyFilesPlugin = new CopyWebpackPlugin([
{ from: PATHS.app + '/manifest.json' },
{ from: PATHS.app + '/service-worker-registration.js' }
])
// generates vendor js file (code splitting)
const CommonsChunkPlugin = new webpack.optimize.CommonsChunkPlugin({
names: ['vendor'],
minChunks: Infinity
})
// service worker generation
const SWPrecachePlugin = new SWPrecacheWebpackPlugin(
{
cacheId: pkg.name, // unique cacheID
filename: pkg.name + '-service-worker.js', // filename for the generated sw file
handleFetch: SWPrecacheHandleFetch, // set to false for DEV Server and Change to True for Production
stripPrefix: 'C:/Users/dist/',
navigateFallback: '/index.html',
navigateFallbackWhitelist: [/^\/auth|logout|eventsFeed|prizesFeed|eventPreview|addEvent|addPrize|howItWorks|confirmEvent|app|manifest|service-worker-registration|style|vendor\//],
runtimeCaching: [{
// web fonts
urlPattern: /^https:\/\/fonts.googleapis.com\/.*/,
handler: 'cacheFirst'
}, {
// firebase storage images
urlPattern: /^https:\/\/fonts.gstatic.com\/.*/,
handler: 'cacheFirst'
}, {
// firebase storage images
urlPattern: /^https:\/\/firebasestorage.googleapis.com\/.*/,
handler: 'cacheFirst'
}, {
// google Map Images images
urlPattern: /^https:\/\/maps.googleapis.com\/maps\/api\/.*/,
handler: 'cacheFirst'
}]
}
)
// minifies all build code
const UglifyJsPlugin = new webpack.optimize.UglifyJsPlugin({
compressor: {
warnings: false
}
})
const ExtractCSSPlugin = new ExtractTextPlugin('/[name].css') // extracts seperate css file for caching instead of inline styles
const WebpackStatsPlugin = new StatsPlugin('../Stats.json', {
chunkModules: true,
exclude: [/node_modules[\\\/]react/]
})
const DedupePlugin = new webpack.optimize.DedupePlugin() // deduplicates equal or similar files
const base = {
entry: {
app: [
'babel-polyfill',
PATHS.app
],
vendor: ['react', 'react-dom', 'react-router', 'redux', 'react-redux']
},
postcss: [ autoprefixer({ browsers: ['last 2 versions'] }) ],
resolve: {
root: path.resolve('./app')
}
}
const developmentConfig = {
devtool: 'cheap-module-inline-source-map',
output: {
path: PATHS.build,
filename: '/[name].js'
},
module: {
loaders: [
{test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader'},
{test: /\.style.js$/, loader: 'style!css!postcss?parser=postcss-js!babel'},
{test: /\.css$/, loader: 'style!css?sourceMap&modules&localIdentName=[name]__[local]___[hash:base64:5]&importLoader=1!postcss'},
{test: /\.scss$/, loader: 'style!css?sourceMap&modules&localIdentName=[name]__[local]___[hash:base64:5]&postcss!sass'}
]
},
devServer: {
contentBase: PATHS.build,
historyApiFallback: true,
hot: true,
inline: true,
progress: true
},
plugins: [HTMLWebpackPluginConfig, new webpack.HotModuleReplacementPlugin(), CleanDistPlugin, CommonsChunkPlugin, CopyFilesPlugin, CreateFaviconsPlugin]
}
const productionConfig = {
devtool: 'cheap-module-source-map',
output: {
path: PATHS.build,
filename: '/[name].[chunkhash].js',
// This is used for require.ensure. The setup
// will work without but this is useful to set.
chunkFilename: '/[chunkhash].js'
},
recordsPath: path.resolve(__dirname, PATHS.root + '/webpack-records.json'), // needed so the vendor js doesnt change hash when not changed only app.js changes
module: {
loaders: [
{test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader'},
{ test: /\.css$/, loader: ExtractTextPlugin.extract('style', 'css?sourceMap&modules&localIdentName=[name]__[local]___[hash:base64:5]&importLoader=1!postcss') },
{ test: /\.scss$/, loader: ExtractTextPlugin.extract('style', 'css?sourceMap&modules&localIdentName=[name]__[local]___[hash:base64:5]&importLoader=1!postcss!sass') }
]
},
plugins: [HTMLWebpackPluginConfig, DefineProductionENVPlugin, CleanDistPlugin, Md5HashPlugin, CopyFilesPlugin, CommonsChunkPlugin, SWPrecachePlugin, DedupePlugin, UglifyJsPlugin, ExtractCSSPlugin, WebpackStatsPlugin, CreateFaviconsPlugin]
}
export default Object.assign({}, base, isProduction === true ? productionConfig : developmentConfig)
@IAMtheIAM
Copy link

Just curious, how does this config work without a module.exports =?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment