Webpack: Using loaders

2 minute read

TIL how to use webpack loaders to transpile React code to ES5, and compile .less stylesheets to .css.

Click here for my previous TIL on setting up webpack-dev-server.

Webpack loaders are used to preprocess the files that are required in your webpack bundle. Loaders perform transformations on files based on a “test” that you provide to webpack in its config. See here for a list of loaders supported by Webpack.

The following gist contains the webpack config I will reference throughout this post.

Anatomy of loader Configuration

In webpack 2, loaders are listed under the module.rules key of your webpack config. You will need to install loaders with the package manager of your choice (npm or yarn) and include them in your package.json as dev dependencies.

module.rules is a list of objects, each of which is a separate loader with its own configuration. Configurations generally follow the following pattern:

  • test: The regex used to to match which files will be targeted by the loader. If the regex matches a loaded (required) file in your bundle, that file will be processed by the loader.

  • use: Defines the loader to use when the test matches a file. Loaders can be chained together using an exclamation point !, to pass the result of one loader to another during a single file load. Chaining occurs from right to left: i.e. in the scenario use: 'css-loader!less-loader' like I have above, the less file is passed to the less loader first (which compiles the less stylesheet to css) and the resulting css is then passed to the css loader for further processing.

  • exclude: Can be a list or a single regex. This option is used to exclude files or folders that would have otherwise matched the test. There is also an “include” option, which acts as a whitelist instead of a blacklist (include is a better approach… I should change my config).

  • enforce: Tells when the loader should be enforced in the loader lifecycle. For example: the ‘eslint-loader’ above is configured as ‘pre’ and matches on files that end in .js. This means the eslint-loader will process js files before they are transpiled by the babel-loader.

It’s as simple as that! Files will be passed through the loader module.rules matchers each time webpack re-bundles your files. Most loaders have loader-specific configuration that can be applied as well, for further customization to meet your application’s specific needs. For specifics, I would point you at the list of loaders which webpack keeps in their documentation.

url-loader callout

One loader that I didn’t mention here that I recently learned of is the url-loader. This loader checks the filesize of images or files that it encounters: if the filesize is small enough (configurable size in bytes) url-loader will inline the file into your HTML by base64 encoding it and swapping out the URL with data URI. If a filesize is larger than the configured limit, url-loader will swap out the URL in your HTML for a hashed version of the URL, and will include this new URL at the publicPath.

This loader is useful, because it reduces the number of HTTP requests required by your application for the smaller files that would be better off inlined into the HTML itself. Pretty nifty.

The more I learn about webpack, the more I find it’s capable of! The next installment in this series will be about plugins, particularly the ExtractTextPlugin and the webpack.optimize.CommonsChunkPlugin which allow you to split your bundles in to smaller chunks. EDIT: Find that post here!