目录:入口、出口、loader、plugin;devServer

初始化目录结构:

出入口:

entry: {
    app: path.resolve(__dirname, '../src/main.js')
},
output: {
    filename: 'js/[name].[chunkhash].js',
    path: path.resolve(__dirname, '../dist'),
    clean: true
},

1.安装 webpack(基于配置文件)、webpack-cli(很多好用的webpack相关命令行)

2.安装 webpack-dev-server(基于express、sockjs的一个node服务器)

配置(development环境):

 devServer: {
        port: 9999,
        open: true,
        // 启用 webpack 的 热模块替换 特性:
        hot: true,
        // 该配置项允许配置从目录提供静态文件的选项(默认是 'public' 文件夹)
        // 监听多个进后台资源目录: static: ['assets', 'css'],
        // v4中有contentBase
        // contentBase: path.resolve(__dirname, 'public')
        // v5中要使用html-webpack-plugin实现静态资源目录和src的组装
        static: path.resolve(__dirname, '../dist'),
        compress: false,
        // 当出现编译错误或警告时,在浏览器中显示全屏覆盖。
        client: {
            // 在浏览器中以百分比显示编译进度。
            progress: true,
            // 告诉 dev-server 它应该尝试重新连接客户端的次数。当为 true 时,它将无限次尝试重新连接。
            // reconnect: true,
            overlay: {
                errors: true,
                warnings: false,
            }
        },
        // 指定要使用的 host。如果你想让你的服务器可以被外部访问,像这样指定:
        // host: '0.0.0.0',
    },

3.安装webpack-merge (合并)

module.exports = ({
    development
}) => merge(config, development ? develop : product)
与
"build": " webpack --env production --config config/webpack.config.js",
"serve": " webpack serve --env development --config config/webpack.config.js",
配合使用

4.安装html-webpack-plugin

// 把webpack  编译后的js  注入到html
new HtmlWebpackPlugin({
    title: 'cyf-react',
    // 此处的变量使用方式 
    //<title><%=htmlWebpackPlugin.options.title %></title>
    // 注入的位置
    template: path.resolve(__dirname, '../public/index.html'),
    // 输出的文件名
    pathname: "index.html",
    inject: true,
    // 设置favicon
    favicon: path.resolve(__dirname, '../public/favicon.ico')
}),

5.js/ts/jsx/tsx

 // 第一条规则:当webpack运行时,如果遇到以.js为后缀的文件时,webpack就使用babel-loader来加载.js文件,然后交给Babel编译器(@babel/core、@babel/preset-env)进行编译转换,最终得到ES5代码。
// babel-loader 专门用于加载javascript文件,然后交给Babel编译器进行编译。
{   
    test: /\.(js|jsx|ts|tsx)$/, 
    use: [{
            loader:'babel-loader',
            options:{}
        }], 
   include: /src/ 
},

6.sass :

 {
     test: /\.s[ac]ss$/i,
     use: [
         // 将 JS 字符串生成为 style 节点
         'style-loader',
         // 将 CSS 转化成 CommonJS 模块
         'css-loader',
         // 将 Sass 编译成 CSS
         'sass-loader',
     ],
 }
 //依赖:sass

7.分离css

// 抽离css文件 不直接注入到style 而是通过link引入
new MiniCssExtractPlugin({
    filename: 'css/[name].[chunkhash].css'
})

// 配合 MiniCssExtractPlugin.loader 处理css
{
    test: /\.(s[ac]ss|css)$/i,
        use: [
            MiniCssExtractPlugin.loader,
            // 将 JS 字符串生成为 style 节点
            // 'style-loader',
            // 将 CSS 转化成 CommonJS 模块
            'css-loader',
            // 将 Sass 编译成 CSS
            'sass-loader',
        ],
},

8.处理图片

// 处理图片模块,下面是v4的写法
// { test: /\.(png|jpg|jpeg|gif|webp|svg)$/, use: ['url-loader'] },
// { test: /\.(png|jpg|jpeg|gif|webp|svg)$/, use: ['file-loader'] },
// 处理图片模块,下面是v5的写法
{
    test: /\.(png|svg|jpg|jpeg|gif)$/,
    type: 'asset/resource'
},

9.解析配置

// 解析配置
resolve: {
    extensions: ['.js', '.jsx', '.ts', '.tsx'],
        // 取别名 直接可以使用@ 指定 ../src
        alias: {
            '@': path.resolve(__dirname, '../src'),
            '@@': path.resolve(__dirname, '../public'),
            'react': path.resolve(__dirname, 	'../node_modules/react/umd/react.development.js')
        }
},

10.eslint

const ESLintPlugin = require('eslint-webpack-plugin'); //(开发环境使用)
plugins: [
        new ESLintPlugin({
        eslintPath: 'eslint',
        extensions: ['js', 'ts', 'jsx'],
        exclude: 'node_modules'
    }),
],

11.vue

const VueLoaderPlugin = require('vue-loader-plugin');
// 请确保引入这个插件来施展魔法  vueloader
new VueLoaderPlugin(),
 
// vue
{
    test: /\.vue$/,
    use: 'vue-loader'
},

// css改写  
process.env.NODE_ENV !== 'production' ?
                    'vue-style-loader' :
                    MiniCssExtractPlugin.loader,
 
    
// 依赖
"vue-loader": "^15.9.8",
"vue-loader-plugin": "^1.3.0",
"vue-template-compiler": "^2.6.14",

12.react

 // 为React开发环境所定制的ESlint检测环境
 extends: [
     "plugin:jsx-a11y/recommended",
     "plugin:react-hooks/recommended",
     "eslint:recommended",
     "plugin:react/recommended",
     // 集成环境
     "airbnb",
     "airbnb/hooks"
 ],
 plugins: ["jsx-a11y", "react", "react-hooks"],
     
     
     
 // rules
 {
     test: /\.(js|ts|jsx|tsx)$/,
     use: [{
         loader: 'babel-loader',
         options: {}
     }]
 }

13.react 图片问题

import React, { useState } from 'react'
import img1 from '../static/22.jpg'  //0.0
export default function App () {
  const [count, setCount] = useState(1)
  return (
    <>
      <div>hello world</div>
      <img src={ img1 }  /> //0.0
      {/* 直接写路径会直接去本地服务去寻找 */}
      <img src="../22.jpg"  />  //0.0
      <h1>{count}</h1>
      <button onClick={()=>setCount(count+1)}>自增</button>
    </>
  )
}


// 配置 rules:
// 处理图片模块,下面是v4的写法
// { test: /\.(png|jpg|jpeg|gif|webp|svg)$/, use: ['url-loader'] },
// { test: /\.(png|jpg|jpeg|gif|webp|svg)$/, use: ['file-loader'] },
// 处理图片模块,下面是v5的写法
{
    test: /\.(png|svg|jpg|jpeg|gif)$/,
    type: 'asset/resource'
},

Error

1.此处忘记写绝对路径解析,一直导致以下错误

2.eslint errors:

(1)在.eslintignore 忽略 src

(2)设置:.eslintrc.js

// 改变eslint规则的检测级别(三种检测级别)
// off (0) -关闭规则
// warn (1) -违反规则给警告
// error (2) -违反规则给报错
    rules: {
        "no-console": "off",
        "indent": "error",
        "no-var": "warn",
        'linebreak-style': ["error", "windows"],
        "semi": "error",
        "space-before-blocks":0,
        "button-has-type":0,
        "lines-between-class-members":0
    },