Using loaders with webpack

We have seen how we can bundle JavaScript together using webpack. In this chapter we will explore loaders to inline stylesheets, assets and pre-process our JavaScript before bundling it.

Prerequisite reading:

To see practical application, you may skip ahead to the example section.

Loaders, what and why ?

A loader can transform a single file into something else. They can for instance be applied to transform a different language like CoffeScript to JavaScript, or inline images as data. Loaders can be chained together in order to achieve a final output.

Loading Css

Style preprocessors allow us to be more efficient when writing our styles by effectively writing fewer lines of code.

Recall that we required all of our JavaScript into css-challenge.js.

var Input = require(‘./input’);
var View = require(‘./view’);

Similarly we can require a css file using a loader.

require(‘style-loader!./my-style.css’);

Style-loader extracts css from my-style.css and inline it. The exclamation mark (!) separates a loader from a file or a different loader. Multiple loaders can be chained.

require(‘style-loader!css-loader!less-loader!./my-styles.less’);

The right-most loader is applied first, before piping the output through each part of the chain. In this case less-loader will transpile our less file into a css file, then css-loader will resolve css resources such as images, urls and fonts, before style-loader inlines the css file.

The example

H5p-css-challenge separates scripts and styles into folders.

We require all styles at the top of css-challenge.js

require('style-loader!css-loader!../styles/input.css');
require('style-loader!css-loader!../styles/layout.css');
require('style-loader!css-loader!../styles/view.css');

At this point we can try to pack our bundle.

webpack scripts/css-challenge.js bundle.js

This will produce an error.

Module not found: Error: Cannot resolve module ‘style-loader’

Loaders are not automatically included inside webpack. In order to get make loaders work we have to grab them from npm. 

npm install -D style-loader css-loader

If we install modules using the -D flag they will be saved as a development dependency. Packing it once again should yield a valid bundle.

Updating our library.json

Since we have inlined our styles, we no longer have to require them from our library config. Open up library.json, and remove the following:

  "preloadedCss": [
    {"path": "styles/input.css"},
    {"path": "styles/layout.css"},
    {"path": "styles/view.css"}
  ]

Our library.json should now only include bundle.js as a dependency.

{
  "title": "Css challenge",
  "description": "Write the correct css",
  "majorVersion": 1,
  "minorVersion": 0,
  "patchVersion": 0,
  "runnable": 1,
  "author": "Thomasmars",
  "license": "cc-by-sa",
  "machineName": "H5P.CssChallenge",
  "preloadedJs": [
    {"path": "bundle.js"}
  ]
}

Where preloadedJs is our focus.

Next time we will use the concepts we have learned and look at how we can write a webpack configuration file in order to avoid typing in the loaders every time you require something, and automatically apply different loaders to different file formats.