Webpack: 如何借助预处理器、PostCSS 等构建现代 CSS 工程环境
概述
-
在开发 Web 应用时,我们通常需要编写大量 JavaScript 代码 —— 用于控制页面逻辑;编写大量 CSS 代码 —— 用于调整页面呈现形式。问题在于,CSS 语言在过去若干年中一直在追求样式表现力方面的提升,工程化能力薄弱,例如缺乏成熟的模块化机制、依赖处理能力、逻辑判断能力等。为此,在开发现代大型 Web 应用时,通常会使用 Webpack 配合其它预处理器编写样式代码
-
我们看下Webpack 中如何使用 CSS 代码处理工具,包括:
- 如何使用
css-loader
、style-loader
、mini-css-extract-plugin
处理原生 CSS 文件? - 如何使用 Less/Sass/Stylus 预处理器?
- 如何使用 PostCSS ?
- 如何使用
Webpack 如何处理 CSS 资源?
- 原生 Webpack 并不能识别 CSS 语法,假如不做额外配置直接导入
.css
文件,会导致编译失败:

-
为此,在 Webpack 中处理 CSS 文件,通常需要用到:
-
css-loader
:该 Loader 会将 CSS 等价翻译为形如module.exports = "${css}"
的JavaScript 代码,使得 Webpack 能够如同处理 JS 代码一样解析 CSS 内容与资源依赖; -
style-loader
:该 Loader 将在产物中注入一系列 runtime 代码,这些代码会将 CSS 内容注入到页面的<style>
标签,使得样式生效; -
mini-css-extract-plugin
:该插件会将 CSS 代码抽离到单独的.css
文件,并将文件通过<link>
标签方式插入到页面中。 -
PS:当 Webpack 版本低于 5.0 时,请使用
extract-text-webpack-plugin
代替mini-css-extract-plugin
。 -
三种组件各司其职:
css-loader
让 Webpack 能够正确理解 CSS 代码、分析资源依赖;style-loader
、mini-css-extract-plugin
则通过适当方式将 CSS 插入到页面,对页面样式产生影响:

-
下面我们先从
css-loader
聊起,css-loader
提供了很多处理 CSS 代码的基础能力,包括 CSS 到 JS 转译、依赖解析、Sourcemap、css-in-module 等,基于这些能力,Webpack 才能像处理 JS 模块一样处理 CSS 模块代码。接入时首先需要安装依赖:$yarn add -D css-loader
-
之后修改 Webpack 配置,定义
.css
规则:module.exports = {module: {rules: [{test: /\.css$/i,use: ["css-loader"],},],}, };
此后,执行 npx webpack
或其它构建命令即可。经过 css-loader
处理后,样式代码最终会被转译成一段 JS 字符串:
源码 | 转译后 |
---|---|
.main-hd { font-size: 10px; } | //... var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default())); // Module ___CSS_LOADER_EXPORT___.push([ module.id, ".main-hd {\n font-size: 10px;\n}", "" ]); // Exports /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___); //... |
-
但这段字符串只是被当作普通 JS 模块处理,并不会实际影响到页面样式,后续还需要:
- 开发环境:使用
style-loader
将样式代码注入到页面<style>
标签; - 生产环境:使用
mini-css-extract-plugin
将样式代码抽离到单独产物文件,并以<link>
标签方式引入到页面中。
- 开发环境:使用
-
经过
css-loader
处理后,CSS 代码会被转译为等价 JS 字符串,但这些字符串还不会对页面样式产生影响,需要继续接入style-loader
加载器。 -
与其它 Loader 不同,
style-loader
并不会对代码内容做任何修改,而是简单注入一系列运行时代码,用于将css-loader
转译出的 JS 字符串插入到页面的style
标签。接入时同样需要安装依赖:$yarn add -D style-loader css-loader
-
之后修改 Webpack 配置,定义
.css
规则:module.exports = {module: {rules: [{test: /\.css$/i,use: ["style-loader", "css-loader"],},],}, };
-
PS:注意保持
style-loader
在前,css-loader
在后 -
上述配置语义上相当于
style-loader(css-loader(css))
链式调用,执行后样式代码会被转译为类似下面这样的代码:// Part1: css-loader 处理结果,对标到原始 CSS 代码 const __WEBPACK_DEFAULT_EXPORT__ = ( "body {\n background: yellow;\n font-weight: bold;\n}" ); // Part2: style-loader 处理结果,将 CSS 代码注入到 `style` 标签 injectStylesIntoStyleTag(__WEBPACK_DEFAULT_EXPORT__ )
至此,运行页面触发 injectStylesIntoStyleTag
函数将 CSS 代码注入到 <style>
标签,样式才真正开始生效。例如:
index.css | index.js |
---|---|
body { background: yellow; font-weight: bold; } | import './index.css'; const node = document.createElement('span'); node.textContent = 'Hello world'; document.body.appendChild(node); |
页面运行效果:
- 经过
style-loader
+css-loader
处理后,样式代码最终会被写入 Bundle 文件,并在运行时通过style
标签注入到页面。这种将 JS、CSS 代码合并进同一个产物文件的方式有几个问题:- JS、CSS 资源无法并行加载,从而降低页面性能;
- 资源缓存粒度变大,JS、CSS 任意一种变更都会致使缓存失效。
- 因此,生产环境中通常会用
mini-css-extract-plugin
插件替代style-loader
,将样式代码抽离成单独的 CSS 文件。使用时,首先需要安装依赖:$yarn add -D mini-css-extract-plugin
- 之后,添加配置信息:
const MiniCssExtractPlugin = require('mini-css-extract-plugin') const HTMLWebpackPlugin = require('html-webpack-plugin')module.exports = {module: {rules: [{test: /\.css$/,use: [// 根据运行环境判断使用那个 loader(process.env.NODE_ENV === 'development' ?'style-loader' :MiniCssExtractPlugin.loader),'css-loader']}]},plugins: [new MiniCssExtractPlugin(),new HTMLWebpackPlugin()] }
这里需要注意几个点:
-
mini-css-extract-plugin
库同时提供 Loader、Plugin 组件,需要同时使用 -
mini-css-extract-plugin
不能与style-loader
混用,否则报错,所以上述示例中第 9 行需要判断process.env.NODE_ENV
环境变量决定使用那个 Loader -
mini-css-extract-plugin
需要与html-webpack-plugin
同时使用,才能将产物路径以link
标签方式插入到 html 中 -
至此,运行 Webpack 后将同时生成 JS、CSS、HTML 三种产物文件,如:
index.css | index.js |
---|---|
body { background: yellow; font-weight: bold; } | import './index.css'; const node = document.createElement('span'); node.textContent = 'Hello world'; document.body.appendChild(node); |
产物 main.css :![]() | 产物 main.js :![]() |
产物 index.html :<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Webpack App</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <script defer src="main.js"></script> <link href="main.css" rel="stylesheet"> </head> <body> </body> </html> |
-
可以看到,样式代码会被抽离到单独的 CSS 文件,并且在最终生成的 html 中包含了指向 JS、CSS 两种资源的标签:
<script defer src="main.js"></script> <link href="main.css" rel="stylesheet">
-
综上,在 Webpack 中处理 CSS,通常需要使用
css-loader + style-loader
或css-loader + mini-css-extract-plugin
组合,两种方式最终都能实现加载样式代码的效果。但鉴于原生 CSS 语言的种种缺陷,我们还可以在此基础上增加更多 Webpack 组件,更优雅、高效地编写页面样式,下面一一展开介绍。
使用预处理器
-
CSS —— Cascading Style Sheet-级联样式表,最初设计用于描述 Web 界面样式的描述性语言,经过这么多年的发展其样式表现力已经突飞猛进,但核心功能、基本语法没有发生太大变化,至今依然没有提供诸如循环、分支判断、扩展复用、函数、嵌套之类的特性,以至于原生 CSS 已经难以应对当代复杂 Web 应用的开发需求。
-
为此,社区在 CSS 原生语法基础上扩展出一些更易用,功能更强大的 CSS 预处理器(Preprocessor),比较知名的有 Less、Sass、Stylus 。这些工具各有侧重,但都在 CSS 之上补充了扩展了一些逻辑判断、数学运算、嵌套封装等特性,基于这些特性,我们能写出复用性、可读性、可维护性更强,条理与结构更清晰的样式代码,以 Less 为例:
// 变量 @size: 12px; @color: #006633;// 混合 .mx-bordered() {border: 1px solid #000; }// 嵌套 body {// 函数计算background: spin(lighten(@color, 25%), 8);font-weight: bold;padding: @size;.main {// 数学运算font-size: @size * 2;.mx-bordered;color: darken(@color, 10%);padding: @size * 0.6;} }
-
在 Webpack 中只需使用适当 Loader 即可接入预处理器,以 Less 为例,首先安装依赖:$
yarn add -D less less-loader
-
其次,修改 Webpack 配置,添加
.less
处理规则:module.exports = {module: {rules: [{test: /\.less$/,use: ['style-loader','css-loader','less-loader']}]} }
可以看到这里需要同时使用三种 Loader,其中 less-loader
用于将 Less 代码转换为 CSS 代码,上述示例转换结果:
.less 源码 | less-loader 处理结果: |
---|---|
// 变量 @size: 12px; @color: #006633; // 混合 .mx-bordered() { border: 1px solid #000; } // 嵌套 body { // 函数计算 background: spin(lighten(@color, 25%), 8); font-weight: bold; padding: @size; .main { // 运算 font-size: @size * 2; .mx-bordered; color: darken(@color, 10%); padding: @size * 0.6; } } | body { background: #00e691; font-weight: bold; padding: 12px; } body .main { font-size: 24px; border: 1px solid #000; color: #00331a; padding: 7.2px; } |
这段 CSS 随后会被 css-loader
与 style-loader
处理,最终在页面生效。
目前,社区比较流行的预处理器框架有:Less、Sass、Stylus,它们接入 Webpack 的方式非常相似:
Less | Sass | Stylus | |
---|---|---|---|
安装依赖 | yarn add -D less less-loader | yarn add -D sass sass-loader | yarn add -D stylus stylus-loader |
添加配置 | module.exports = { module: { rules: [ { test: /\.less$/, use: [ "style-loader", "css-loader", "less-loader" ], }, ], } }; | module.exports = { module: { rules: [ { test: /\.s(ac)ss$/, use: [ "style-loader", "css-loader", "sass-loader" ], }, ], } }; | module.exports = { module: { rules: [ { test: /\.styl$/, use: [ "style-loader", "css-loader", "stylus-loader" ], }, ], } }; |
- 大家可根据项目背景选择接入适当的预处理器框架
使用 post-css
-
与上面介绍的 Less/Sass/Stylus 这一类预处理器类似,PostCSS 也能在原生 CSS 基础上增加更多表达力、可维护性、可读性更强的语言特性。两者主要区别在于预处理器通常定义了一套 CSS 之上的超集语言;PostCSS 并没有定义一门新的语言,而是与
@babel/core
类似,只是实现了一套将 CSS 源码解析为 AST 结构,并传入 PostCSS 插件做处理的流程框架,具体功能都由插件实现。 -
预处理器之于 CSS,就像 TypeScript 与 JavaScript 的关系;而 PostCSS 之于 CSS,则更像 Babel 与 JavaScript。
-
PostCSS 的接入步骤也很简单,首先安装依赖:$
yarn add -D postcss postcss-loader
-
之后添加 Webpack 配置:
module.exports = {module: {rules: [{test: /\.css$/,use: ["style-loader", "css-loader", "postcss-loader"],},],} };
-
不过,这个时候的 PostCSS 还只是个空壳,下一步还需要使用适当的 PostCSS 插件进行具体的功能处理,例如我们可以使用
autoprefixer
插件自动添加浏览器前缀,首先安装依赖:$yarn add -D autoprefixer
-
之后,修改 Webpack 配置:
module.exports = {module: {rules: [{test: /\.css$/,use: ["style-loader", {loader: "css-loader", options: {importLoaders: 1}}, {loader: "postcss-loader",options: {postcssOptions: {// 添加 autoprefixer 插件plugins: [require("autoprefixer")],},},}],},],} };
-
之后,再次运行 Webpack 即可为 CSS 代码自动添加浏览器前缀,例如:
CSS 源码 | PostCSS 处理结果 |
---|---|
::placeholder { color: gray; } | ::-moz-placeholder { color: gray; } :-ms-input-placeholder { color: gray; } ::placeholder { color: gray; } |
此外,还可以选择将 PostCSS 相关配置抽离保存到 postcss.config.js
文件:
postcss.config.js | webpack.config.js |
---|---|
module.exports = { plugins: [ require("autoprefixer") ], }; | module.exports = { module: { rules: [ { test: /\.css$/, use: [ "style-loader", { loader: "css-loader", options: { importLoaders: 1 } }, "postcss-loader" ], }, ], } }; |
-
值得一提的是,PostCSS 与预处理器并非互斥关系,我们完全可以在同一个项目中同时使用两者,例如:
module.exports = {module: {rules: [{test: /\.less$/,use: ["style-loader", {loader: "css-loader", options: {importLoaders: 1}}, "postcss-loader","less-loader"],},],} };
-
基于这一特性,我们既能复用预处理语法特性,又能应用 PostCSS 丰富的插件能力处理诸如雪碧图、浏览器前缀等问题。
-
PostCSS 最大的优势在于其简单、易用、丰富的插件生态,基本上已经能够覆盖样式开发的方方面面。实践中,经常使用的插件有:
- autoprefixer:基于 Can I Use 网站上的数据,自动添加浏览器前缀
- postcss-preset-env:一款将最新 CSS 语言特性转译为兼容性更佳的低版本代码的插件
- postcss-less:兼容 Less 语法的 PostCSS 插件,类似的还有:postcss-sass、poststylus
- stylelint:一个现代 CSS 代码风格检查器,能够帮助识别样式代码中的异常或风格问题
总结
-
本文介绍
css-loader
、style-loader
、mini-css-extract-plugin
、less-loader
、postcss-loader
等组件的功能特点与接入方法,内容有点多,重点在于: -
Webpack 不能理解 CSS 代码,所以需要使用
css-loader
、style-loader
、mini-css-extract-plugin
三种组件处理样式资源; -
Less/Sass/Stylus/PostCSS 等工具可弥补原生 CSS 语言层面的诸多功能缺失,例如数值运算、嵌套、代码复用等
-
这些工具几乎已经成为现代 Web 应用开发的标配,能够帮助我们写出更清晰简洁、可复用的样式代码,帮助我们解决诸多与样式有关的工程化问题
相关文章:

Webpack: 如何借助预处理器、PostCSS 等构建现代 CSS 工程环境
概述 在开发 Web 应用时,我们通常需要编写大量 JavaScript 代码 —— 用于控制页面逻辑;编写大量 CSS 代码 —— 用于调整页面呈现形式。问题在于,CSS 语言在过去若干年中一直在追求样式表现力方面的提升,工程化能力薄弱ÿ…...
一篇文章告诉你如何正确使用chatgpt提示词
在chatgpt大火的时候,出现了一波学习chatgpt提示词的热潮,互联网出现很多了使用的学习提示词的课程。其中我觉得斯坦福大学教授吴恩达博士推出prompt engineer课最全面。接下来总结他课程中正确使用提示词工程的方法。 1. 明确目标 明确你希望ChatGPT完…...
qt基于QGraphicsView的屏幕旋转
一、代码实现 实现代码示例 MainWindow2 w;QGraphicsScene *scene new QGraphicsScene;QGraphicsProxyWidget *gw scene->addWidget(&w);// 旋转角度gw->setRotation(90);QGraphicsView *view new QGraphicsView(scene);//view->resize(1024, 600);//scene-&g…...

一个土木工程专业背景的开发者,讲述开源带给他的力量
在前段时间我们举办的“TDengine Open Day”第一季技术沙龙中,TDengine 应用研发高级工程师谭雪峰进行的“开源之路:程序员的成长与探索”主题分享获得了众多参会者的好评。谭雪峰从自身独特的职业发展经历出发,分享了自己在开源领域的种种收…...

express+vue在线im实现【四】
往期内容 expressvue在线im实现【一】 expressvue在线im实现【二】 expressvue在线im实现【三】 本期示例 本期总结 支持了音频的录制和发送,如果觉得对你有用,还请点个免费的收藏与关注 下期安排 在线语音 具体实现 <template><kl-dial…...
【Qt 实现3D按钮】
要在Qt中实现3D按钮,你可以使用QML和Qt 3D模块。这是一个简单的例子,展示了如何在Qt中创建一个3D按钮: 首先,确保你的系统中已经安装了Qt 3D模块。在命令行中输入以下命令检查: qmlscene --version如果没有安装&…...
8.每日LeetCode-笔试题,交替打印数字和字母
代码地址:interview-go: Go高级面试总结 问题描述 交替打印数字和字母 使用两个 goroutine 交替打印序列,一个 goroutine 打印数字, 另外一个 goroutine 打印字母, 最终效果如下: 12AB34CD56EF78GH910IJ1112KL…...

UE5近战对抗系统Tutorial
文章目录 BP_Character 组合攻击Notify State 检测攻击BP_Character 攻击反馈BP_Character 生命系统BP_Character 死亡效果BP_Character 武器系统BP_Enemy 初始化和行为树 BP_Character 组合攻击 首先我们获取攻击动画,在这里使用的是 Easy Combo Buffering 的攻击…...
Typescript: declear
问: const book: string 这样就可以声明而且赋值为什么还用declear去分成好几步骤走呢? 同时即使不赋值只需要使用const book: string;难道不也行吗? 为什么要加上一个declear呢? 回答: 在 TypeScript 中,声明变量和使用 declare 声明类型信息是两个不同的概念…...
Linux内核编译流程
删除之前编译生成的文件和配置文件 make mrproper生成.config文件 make menuconfig编译 make -j41. No rule to make target ‘debian/canonical-certs.pem‘, needed by ‘certs/x509_certificate_list‘ vim .config 修改CONFIG_SYSTEM_TRUSTED_KEYS为"" 修改C…...

昇思25天学习打卡营第2天 | 张量Tensor
张量Tensor 张量(Tensor)基础 张量是MindSpore中的基本数据结构的一种,类似于NumPy中数组和矩阵非常相似。它具有以下重要属性: 形状(shape)和数据类型(dtype):每个张量…...
时间安排 |规划
计算机网络(记得完成作业本上的习题) 先看王道知识点讲解 然后不懂得看 计算机网络微课堂(有字幕无背景音乐版)_哔哩哔哩_bilibili 最后做本章习题 【乱讲的】《计算机网络》(第8版)课后习题讲解_哔哩…...

PS系统教程28
Alpha通道(透明通道) 8位的灰度通道,也有256个位置记录图片当中的透明度信息 作用:定义透明、半透明、不透明通道信息。保存、存储选区。 白色不透明区域黑色透明区域灰色半透明区域 案例 为了将我们抠出来的人物方便下次修改…...

如何在web页面下做自动化测试?
自动化测试是在软件开发中非常重要的一环,它可以提高测试效率并减少错误率。在web页面下进行自动化测试,可以帮助我们验证网页的功能和交互,并确保它们在不同浏览器和平台上的一致性。本文将从零开始,详细介绍如何在web页面下进行…...

spring源码环境的搭建
为什么要编译spring源码 为了高效调试Spring源码、验证个人猜想,并从开发者的视角深化理解,编译自定义的Spring源码版本显得尤为重要。这样可以避免因缺乏预编译版本而带来的不便,并允许直接在源码上进行注释或修改,以记录学习心…...
小山菌_代码随想录算法训练营第三十四天| 56. 合并区间、
56. 合并区间 文档讲解:代码随想录.合并区间 视频讲解:贪心算法,合并区间有细节!LeetCode:56.合并区间 状态:已完成 代码实现 class Solution { public:vector<vector<int>> merge(vector<…...

让工厂像手机一样更“聪明”
手机,作为我们日常生活中不可或缺的一部分,以其智能、便捷、高效的特点,彻底改变了我们的沟通、娱乐和工作方式。那么,想象一下,如果工厂能像手机一样便捷,那么生产过程中的每一个环节都将变得触手可及。通…...

vue2与vue3数据响应式对比之检测变化
vue2 由于javascript限制,vue不能检测数组和对象的变化 什么意思呢,举例子来说吧 深入响应式原理 对象 比如说我们在data里面定义了一个info的对象 <template><div id"app"><div>姓名: {{ info.name }}</div><…...

Spring Cloud - 开发环境搭建
1、JDK环境安装 1、下载jdk17:下载地址,在下图中红色框部分进行下载 2、双击安装,基本都是下一步直到完成。 3、设置系统环境变量:参考 4、设置JAVA_HOME环境变量 5、在PATH中添加%JAVA_HOME%/bin 6、在命令行中执行:j…...

绘制图形
自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 在前3节的实例中,我们一直绘制的都是直线,实际上,海龟绘图还可以绘制其他形状的图形,如圆形、多边形等…...

无法与IP建立连接,未能下载VSCode服务器
如题,在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈,发现是VSCode版本自动更新惹的祸!!! 在VSCode的帮助->关于这里发现前几天VSCode自动更新了,我的版本号变成了1.100.3 才导致了远程连接出…...
Java多线程实现之Callable接口深度解析
Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

【2025年】解决Burpsuite抓不到https包的问题
环境:windows11 burpsuite:2025.5 在抓取https网站时,burpsuite抓取不到https数据包,只显示: 解决该问题只需如下三个步骤: 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...

PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...
Go语言多线程问题
打印零与奇偶数(leetcode 1116) 方法1:使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...

【Linux系统】Linux环境变量:系统配置的隐形指挥官
。# Linux系列 文章目录 前言一、环境变量的概念二、常见的环境变量三、环境变量特点及其相关指令3.1 环境变量的全局性3.2、环境变量的生命周期 四、环境变量的组织方式五、C语言对环境变量的操作5.1 设置环境变量:setenv5.2 删除环境变量:unsetenv5.3 遍历所有环境…...

链式法则中 复合函数的推导路径 多变量“信息传递路径”
非常好,我们将之前关于偏导数链式法则中不能“约掉”偏导符号的问题,统一使用 二重复合函数: z f ( u ( x , y ) , v ( x , y ) ) \boxed{z f(u(x,y),\ v(x,y))} zf(u(x,y), v(x,y)) 来全面说明。我们会展示其全微分形式(偏导…...
React父子组件通信:Props怎么用?如何从父组件向子组件传递数据?
系列回顾: 在上一篇《React核心概念:State是什么?》中,我们学习了如何使用useState让一个组件拥有自己的内部数据(State),并通过一个计数器案例,实现了组件的自我更新。这很棒&#…...
CppCon 2015 学习:Reactive Stream Processing in Industrial IoT using DDS and Rx
“Reactive Stream Processing in Industrial IoT using DDS and Rx” 是指在工业物联网(IIoT)场景中,结合 DDS(Data Distribution Service) 和 Rx(Reactive Extensions) 技术,实现 …...

React、Git、计网、发展趋势等内容——前端面试宝典(字节、小红书和美团)
React React Hook实现架构、.Hook不能在循环嵌套语句中使用 , 为什么,Fiber架构,面试向面试官介绍,详细解释 用户: React Hook实现架构、.Hook不能在循环嵌套语句中使用 , 为什么,Fiber架构,面试向面试官介绍&#x…...