前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Babel 配置实验报告

Babel 配置实验报告

作者头像
河马嘴不大
发布于 2022-12-24 04:20:09
发布于 2022-12-24 04:20:09
1.1K00
代码可运行
举报
运行总次数:0
代码可运行

写在前面的话

JavaScript语言的更新,也伴随着 Babel 的成长, 对于一个前端而言,JavaScript 新的 API 自然很香,但代价就是我们要转译它,比较常用工具的就是 Babel 。

ECMA有很多版本,6、7、8、9 ….,前端浏览器也有多种,每种也有着不同的版本,为了实现这多对多的关系,Babel 也表示非常难,最后的结果就是,随着 Babel 的升级,前端同学有一堆包要学习和了解,如 @babel/cli@babel/core@babel/polyfill@babel/preset-env 等等,Babel 目前最新的版本是 7.7.0,前一次比较重大的升级是 7.4.0,本着客户第一(Babel 很香)的原则, 下面对 Babel 的配置做了一些实验,本文主要是对于 Babel 的使用,不针对工作原理。

一、实验目的

测试 Babel 的不同配置对于 JavaScript 编译结果的影响

二、实验环境和要求

依赖包版本

@babel/core 7.7.0 @babel/cli 7.7.0 @babel/preset-env 7.7.1 @babel/runtime 7.7.0 @babel/plugin-transform-runtime 7.7.0 @babel/corejs@3 7.7.0

实验基础数据

创建实验基本的样本文件 index.js

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const cat = 'May'
const arrow = () => `Name: ${cat}`.padStart(2);
const promise = new Promise();
let map = new Map();

我们通过对 Babel 的配置进行修改,实验在不同配置下的编译结果 。 本实验使用 babel-cli 命令行直接编译和输出文件,对应的命令如下: npx babel index.js --out-file index_compile.js 将样本文件 index.js 编译输出到 index_compile.js 目标浏览器不配置,采用 Babel 默认,即转换所有 ECMAScript 2015+。

三、实验内容

初始化准备

首先安装实验用到的依赖包

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
npm install --save-dev @babel/core @babel/cli @babel/preset-env

项目根目录下创建 babel.config.js 文件,用于配置 Babel

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
module.exports = {};

####

配置一

不进行配置

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
module.exports = {};

实验结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const cat = 'May';

const arrow = () => `Name: ${cat}`.padStart(2);

const promise = new Promise();
let map = new Map();

除了多了两行空白,没有什么其它变化,说明 Babel 是基于插件架构的,假如你什么插件也不提供,那么 Babel 什么也不会做,即你输入什么输出的依然是什么。

配置二

增加 ES+ 转换集合包 @babel/preset-env

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
module.exports = {
  presets: ['@babel/preset-env'],
};

实验结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
"use strict";

var cat = 'May';

var arrow = function arrow() {
  return "Name: ".concat(cat).padStart(2);
};

var promise = new Promise();
var map = new Map();

对样本中的 constlet 以及箭头函数和模板字符串语法进行了处理,但对于 padStartPromiseMap 并没有处理,说明 @babel/preset-env 只能处理 ES+ 中新增的基本语法,不能对新增类和类的扩展属性进行处理。

这里就需要我们使用 @babel/polyfill ,实现新的内置函数、实例方法的转换。在我们使用 @babel/preset-env 的同时,它有个 useBuiltIns 选项,用来控制怎么样处理 @babel/polyfill。这里的 useBuiltIns 有三个可选属性: 'entry' | 'usage' | false,默认是 false

为了实现编译结果的可运行,我们需要改变样本代码,如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import "@babel/polyfill";

const cat = 'May';
const arrow = () => `Name: ${cat}`.padStart(2);
const promise = new Promise();
let map = new Map();
配置三
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
module.exports = {
  presets: [
    ['@babel/preset-env', {
      useBuiltIns: false,
    }]
  ],
};

实验结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
"use strict";

require("@babel/polyfill");

var cat = 'May';

var arrow = function arrow() {
  return "Name: ".concat(cat).padStart(2);
};

var promise = new Promise();
var map = new Map();

实验结果同配置二,做了基本语法的转译,直接引入了 @babel/polyfill 整个包。

配置四
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
module.exports = {
  presets: [
    ['@babel/preset-env', {
      useBuiltIns: 'usage',
    }]
  ],
};

实验结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
"use strict";

require("core-js/modules/web.dom.iterable");

require("core-js/modules/es6.array.iterator");

require("core-js/modules/es6.string.iterator");

require("core-js/modules/es6.map");

require("core-js/modules/es6.promise");

require("core-js/modules/es6.object.to-string");

require("core-js/modules/es7.string.pad-start");

var cat = 'May';

var arrow = function arrow() {
  return "Name: ".concat(cat).padStart(2);
};

var promise = new Promise();
var map = new Map();

同时我们得到了一些 Warning:

Warning1

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
WARNING: We noticed you re using the `useBuiltIns` option without declaring a core-js version. Currently, we assume version 2.x when no version is passed. Since this default version will likely change in future versions of Babel, we recommend explicitly setting the core-js version you are using via the `corejs` option.

大致意思是,如果我们使用了 useBuiltIns 选项,建议配置 corejs 选项,如果不配置,默认提供 2.x 版本的 corejs

Warning2

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
When setting `useBuiltIns: 'usage'`, polyfills are automatically imported when needed.
Please remove the `import '@babel/polyfill'` call or use `useBuiltIns: 'entry'` instead.

这个警告是,让我们移除 import '@babel/polyfill ,polyfill 会被自动按需导入加载。所以我们在设置useBuiltIns'usage' 时,不需要手动引入 @babel/polyfill

这里的编译结果,不但对 ES+ 的新增语法进行了转译,而且对类和类的类的扩展属性也进行了转译,结果是比较符合我们期待的,能够直接运行在浏览器上。这里我们看不到 import "@babel/polyfill"; 它被拆成小模块,按需引入。

配置四
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
module.exports = {
  presets: [
    ['@babel/preset-env', {
      useBuiltIns: 'entry',
    }]
  ],
};

实验结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
"use strict";

require("core-js/modules/es6.array.copy-within");

require("core-js/modules/es6.array.fill");

require("core-js/modules/es6.array.find");

## 中间还有 200+ 个包省略。。。。。。

require("core-js/modules/web.immediate");

require("core-js/modules/web.dom.iterable");

require("regenerator-runtime/runtime");

var cat = 'May';

var arrow = function arrow() {
  return "Name: ".concat(cat).padStart(2);
};

var promise = new Promise();
var map = new Map();

这里同样也得到了同配置四中的 warning1,需要我们配置 corejs 选项,但没有 warning2,同时这里把 import "@babel/polyfill" 拆成小包,全量引入。

我们综合一下配置二三四,分别对 useBuiltIns 的三个可选 option 分别进行了实验,得出了如下结论

  • false:不处理 polyfill
  • ‘usage’:按需加载 polyfill,且不需要手动引入@babel/polyfill 文件
  • ‘entry’:必须手动引入 @babel/polyfill 文件,会把 @babel/polyfill 切为小包,全量引入,但要注意的是,这里的全量并不是真的全量,因为我们没有配置目标浏览器,Babbel 默认转了全量的 ECMAScript 2015+,如果配置了如: targets: "chrome>60" ,会在配置四的编译结果中,包减少到 20+ ,也就是 ‘entry’ 会加载目标浏览器所需的 polyfill
配置五
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
module.exports = {
  presets: [
    ['@babel/preset-env', {
      useBuiltIns: 'usage',
      corejs: 3
    }]
  ],
};

实验结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
"use strict";

require("core-js/modules/es.array.iterator");

require("core-js/modules/es.map");

require("core-js/modules/es.object.to-string");

require("core-js/modules/es.promise");

require("core-js/modules/es.string.iterator");

require("core-js/modules/es.string.pad-start");

require("core-js/modules/web.dom-collections.iterator");

var cat = 'May';

var arrow = function arrow() {
  return "Name: ".concat(cat).padStart(2);
};

var promise = new Promise();
var map = new Map();

为了解决配置三四中的warning1,我们手动手动设置了 corejs 选项,区别于默认值 2 ,我们设置了 3

配置四的编译结果相比,引用部分发生了变化,默认的 core-js:2 处理依赖是 require("core-js/modules/es6.map"); 这里的 core-js:3require("core-js/modules/es.map");

使用 core-js@3 的原因是,core-js@2 分支中已经不会再添加新特性,新特性都会添加到 core-js@3。例如你使用了 Array.prototype.flat(),如果你使用的是 core-js@2,那么其不包含此新特性。为了可以使用更多的新特性,建议大家使用 core-js@3

到这里好像一切近乎完美,但还有个问题没有处理,抽象和剥离。

配置六

我们改变样本文件:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const promise = new Promise();
class Cat {
  constructor(name){
    this.name= name
  }
  getName(){
    return
  }
}

配置:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
module.exports = {
  presets: [
    ['@babel/preset-env', {
      useBuiltIns: 'usage',
      corejs: 3
    }]
  ],
};

实验结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
"use strict";

require("core-js/modules/es.function.name");

require("core-js/modules/es.object.define-property");

require("core-js/modules/es.object.to-string");

require("core-js/modules/es.promise");

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }

var promise = new Promise();

var Cat =
/*#__PURE__*/
function () {
  function Cat(name) {
    _classCallCheck(this, Cat);

    this.name = name;
  }

  _createClass(Cat, [{
    key: "getName",
    value: function getName() {
      return;
    }
  }]);

  return Cat;
}();

这里出现了很多公共方法, _classCallCheck_createClass 等,我们统称为 Babel 的注入帮助程序。如果每个文件都这么注入,必然是巨大的浪费资源,这个时候,需要使用 @babel/plugin-transform-runtime

首先安装依赖,@babel/plugin-transform-runtime 通常仅在开发时使用,但是运行时最终代码需要依赖 @babel/runtime,所以 @babel/runtime 必须要作为生产依赖被安装,如下 :

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
npm install --save-dev @babel/plugin-transform-runtime
npm install --save @babel/runtime

同时,它还会为代码创建一个沙箱环境,这在我们写类库或者工具库时是很有必要的,避免污染全局变量。

配置七
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
module.exports = {
  presets: [
    ['@babel/preset-env', {
      useBuiltIns: 'usage',
      corejs: 3
    }]
  ],
  plugins: [
    ['@babel/plugin-transform-runtime']
  ],
};

实验结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

require("core-js/modules/es.function.name");

require("core-js/modules/es.object.to-string");

require("core-js/modules/es.promise");

var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));

var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));

var promise = new Promise();

var Cat =
/*#__PURE__*/
function () {
  function Cat(name) {
    (0, _classCallCheck2.default)(this, Cat);
    this.name = name;
  }

  (0, _createClass2.default)(Cat, [{
    key: "getName",
    value: function getName() {
      return;
    }
  }]);
  return Cat;
}();

我们发现,之前的帮助函数,是直接定义在文件内部的,如 :

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

现在变成:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));

@babel/runtime 统一引入,减少了文件体积。并且对变量名做了处理,避免了全局污染,但同时又发现了新问题,编译后的文件,仅仅对 class 相关的函数做了变量名处理,但是对 Promise 相关的变量名并没有处理。

配置八
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
module.exports = {
  presets: ['@babel/preset-env'],
  plugins: [
    ['@babel/plugin-transform-runtime', {
      'corejs': 3
    }]
  ]
};

实验结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
"use strict";

var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault");

var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/classCallCheck"));

var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/createClass"));

var _promise = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/promise"));

var promise = new _promise.default();

var Cat =
/*#__PURE__*/
function () {
  function Cat(name) {
    (0, _classCallCheck2.default)(this, Cat);
    this.name = name;
  }

  (0, _createClass2.default)(Cat, [{
    key: "getName",
    value: function getName() {
      return;
    }
  }]);
  return Cat;
}();

这样感觉就比较完美了,即实现了对 polyfill 的按需加载,对注入的帮助函数的统一抽象剥离,又实现了对变量的处理,避免污染全局作用域,感觉很香。

四、实验结果和思考

我们通过对 Babel 中基本使用的 @babel/preset-env@babel/plugin-transform-runtime 进行配置,测试了不同配置下的实验结果,得出了比较合适的实践,但出现了一个灵魂的思考,既然 @babel/plugin-transform-runtime 能实现按需加载,沙箱环境,公用函数的统一抽象,还要在 useBuiltIns 里面搞三个参数干啥。这里猜测是考虑到包的体积大小。在 Babel 7.4.0 之后的版本,Babel官方明确建议了不再使用 @babel/polyfill ,建议使用 core-js/stable( polyfill ECMAScript features)和 regenerator-runtime/runtime,(needed to use transpiled generator functions)。

我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=780f3ys6oy21

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-01-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
搞懂babel7常用的配置和优化,这篇就够了!
网上关于babel7的文章很多,但是大多都没有实践,很多讲的模棱两可。 本文将手把手的带你看各种配置下的输入输出转换,彻底让你了解babel7到底该怎么去配置和优化。
ssh_晨曦时梦见兮
2020/04/10
2.9K0
搞懂babel7常用的配置和优化,这篇就够了!
网上关于babel7的文章很多,但是大多都没有实践,很多讲的模棱两可。 本文将手把手的带你看各种配置下的输入输出转换,彻底让你了解babel7到底该怎么去配置和优化。
ssh_晨曦时梦见兮
2024/01/27
3490
入门babel,我们需要了解些什么
说实话,我从工作开始就一直在接触babel,然而对于babel并没有一个清晰的认识,只知道babel是用于编译javascript,让开发者能使用超前的ES6+语法进行开发。自己配置babel的时候,总是遇到很多困惑,下面我就以babel@7为例,重新简单认识下babel。
程序员白彬
2020/07/10
7530
入门babel,我们需要了解些什么
十问babel,用最简单的话说清楚babel
我们都知道JS的新的API,语法糖层出不穷,在丰富了我们的知识库的同时,也极大的便利了我们的开发。
虎妞先生
2023/03/11
1.1K0
十问babel,用最简单的话说清楚babel
3-11-12 使用 babel 处理 es6 语法
关于 es6 的内容想必大家都已不再陌生,因为 es10 都已经出来了,只要不是太老的浏览器版本基本都支持 es6 的大多数特性了。可以看这里:http://kangax.github.io/compat-table/es6/ 当然,要保证 es6 或者 es7 的语法进行源码编写后完全可用,我们可以用 babel 将其转成 es5。Babel 是一个工具链,主要用于将 ECMAScript 2015+ 版本的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中。 关于 babel 的使用方法和原理都可以单列一个系列了,在此我们只讲述 babel 如何结合 webpack 使用。
love丁酥酥
2020/02/19
6830
前端科普系列(4):Babel —— 把 ES6 送上天的通天塔
在上一节 《CommonJS:不是前端却革命了前端》中,我们聊到了 ES6 Module,它是 ES6 中对模块的规范,ES6 是 ECMAScript 6.0 的简称,泛指 JavaScript 语言的下一代标准,它的第一个版本 ES2015 已经在 2015 年 6 月正式发布,本文中提到的 ES6 包括 ES2015、ES2016、ES2017等等。在第一节的《Web:一路前行一路忘川》中也提到过,ES2015 从制定到发布历经了十几年,引入了很多的新特性以及新的机制,浏览器对 ES6 的支持进度远远赶不上前端开发小哥哥们使用 ES6 的热情,于是矛盾就日益显著……
2020labs小助手
2020/07/20
9550
从零学脚手架(四)---babel
这是因为webpack本身不会处理代码中的ES6(ES2015+)特性,所以也就没有使用。
莫问今朝
2021/03/16
1.3K0
从零学脚手架(四)---babel
前端工程师的自我修养-关于 Babel 那些事儿
随着 Nodejs 的崛起,编译这个昔日在 Java、C++ 等语言中流行的词,在前端也逐渐火了起来,现在一个前端项目在开发过程中没有编译环节,总感觉这个项目是没有灵魂的。说起前端编译就不得不提前端编译界的扛把子 Babel ,大部分前端攻城狮对 Babel 并不陌生,但是在这个 Ctrl+C 和 Ctrl+V 的年代,大多数人对它也只是知道、了解或者听过,少数可能配置过 Babel,但也仅此而已。作为一个有想法和灵魂的前端攻城狮仅仅知道这些是不够的,你需要对 Babel 有一个系统的了解,今天就来聊聊 Babel 那些事儿。
政采云前端团队
2020/03/10
9490
前端工程师的自我修养-关于 Babel 那些事儿
一文聊完前端项目中的Babel配置
As a Front-end engineer,浏览器兼容性对于每个人来讲都是必不可少的话题。
19组清风
2022/10/08
1.8K0
一文聊完前端项目中的Babel配置
前端工程化:你所需要知道的最新的babel兼容性实现方案
core-js[1]是JavaScript的模块化标准库,包括了ECMAScript到2021年的新api的向后兼容实现。它和babel高度集成,是babel解决新特性在浏览器中兼容问题的核心依赖。
coder_koala
2021/08/26
1.2K0
3、webpack从0到1-使用babel打包
webpack从0到1-使用babel打包 讲下webpack中的loaders的概念,然后结合使用babel-loader来对项目中的es6语法做下转换。 git仓库:webpack-demo 1、什么是loaders? 先看官网对Loaders的解释:webpack enables use of loaders to preprocess files。 简单一点来说就是一个可以帮我们处理文件的东西,比如一个js文件,在webpack打包的时候看到这个js文件就会走我们定义的比如接下来要说的bab
Ewall
2020/03/20
1.5K0
语法降级与Polyfill:消灭低版本浏览器兼容问题
提到前端编译工具链方面,可能大家最新想到的是诸如@babel/preset-env、core-js、regenerator-runtime等工具。不过,我们今天要讲的是官方的 Vite 插件@vitejs/plugin-legacy,以及如何将这些底层的工具链接入到 Vite 中,并实现开箱即用的解决方案。
xiangzhihong
2023/07/09
4.2K1
语法降级与Polyfill:消灭低版本浏览器兼容问题
「Webpack5 专题(四)」Babel 的配置
有一些版本的浏览器对于JS新的语法(例如 ES6+)的支持不好,这时就需要将新的语法转换成 ES5 标准的语法,让浏览器正常识别它们,保证程序的稳定运行。
前端达人
2021/11/16
7320
「前端基建」探索不同项目场景下Babel最佳实践方案
无论是日常业务架构、前端框架设计甚至在前端面试过程中,一定会存在 Babel 的身影。
19组清风
2022/02/28
7640
「前端基建」探索不同项目场景下Babel最佳实践方案
解剖Babel —— 向前端架构师迈出一小步
作为一个庞大的家族,Babel生态中有很多概念,比如:preset、plugin、runtime等。
公众号@魔术师卡颂
2021/03/15
1.2K0
你可能并没有理解的 babel 配置的原理
babel 是一个 JS、TS 的编译器,它能把新语法写的代码转换成目标环境支持的语法的代码,并且对目标环境不支持的 api 自动 polyfill。
神说要有光zxg
2022/06/06
5680
你可能并没有理解的 babel 配置的原理
使用babel插件的注意事项
首先第一点就是babel的三个核心包:@babel/core、@babel/cli、@babel/type。
挥刀北上
2021/02/20
6380
使用babel插件的注意事项
最详细、最全面的 Babel 小抄
Babel 是一个工具链,主要用于将采用 ECMAScript 2015+ 语法编写的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中。(我摊牌了,直接从 `Babel` 中文官网[1]复制),我们一般用 Babel 做下面几件事:
码农小余
2022/06/16
8330
最详细、最全面的 Babel 小抄
Babel有关基础内容
项目中babel的设置一团遭,确实有必要搞懂这个babel。有的项目中直接在配置文件.babelrc中配置好,有的在main.js中全局import 这个polyfill,有的是在webpack中配置,有的引入了大量的第三方babel插件,这样可不行啊,如果不对babel有个全面的认知,在面对这些一系列满眼的配置下去修改,就有点力不从心。 本文,抽丝剥茧,彻底的搞懂babel,并测试、去实践修改babe的配置。
六个周
2022/10/28
5070
Babel有关基础内容
【前端词典】关于 Babel 你必须知道的
我第一次打开搜索引擎查询关于 Babel 的资料时,出现的竟然是关于 Babel 的传说。后来我花了小一天的时间去了解这个传说(来自《旧约圣经》)。
小生方勤
2019/07/23
6660
【前端词典】关于 Babel 你必须知道的
推荐阅读
相关推荐
搞懂babel7常用的配置和优化,这篇就够了!
更多 >
LV.0
这个人很懒,什么都没有留下~
目录
  • 写在前面的话
  • 一、实验目的
  • 二、实验环境和要求
    • 依赖包版本
    • 实验基础数据
  • 三、实验内容
    • 初始化准备
    • 配置一
    • 配置二
    • 配置三
    • 配置四
    • 配置四
    • 配置五
    • 配置六
    • 配置七
    • 配置八
  • 四、实验结果和思考
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档