【webpack 从入门到使用】webpack5 从零搭建一个基础的 react 项目

110 阅读2分钟

1. 初始化项目

创建一个空间文件夹 my-project,进入my-project 初始化项目:

npm init -y

2. 安装 webpack 相关的依赖:

安装 webpackwebpack-cliwebpack-dev-server

npm i -D webpack webpack-cli webpack-dev-server

3. 安装 html 模板解析

项目模板解析我们需要用到 html-webpack-plugin:

npm i -D html-webpack-plugin

4. 安装 babel 相关的依赖:

通常,线上运行的项目的 js 脚本都是 es5 (考虑兼容性),而我们源码编写的通常是 es6代码。因此,我们需要借助 babel 这个工具帮助我们做代码垫片(babel polyfill):

  • babel : babel 库
  • babel-loader : 处理 js 代码的 babel 解析器
  • @babel/core : babel处理代码核心,babel-loader 必须要依赖的
  • @babel/preset-env : babel的兼容环境预设,它可以帮助我们将 es6 语法转成 es5 语法
  • @babel/preset-react : babel 的 react 语法预设,它可以帮助我们解析 jsx 语法
npm i -D babel babel-loader @babel/core @babel/preset-env @babel/preset-react

5. 安装 style 相关(以 sass 为例)

# 开发请使用 style-loader , 生产构建请使用 MiniCssExtractPlugin
npm i -D sass sass-loader css-loader style-loader postcss-loader mini-css-extract-plugin

6. 安装 react 和 react-dom

在 react 项目中,reactreact-dom 是必不可少的:

npm i -S react react-dom

注意

react 和 react-dom 是否需要安装运行时依赖看项目上线情况而定(如果项目是将依赖分包打成 umd 模块的话可以使用开发时依赖) react 和 react-dom 安装的时候需要注意依赖版本(笔者这里是直接使用 v18.2.0

7. 在目录下面创建 webpack.config.jspublic/index.htmlsrc/index.jsx

my-project
|- node_modules
|- public
    |- index.html
    |- favicon.ico
|- src
    |- index.jsx
|- webpack.config.js

webpack.config.js

const { resolve } = require('path');

const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
  // 指定一下当前 webpack 服务器运行的环境, 取值: 'development' | 'production'
  mode: process.env.NODE_ENV || 'development',
  
  // 指定一下入口
  entry: {
    'index': resolve(__dirname, 'src/index.jsx'),
  },
  
  // 指定一下开发者工具
  devtool: 'source-map',
  
  // 打包信息配置
  output: {
    // 指定路径
    path: resolve(__dirname, 'dist'),
    // 指定文件名
    filename: '[name].[hash:8].js',
  },
  
  // 配置 plugins
  plugins: [
    // 配置 html-webpack-plugin
    new HtmlWebpackPlugin({
      title: 'React 学习',
      template: resolve(__dirname, 'public/index.html'),
      filename: 'index.html',
      minify: {
        collapseWhitespace: true,
        removeComments: true,
      },
      chunks: ['index'],
      excludeChunks: ['node_modules']
    }),
    
    // 初始化 mini-css-extract-plugin
    new MiniCssExtractPlugin({
      filename: '[name].[hash:8].css',
    })
  ],
  
  // 配置 loader
  module: {
    rules: [
      // 处理 js/jsx 脚本文件
      {
        test: /\.(js|jsx)$/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env', '@babel/preset-react'],
          }
        }
      },
      // 处理样式文件
      {
        test: /\.(css|sass|scss)/,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
          'sass-loader'
        ]
      }
    ],
  },
  
  // 配置相对路径和别名
  resolve: {
    alias: {
      '@': resolve(__dirname, 'src')
    },
    extensions: ['.js', '.jsx', '.json'],
  },
  
  // 配置开发服务器
  devServer: {
    host: '0.0.0.0',
    port: 8762,
    historyApiFallback: true,
    proxy: {}
  }
};

public/index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title><%= htmlWebpackPlugin.options.title %></title>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>

src/index.jsx

// 引入 react 中的 createElement 方法 
import { createElement } from 'react';
// 引入 createRoot 方法
import { createRoot } from 'react-dom/client';

// 1. 创建 react 元素
const reactElement = createElement(
  'div',
  {},
  'Hello world!'
);

// 2. 根据真实的 html 节点创建 reactRoot
const reactRoot = createRoot(document.getElementById('root'));

// 3,使用 reactRoot 把 react 元素渲染到真实的 dom 节点中
reactRoot.render(reactElement);

8. 给 package.json 添加两条命令

package.json

{
  "scripts": {
    "dev": "NODE_ENV=development webpack-dev-server --config ./webpack.config.js --hot --color",
    "build": "NODE_ENV=production webpack --config ./webpack.config.js --mode production --stats --progress"
  }
}

9. 运行项目