Packing for the Web with Webpack THIAGO TEMPLE
Packing for the Web with WebpackTHIAGO TEMPLE
A few months ago…
Initial state• Plain JavaScript
• Global functions and variables
• Unorganized code (no structure)
• Repeated code
• No tests
• Server and client code together
• Different libraries
What we wanted• TypeScript
• Modules
• Structure
• Tests
Modules
Loading
Module loaders
SystemJS
Bundling
Module bundlers
SystemJS
Task runners
=+
+
One tool
To rule them all
How does it work?
App.js
MoviesService.js
AnotherModule.js
MoviesCache.js
UsersService.js Lodash.js
Configuration
module.exports = { entry: './src/app.js', output: { path: './dist', filename: 'bundle.js' }}
Module resolution• CommonJS
• AMD (RequireJS)
• ES6 (version 2)
Migration
Multiple entry points
module.exports = { entry: { page1: './src/app.js', page2: './src/movies.js', page3: './src/admin.js', }, output: { path: './dist', filename: '[name].js' }}
Loaders
A loader
module.exports = { … module: { loaders:[ { test: /\.jsx?$/, include: path.resolve(__dirname, 'src'), loader: 'babel', } ]}
TypeScript loader
module.exports = { … module: { loaders:[ { test: /\.tsx?$/, include: path.resolve(__dirname, 'src'), loader: 'ts', } ]}
Multiple loaders
module.exports = { … module: { loaders:[ { test: /\.tsx?$/, include: path.resolve(__dirname, 'src'), loaders: ['babel', 'ts'], } ]}
Not only JavaScript, css…
module.exports = { … module: { loaders:[ { test: /\.css?$/, include: path.resolve(__dirname, 'src'), loaders: ['style', 'css'], } ]}
Sass
module.exports = { … module: { loaders:[ { test: /\.scss?$/, include: path.resolve(__dirname, 'src'), loaders: ['style', 'css', 'sass'], } ]}
Importing CSS
/// a file.js
require('./mymodule.css');
import './mymodule.css';
CSS with images
module.exports = { … module: { loaders:[ { test: /\.(gif|jpg|png)?$/, include: path.resolve(__dirname, 'src'), loader: 'url?limit=10000?name=images/[name].[ext]', } ]}
CSS modules
module.exports = { … module: { loaders:[ { test: /\.css?$/, include: path.resolve(__dirname, 'src'), loader: 'style!css?modules&camelCase' } ]}
CSS modules
var styles = require('./app.css');
var el = document.createElement('div');el.innerText = 'Hello opencode';el.className = styles.testClass;
document.body.appendChild(el);
CSS modules
.test-class { width: 200px; height: 200px; background-color: purple; font-size: 1.5em;}
CSS modules
Create your own
module.exports = function (source) { return source;};
Developing tools
Dev server• Easy to configure
• In memory
• Hot reloading
Hot reloading
React hot reloader loader
Source maps
module.exports = { entry: './src/app.js', devtool: 'eval-source-map', output: { path: './dist', filename: 'bundle.js' }}
Linting
module.exports = { … module: { preloaders:[ { test: /\.tsx?$/, loader: 'tslint', } ], tslint: { emitErrors: true, failOnHint: true }}
Plugins
Extract CSS
var ExtractTextPlugin = require('extract-text-webpack-plugin');module.exports = { … module: { loaders:[ { test: /\.css$/, loader: ExtractTextPlugin.extract('style', 'css'), } ], plugins:[ new ExtractTextPlugin('bundle.css') ]
Long-term caching
var ExtractTextPlugin = require('extract-text-webpack-plugin');module.exports = { … output: { path: '…', filename: 'bundle.[hash].js' }, plugins:[ new ManifestPlugin(), ]
Long-term caching
{ "bundle.js": "bundle.2f0ffb545e5607fc8b8d.js"}
Long-term caching• Generate html from server
• Generate html using Webpack• HtmlWebpackPlugin
Common chunk plugin
module.exports = { entry: { page1: './src/app.js', page2: './src/movies.js', page3: './src/admin.js', }, plugins: [ new webpack.optimize.CommonsChunkPlugin({ name: 'shared' }) ]}
Common chunk plugin - vendors
module.exports = { entry: { app: './src/app.js', vendor: ['jquery', 'react', 'lodash'] }, plugins: [ new webpack.optimize.CommonsChunkPlugin({ name: 'vendor' }) ]}
Some other plugins• Provide
• I18n
Some other considerations• Webpack –p
• Webpack validator
• Attention to the object exported
Conclusion• One tool for bundling and building
• Loaders for individual files
• Plugins for the complete bundle
Merci
@vintem12
Thiago Temple
https://templecoding.com