webpack does what the browser would do if given your app: » find all images in your CSS and download them » parse your JavaScript dependencies and download them » parse all CSS for imports and download them
webpack.config.js var path = require('path') module.exports = { // where should it look? entry: path.resolve('src', 'main.js'), // where should it output to? output: { path: path.resolve(__dirname, 'dist'), filename: 'main.js', publicPath: '/dist/' } }
{ // apply this rule to any files that end in ".js" test: /\.js$/, // only look for files in the src directory include: path.resolve('src'), // configure the loaders for this rule use: [{ }] }
{ test: /\.js$/, include: path.resolve('src'), use: [{ // for files that this rule applies to // run the babel-loader against them loader: 'babel-loader', // specific options for the babel loader options: { presets: ['es2015'] } }] }
Let's get some CSS in here Remember, the goal of webpack is for it to manage all our assets, CSS included. This is weird at first but stick with me... (Also I suck at design, please forgive)
ERROR in ./src/style.css Module parse failed: /github-app/src/style.css Unexpected token (1:5) You may need an appropriate loader to handle this file type. | form { | width: 200px; | margin: 10px auto; @ ./src/main.js 3:0-22 @ multi main
Add another rule { test: /\.css$/, include: path.resolve('src'), use: [{ loader: 'style-loader', }, { loader: 'css-loader', }] } Loaders are applied from right to left, or bottom to top
var { getIfUtils, removeEmpty } = require('webpack-config-utils') var { ifProduction, ifNotProduction } = getIfUtils(process.env.NODE_ENV || 'development') » removeEmpty: removes undefined from arrays » ifProduction: returns what it's given if NODE_ENV === 'production' » ifNotProduction: returns what it's given if NODE_ENV !== 'production'
Wait, the build went up? This is a contrived example, because this app is tiny! You pay a small cost because webpack has code that it inserts for lazily loading modules, but if your pages are big enough you'll get still save.
ES2015 module imports and exports have to be static. So we can go through them and see which ones are used and which ones aren't needed. This means we can eliminate any code relating to ununsed exports!
src/not-used.js export const SO_NOT_USED = 'I AM NOT USED BY ANYTHING EVER' export const SO_USED = 'I GET USED BY THINGS' src/main.js import { SO_USED } from './not-used' console.log(SO_USED)
webpack 2 » Much improved documentation & community engagement » Improved configuration with a nicer API and automatic validation of config » Tree shaking, easier code splitting and lazy loading » More performant
Fin » Slides & code: https://github.com/jackfranklin/half-stack- webpack » webpack 2: webpack.js.org » Me: @Jack_Franklin, javascriptplayground.com, elmplayground.com Thanks to: Glen Maddern, Sean Larkinn, Kent C Dodds