Last active
April 4, 2024 12:43
-
-
Save andfaulkner/8a6e9f911e89899d328c7ca91a0be267 to your computer and use it in GitHub Desktop.
Split Webpack configuration into modules by functionality (rather than environment)
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
const prodExternals = { | |
'react': 'React', | |
'react-dom': 'ReactDOM', | |
'lodash': '_', | |
'redux': 'Redux', | |
'react-redux': 'ReactRedux', | |
'react-bootstrap': 'ReactBootstrap' | |
}; | |
const testExternals = { | |
jsdom: 'window', | |
cheerio: 'window', | |
}; | |
const devExternals = { }; | |
const externals = { | |
'react/addons': true, | |
'react/lib/ExecutionEnvironment': true, | |
'react/lib/ReactContext': true | |
}; | |
module.exports = (NODE_ENV, TEST_ENV = false) => { | |
return Object.assign({}, | |
externals, | |
(TEST_ENV === 'karma') ? testExternals: {}, | |
(NODE_ENV === 'production') ? prodExternals : devExternals | |
); | |
}; |
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
const path = require('path'); | |
const webpack = require('webpack'); | |
// TODO fix the repetition here | |
const srcPath = path.join(__dirname, '..', 'client'); | |
const loaders = [ | |
{ | |
test: /\.tsx?$/, | |
exclude: ['node_modules', '../node_modules'], | |
loaders: ['babel?presets[]=react&presets[]=es2015&presets[]=stage-0', 'ts-loader'] | |
}, | |
{ | |
test: /\.((hbs)|(handlebars))$/, | |
loader: 'handlebars-loader' | |
}, | |
{ | |
test: /\.json/, | |
loader: 'json-loader' | |
}, | |
{ | |
test: /\.ya?ml$/, | |
exclude: ['node_modules', '../node_modules'], | |
loaders: ['yaml', 'json'], | |
}, | |
{ | |
test: /\.(jpg|png)$/, | |
loader: 'url?limit=25000', | |
include: path.join(srcPath, 'components') | |
}, | |
{ | |
test: /\.jsx?$/, | |
loader: 'babel', | |
exclude: /node_modules/ | |
}, | |
{ | |
test: /\.css$/, | |
exclude: ['node_modules', '../node_modules', '../../node_modules'], | |
loader: "style-loader!css-loader!postcss-loader" | |
} | |
]; | |
const devLoaders = []; | |
const loadersWithEnvSpecific = (process.env.NODE_ENV === 'production') | |
? loaders | |
: loaders.concat(devLoaders) | |
module.exports = loadersWithEnvSpecific; |
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
const path = require('path'); | |
const webpack = require('webpack'); | |
const config = require("../config.js"); | |
// Load required plugins | |
const HandlebarsPlugin = require('handlebars-webpack-plugin'); | |
const ExtractTextPlugin = require('extract-text-webpack-plugin'); | |
const LodashModuleReplacementPlugin = require('lodash-webpack-plugin'); | |
// Get paths to important files | |
const buildPath = path.join(__dirname, '../..', 'build'); | |
const buildFilePath = (currentPath) => path.join(buildPath, currentPath); | |
const srcPath = path.join(__dirname, '../..', 'client'); | |
const srcFilePath = (currentPath) => path.join(srcPath, currentPath); | |
console.log('\n\nbuildFilePath: ', buildFilePath); | |
console.log('srcFilePath: ', srcFilePath, '\n\n'); | |
/** | |
* Plugins shared by prod and dev | |
*/ | |
const basePlugins = (NODE_ENV, LOG_LEVEL) => [ | |
new ExtractTextPlugin("[name].css"), | |
new webpack.DefinePlugin({ | |
NODE_ENV: JSON.stringify(NODE_ENV), | |
LOG_LEVEL: JSON.stringify(LOG_LEVEL), | |
'process.env': { | |
NODE_ENV: JSON.stringify(NODE_ENV), | |
LOG_LEVEL: JSON.stringify(LOG_LEVEL) | |
} | |
}), | |
new HandlebarsPlugin({ | |
entry: srcFilePath("index.hbs"), // path to main hbs template | |
output: buildFilePath((NODE_ENV === 'development') ? "index.html" : "public/index.html"), // filepath to result | |
// output: buildFilePath("index.html"), // << ORIGINAL | |
data: config.indexHtmlData // data passed to main hbs template | |
}) | |
]; | |
/** | |
* Production-only Webpack plugins | |
*/ | |
const prodPlugins = [ | |
new webpack.optimize.UglifyJsPlugin({ | |
compress: { | |
warnings: false, | |
screw_ie8: true, | |
drop_console: true, | |
drop_debugger: true, | |
dead_code: true, | |
unused: true, | |
evaluate: true, | |
if_return: true, | |
join_vars: true, | |
}, | |
sourceMap: false, | |
}), | |
new LodashModuleReplacementPlugin({ | |
chaining: true, | |
collections: true, | |
paths: true, | |
flattening: true, | |
caching: true, | |
currying: true, | |
placeholders: true | |
}), | |
new webpack.optimize.DedupePlugin() | |
]; | |
/** | |
* @EXPORT | |
*/ | |
module.exports = (NODE_ENV = 'development', LOG_LEVEL = 'verbose') => { | |
const plugins = basePlugins(NODE_ENV, LOG_LEVEL) | |
.concat((NODE_ENV === 'production') ? prodPlugins : []); | |
if (LOG_LEVEL === 'verbose' || LOG_LEVEL === 'silly') { | |
console.log('\n\nPLUGINS:\n', plugins, 'END PLUGINS\n\n'); | |
} | |
return plugins; | |
}; |
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
const path = require('path'); | |
const webpack = require('webpack'); | |
module.exports = (webpack) => { | |
return [ | |
// !------ ALREADY INCLUDED BY cssnext: require('autoprefixer'), | |
require('postcss-import')({ | |
addDependencyTo: webpack | |
}), | |
require('postcss-env-replace')({ | |
environment: process.env.NODE_ENV || 'development', | |
replacements: { | |
BASE_URL: { | |
production: '/assets/img', | |
development: 'http://localhost:8080/assets/img', | |
} | |
} | |
}), | |
require('postcss-mixins')({ | |
mixinsFiles: path.join(__dirname, '../..', 'client/styles/mixins.css') | |
}), | |
require('postcss-partial-import')({ | |
addDependencyTo: webpack | |
}), | |
require('postcss-inherit'), | |
require('postcss-each'), | |
require('postcss-inline-comment'), // allows '//' comments -- OK | |
require('postcss-flexibility'), // flexbox -- OK | |
require('lost'), // grids -- OK | |
require('postcss-nesting'), | |
require('postcss-simple-vars'), | |
require('postcss-utilities'), // see https://ismamz.github.io/postcss-utilities/docs | |
require('postcss-cssnext'), | |
require('postcss-calc') | |
]; | |
} |
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
/********************************** THIRD-PARTY UTILITY MODULES ***********************************/ | |
const path = require('path'); | |
const webpack = require('webpack'); | |
const _ = require('lodash'); | |
/**************************************** ENVIRONMENT VARS ****************************************/ | |
// Extract environment vars from process.env, with fallbacks if expected vars not present | |
var NODE_ENV = process.env.NODE_ENV || 'development'; | |
var TEST_ENV = process.env.TEST_ENV || false; | |
var LOG_LEVEL = process.env.LOG_LEVEL || 'verbose'; | |
var WATCH = !_.includes(process.argv, '--block-watch'); | |
// Detect if verbose mode is active | |
const isVerbose = (LOG_LEVEL === 'verbose') || (LOG_LEVEL === 'silly') || | |
_.includes(process.argv, '--verbose'); | |
// Display current environment ('development' or 'production') | |
console.log('\nprocess.env.NODE_ENV: ', NODE_ENV, '\n process.env.TEST_ENV: ', TEST_ENV, '\n'); | |
// SET THE BABEL ENVIRONMENT (for use under the hood in transpiling) | |
const TARGET = process.env.npm_lifecycle_event; | |
process.env.BABEL_ENV = TARGET; | |
/************************************* WEBPACK CONFIG OPTIONS *************************************/ | |
const config = require('./config'); | |
const loaders = require('./webpack-modules/loaders-webpack.config'); | |
const postCSSConfig = require('./webpack-modules/postcss-webpack.config'); | |
const pluginsConfig = require('./webpack-modules/plugins-webpack.config')(NODE_ENV, LOG_LEVEL); | |
const externalsConfig = require('./webpack-modules/externals-webpack.config')(NODE_ENV, TEST_ENV); | |
/**************************************** DIRECTORY PATHS *****************************************/ | |
// common paths | |
const srcPath = path.join(__dirname, '..', 'client'); | |
const buildPath = path.join(__dirname, '..', 'build'); | |
const publicBuildPath = path.join(__dirname, '..', 'build/public'); | |
const libPaths = [path.join(__dirname, '..', 'node_modules')]; | |
const srcFilePath = (currentPath) => path.join(srcPath, currentPath); | |
/****************************************** LOG CONFIGS *******************************************/ | |
if (isVerbose) { | |
console.log('\nwebpack.dev.config.js:: OUTPUT CONFIG INFO: '); | |
console.log('\nloaders:\n', loaders, '\n'); | |
console.log('\npostCSSConfig:\n', postCSSConfig, '\n'); | |
console.log('\npluginsConfig:\n', pluginsConfig, '\n'); | |
console.log('\nexternalsConfig:\n', externalsConfig, '\n'); | |
} | |
/********************** WEBPACK DEVELOPMENT CONFIG (MERGES INTO BASE CONFIG) **********************/ | |
/** | |
* Development-specific webpack configuration (settings of keys not provided to the | |
* production config, and keys with little config overlap between dev and prod). | |
* @type {Object} | |
*/ | |
const webpackDevOptions = { | |
devtool: 'inline-source-map', | |
devServer: { | |
contentBase: buildPath, | |
progress: true, | |
colors: true, | |
port: config.port.WEBPACK_DEV_SERVER_PORT, | |
inline: true, | |
progress: true, | |
hot: true, | |
}, | |
port: config.port.WEBPACK_DEV_SERVER_PORT, | |
output: { | |
path: buildPath, | |
filename: "app.js", | |
}, | |
}; | |
/********************** WEBPACK PRODUCTION CONFIG (MERGES INTO BASE CONFIG) ***********************/ | |
/** | |
* Production-specific webpack configuration | |
* @type {Object} | |
*/ | |
const webpackProdOptions = { | |
output: { | |
path: publicBuildPath, | |
publicPath: "/", | |
filename: "app.js", | |
}, | |
}; | |
/*********************************** BASE WEBPACK CONFIG OBJECT ***********************************/ | |
/** | |
* Actual webpack config object. | |
* Environment-specific Webpack settings get merged into this base object. | |
*/ | |
const webpackConfig = Object.assign({}, | |
{ | |
colors: true, | |
pathinfo: true, | |
progress: true, | |
watch: ((NODE_ENV === 'development') && WATCH), | |
context: path.join(__dirname, '..', '/client'), | |
entry: srcFilePath('root.tsx'), | |
externals: externalsConfig, | |
module: { | |
loaders, | |
noParse: [ | |
/node_modules\/sinon/, | |
/client\/vendor\/jsonpath/ | |
], | |
}, | |
plugins: pluginsConfig, | |
postcss: postCSSConfig, | |
resolve: { | |
modulesDirectories: [ | |
"./client", | |
"../node_modules", | |
"../node_modules/babel", | |
"./node_modules", | |
"./node_modules/babel" | |
], | |
extensions: ['', '.js', '.jsx', '.tsx', '.ts', '.css'] | |
}, | |
resolveLoader: { root: libPaths }, | |
}, | |
// ENVIRONMENT SPECIFIC BUILD OPTIONS | |
(NODE_ENV === 'development') ? webpackDevOptions : webpackProdOptions | |
(TEST_ENV === 'karma') ? { devtool: 'inline-source-map' } : {} | |
); | |
if (TEST_ENV === 'karma') { | |
webpackConfig.resolve.alias = Object.assign({}, | |
webpackConfig.resolve.alias || {}, | |
{ sinon: require.resolve('sinon/pkg/sinon') } | |
); | |
} | |
/********************************************* EXPORT *********************************************/ | |
if (isVerbose) { | |
console.log('WEBPACK FINAL CONFIG OPTIONS: ', webpackConfig) | |
} | |
module.exports = webpackConfig; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment