Workshop: Webpack - Part 1: Theory
von Matthis Buschtöns (Kommentare: 0)
Due to the fact that webpack is a very complex subject I will split my posts in 3 parts which will be posted every 2 weeks.
Today we're starting with a little theory.
What is webpack?
In short, webpack is a JavaScript module bundler and its main purpose is reducing the initial load of your website. It combines the idea of building your assets and bundling them into one by analyzing the dependencies of the configured entry point. By having the opportunity to use synchronous and asynchronous dependencies, webpack is able to split the code into chunks to create contextual bundles.
Why do I need it?
Think about having a complex website. The easiest way to load your code is bundling it into one giant file - the main.js. It can easily reach a total size of 30mb. Now imagine the client is browsing with 3G-Network and is visiting your website. What happens? In order to navigate on your website, the client needs to download the whole main.js first. This will take ages.
According to a research from Doubleclick (owned by Google) published in September 2016: "Slow loading sites frustrate users and negatively impact publishers. In our new study, "The Need for Mobile Speed", we found that 53% of mobile site visits are abandoned if pages take longer than 3 seconds to load." (Source: http://www.hobo-web.co.uk/your-website-design-should-load-in4-seconds/)
So, as you can think, our clients will jump off our website faster than 30 speed, and will probably never come back again.
You'll need other strategies to keep the users on your website. The common way is to split the main.js and start to load dependencies on demand, but you still got most of the assets separated from your code which leads us to two of the frequently asked questions in web development: What else does this style affect? and Where else do we need it?
This is where webpack enters the court.
Webpack treats all the assets as modules. It doesn't matter whether you want to display images, transpile ES6-code, apply Stylesheets etc. You can import them, modify them and use them directly in your JavaScript and in the end they were packed into a bundle-file consisting of one or multiple chunks. With features like Hot Module Replacement, Code Splitting, its rich plugin system and the loader-principle webpack can become a very powerful friend, if you keep an eye on your website's architecture and follow the rules of modularization.
Okay, sounds handy. Tell me more.
For now, let's focus on two of the key-features: Code Splitting and Loaders
Code Splitting is a big thing in web-development. It is not efficient to put everything in one file, especially when some of the code isn't truly needed when you enter a website. Webpack solves this by splitting the code into on-demand chunks, which are loaded - guess what - only when you need them. It does that by distinguishing between two types of dependencies: synchronous and asynchronous.
If webpack's analyzing process runs over a synchronous imported module, the module will be packed directly into the current bundle-file. If the same module instead would be imported asynchronously, webpack would create a new, lazy-loaded chunk, and every dependency this module has will be packed into the same chunk. This goes on as long as an async dependency occurs, because then a new chunk will be formed with its own dependency-tree.
After all dependencies are analyzed and optimized, a file is emitted for each chunk.
Loaders help us to make webpack more powerful. Since webpack can only handle JavaScript natively, we need to use loaders to unleash the full functionality of webpack. They are special modules used to load other modules in another "language" and allow us to preprocess files as we use them. For example transpiling your ES6 code with babel, transforming inline images as data URLs or requiring stylesheets. We can even write our own custom loader if none of the existing ones cater to our needs. Common examples for loaders are:
css-loader: loads a stylesheet style-loader: applies the loaded stylesheet to the DOM file-loader: loads a binary file babel-loader: transpiles the given module
All of the loaders are installed via npm and can be used right in one of our modules
It's simply done by prepending the loader to the require path. The "!" separates the loader from the module and is used to chain loaders as well. The chaining is applied from right to left, so in this example, the css-loader is processed first. This is important to know when you, for example, use Sass, because the styles must be transformed to css first before you can apply them.
In conclusion: if you want to use a file that is not written in ECMAScript 5, you need to use a loader to make webpack handle it.
TL;DR
Webpack is an awesome tool, that can help you to solve many problems in web development. With Code Splitting you can implement route based chunking and decrease the loading time of the website. The Loaders help to organize the assets and modules, and with webpack's plugin system you can perform actions and custom functionality on your bundled modules or chunks. (I will talk about Plugins in one of the next posts.)
But it is only as powerful and helpful as you make it. Means that if you start to synchronously import all modules into one bundle and then use assets as modules as well, it makes it even more worse than the previous solution (the one with the giant main.js). So you have to keep an eye on your project structure and architecture.