by Fabian Ihl
Webpack is NOT a task runner
≠
Will it replace my task runner?
Maybe...
"Webpack is a module bundler for modern JavaScript applications"
It will resolve any kind of dependency ...
and bundle them into a final build
It will transpile / process
And do a lot more ...
What is a module?
How do I declare dependencies?
Supported are CommonJS, AMD and ES2015 imports
var SomeModule = require('./some-module.js');
SomeModule.doAwesomeStuff();
"require" the module
Use it
module.exports = {
doAwesomeStuff: function() {...}
}
function somePrivateMethod() {...}
function doAwesomeStuff() {...}
module.exports = {
doAwesomeStuff: doAwesomeStuff
}
not exported
exported
(function() {
'use strict';
module.exports = {
doAwesomeStuff: function() {...}
}
})();
import {myMember} from 'my-module';
import {foo, bar} from 'my-module';
import {longModuleMemberName as shortName} from 'my-module';
Import one member
Import multiple members
Use aliases
function somePrivateMethod() {...}
export function doAwesomeStuff() {...}
var data = require('someData.json');
Will load the json data and convert them to an object.
var template = require('template.html');
Will return the template as string or template funtion
require('prettyStyles.css');
Will inject the css as style block into the <head> section
Such files will usualy be bundled into the corresponding js bundle saving additional http requests.
.button-delete {
background-image: url('./assets/deleteIcon.png');
}
Will...
<img src=require("./assets/someImage.png")/>
const path = require('path');
module.exports = {
entry: './app/index.js',
output: {
filename: 'bundle[chunkhash].js',
path: path.resolve(__dirname, 'dist'),
},
};
(Yes, it's a module, too)
Your main script file as entry point.
Output config
Name of your final js bundle, with cache busting enabled
Output folder
const path = require('path');
module.exports = {
entry: './app/index.js',
output: {
filename: 'bundle[chunkhash].js',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [
{test: /\.(jpe?g|png|gif|svg)$/i, use: ['file-loader']},
{test: /\.css$/, use: ['style-loader', 'css-loader']},
],
},
};
Loaders are defined in the module section, they tell webpack how to recognize and handle files.
Handling assets using the file-loader.
Loaders can be chained.
There are loaders for almost everything out there.
Entrypoint will always be a js file.
How do we tell wepack to handle our index template?
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
module.exports = {
entry: './app/index.js',
output: {
filename: 'bundle[chunkhash].js',
path: path.resolve(__dirname, 'dist'),
},
plugins: [
new HtmlWebpackPlugin({ template: './src/index.html', }),
]
};
Require the plugin
Plugin section
HtmlWebpackPlugin will ...
$ webpack
Will look for webpack.config.js and build your app as configured
$ webpack-dev-server
Will look for webpack.config.js and launch a dev server with auto reload
Splitting bundles
const webpack = require('webpack');
const path = require('path');
module.exports = {
entry: {
'app': './src/app.js',
'vendor': './src/vendor.js',
},
output: {
filename: '[name]-[chunkhash].js'
path: path.resolve(__dirname, 'dist'),
},
module: {...},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: ['vendor', 'manifest']
}),
]
};
Define multiple entry points
Use the CommonsChunkPlugin to build chunks
This will create:
module.exports = {
entry: './src/entry.js',
output: {...},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: "eslint-loader",
options: {
// eslint options (if necessary)
}
},
],
},
};
Have a look at karma-webpack
or mocha-loader
For a full sample have a look at the config of this presentation:
var HtmlWebpackPlugin = require('html-webpack-plugin');
var path = require('path');
var webpack = require('webpack');
module.exports = {
entry: {
'main': './src/main.js',
'vendor': './src/vendor.js',
},
resolve: {
modules: [
'node_modules',
path.join(__dirname, 'src'),
]
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name]-[chunkhash].js',
},
module: {
rules: [
{test: /\.pug$/, use: ['pug-loader']},
{test: /\.css$/, use: ['style-loader', 'css-loader']},
{test: /\.styl$/, use: ['style-loader', 'css-loader', 'stylus-loader']},
{test: /\.(jpe?g|png|gif)$/i, use: ['file-loader']},
{test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, use: ['file-loader']},
{test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, use: ['svg-url-loader?noquotes']},
{test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, use: ['file-loader']},
{test: /\.woff(\?v=\d+\.\d+\.\d+)?$/, use: ['file-loader']},
{test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/, use: ['file-loader']},
]
},
plugins: [
new HtmlWebpackPlugin({ template: 'src/index.pug', }),
new webpack.optimize.CommonsChunkPlugin({
name: ['vendor', 'manifest']
})
],
devServer: {
host: '0.0.0.0',
},
};
const webpack = require('webpack');
const merge = require('webpack-merge');
const base = require('./webpack.config');
module.exports = function(env) {
return merge(base, {
plugins: [
new webpack.LoaderOptionsPlugin({
minimize: true,
debug: false
}),
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': JSON.stringify('production')
}
}),
new webpack.optimize.UglifyJsPlugin({
beautify: false,
mangle: {
screw_ie8: true,
keep_fnames: true
},
compress: {
screw_ie8: true
},
comments: false
})
]
})
}
Official webpack docs:
View this presentation at:
akuryou.github.io/introduction-to-webpack
Clone it, fork it at: