Skip to content

Instantly share code, notes, and snippets.

@JBreit
Last active July 16, 2017 13:49
Show Gist options
  • Save JBreit/a73dccf20bc94eab494ae6150d0e8093 to your computer and use it in GitHub Desktop.
Save JBreit/a73dccf20bc94eab494ae6150d0e8093 to your computer and use it in GitHub Desktop.
Webpack 2.0 Configuration Demo
{
"presets": [
["env", {
"modules": false
}],
"react"
],
"plugins": []
}
module.exports = {
"name": "imco.ui",
"version": "0.1.0",
"extends": "airbnb-base",
"env": {
"browser": true,
"node": true,
"mocha": true,
"jasmine": true,
"phantomjs": true,
"protractor": true,
"serviceworker": true
},
"globals": {
"document": true,
"window": true
},
"parser": "babel-eslint",
"parserOptions": {
"ecmaVersion": 2017,
"sourceType": "module",
"ecmaFeatures": {
"jsx": true
}
},
"plugins": [
"import",
"react"
],
"root": true,
"rules": {
"comma-dangle": ["error", "never"],
"indent": ["error", 2, { "SwitchCase": 1 }],
"linebreak-style": ["error", process.env.NODE_ENV === "production" ? "unix" : "windows"]
}
};
{
"title": "Inner Mind Co. UI",
"name": "imco.ui",
"version": "0.1.0",
"description": "Inner Mind Consulting UI",
"main": "./src/index.js",
"scripts": {
"prebuild": "npm run lint",
"build": "webpack --env=prod",
"update-deps": "npm update",
"prestart": "npm install && npm run lint",
"lint": "eslint ./src",
"start": "webpack-dev-server --env=dev --open",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": {
"name": "Jason Breitigan",
"email": "<[email protected]"
},
"license": "MIT",
"browserslist": [
"last 2 versions",
"ie >= 10"
],
"homepage": "http://www.innermindco.com/",
"devDependencies": {
"autoprefixer": "^7.0.1",
"babel-core": "^6.24.1",
"babel-eslint": "^7.2.3",
"babel-loader": "^7.0.0",
"babel-plugin-external-helpers": "^6.22.0",
"babel-preset-env": "^1.4.0",
"babel-preset-react": "^6.24.1",
"clean-webpack-plugin": "^0.1.16",
"css-loader": "^0.28.1",
"cssnano": "^3.10.0",
"eslint": "^3.19.0",
"eslint-config-airbnb-base": "^11.1.3",
"eslint-plugin-import": "^2.2.0",
"eslint-plugin-react": "^7.1.0",
"eslint-watch": "^3.1.0",
"extract-text-webpack-plugin": "^2.1.0",
"file-loader": "^0.11.2",
"glob": "^7.1.2",
"html-loader": "^0.4.5",
"html-webpack-plugin": "^2.28.0",
"json-loader": "^0.5.4",
"markdown-loader": "^2.0.1",
"marked": "^0.3.6",
"node-sass": "^4.5.3",
"npm-run-all": "^4.0.2",
"postcss": "^6.0.6",
"postcss-cssnext": "^3.0.2",
"postcss-import": "^10.0.0",
"postcss-import-url": "^2.2.0",
"postcss-loader": "^2.0.5",
"postcss-modules": "^0.8.0",
"postcss-nested": "^2.0.2",
"postcss-pxtorem": "^4.0.1",
"postcss-simple-vars": "^4.0.0",
"posthtml": "^0.9.2",
"purify-css": "^1.2.5",
"purifycss-webpack": "^0.7.0",
"sass-loader": "^6.0.5",
"style-loader": "^0.17.0",
"url-loader": "^0.5.9",
"webpack": "^2.5.1",
"webpack-dashboard": "^0.4.0",
"webpack-dev-server": "^2.4.5",
"webpack-merge": "^4.1.0"
},
"dependencies": {
"babel-polyfill": "^6.23.0"
}
}
module.exports = ({ file, options, env }) => ({
parser: file.extname === '.sss' ? 'sugarss' : false,
plugins: {
'postcss-import': { root: file.dirname },
'postcss-modules': options.cssmodules ? options.cssmodules : false,
'postcss-cssnext': options.cssnext ? options.cssnext : false,
'autoprefixer': env == 'production' ? options.autoprefixer : false,
'cssnano': env === 'production' ? options.cssnano : false,
},
});
const fs = require('fs');
const path = require('path');
const webpack = require('webpack');
const merge = require('webpack-merge');
const Clean = require('clean-webpack-plugin');
const Html = require('html-webpack-plugin');
const Text = require('extract-text-webpack-plugin');
const marked = require('marked');
const renderer = new marked.Renderer();
const cssimport = require('postcss-import');
const cssmodules = require('postcss-modules');
const simplevars = require('postcss-simple-vars');
const nested = require('postcss-nested');
const cssnext = require('postcss-cssnext');
const autoprefixer = require('autoprefixer');
const cssnano = require('cssnano');
const pkg = require('./package');
const banner = `
${pkg.name} - ${pkg.description}
Author: ${pkg.author.name}
Version: ${pkg.version}
Url: ${pkg.homepage}
License(s): ${pkg.license}
`;
const dir = {
dist: path.resolve(`${__dirname}/dist`),
npm: path.resolve(`${__dirname}/node_modules`),
src: path.resolve(`${__dirname}/src`),
};
const style = new Text({
filename: `app/css/[name].css`,
allChunks: true,
});
const base = {
context: dir.src,
entry: {
app: 'index.js',
},
resolve: {
extensions: ['.css', '.htm', '.html', '.js', '.json', '.scss'],
modules: [dir.src, dir.npm],
},
performance: {
hints: 'warning',
maxAssetSize: 200000, // int (in bytes)
maxEntrypointSize: 400000, // int (in bytes)
assetFilter: (assetFileName) => {
return assetFileName.endsWith('.css') || assetFileName.endsWith('.js');
},
},
externals: [],
target: 'web',
watch: true,
watchOptions: {
aggregateTimeout: 300,
poll: 1000,
},
module: {
rules: [
{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
cacheDirectory: true,
},
},
},
{
test: /\.json$/,
use: {
loader: 'json-loader',
},
},
{
test: /\.(md|markdown)$/,
use: [
{
loader: 'html-loader',
options: {},
},
{
loader: 'markdown-loader',
options: {
pendantic: true,
renderer,
},
},
],
},
{
test: /\.(sass|scss)$/,
use: style.extract([
{
loader: 'css-loader',
options: {
importLoaders: 1,
localIdentName: '[name]__[local]___[hash:base64:5]',
modules: true,
sourceMap: true,
},
},
{
loader: 'postcss-loader',
options: {
sourceMap: true,
},
},
{
loader: 'sass-loader',
options: {
sourceMap: true,
},
},
]),
},
{
test: /\.(html|htm)$/,
use: {
loader: 'html-loader',
options: {
minimize: false,
},
},
},
{
test: /\.(ico|png|svg|jpeg|gif)$/,
use: ['file-loader'],
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: ['file-loader'],
},
],
},
plugins: [
style,
new webpack.LoaderOptionsPlugin({
options: {
postcss: (loader) => [
cssimport({ root: loader.resourcePath }),
cssmodules({
generateScopedName: '[name]__[local]___[hash:base64:5]',
getJSON: (cssFileName, json) => {
const cssName = path.basename(`${cssFileName}.css`);
const jsonFileName = path.resolve(`${dir.dist}/app/css/${cssName}.json`);
fs.writeFileSync(jsonFileName, JSON.stringify(json));
},
scopeBehaviour: 'local',
}),
simplevars(),
nested(),
cssnext({
dynamic: false,
include: ['**/*.css', '**/*.scss'],
browsers: pkg.browserslist,
warnForDuplicates: true,
}),
autoprefixer(pkg.browserslist),
cssnano(),
],
},
}),
new webpack.BannerPlugin(banner),
],
};
const dev = {
devtool: 'eval-source-map',
plugins: [
new Html({
favicon: path.resolve(`${dir.src}/app/img/favicon.ico`),
title: pkg.title,
template: path.resolve(`${dir.src}/index.html`),
inject: 'body',
}),
],
};
const prod = {
devtool: 'source-map',
output: {
path: dir.dist,
filename: `app/[name].js`,
sourceMapFilename: 'app/[name].map',
},
plugins: [
new Clean(path.resolve(`${dir.dist}/**/*`), { root: dir.dist }),
new webpack.optimize.UglifyJsPlugin({
mangle: {
except: ['webpackJsonp'],
},
}),
],
};
const environments = { dev, prod };
module.exports = env => merge(base, environments[env]);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment