Webpack介绍大全

news2024/11/24 21:03:17

Webpack

一 、什么是webpack

在这里插入图片描述

WebPack是一个现代JS应用程序的静态模块打包器(module bundler)

模块(模块化开发,可以提高开发效率,避免重复造轮子)

打包(将各个模块,按照一定的规则组装起来)

官网:https://webpack.js.org/ 中文网 https://webpack.docschina.org/

特点:功能强大(打包,构建,发布web服务),学习成本高

二、什么是前端工程化

前端工程化是依据业务特点,将前端开发的规范、流程、技术、工具、经验等形成规范并建立成一种标准的体系

三、构建工具

构建工具的主要功能就是实现自动化处理,例如对代码进行检查、预编译、合并、压缩;生成雪碧图、sourceMap、版本管理;运行单元测试、监控等,当然有的工具还提供模块化、组件化的开发流程功能。

网上各类的构建工具非常多,有家喻户晓的 Webpack、Gulp、 Grunt,也有各大公司团队开源的构建工具,这里通过 Github 的 Star 数量来简单的对比下各个工具的流行度

在这里插入图片描述

四、安装webpack

  1. 初始化包描述文件

    npm init -y
    
  2. 全局安装webpack

    npm i webpack webpack-cli -g
    
  3. 将webpack添加到package.json的依赖

    npm i webpack webpack-cli -D
    
  4. 运行命令

    webpack
    
  5. 创建以下文件夹

    • public文件夹-index.html文件
    • src文件夹 – main.js 和assets文件夹

    public和assets的区别?

    assets会打包,public不会打包,public任何人都可以访问

  6. 运行命令

    1.开发环境,默认生成dist文件夹以及下面的main.js文件

    webpack ./src/main.js -o ./dist --mode=development
    

    2.生产环境,默认生成dist文件夹以及下面的main.js文件

    webpack ./src/main.js -o ./dist --mode=production
    

    由于每次运行都需要写这么长的命令,因此把他配置到package.json文件夹

    在这里插入图片描述

    "dev":"webpack"
    这个是配置一个webpack.config.js的配置文件
    
  7. webpack.config.js配置文件

    const path=require("path")
    module.exports = {
         // 入口
      // 相对路径和绝对路径都行
        entry: path.join(__dirname, "./src/main.js"),
         // 输出
        output: {
             // path: 文件输出目录,必须是绝对路径
        // path.resolve()方法返回一个绝对路径
        // __dirname 当前文件的文件夹绝对路径
            path: path.join(__dirname, "./dist"),
              // filename: 输出文件名
            filename: "main.js"
        },
         // 加载器
        module: {},
         // 插件
        plugins: [],
          // 模式
        mode: "development",// 开发模式
    }
    

    运行的时候,直接敲 npm run dev

五大核心概念

  1. entry(入口)

指示 Webpack 从哪个文件开始打包

  1. output(输出)

指示 Webpack 打包完的文件输出到哪里去,如何命名等

  1. loader(加载器)

webpack 本身只能处理 js、json 等资源,其他资源需要借助 loader,Webpack 才能解析

  1. plugins(插件)

扩展 Webpack 的功能

  1. mode(模式)

主要由两种模式:

  • 开发模式:development
  • 生产模式:production

六、loader

Webpack 本身是不能识别样式资源的,所以我们需要借助 Loader 来帮助 Webpack 解析样式资源

我们找 Loader 都应该去官方文档中找到对应的 Loader,然后使用

官方文档找不到的话,可以从社区 Github 中搜索查询

Webpack 官方 Loader 文档

七、css 资源和sass资源

  1. 下载包

    sass

    npm i sass-loader sass -D
    

    css

    npm i css-loader style-loader -D
    
  2. 功能介绍

    • css-loader:负责将 Css 文件编译成 Webpack 能识别的模块
    • style-loader:会动态创建一个 Style 标签,里面放置 Webpack 中 Css 模块内容
      此时样式就会以 Style 标签的形式在页面上生效
    • sass-loader:负责将 Sass 文件编译成 css 文件
    • sass:sass-loader 依赖 sass 进行编译
    const path = require("path");
    
    module.exports = {
      entry: "./src/main.js",
      output: {
        path: path.resolve(__dirname, "dist"),
        filename: "main.js",
      },
      module: {
        rules: [
          {
            // 用来匹配 .css 结尾的文件
            test: /\.css$/,
            // use 数组里面 Loader 执行顺序是从右到左
            use: ["style-loader", "css-loader"],
          },
          {
            test: /\.s[a|c]ss$/,
            use: ["style-loader", "css-loader", "sass-loader"],
          },
        ],
      },
      plugins: [],
      mode: "development",
    };
    
    
  3. 添加 Css 资源

    • src/assets/css/index.css
      在这里插入图片描述

      在这里插入图片描述

    • src/main.js

      import "./assets/css/index.css"
      import "./assets/sass/index.scss"
      
    • public/index.html

      在这里插入图片描述

八、Html 资源

配置以下内容,就不需要到index.html文件下面导入js文件,会自动导入

  1. 下载

    npm i html-webpack-plugin -D
    
  2. 配置webpack.config.js

    在这里插入图片描述

     const HtmlWebpackPlugin = require("html-webpack-plugin")
     plugins: [
            new HtmlWebpackPlugin({
                inject: "body",
                template: path.join(__dirname, "./public/index.html")
            })
    
  3. 修改 index.html

    去掉引入的 js 文件,因为 HtmlWebpackPlugin 会自动引入

九、devServer

文件内容改变,自动更新浏览器模块,并且自动打开页面

  1. 安装

    npm i webpack-dev-server -D
    
  2. 配置在webpack.config.js文件中

    在这里插入图片描述

     // 开发服务器
      devServer: {
        host: "localhost", // 启动服务器域名
        port: "3000", // 启动服务器端口号
        open: true, // 是否自动打开浏览器,
        compress:true, //开启gzip 
        hot: true, // 开启HMR功能(只能用于开发环境,生产环境不需要了
      },
    
  3. 启动

     "serve": "webpack-dev-server"
    

十、proxy代理

在这里插入图片描述

 proxy: {
            '/api': {
                target: 'http://127.0.0.1:8888',//目标代理接口
                pathRewrite: {
                    '^/api': ''
                }//把请求路径中的api替换成""
            }

十一、图片资源

webpack.config.js文件的module模块下面的rules

 {
        test: /\.(png|jpe?g|gif|webp)$/,
        type: "asset",
        parser: {
          dataUrlCondition: {
            maxSize: 10 * 1024 // 小于10kb的图片会被base64处理
          }
        }
        generator: {
          // 将图片文件输出到 static/imgs 目录中
          // 将图片文件命名 [hash:8][ext][query]
          // [hash:8]: hash值取8位
          // [ext]: 使用之前的文件扩展名
          // [query]: 添加之前的query参数
         filename: "static/imgs/[hash:8][ext][query]",
      },

十二、自动清空上次打包资源

webpack.config.js文件

output: {
    path: path.resolve(__dirname, "dist"),
    filename: "static/js/main.js",
    clean: true, // 自动将上次打包目录资源清空
},

十三、处理字体图标资源

1.打开阿里巴巴矢量图标库

2。选择想要的图标添加到购物车,统一下载到本地

●src/main.js

import "./css/iconfont.css";
  • public/index.html

    <i class="iconfont icon-arrow-down"></i>
        <i class="iconfont icon-ashbin"></i>
        <i class="iconfont icon-browse"></i>
    
  • 配置webpack.config.js文件

          {
            test: /\.(ttf|woff2?)$/,
            type: "asset/resource",
            generator: {
              filename: "static/media/[hash:8][ext][query]",
            },
          },
    

    type: "asset/resource"和type: "asset"的区别:

    1. type: “asset/resource” 相当于file-loader, 将文件转化成 Webpack 能识别的资源,其他不做处理
    2. type: “asset” 相当于url-loader, 将文件转化成 Webpack 能识别的资源,同时小于某个大小的资源会处理成 data URI 形式

    视频音频也可以使用以上配置,只需要修改 test: /.(ttf|woff2?|map4|map3|avi)$/

十四、tree shaking(打包优化)

  // webpack的优化1 tree shaking在webpack的配置下,添加一个  optimization的usedExports
    // webpack的优化2 splitChunk分包
    optimization: {
        usedExports: true
    }

在production 模式下不用在webpack.config.js中配置

官方有标准的说法:Tree-shaking的本质是消除无用的js代码。无用代码消除在广泛存在于传统的编程语言编译器中,编译器可以判断出某些代码根本不影响输出,然后消除这些代码,这个称之为DCE(dead code elimination)

十五、Eslint

使用 Eslint,关键是写 Eslint 配置文件,里面写上各种 rules 规则,将来运行 Eslint 时就会以写的规则对代码进行检查,完成 Eslint,检测代码格式无误后,在由 Babel 做代码兼容性处理

1.配置文件

配置文件由很多种写法:

●.eslintrc.*:新建文件,位于项目根目录

○.eslintrc

○.eslintrc.js

○.eslintrc.json

○区别在于配置格式不一样

●package.json 中 eslintConfig:不需要创建文件,在原有文件基础上写

ESLint 会查找和自动读取它们,所以以上配置文件只需要存在一个即可

2.具体配置

我们以 .eslintrc.js 配置文件为例:

module.exports = {
    // 继承 Eslint 规则
    extends: ["eslint:recommended"],
    env: {
      node: true, // 启用node中全局变量
      browser: true, // 启用浏览器中全局变量
    },
    parserOptions: {
      ecmaVersion: 6,
      sourceType: "module",
    },
    rules: {
        "no-var": 2, // 不能使用 var 定义变量
        "no-console":0
    },
  };

2.rules 具体规则

●"off" 或 0 - 关闭规则

●"warn" 或 1 - 开启规则,使用警告级别的错误:warn (不会导致程序退出)

●"error" 或 2 - 开启规则,使用错误级别的错误:error (当被触发的时候,程序会退出)

rules: {
  semi: "error", // 禁止使用分号
  'array-callback-return': 'warn', // 强制数组方法的回调函数中有 return 语句,否则警告
  'default-case': [
    'warn', // 要求 switch 语句中有 default 分支,否则警告
    { commentPattern: '^no default$' } // 允许在最后注释 no default, 就不会有警告了
  ],
  eqeqeq: [
    'warn', // 强制使用 === 和 !==,否则警告
    'smart' // https://eslint.bootcss.com/docs/rules/eqeqeq#smart 除了少数情况下不会有警告
  ],
}

更多规则详见:规则文档

3.extends 继承

开发中一点点写 rules 规则太费劲了,所以有更好的办法,继承现有的规则。

现有以下较为有名的规则:

●Eslint 官方的规则:eslint:recommended

●Vue Cli 官方的规则:plugin:vue/essential

●React Cli 官方的规则:react-app

// 例如在React项目中,我们可以这样写配置
module.exports = {
  extends: ["react-app"],
  rules: {
    // 我们的规则会覆盖掉react-app的规则
    // 所以想要修改规则直接改就是了
    eqeqeq: ["warn", "smart"],
  },
};
  1. 在 Webpack 中使用

1下载包

npm i eslint-webpack-plugin eslint -D

2 定义 Eslint 配置文件

●.eslintrc.js

module.exports = {
  // 继承 Eslint 规则
  extends: ["eslint:recommended"],
  env: {
    node: true, // 启用node中全局变量
    browser: true, // 启用浏览器中全局变量
  },
  parserOptions: {
    ecmaVersion: 6,
    sourceType: "module",
  },
  rules: {
    "no-var": 2, // 不能使用 var 定义变量
  },
};

3修改 js 文件代码

●main.js

var result1 = count(2, 1);
console.log(result1);
var result2 = sum(1, 2, 3, 4);
console.log(result2);

4.配置

●webpack.config.js

const path = require("path");
const ESLintWebpackPlugin = require("eslint-webpack-plugin");
module.exports = {

  plugins: [
    new ESLintWebpackPlugin({
      // 指定检查文件的根目录
      context: path.resolve(__dirname, "src"),
    }),
  ],
  mode: "development",
};

●.eslintignore

# 忽略dist目录下所有文件
dist

Babel

JavaScript 编译器。

主要用于将 ES6 语法编写的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中

1.配置文件

配置文件由很多种写法:

●babel.config.*:新建文件,位于项目根目录 babel.config.js babel.config.json

●.babelrc.*:新建文件,位于项目根目录 .babelrc .babelrc.js .babelrc.json

●package.json 中 babel:不需要创建文件,在原有文件基础上写 Babel 会查找和自动读取它们,所以以上配置文件只需要存在一个即可

2.具体配置

我们以 babel.config.js 配置文件为例:

module.exports = {
  // 预设
  presets: [],
};

1.presets 预设

简单理解:就是一组 Babel 插件, 扩展 Babel 功能

●@babel/preset-env: 一个智能预设,允许您使用最新的 JavaScript。

●@babel/preset-react:一个用来编译 React jsx 语法的预设

●@babel/preset-typescript:一个用来编译 TypeScript 语法的预设

  1. 在 Webpack 中使用

1.下载包

npm i babel-loader @babel/core @babel/preset-env -D

2.定义 Babel 配置文件

●babel.config.js

module.exports = {
  presets: ["@babel/preset-env"],
};

3.配置

●webpack.config.js

module.exports={
  module:{
    rules:[
        {
        test: /\.js$/,
        exclude: /node_modules/, // 排除node_modules代码不编译
        loader: "babel-loader",
      },
    ]
  }
}

package.json

{
  "name": "mywepack",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "serve": "webpack-dev-server"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "css-loader": "^6.7.3",
    "css-minimizer-webpack-plugin": "^4.2.2",
    "less-loader": "^6.2.0",
    "node-sass": "^8.0.0",
    "sass-loader": "^13.2.0",
    "style-loader": "^3.3.1",
    "terser-webpack-plugin": "^5.3.6",
    "vue": "^2.7.14",
    "vue-style-loader": "^4.1.3"
  },
  "devDependencies": {
    "html-webpack-plugin": "^5.5.0",
    "webpack": "^5.75.0",
    "webpack-cli": "^5.0.1",
    "webpack-dev-server": "^4.11.1",
    "vue-loader": "^15.7.2",
    "vue-template-compiler": "^2.6.10"
  }
}

webpack.config.js

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const TerserPlugin = require("terser-webpack-plugin");
// cpu核数
const os=require("os");
// 线程
const threads = os.cpus().length;

module.exports = {
  mode: "development",
  entry: path.resolve(__dirname, "/src/main.js"),
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "build.js",
    clean: true,
  },
  module: {
    rules: [
    //   {
    //     test: /\.css$/i,
    //     use: ["style-loader", "css-loader"],
    //   },
      {
        test: /\.less$/,
        use: ["style-loader", "css-loader", "less-loader"],
      },
      {
        test: /\.s(a|c)ss$/,
        use: ["style-loader", "css-loader", "sass-loader"],
      },

      {
        test: /\.(jpg|jpeg|png|gif|webp)$/,
        type: "asset",
        parser: {
          dataUrlCondition: {
            maxSize: 30 * 1024, // 小于10kb的图片会被base64处理
          },
        },
        generator: {
          filename: "./images/[hash:8][ext][query]",
        },
      },
      {
        test: /\.vue$/,
        use: ["vue-loader"],
      },
      {
        test: /\.css$/,
        use: [
          'vue-style-loader',
          'css-loader'
        ]
      }
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, "public/index.html"),
      filename: "index.html",
      inject: "body",
    }),
    new VueLoaderPlugin(),
  ],
  optimization: {
    minimizer: [
      // css压缩也可以写到optimization.minimizer里面,效果一样的
      new CssMinimizerPlugin(),
      // 当生产模式会默认开启TerserPlugin,但是我们需要进行其他配置,就要重新写了
      new TerserPlugin({
        parallel: threads, // 开启多进程
      }),
    ]
},
  // 开发服务器
  devServer: {
    compress:false,
    host: "localhost", // 启动服务器域名
    port: "3000", // 启动服务器端口号
    open: true, // 是否自动打开浏览器
  },
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1178308.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

“第六十二天”

新东西 %[^\n] 这个题测试的时候不知道哪里为什么一直错一个。 int main() {char a[81] { 0 };fgets(a, 80, stdin);int i 0;int n strlen(a);for(i0;i<n;i){if ((a[i] > a && a[i] < y) || (a[i] > A && a[i] < Y))a[i] 1;else if (a[i…

中介模式(Mediator)

简介 当各个模块的调用变得错综复杂时&#xff0c;可以使用中介模式&#xff0c;用一个中介对象完成对象交互&#xff0c;各个对象不需要显示的相互引用。 创建一个中介对象完成所有的调用&#xff1a;Mediator->A ,Mediator->B,Mediator->C,Mediator->D&#xf…

设计模式—结构型模式之桥接模式

设计模式—结构型模式之桥接模式 将抽象与实现解耦&#xff0c;使两者都可以独立变化。 在现实生活中&#xff0c;某些类具有两个或多个维度的变化&#xff0c;如图形既可按形状分&#xff0c;又可按颜色分。如何设计类似于 Photoshop 这样的软件&#xff0c;能画不同形状和不…

gcov c++代码覆盖率测试工具(原理篇)

一、gcov简单介绍 Gcov是一个测试C/C代码覆盖率的工具&#xff0c;伴随GCC发布&#xff0c;配合GCC共同实现对C/C文件的语句覆盖、功能函数覆盖和分支覆盖测试。 二、gcov统计生成覆盖率流程 图1 gcov覆盖率生成过程 Gcc在编译阶段指定 –ftest-coverage 等覆盖率测试选项后…

8-2、T型加减速计算简化【51单片机控制步进电机-TB6600系列】

摘要&#xff1a;本节介绍简化T型加减速计算过程&#xff0c;使其适用于单片机数据处理。简化内容包括浮点数转整型数计算、加减速对称处理、预处理计算 一、浮点数转整型数计算 1.1简化∆t_1计算 根据上一节内容已知 K0.676 step1.8/X&#xff08;x为细分值&#xff0c;1.8对…

Oracle(11)Managing Tables

Managing Tables 管理表 目标&#xff1a; 识别存储数据的各种方法概述甲骨文数据类型区分扩展ROWID与限制ROWID勾勒出一行的结构创建常规表和临时表管理表中的存储结构重新组织、截断和删除表删除表中的列 一、基础知识 1、Oracle Built-in Data Types Oracle内置数据类型 2…

泛微OA_lang2sql 任意文件上传漏洞复现

简介 泛微OA E-mobile系统 lang2sql接口存在任意文件上传漏洞&#xff0c;由于后端源码中没有对文件没有校验&#xff0c;导致任意文件上传。攻击者可利用该参数构造恶意数据包进行上传漏洞攻击。 漏洞复现 FOFA语法&#xff1a; title"移动管理平台-企业管理" 页…

jbase编译与部署的优化

上一篇的演示只是涉及自动编译业务脚本。演示时候工程编译是超级慢的。因为把静态资源放在了Web工程下&#xff0c;每次编译都要拷贝&#xff0c;运行起码是1分钟&#xff0c;不能忍受&#xff0c;为此思考工程结构改解决这个问题&#xff0c;顺带方便开发的发布。运行WebLoade…

代码随想录第四十四天 | 动态规划 完全背包:纯完全背包理论基础(卡码网第52题);应用(注意遍历顺序):组合(518),排列(377)

1、动态规划&#xff1a;完全背包理论基础 有N件物品和一个最多能背重量为W的背包。第i件物品的重量是weight[i]&#xff0c;得到的价值是value[i] 。每件物品都有无限个&#xff08;也就是可以放入背包多次&#xff09;&#xff0c;求解将哪些物品装入背包里物品价值总和最大…

详解基于Android的Appium+Python自动化脚本编写

&#x1f4e2;专注于分享软件测试干货内容&#xff0c;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;交流讨论&#xff1a;欢迎加入我们一起学习&#xff01;&#x1f4e2;资源分享&#xff1a;耗时200小时精选的「软件测试」资…

排序算法之-选择

算法原理 在未排序的数列中找出最大&#xff08;或最小&#xff09;的元素&#xff0c;然后将其存入到已排序的数列起始位置&#xff0c;紧接着在剩余的未排序数列中继续查找最大&#xff08;或最小&#xff09;的元素&#xff0c;并将其放入到已排序的数列末尾&#xff0c;依…

数据结构:Map和Set(1)

搜索树 概念 若它的左子树不为空&#xff0c;则左子树上所有节点的值都小于根节点的值 若它的右子树不为空&#xff0c;则右子树上所有节点的值都大于根节点的值 它的左右子树也分别为二叉搜索树 这棵树的中序遍历结果是有序的 接下来我们来模拟一棵二叉搜索树&#xff0c…

串口通信(3)-接收一组固定长度的数据

本文为博主 日月同辉&#xff0c;与我共生&#xff0c;csdn原创首发。希望看完后能对你有所帮助&#xff0c;不足之处请指正&#xff01;一起交流学习&#xff0c;共同进步&#xff01; > 发布人&#xff1a;日月同辉,与我共生_单片机-CSDN博客 > 欢迎你为独创博主日月同…

Godot4实现游戏的多语言版本

要在Godot 4中实现多语言版本的游戏&#xff0c;您需要按照以下几个步骤来设置和管理游戏文本以及可能的其他资源&#xff0c;如图像或声音。以下是根据官方文档和详细教程整理的简明指南&#xff1a; 准备翻译文件&#xff1a; Godot支持使用.csv文件或.po文件进行国际化​​…

C语言习题整理①

一些C语言习题的整理。 目录 一、判断质数 二、判断回文数 三、判断水仙花数 四、输出乘法表 五、输出杨辉三角 一、判断质数 质数是指在大于1的自然数中&#xff0c;除了1和它本身以外不再有其他因数的自然数。质数又称素数。一个大于1的自然数&#xff0c;除了1和它自身…

数据结构与算法C语言版学习笔记(2)-线性表、顺序存储结构的线性表

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 数据结构部分的知识框架一、线性表的定义和特点1.定义2.特点 二、线性表的实际案例引入1.案例一&#xff1a;多项式的加减乘除2.案例二&#xff1a;当多项式是稀疏多…

AI 女友突然下线,大叔集体「崩溃」;谷歌聊天机器人称谷歌滥用垄断力量丨 RTE 开发者日报 Vol.78

开发者朋友们大家好&#xff1a; 这里是 「RTE 开发者日报」 &#xff0c;每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE &#xff08;Real Time Engagement&#xff09; 领域内「有话题的 新闻 」、「有态度的 观点 」、「有意思的 数据 」、「有思考的 文…

微服务项目,请求从发出到后端处理器的历程

点击登录按钮,发出 http://localhost:8803/service_6001/admin/login/in请求,这是一个由nginx配置的前端项目 查看配置文件,该条请求会被映射形成对http://localhost:51603/admin/login/in的post请求 upstream heima-admin-gateway {server localhost:51603; } server {liste…

笔记50:正则表达式入门宝典

引自&#xff1a;正则表达式是什么? - 知乎 中“龙吟九野”所写的一个回答&#xff0c;个人感觉看完之后如同醍醐灌顶&#xff0c;查了很多资料都没有这篇文章写的基础和通透&#xff0c;感觉是正则表达式扫盲好文&#xff0c;所以搬运一下&#xff0c;侵权删&#xff0c;感谢…

吃透BGP,永远绕不开这些基础概述,看完再也不怕BGP了!

你们好&#xff0c;我的网工朋友。 总有人在私信里抱怨&#xff0c;BGP实在是太难了&#xff01; 一是这玩意儿本来就很复杂&#xff0c;需要处理大量的路由信息和复杂的算法&#xff1b;再一个是需要你有一定的实战经验才能深入理解运作。 虽然BGP确实有一定难度&#xff0c…