Loaders are transformation programs that run on the source files individually. For example, you'd use loaders to transform CoffeeScript/TypeScript into ES5 before bundling them; in our case, we use it to transform ES2015+ syntax and JSX into ES5. First, let's install the loader using yarn.
$ yarn add babel-loader --dev
Next, we will update webpack.config.js to instruct Webpack to use the loader. We can do this by defining loader specifications inside the module.rules property.
const webpack = require('webpack');
module.exports = {
entry: { app: './src/index.jsx' },
output: { filename: 'bundle.js' },
module: {
rules: [{
test: /\.jsx?$/,
exclude: /node_modules/,
use: [{
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env', '@babel/preset-react'],
plugins: [require('@babel/plugin-proposal-class-properties')],
},
}],
}],
},
};
Each loader specification contains two important sub-properties:
- test determines which files should be processed by this loader. Here, we are using a regular expression, /\.jsx?$/, to tell Webpack to use this loader to process all files with an extension of .jsx.
- use specifies which loaders should be used to transform these files, plus any additional options to pass into the loaders. Here, we are instructing Webpack to use the babel-loader module we just installed, and Babel should use the React and env presets, as well as the Transform Class Properties plugin.
Now, when we run webpack again, you will see that dist/bundle.js being created.
$ npx webpack
Hash: adbe083c08891bf4d5c7
Version: webpack 4.6.0
Time: 4933ms
Built at: 2018-04-24 19:34:55
Asset Size Chunks Chunk Names
bundle.js 322 KiB 0 [emitted] [big] app
Entrypoint app [big] = bundle.js
[7] (webpack)/buildin/global.js 489 bytes {0} [built]
[73] (webpack)/buildin/module.js 497 bytes {0} [built]
[74] ./src/utils/index.js 324 bytes {0} [built]
[120] crypto (ignored) 15 bytes {0} [optional] [built]
[121] buffer (ignored) 15 bytes {0} [optional] [built]
[153] util (ignored) 15 bytes {0} [built]
[155] util (ignored) 15 bytes {0} [built]
[162] ./src/index.jsx 327 bytes {0} [built]
+ 155 hidden modules
Now that we have bundle.js at the root of the dist/ directory, we should update our src/index.html to use the bundled script. Replace the <script type="text/babel">...</script> block with <script src="/bundle.js"></script>.
However, the index.html is not copied across from the src/ directory to the dist/ directory. This is because Webpack only processes JavaScript (.js / .mjs), JSON, and WebAssembly files (.wasm). To copy the index.html file across, we need another type of tool called a plugin.