Webpack
- 19. “This is my webpack.config.js. There are many like it, but
this one is mine.”
Editor's Notes
- Let’s talk about documentation…
- Split the dependency tree into chunks loaded on demand
Keep initial loading time low
Ability to integrate 3rd-party libraries as modules
Ability to customize nearly every part of the module bundler
Suited for big projects
Configuration-based systems are preferable to imperative systems if they make the right assumptions about your goals up front.
Webpack assumes you need to move files from a source directory to a destination directory.
It assumes you want to work with JavaScript libraries in various module formats like CommonJS, and AMD.
It assumes you’ll want to compile various formats using a long list of loaders. Sure, you can do all this via Browserify and Gulp, but you have to do more wiring yourself. And you’re manually wiring together two totally separate technologies.
- Basic webpack usage
Jump to console
- http://webpack.github.io/docs/loaders.html
Specifying loaders in each module request can be brittle and repetitive. Webpack provides a way to specify which loaders apply to different file types in your Webpack configuration file. Specifying loaders in the configuration is the recommended approach in most cases as it doesn’t add any build specific syntax to the code, making it more reusable.
After the file is read from the filesystem, loaders are executed against it in the following order.
preloaders specified in the configuration
loaders specified in the configuration
loaders specified in the request (e.g. require('raw!./file.js'))
postLoaders specified in the configuration
You can also override the configuration loader order in the module request to suit special cases.
You can write custom loaders:
Sync
Async
Raw
By default the resource file is treated as utf-8 string and passed as String to the loader. By setting raw to true the loader is passed the raw Buffer.
- http://webpack.github.io/docs/loaders.html
Basic loader
- http://webpack.github.io/docs/loaders.html
Loader with parameter
The format of the query string is up to the loader, so check the loaders documentation to find out about the parameters the loader accept, but generally most loaders support the traditional query string format.
- http://webpack.github.io/docs/usage.html
- http://webpack.github.io/docs/usage.html
- http://webpack.github.io/docs/usage.html
We are excluding node_modules here because otherwise all external libraries will also go through Babel, slowing down compilation.
- http://webpack.github.io/docs/usage.html
The Uglify plugin is included with webpack so you don’t need to add additional modules, but this may not always be the case. You can write your own custom plugins. For this build, the uglify plugin cut the bundle size from 1618 bytes to 308 bytes
- https://webpack.github.io/docs/plugins.html
Eh… go read. Write your own.
Basically, these have access to some of the internal webpack objects, and they have a plugin method that allows you to inject custom build steps.
Think of MS Build Tasks
The plugin calls bind callbacks to fire at specific steps throughout the build process.
A plugin is installed once as Webpack starts up. Webpack installs a plugin by calling its apply method, and passes a reference to the Webpack compiler object. You may then call compiler.plugin to access asset compilations and their individual build steps.
- https://webpack.github.io/docs/webpack-dev-server.html
Uses a small expressJS server and webpack-dev-middleware to serve a webpack bundle
Also has a runtime attached via Socket.IO
Server emits info about compilation state to the client
The webpack-dev-server will serve the files in the current directory, unless you configure a specific content base.
- https://webpack.github.io/doc
It’s an opt-in feature. You can define split points in your code base. Webpack takes care of the dependencies, output files and runtime stuff.
To clarify a common misunderstanding: Code Splitting is not just about extracting common code into a shared chunk. The more notable feature is that Code Splitting can be used to split code into an on demand loaded chunk. This can keep the initial download small and downloads code on demand when requested by the application.
s/code-splitting.html
CommonJS: require.ensure(dependencies, callback)
Note: require.ensure only loads the modules, it doesn’t evaluate them.
The require.ensure method ensures that every dependency in dependencies can be synchronously required when calling the callback. callback is called with the require function as parameter.
AMD: require(dependencies, callback)
When called, all dependencies are loaded and the callback is called with the exports of the loaded dependencies.
tl;dr: Webpack doesn’t support ES6 modules; use require.ensure or require directly depending on which module format your transpiler creates.
- https://webpack.github.io/docs/code-splitting.html
If two chunks contain the same modules, they are merged into one. This can cause chunks to have multiple parents.
If a module is available in all parents of a chunk, it’s removed from that chunk.
If a chunk contains all modules of another chunk, this is stored. It fulfills multiple chunks.
Depending on the configuration option target a runtime logic for chunk loading is added to the bundle. I. e. for the web target chunks are loaded via jsonp. A chunk is only loaded once and parallel requests are merged into one. The runtime checks for loaded chunks whether they fulfill multiple chunks.
Entry chunk
An entry chunk contains the runtime plus a bunch of modules. If the chunk contains the module 0the runtime executes it. If not, it waits for chunks that contains the module 0 and executes it (every time when there is a chunk with a module 0).
Normal chunk
A normal chunk contains no runtime. It only contains a bunch of modules. The structure depends on the chunk loading algorithm. I. e. for jsonp the modules are wrapped in a jsonp callback function. The chunk also contains a list of chunk id that it fulfills.
Initial chunk (non-entry)
An initial chunk is a normal chunk. The only difference is that optimization treats it as more important because it counts toward the initial loading time (like entry chunks). That chunk type can occur in combination with the CommonsChunkPlugin.
- With the CommonsChunkPlugin the runtime is moved to the commons chunk. The entry points are now in initial chunks. While only one initial chunk can be loaded, multiple entry chunks can be loaded. This exposes the possibility to run multiple entry points in a single page.
- webpack -p --config webpack.production.config.js
-d includes source maps
- https://medium.com/@dtothefp/why-can-t-anyone-write-a-simple-webpack-tutorial-d0b075db35ed#.irh9sqwg4
- Enhance debugging with sourcemaps, linters, etc.