webpack is a very popular Web asset bundler (GitHub shows it being used by 3.9m repos). First introduced in 2012, the current version is webpack 4 (with version 5.0 in the works).
webpack is extremely capable but it is also quite complex to configure correctly. Out of the box it does offer a zero-configuration mode, but to do anything worthwhile with webpack 4 you need to create a configuration file.
Some of the things you'd expect a bundler to do for you include:
- Bundle and minify Javascript
- Bundle and minify CSS
- Minimize images
- Cache bust assets
- Compile SASS/LESS
- Compile TypeScript/CoffeeScript
- Build for dev or production
- Work with multiple entry points
- Code splitting
- Hot module replacement
The last two tasks above are probably not "basic" things; they would probably be used more in very large applications. However, most of the other tasks above are usually used in apps of any size.
To perform the basic tasks above webpack needs several (at least 6 or 8) plugins and at least a 100+ line configuration file. webpack configuration gets more even more complex when you throw code splitting and hot module replacement into the mix. Once you understand webpack's general concepts, configuring it isn't as hard as it first looks--but it is fiddly and requires some dedicated study and a solid knowledge of the most-frequently used webpack plugins.
If you need help learning webpack, Colt Steele's 10-part YouTube series is highly recommended. He covers all but the last two items in the list above. This Smashing Magazine article is also very helpful.
Introducing Parcel
webpack is infinitely configurable and may be needed for very large apps with complex needs. However, for many applications webpack is JustTooMuch™. One superb alternative to webpack is Parcel. Parcel's first GA was released in September, 2018. While 3.9m GitHub repos use webpack, Parcel is only used by 6.7K repos. Despite its relative youth, though, Parcel is a mature and quite capable bundler and substantially easier to get up and running than webpack is.
Using Parcel with SASS
1 |
node_modules/.bin/parcel src-sass/index.html --public-url ./ |
Use the
--public-url
./ option when you're using a build server like VS Code's LiveServer or displaying the HTML from your local file system with thefile://
protocol.
A way to do a hot reload is to start parcel like this:
1 |
npm parcel watch src-sass/*.html --public-url ./ |
and use VS Code's Live Server to view pages.
Using Parcel's watch mode with VS Code's LiveServer
By default, Parcel sets the public URL to /
which produces asset URLs preceded by a single slash as shown below. When using VS Code's Live Server that single slash causes assets to not be found with Parcel's watch
mode.
1 2 |
<script src="/vendor.11ac4098.js"></script> <script src="/js.5c615dc2.js"></script> |
To fix this, set Parcel's --public-url option to ./
when using Parcel's watch
command.
1 |
node_modules/.bin/parcel src/index.html watch --port 8080 --public-url ./ |
This produces asset URLs without the preceding slash as shown below.
1 2 |
<script src="vendor.11ac4098.js"></script> <script src="js.5c615dc2.js"></script> |
Note: Use the --public-url option for Parcel's
watch
mode specifically when using VS Code's LiveServer.
TypeScript stuff
You should do this!
1 |
npm install --save-dev @types/node |
A starter tsconfig.json file for TypeScript
1 2 3 4 5 6 7 8 9 |
{ "compilerOptions": { "module": "commonjs", "target": "ES6", "noImplicitAny": false, "sourceMap": true, "outDir": "./js" } } |
Example folder structure
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
┌── app │ ├── alert.service.js │ ├── app.js │ ├── component.service.js │ └── utils │ ├── inputs-are-valid.js │ └── parse-inputs.js ├── assets │ ├── images │ │ └── webpack.svg │ ├── js │ │ ├── index.js │ │ └── vendor.js │ └── sass │ └── main.scss |
Without any configuration, use this command line (where the only argument is the app's entry point):
1 |
node_modules/.bin/parcel src/index.html |
to produce a dist
folder with the packaged application in dev mode (that is, nothing is yet minimized).
1 2 3 4 5 6 7 8 9 |
┌── dist │ ├── index.html │ ├── js.5c615dc2.css │ ├── js.5c615dc2.css.map │ ├── js.5c615dc2.js │ ├── js.5c615dc2.js.map │ ├── vendor.11ac4098.js │ ├── vendor.11ac4098.js.map │ └── webpack.46713f8f.svg |
Plugins
Automatically clearing Parcel's dist
directory
Parcel doesn't implicitly provide for automatically clearing the dist
directory. However, there is a Parcel plugin, parcel-plugin-clean-dist, that does that:
1 |
npm install --save-dev parcel-plugin-clean-dist |
Compressing images
Parcel doesn't implicitly provide for compressing images. However there is a Parcel plugin, parcel-plugin-imagemin, that does that:
1 |
npm install --save-dev parcel-plugin-imagemin |