Construction d'un projet React avec configuration webpack manuelle

Mise en place d'un environnement React personnalisé

Première étape : Structuration des répertoires

Voici l'organisation des dossiers pour notre projet :

config

webpack.base.js webpack.dev.js webpack.pro.js

dist(dossier pour les fichiers compilés)

js css index.html

src(dossier principal)

actions apis assets composants mocks pages reducers routes store index.jsx(fichier d'entrée)

.babelrc(configuration de babel)

.gitignore(fichiers à ignorer pour git)

.npmignore(fichiers à ignorer pour npm)

package.json(fichier de configuration du paquet)

README.md(fichier descriptif du projet)

Deuxième étape : Configuration des fichiers webpack

// webpack.base.js
const chemin = require('path');
const ExtracteurCssMini = require('mini-css-extract-plugin');
const GenerateurHtml = require('html-webpack-plugin');
const { NettoyeurWebpack } = require('clean-webpack-plugin');

const resoudre = (url) => {
  return chemin.resolve(__dirname, url);
}

module.exports = {
  entry: resoudre("../src/index"),
  output: {
    path: resoudre("../dist/js"),
    filename: "js/principal.js",
    publicPath: "/",
    library: "MaBibliotheque",
    libraryTarget: "umd",
  },

  module: {
    rules: [
      {
        test: /\.js|jsx$/,
        exclude: /node_modules/,
        include: [
          resoudre("../src")
        ],
        loader: "babel-loader",
        options: {
          presets: ["@babel/preset-env", "@babel/preset-react"]
        },
      },
      {
        test: /\.html$/,
        use: [
          "htmllint-loader",
          {
            loader: "html-loader"
          }
        ]
      },
      {
        test: /\.less$/,
        use: [
          {
            loader: ExtracteurCssMini.loader,
            options: {
              publicPath: './css'
            },
          },
          'css-loader',
          'less-loader',
        ]
      },
      {
        test: /\.css$/,
        exclude: /node_modules/,
        use: [
          {
            loader: ExtracteurCssMini.loader,
          },
          'css-loader'
        ]
      },
      {
        test: /\.(png|jpg|gif)$/,
        use: [
          {
            loader: 'url-loader',
            options: {
              limit: 8192
            }
          }
        ]
      }
    ],
  },
  resolve: {
    modules: [
      "node_modules",
      resoudre("src")
    ],
    extensions: [".js", ".json", ".jsx", ".css", ".less"],
    alias: {
      "Actions": resoudre("../src/actions"),
      "Apis": resoudre("../src/apis"),
      "Assets": resoudre("../src/assets"),
      "Composants": resoudre("../src/composants"),
      "Mocks": resoudre("../src/mocks"),
      "Pages": resoudre("../src/pages"),
      "Reducers": resoudre("../src/reducers"),
      "Routes": resoudre("../src/routes"),
      "Store": resoudre("../src/store"),
    },
  },
  plugins: [
    new ExtracteurCssMini({
      filename: 'css/[name].css',
      chunkFilename: 'css/[id].css',
    }),
    new GenerateurHtml({
      filename: 'index.html',
      template: resoudre('../src/assets/index.html')
    }),
    new NettoyeurWebpack(),
  ],
}


// webpack.dev.js
const PluginTableauBord = require('webpack-dashboard/plugin');

const chemin = require('path');
const webpack = require('webpack');

const configuration = require('./webpack.base');

const resoudre = (url) => {
  return chemin.resolve(__dirname, url);
}

process.env.NODE_ENV = 'development';

module.exports = {
  ...configuration,
  mode: 'development',
  devtool: "source-map",
  context: __dirname,
  target: "web",
  stats: "errors-only",
  devServer: {
    proxy: { 
      '/api': 'http://localhost:8888'
    },
    publicPath: "/",
    contentBase: resoudre('../dist/index.html'),
    compress: true,
    port: 3333,
    open: true,
    hot: true,
    after: function(app, serveur, compilateur) {
      console.log(app, serveur, compilateur);
    }
  },

  plugins: [
    ...configuration.plugins,
    new PluginTableauBord(),
    new webpack.HotModuleReplacementPlugin(),
  ]
}


// webpack.pro.js
const PluginTerser = require('terser-webpack-plugin');
const webpack = require('webpack');

const configuration = require('./webpack.base');

process.env.NODE_ENV = 'production';

module.exports = {
  ...configuration,
  mode: 'production',
  devtool: "enum",
  stats: "errors-only",
  optimization: {
    splitChunks: {
      cacheGroups: {
        communs: {
          name: "fournisseur",
          filename: 'fournisseur-[hash].min.js',
          minChunks: 2
        }
      }
    },
    minimizer: [
      new PluginTerser({
        cache: true,
        parallel: true,
        sourceMap: true,
      }),
    ]
  },
  plugins: [
    ...configuration.plugins,
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': '"development"',
    }),
    new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
  ]
}


Troisième étape : Création du fichier d'entrée

// index.jsx
import React from "react";
import ReactDOM from "react-dom";

import BonjourMonde from 'composants/test/BonjourMonde';

function afficher() {
  console.log(111);
  ReactDOM.render(
    <BonjourMonde />,
    document.getElementById("racine")
  );
}

afficher();


Conclusion

La configuration de base pour un projet React est maintenant opérationnelle. Vous pouvez maintenant personnaliser ce setup selon les besoins spécifiques de votre projet.

Problèmes rencontrés

  1. En raison de l'utilisation d'une version récente de webpack, de nombreuses configurations ont changé.
  • Par exemple, webpack.optimize.CommonsChunkPlugin est devenu l'option optimization.splitChunks.
  • webpack.optimize.UglifyJsPlugin est maintenant dans optimization.minimizer.
  • extract-text-webpack-plugin n'est plus compatible avec webpack 4.0+, donc j'ai utilisé mini-css-extract-plugin comme alternative.
  1. Pour démarrer webpack-dev-server, il est nécessaire de spécifier le fichier de configuration avec la commande webpack-dev-server --config config/webpack.dev.js.

Prochaines étapes

Il serait intéressant d'ajouter un routage avancé, une configuration Redux et d'autres fonctionnalités spécifiques à votre projet actuel.

Étiquettes: React webpack Configuration babel JavaScript

Publié le 1 août à 05h02