Created
February 4, 2017 19:00
-
-
Save tonyalaribe/5c1f091e7a7c1280590f8c5844894d1d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* COMMON WEBPACK CONFIGURATION | |
*/ | |
const path = require('path'); | |
const webpack = require('webpack'); | |
module.exports = (options) => ({ | |
entry: options.entry, | |
output: Object.assign({ // Compile into js/build.js | |
path: path.resolve(process.cwd(), 'build'), | |
publicPath: '/', | |
}, options.output), // Merge with env dependent settings | |
module: { | |
loaders: [{ | |
test: /\.js$/, // Transform all .js files required somewhere with Babel | |
loader: 'babel', | |
exclude: /node_modules/, | |
query: options.babelQuery, | |
}, { | |
// Transform our own .css files with PostCSS and CSS-modules | |
test: /\.css$/, | |
exclude: /node_modules/, | |
loader: options.cssLoaders, | |
}, { | |
// Do not transform vendor's CSS with CSS-modules | |
// The point is that they remain in global scope. | |
// Since we require these CSS files in our JS or CSS files, | |
// they will be a part of our compilation either way. | |
// So, no need for ExtractTextPlugin here. | |
test: /\.css$/, | |
include: /node_modules/, | |
loaders: ['style-loader', 'css-loader'], | |
}, { | |
test: /\.(eot|svg|ttf|woff|woff2)$/, | |
loader: 'file-loader', | |
}, { | |
test: /\.(jpg|png|gif)$/, | |
loaders: [ | |
'file-loader', | |
'image-webpack?{progressive:true, optimizationLevel: 7, interlaced: false, pngquant:{quality: "65-90", speed: 4}}', | |
], | |
}, { | |
test: /\.html$/, | |
loader: 'html-loader', | |
}, { | |
test: /\.json$/, | |
loader: 'json-loader', | |
}, { | |
test: /\.(mp4|webm)$/, | |
loader: 'url-loader?limit=10000', | |
}], | |
}, | |
plugins: options.plugins.concat([ | |
new webpack.ProvidePlugin({ | |
// make fetch available | |
fetch: 'exports?self.fetch!whatwg-fetch', | |
}), | |
// Always expose NODE_ENV to webpack, in order to use `process.env.NODE_ENV` | |
// inside your code for any environment checks; UglifyJS will automatically | |
// drop any unreachable code. | |
new webpack.DefinePlugin({ | |
'process.env': { | |
NODE_ENV: JSON.stringify(process.env.NODE_ENV), | |
}, | |
}), | |
]), | |
postcss: () => options.postcssPlugins, | |
resolve: { | |
modules: ['app', 'node_modules'], | |
extensions: [ | |
'', | |
'.js', | |
'.jsx', | |
'.react.js', | |
], | |
packageMains: [ | |
'jsnext:main', | |
'main', | |
], | |
}, | |
devtool: options.devtool, | |
target: 'web', // Make web variables accessible to webpack, e.g. window | |
stats: false, // Don't show stats in the console | |
progress: true, | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* DEVELOPMENT WEBPACK CONFIGURATION | |
*/ | |
const path = require('path'); | |
const fs = require('fs'); | |
const webpack = require('webpack'); | |
const HtmlWebpackPlugin = require('html-webpack-plugin'); | |
const logger = require('../../server/logger'); | |
const cheerio = require('cheerio'); | |
const pkg = require(path.resolve(process.cwd(), 'package.json')); | |
const dllPlugin = pkg.dllPlugin; | |
// PostCSS plugins | |
const cssnext = require('postcss-cssnext'); | |
const postcssFocus = require('postcss-focus'); | |
const postcssReporter = require('postcss-reporter'); | |
const plugins = [ | |
new webpack.HotModuleReplacementPlugin(), // Tell webpack we want hot reloading | |
new webpack.NoErrorsPlugin(), | |
new HtmlWebpackPlugin({ | |
inject: true, // Inject all files that are generated by webpack, e.g. bundle.js | |
templateContent: templateContent(), // eslint-disable-line no-use-before-define | |
}), | |
]; | |
module.exports = require('./webpack.base.babel')({ | |
// Add hot reloading in development | |
entry: [ | |
'eventsource-polyfill', // Necessary for hot reloading with IE | |
'webpack-hot-middleware/client', | |
path.join(process.cwd(), 'app/app.js'), // Start with js/app.js | |
], | |
// Don't use hashes in dev mode for better performance | |
output: { | |
filename: '[name].js', | |
chunkFilename: '[name].chunk.js', | |
}, | |
// Add development plugins | |
plugins: dependencyHandlers().concat(plugins), // eslint-disable-line no-use-before-define | |
// Load the CSS in a style tag in development | |
cssLoaders: 'style-loader!css-loader?importLoaders=1&sourceMap!postcss-loader', | |
// Process the CSS with PostCSS | |
postcssPlugins: [ | |
postcssFocus(), // Add a :focus to every :hover | |
cssnext({ // Allow future CSS features to be used, also auto-prefixes the CSS... | |
browsers: ['last 2 versions', 'IE > 10'], // ...based on this browser list | |
}), | |
postcssReporter({ // Posts messages from plugins to the terminal | |
clearMessages: true, | |
}), | |
], | |
// Tell babel that we want to hot-reload | |
babelQuery: { | |
presets: ['react-hmre'], | |
}, | |
// Emit a source map for easier debugging | |
devtool: 'cheap-module-eval-source-map', | |
}); | |
/** | |
* Select which plugins to use to optimize the bundle's handling of | |
* third party dependencies. | |
* | |
* If there is a dllPlugin key on the project's package.json, the | |
* Webpack DLL Plugin will be used. Otherwise the CommonsChunkPlugin | |
* will be used. | |
* | |
*/ | |
function dependencyHandlers() { | |
// Don't do anything during the DLL Build step | |
if (process.env.BUILDING_DLL) { return []; } | |
// If the package.json does not have a dllPlugin property, use the CommonsChunkPlugin | |
if (!dllPlugin) { | |
return [ | |
new webpack.optimize.CommonsChunkPlugin({ | |
name: 'vendor', | |
children: true, | |
minChunks: 2, | |
async: true, | |
}), | |
]; | |
} | |
const dllPath = path.resolve(process.cwd(), dllPlugin.path || 'node_modules/react-boilerplate-dlls'); | |
/** | |
* If DLLs aren't explicitly defined, we assume all production dependencies listed in package.json | |
* Reminder: You need to exclude any server side dependencies by listing them in dllConfig.exclude | |
* | |
* @see https://github.com/mxstbr/react-boilerplate/tree/master/docs/general/webpack.md | |
*/ | |
if (!dllPlugin.dlls) { | |
const manifestPath = path.resolve(dllPath, 'reactBoilerplateDeps.json'); | |
if (!fs.existsSync(manifestPath)) { | |
logger.error('The DLL manifest is missing. Please run `npm run build:dll`'); | |
process.exit(0); | |
} | |
return [ | |
new webpack.DllReferencePlugin({ | |
context: process.cwd(), | |
manifest: require(manifestPath), // eslint-disable-line global-require | |
}), | |
]; | |
} | |
// If DLLs are explicitly defined, we automatically create a DLLReferencePlugin for each of them. | |
const dllManifests = Object.keys(dllPlugin.dlls).map((name) => path.join(dllPath, `/${name}.json`)); | |
return dllManifests.map((manifestPath) => { | |
if (!fs.existsSync(path)) { | |
if (!fs.existsSync(manifestPath)) { | |
logger.error(`The following Webpack DLL manifest is missing: ${path.basename(manifestPath)}`); | |
logger.error(`Expected to find it in ${dllPath}`); | |
logger.error('Please run: npm run build:dll'); | |
process.exit(0); | |
} | |
} | |
return new webpack.DllReferencePlugin({ | |
context: process.cwd(), | |
manifest: require(manifestPath), // eslint-disable-line global-require | |
}); | |
}); | |
} | |
/** | |
* We dynamically generate the HTML content in development so that the different | |
* DLL Javascript files are loaded in script tags and available to our application. | |
*/ | |
function templateContent() { | |
const html = fs.readFileSync( | |
path.resolve(process.cwd(), 'app/index.html') | |
).toString(); | |
if (!dllPlugin) { return html; } | |
const doc = cheerio(html); | |
const body = doc.find('body'); | |
const dllNames = !dllPlugin.dlls ? ['reactBoilerplateDeps'] : Object.keys(dllPlugin.dlls); | |
dllNames.forEach(dllName => body.append(`<script data-dll='true' src='/${dllName}.dll.js'></script>`)); | |
return doc.toString(); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* WEBPACK DLL GENERATOR | |
* | |
* This profile is used to cache webpack's module | |
* contexts for external library and framework type | |
* dependencies which will usually not change often enough | |
* to warrant building them from scratch every time we use | |
* the webpack process. | |
*/ | |
const { join } = require('path'); | |
const defaults = require('lodash/defaultsDeep'); | |
const webpack = require('webpack'); | |
const pkg = require(join(process.cwd(), 'package.json')); | |
const dllPlugin = require('../config').dllPlugin; | |
if (!pkg.dllPlugin) { process.exit(0); } | |
const dllConfig = defaults(pkg.dllPlugin, dllPlugin.defaults); | |
const outputPath = join(process.cwd(), dllConfig.path); | |
module.exports = { | |
context: process.cwd(), | |
entry: dllConfig.dlls ? dllConfig.dlls : dllPlugin.entry(pkg), | |
devtool: 'eval', | |
output: { | |
filename: '[name].dll.js', | |
path: outputPath, | |
library: '[name]', | |
}, | |
plugins: [ | |
new webpack.DllPlugin({ name: '[name]', path: join(outputPath, '[name].json') }), // eslint-disable-line no-new | |
], | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Important modules this config uses | |
const path = require('path'); | |
const webpack = require('webpack'); | |
const HtmlWebpackPlugin = require('html-webpack-plugin'); | |
const ExtractTextPlugin = require('extract-text-webpack-plugin'); | |
const OfflinePlugin = require('offline-plugin'); | |
// PostCSS plugins | |
const cssnext = require('postcss-cssnext'); | |
const postcssFocus = require('postcss-focus'); | |
const postcssReporter = require('postcss-reporter'); | |
module.exports = require('./webpack.base.babel')({ | |
// In production, we skip all hot-reloading stuff | |
entry: [ | |
path.join(process.cwd(), 'app/app.js'), | |
], | |
// Utilize long-term caching by adding content hashes (not compilation hashes) to compiled assets | |
output: { | |
filename: '[name].[chunkhash].js', | |
chunkFilename: '[name].[chunkhash].chunk.js', | |
}, | |
// We use ExtractTextPlugin so we get a seperate CSS file instead | |
// of the CSS being in the JS and injected as a style tag | |
cssLoaders: ExtractTextPlugin.extract( | |
'style-loader', | |
'css-loader?importLoaders=1!postcss-loader' | |
), | |
// In production, we minify our CSS with cssnano | |
postcssPlugins: [ | |
postcssFocus(), | |
cssnext({ | |
browsers: ['last 2 versions', 'IE > 10'], | |
}), | |
postcssReporter({ | |
clearMessages: true, | |
}), | |
], | |
plugins: [ | |
new webpack.optimize.CommonsChunkPlugin({ | |
name: 'vendor', | |
children: true, | |
minChunks: 2, | |
async: true, | |
}), | |
// OccurrenceOrderPlugin is needed for long-term caching to work properly. | |
// See http://mxs.is/googmv | |
new webpack.optimize.OccurrenceOrderPlugin(true), | |
// Merge all duplicate modules | |
new webpack.optimize.DedupePlugin(), | |
// Minify and optimize the JavaScript | |
new webpack.optimize.UglifyJsPlugin({ | |
compress: { | |
warnings: false, // ...but do not show warnings in the console (there is a lot of them) | |
}, | |
}), | |
// Minify and optimize the index.html | |
new HtmlWebpackPlugin({ | |
template: 'app/index.html', | |
minify: { | |
removeComments: true, | |
collapseWhitespace: true, | |
removeRedundantAttributes: true, | |
useShortDoctype: true, | |
removeEmptyAttributes: true, | |
removeStyleLinkTypeAttributes: true, | |
keepClosingSlash: true, | |
minifyJS: true, | |
minifyCSS: true, | |
minifyURLs: true, | |
}, | |
inject: true, | |
}), | |
// Extract the CSS into a seperate file | |
new ExtractTextPlugin('[name].[contenthash].css'), | |
// Put it in the end to capture all the HtmlWebpackPlugin's | |
// assets manipulations and do leak its manipulations to HtmlWebpackPlugin | |
new OfflinePlugin({ | |
relativePaths: false, | |
publicPath: '/', | |
// No need to cache .htaccess. See http://mxs.is/googmp, | |
// this is applied before any match in `caches` section | |
excludes: ['.htaccess'], | |
caches: { | |
main: [':rest:'], | |
// All chunks marked as `additional`, loaded after main section | |
// and do not prevent SW to install. Change to `optional` if | |
// do not want them to be preloaded at all (cached only when first loaded) | |
additional: ['*.chunk.js'], | |
}, | |
// Removes warning for about `additional` section usage | |
safeToUseOptionalCaches: true, | |
AppCache: { | |
// Starting from offline-plugin:v3, AppCache by default caches only | |
// `main` section. This lets it use `additional` section too | |
caches: ['main', 'additional'], | |
}, | |
}), | |
], | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment