Nous allons aujourd'hui découvrir comment configurer Webpack dans le cadre de l'utilisation de ReactJS et mettre en place React Hot Loader.
Gestion du JSX
La première étape est de mettre en place la configuration pour gérer les fichiers JSX. Pour cela nous allons utiliser babel (pour convertir le code en ES5) et webpack (pour gérer les imports de modules).
npm i -D babel-core babel-loader babel-preset-es2015 babel-preset-react cross-env react-hot-loader webpack webpack-dev-server
Nous utilisons cross-env afin de rendre la configuration compatible avec Windows. Afin de nous faciliter la vie nous allons créer plusieurs scripts qui serviront de racourci :
// ...
"scripts": {
"dev": "cross-env NODE_ENV=development webpack-dev-server --hot",
"build": "cross-env NODE_ENV=production webpack"
},
// ...
Maintenant nous allons configurer webpack et activer l'utilisation de babel pour traiter les fichiers .js
et .jsx
.
const path = require('path')
const webpack = require('webpack')
let config = {
entry: './src/main.jsx',
output: {
path: path.resolve(__dirname, 'assets'),
filename: 'main.js',
publicPath: '/assets/'
},
resolve: {
extensions: ['.js', '.jsx']
},
module: {
loaders: [{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
loader: 'babel-loader'
}]
},
plugins: [
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify(process.env.NODE_ENV)
}
})
]
}
if (process.env.NODE_ENV === 'production') {
config.plugins.push(
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
}
})
)
config.plugins.push(
new webpack.optimize.OccurrenceOrderPlugin()
)
}
module.exports = config
Enfin, il va falloir expliquer à babel comment gérer le JSX via son fichier de configuration .babelrc
{
"presets": ["es2015", "react"]
}
Et voila ! Avec cette configuration vous devriez être en mesure d'écrire et de tester votre projet.
React Hot Loader
React Hot Loader permet de faire fonctionner React avec le hot module replacement de webpack ce qui va vous permettre de recharger un composant sans recharger la page. Pour cela nous allons utiliser React Hot Loader.
npm i react-hot-loader
Nous allons ajouter ce loader à notre point d'entrée webpack
// On ajoute le loader
let config = {
// ...
module: {
loaders: [{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
loader: ['react-hot-loader/webpack', 'babel-loader']
}]
}
// ...
}
// ...
// On ajoute notre react-hot-loader/patch au point d'entrée
if (process.env.NODE_ENV != 'production') {
config.plugins.push(new webpack.NamedModulesPlugin())
config.entry = ['react-hot-loader/patch', config.entry]
}
On ajoute en plus le plugin NamedModulesPlugin qui permet d'afficher le nom original des fichiers dans la console lors du rechargement à chaud. Ensuite, il faut modifier notre projet pour englober notre application dans un container.
import React from 'react'
import ReactDom from 'react-dom'
import App from './components/App'
import {AppContainer} from 'react-hot-loader'
const renderApp = () => {
ReactDom.render(
<AppContainer><App/></AppContainer>,
document.getElementById('app')
)
}
if (module.hot) {
module.hot.accept('./components/App', renderApp)
}
renderApp()
Enfin, il faut aussi modifier notre configuration babel pour l'empêcher de réécrire l'import des modules afin de laisser webpack gérer les choses (et ainsi faire fonctionner le react hot loader).
{
"presets": [["es2015", {"modules": false}], "react"]
}
Maintenant, vous pouvez relancer npm run dev
et vous devriez voir vos composants se recharger automatiquement lors de vos changements.