Code spliting in webpack to help decrease loaded dependencies on load.
- UI that gets displayed as a callback from an event can benefit.
- We can async. load a ES6
import()
and code after it is returned using a promise.
// At top of file, assign an `import()` that is returned from a function.
const getBloodhound = () => import('bloodhound-js');
// Add an event that will trigger loading the module.
this.searchTrigger.addEventListener('click', () => {
// Call the reference to the `import()` and return a promise.
getBloodhound().then((Bloodhound) => {
// Do stuff here after the module is loaded and ready.
// `Bloodhound` is an example of a named export we can access from the module.
});
});
- Everything is a plugin! Mastering webpack from the inside out - Sean Larkin
- CSS-Tricks Screencast #156: Let's Talk About Webpack
This basic set up in package.json
will compile a single JS file.
- To create a
package.json
file runnpm init
. - install Webpack
npm install webpack --save-dev
{
"name": "webpack-starter",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "webpack src/main.js dist/bundle.js",
"watch": "webpack src/main.js dist/bundle.js --watch",
},
"devDependencies": {
"webpack": "^2.2.1"
}
}
- When running
webpack
, it's default location is in the root of the project. - Specifying a different location is done by using
--config
flag. path
is used to create an absolute path which is usually required.
var webpack = require('webpack');
var path = require('path');
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, './dist'),
filename: 'bundle.js'
}
}
package.json
would be updated to the following:
{
'scripts': {
'build': 'webpack',
},
}
- update
package.json
to flag production and dev
{
'scripts': {
'build': 'webpack',
'production': 'NODE_ENV=production webpack',
'watch': 'npm run build -- --watch'
},
}
- add variable to
webpack.config.json
to test when the production flag is set.
var inProduction = (process.env.NODE_ENV === 'production')
- allows you to keep pieces of code in other files and import them.
//== ECMAScript 2015 Syntax
// This function in `yap.js` is being exported
export default function (yap) {
alert(yap);
}
// It can be used in `main.js` using an import statement
import growl from './yap';
growl('Alert');
//== CommonJS Syntax (deprecated)
// This function in `yap.js` is being exported
module.exports = function (yap) {
alert(yap);
}
// It can be used in `main.js` using an import statement
var growl = require('./yap');
growl('Alert');
- Loaders deal with requiring Sass, compiling with Babel and alike.
- Example,
css-loader
installed from npm can be configured inwebpack.config.json
to load a CSS file.style-loader
installed from npm can then inject the<style />
into the<head>
of the document
// entry points, etc ...
module: {
rules: [
{
css: /\.css$/,
// reads right to left
use: ['style-loader', 'css-loader'],
}
]
}
- Example Babel loader, also requires additional configuration using a
.babelrc
file.
// entry points, etc ...
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
query: {
presets: ['es2015'],
},
},
]
}
- Example, adding
sass
loader - also need to run
npm install sass-loader node-sass --save-dev
sass-loader
handles Webpack process;node-sass
handles the compiling
// entry points, etc ...
module: {
rules: [
{
test: /\.scss$/,
// reads right to left
use: ['style-loader', 'css-loader', 'sass-loader'],
},
]
}
- Example, referencing relative image paths.
- Note, existing absolute paths can be solved w/o loader
background: url('/img/test.jpg')
- use
file-loader
npm install file-loader --save-dev
// entry points, etc ...
module: {
rules: [
{
test: /\.(png|jpg|gif|svg|eot|ttf|woff|woff2)$/,
loader: 'file-loader',
options: 'images/[name].[hash].[ext]',
},
]
}
- plugins extend webpack functionality.
- Example, minify JS on build for production
if (process.env.NODE_ENV === 'production') {
module.exports.plugins.push (
new webpack.optimize.UglifyJsPlugin();
);
}
script
can be added topackage.json
like so:
//...
develop: "webpack",
production: "NODE_ENV=production webpack"
//...
- Example, compile SCSS styles to an external file.
- Use
extract-text-webpack-plugin
- Run
npm install extract-text-webpack-plugin
const ExtractTextPlugin = require('extract-text-webpack-plugin');
// ...
module: {
rules: [
{
test: /\.scss$/,
use: ExtractTextPlugin.extract({
// reads right to left
use: ['css-loader', 'sass-loader'],
fallback: 'style-loader',
}),
},
],
},
plugins: [
new ExtractTextPlugin('[name].css'),
],
- hashing generated files allow for long term caching
- Webpack has hashing built in
- Here is some code:
module.exports = {
entry: {
app: './src/main.js'
},
output: {
path: path.resolve(__dirname, './dist'),
// filename: '[name].js',
// filename: '[name].[hash].js', [hash] adds current hash for build.
// filename: '[name].[chunkhash].js', [chunkhash] hash for single file.
}
}
- [hash] works well if only one file is being cached
- [chunkhash] is better for multiple file b/c each file gets it's own hash when it has been changed. This allows files that have not changed to keep it's previous hash remain cached.
- to deal with files being added to the
dist/
directory on each run, a plugin can be used to remove and recreate thedist
folder on each build. An example plugin to use is calledclean-webpack-plugin