Imagine you have a React project with the following package.json
:
{
"dependencies": {
"react": "15",
"react-dom": "15"
}
}
You have an index.html
:
<!-- index.html -->
<html>
<body>
<div id="root"></div>
<script src="main.js"></script>
</body>
</html>
And your main.js
looks like this:
// main.js
var React = require('react');
var ReactDOM = require('react-dom');
function Component(props) {
return <h1>Hello, {props.name}!</h1>;
}
ReactDOM.render(
<Component name='Mark' />,
document.getElementById('root')
);
If you try to load the page, it fails because the browser doesn’t understand JSX syntax.
As a result, the code needs to be transpiled for it to be run in the browser. Here’s where webpack, a module bundler, comes in.
Dependencies
Install webpack:
$ npm install [email protected]
Then install babel-loader and babel-core, which will help with the transpilation:
$ npm install [email protected] [email protected]
To transpile JSX, you’ll need babel-preset-react:
$ npm install [email protected]
Configuration
Create your webpack config:
// webpack.config.js
module.exports = {
entry: './main.js',
output: {
path: __dirname,
filename: 'bundle.js'
},
module: {
loaders: [
{
loader: 'babel-loader',
query: {
presets: ['react']
},
// match files based on pattern
test: /\.js$/,
// ignore files matching pattern
exclude: /node_modules/
}
]
}
};
You could also create a build script in your package.json
:
{
"scripts": {
"build": "webpack"
}
}
To generate the bundle, run:
$ npm run build
Update index.html
with the new file path:
<!-- index.html -->
<html>
<body>
<div id="root"></div>
<script src="bundle.js"></script>
</body>
</html>
When you refresh the page, the app now loads.
ES6
But what if you want to use ES6 syntax?
You’ll need babel-preset-es2015:
$ npm install babel-preset-es2015
Add the preset to your webpack config:
// webpack.config.js
module.exports = {
// ...
module: {
loaders: [
{
loader: 'babel-loader',
query: {
// add `es2015` to presets
presets: ['react', 'es2015']
},
// ...
}
]
}
};
Now you can refactor main.js
with ES6:
// main.js
import React from 'react';
import { render } from 'react-dom';
const Component = ({ name }) => <h1>Hello, {name}!</h1>;
render(
<Component name='Mark' />,
document.getElementById('root')
);
Don’t forget to rebuild your bundle before refreshing the page:
$ npm run build
.babelrc
Alternatively, you can keep your babel presets in .babelrc:
{
"presets": ["react", "es2015"]
}
Instead of defining them in your webpack config:
// webpack.config.js
module.exports = {
// ...
module: {
loaders: [
{
loader: 'babel-loader',
// query: {
// presets: ['react', 'es2015']
// },
test: /\.js$/,
exclude: /node_modules/
}
]
}
};