webpack使用
一、简介
概述
本次使用webpack4进行构建打包
二、webpack
安装webpack、webpack-cli
npm install webpack@4.2.0 webpack-cli@4.2.0 -D
三、loader
加载器概述
-
raw-loader:加载文件原始内容(utf-8)
-
file-loader:把文件输出到一个文件夹中,在代码中通过相对URL去引用输出的文件
-
url-loader:和file-loader类似,但是能在文件很小的情况下以base64的方式把文件内容注入到代码中
-
source-map-loader:加载额外的Source Map文件,以方便断点调试
-
svg-inline-loader:将压缩后的 SVG 内容注入代码中
-
image-loader:加载并且压缩图片文件
-
handlebars-loader: 将 Handlebars 模版编译成函数并返回
-
babel-loader:把ES6转化成ES5
let----降级---->plugin
箭头函数----降级—>plugin
-
ts-loader: 将 TypeScript 转换成 JavaScript
-
awesome-typescript-loader:将 TypeScript 转换成 JavaScript,性能优于 ts-loader
-
css-loader:加载css,支持模块化、压缩、文件导入等特性,帮我们分析出各个css文件之间的关系,把各个css文件合并成一段css;
-
style-loader:把css代码注入到js中,通过DOM操作去加载css
-
eslint-loader:通过ESLint检查JS代码
-
tslint-loader:通过 TSLint检查 TypeScript 代码
-
postcss-loader:扩展 CSS 语法,使用下一代 CSS,可以配合 autoprefixer 插件自动补齐 CSS3 前缀
-
vue-loader:加载 Vue.js 单文件组件,它可以解析和转换.vue文件。提取出其中的逻辑代码 script,样式代码style,以及HTML 模板template,再分别把他们交给对应的loader去处理
-
cache-loader: 可以在一些性能开销较大的 Loader 之前添加,目的是将结果缓存到磁盘里
1.安装sass加载器和模块
其实之所以用到node-sass、是因为sass-loader的缘故。sass-loader 是将sass文件编译成css,而sass-loader又依赖于node-sass,所以需要安装node-sass
npm install node-sass sass-loader -D
2.安装css加载器和安装style加载器
大概流程是,css loader将css包裹成js, 传给style loader 然后style loader再将它处理成一个立即执行函数封装到bundle中. 这个立即执行函数会生成一个style标签嵌入到HTML页面中
-
css-loader:加载css,支持模块化、压缩、文件导入等特性
-
style-loader:把css代码注入到js中,通过DOM操作去加载css
npm install css-loader style-loader -D
npm install style-loader -D
3.安装ts加载器
将 TypeScript 转换成 JavaScript
npm install ts-loader -D
4.安装vue加载器
它可以解析和转换.vue文件。提取出其中的逻辑代码 script,样式代码style,以及HTML 模板template,再分别把他们交给对应的loader去处理
npm install vue-loader@15.10.1 -D
5.安装babel加载器
能够把es6高级内容变为es5,es6/es7/es8等等高级标准有很多(let、箭头函数、对象解构赋值、…展开运算符、反勾号字符串等等),每个标准都需要一个独立的plugin进行降级处理,如果使用许多高级标准内容,那么势必要为此安装许多plugin,这样工作比较繁琐,系统已经考虑到这点了,其通过preset把许多常用的plugin给做了集合,因此一般性的使用只需要安装preset即可搞定(如果项目应用到了一个生僻的高级标准内容,preset处理不来,就还需要再安装对应的plugin处理)
npm i babel-loader @babel/core @babel/preset-env -D
{test: /.js$/,exclude: /node_modules/, // 排除目录use: [{loader:'babel-loader',options: {presets: ['@babel/preset-env']}}] // es6转es5 }
说明: @babel/preset-env用来指定按什么样的预设来进行降级处理
-
打包测试 打包之后,去打包后的文件中检查是否已经把const和箭头函数这种es6的代码转成了es5的代码。
6.PostCSS
-
PostCSS是一个通过JavaScript来转成样式的工具
-
这个工具可以帮助我们进行一些css的转化和适配,比如自动添加浏览前缀,css样式的重置
PostCSS内部也是通过各种插件来实现转化的,所以需要安装各种插件来使用
npm install postcss-loader -D npm install autoprefixer -D //需要安装插件,添加浏览器前缀的
module: {rules: [{test: /\.less$/,use: ['style-loader', 'css-loader', 'less-loader', {loader: 'postcss-loader',options: {//可以提出一个单独的文件postcssOptions: {plugins: [require('autoprefixer')]}}}]}] }
当使用postcss-loader的时候,会先查找有不有自己options选项,如果没有就去查找postcss.config.js
这个配置文件
postcss.config.js
module.exports = {plugins: [require('autoprefixer')] }
webpack.config.js
{test: /\.less$/,use: ['style-loader', 'css-loader', 'less-loader', 'postcss-loader'] }
postcss-preset-env
一个比较强大的postcss插件
它可以帮助我们将一些现代的CSS特性,转成大多数浏览器认识的CSS,并且会根据目标浏览器或者运行时环境 添加所需的polyfill;
也包括会自动帮助我们添加autoprefixer(所以相当于已经内置了autoprefixer)
安装:
npm install postcss-preset-env -D
使用:
跟autoprefixer使用是一样的,可以直接用postcss-preset-env
替换autoprefixer
效果也是一样的
7. file-loader
file-loader的作用就是帮助我们处理import / require()方式引入的一个文件资源,并且会将它放到我们输出的文件夹中
在使用图片有两种形式,一种是背景图片
,另外一种是img标签
//简单创建一个img标签import image from '../imgs/mode.png'const el = document.createElement('img')el.src = imagedocument.body.appendChild(el)
注意:当使用img标签的时候,我们把图片看成是一个模块
,不要直接写成是一个字符串
安装
npm install file-loader -D
使用
//webpack.config.jsmodule: {rules: [{test: /\.(jpe?g|png|gif|svg)$/i,use: [{loader: 'file-loader'}]}] }
上面的配置,可以直接展示出图片来了,也就说明加载成功了。
但是还是存在一种不是很友好的现象
打包过后的文件,就直接存在build文件夹中,如果是一张图片还好,如果有很多张图片,就会造成打包文件夹的结构混乱
。图片被打包的文件名是32位hash值
,我们不能分辨
哪张是对应的哪张图片。所以需要进行处理。
所以需要对file-loader进行options
配置
常见的配置: [ext] 处理文件的扩展名 [name] 处理文件的名字 [hash:] 截取hash的长度,默认的32个字符太长了 [path] 文件相对于webpack配置文件的路径
//重新对file-loader进行配置 module: {rules: [{test: /\.(jpe?g|png|gif|svg)$/i,use: [{loader: 'file-loader',options: {//在打包的文件夹中创建一个images文件夹,用来保存图片的outputPath: 'images',//给图片取名字name: "[name]_[hash:8].[ext]"}}]}] }
效果图:
8.url-loader
url-loader跟file-loader的工作原理是一样的
url-loader的区别: 就是对图片有限制,对图片较小的进行base64编码
所以会发现,打包过后的文件,就一个build.js,而且里面都还是base64
这也不是我们想要的,只对限制一下的图片,进行base64的转换。
为什么呢?
小的图片转换base64之后可以和页面一起被请求,减少不必要的请求过程 而大的图片也进行转换,反而会影响页面的请求速度
小于100kb
的图片,进行转化
{test: /\.(jpe?g|png|gif|svg)$/,use: [{loader: 'url-loader',options: {//在打包的文件夹中创建一个images文件夹,用来保存图片的outputPath: 'images',//给图片取名字name: "[name]_[hash:8].[ext]",//配置limitlimit: 100 * 1024}}] }
9.加载数据(CSV/TSV/XML)
除了js,json,images, 可以加载的有用数据还有CSV/TSV/XML,要导入CSV, TSV和XML,可以
使用csv-loader和xml-loader
安装插件:
npm i csv-loader xml-loader -D
module.exports = {...module: {rules: [{test: /\.(csv|tsv)$/,use: 'csv-loader'},{test: /\.xml$/,use: 'xml-loader'}]} }
四、插件(Plugin)
1.webpack-dev-server
项目开发都是对src目录内部的文件进行更新,不要去修改dist打包好的文件,现在对src内部的任何文件做修改操作后,都需要重新打包,才可以看到对应效果
npm i webpack-dev-server -D
在webpack.config.js中做如下配置
module.exports = {// 其他省略....// 配置 webpack-dev-server的选项devServer: {host: '127.0.0.1', // 配置启动ip地址port: 10088, // 配置端口open: true // 配置是否自动打开浏览器} }
在package.json中补充一个script
"scripts": { + "dev": "webpack-dev-server", // 它默认会找webpack.config.js文件"build": "webpack-dev-server --config webpack.config.js" // 指定使用webpack.config.js配置文件文件 },
-
启动命令 现在通过
npm run dev
就可以实现 实时打包、实时编译、实时浏览器查看效果了。它会自动打开一个浏览器窗口。 -
测试
-
-
修改.js代码,
-
修改.css代码,检查是否会重启
-
2.HtmlWebpackPlugin
npm i html-webpack-plugin -D
const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports={plugins:[new HtmlWebpackPlugin({//设置模板文件template:'./src/index.html',//使用打包后的模板文件filename:'index.html'//打包后文件的名字}) ,] }
上述的这个如果需要在index中假如一些自动以的内容是根据development与production不同,而添加不同的内容。在这里html-webpack-plugin插件已经帮助我们做好了这部分。在你需要打包是自动需要假如的内容 使用
<%= htmlWebpackPlugin.options.urlScript %>
要说明的是urlScript 这个是我们自己定义的,你可以叫任何的名字,在传入的时候使用这个变量放入插件的内置中
const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports={plugins:[new HtmlWebpackPlugin({//设置模板文件template:'./src/index.html',//使用打包后的模板文件filename:'index.html'//打包后文件的名字urlScript:'<script src="./js/zepto.min.js"></script> '//---<<---就这里}) ,] }
未经过html转换的文件
<!DOCTYPE html> <html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" /><meta http-equiv="X-UA-Compatible" content="ie=edge" /><title></title> <head> <body> </body><%= htmlWebpackPlugin.options.urlScript %> </html>
经过 html-webpack-plugin 的转换之后就会变成
<!DOCTYPE html> <html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" /><meta http-equiv="X-UA-Compatible" content="ie=edge" /><title></title> <head> <body> </body><script src="./js/zepto.min.js"></script> -->>之前的标间就被替换成为了 我们之前的插件设置的内容了,这个很有用 </html>
3.VueLoaderPlugin
作用是 对本次webpack编译的所有rules做操作,添加pitch-loader和vue-loader,进行一个顺序的重新排放,
最终rule中的顺序是这样的: [ pitch-loader, … … , vue-loader] (pitcher在在开始,vue-loader在最后,这一切是通过把...clonedrule放到中间来实现的)
( * pitchloader的resourceQuery函数表明了,这个loader只会对request中带有vue字段query的request使用pitchloader)
4. process
npm i --save-dev process
5.抽离css为单独的文件
安装抽离css为单独文件的插件:该插件基于webpack5构成,主要是把style标签引入css转化为link
引入css
安装插件:
npm i mini-css-extract-plugin -D
配置:
// 引入抽离css为独立文件的插件 const MiniCssExtractPlugin = require('mini-css-extract-plugin')module.exports = {...plugins: [new MiniCssExtractPlugin({// 指定抽离的之后形成的文件名filename: 'styles/[contenthash].css'})],module: {rules: [// 处理后缀名为.css或者是.less的文件{test: /\.(css|less)$/,// stuyle-loader作用是在 head 中创建 style 标签// MiniCssExtractPlugin.loader是将css抽离为独立的文件use: [MiniCssExtractPlugin.loader, 'css-loader', 'less-loader']}]} }
五、CSS优化(压缩)
安装插件:
npm i css-minimizer-webpack-plugin -D
配置:
/ 引入css压缩插件 const CssMinimizerPlugin = require("css-minimizer-webpack-plugin")module.exports = {...// 优化配置项optimization: {minimizer: [// 使用插件优化 css 代码new CssMinimizerPlugin()],},// 模式,因为压缩css代码只在生产模式下生效mode: 'production' }
六、字体资源
通过 CSS 引入字体资源
@font-face {font-family: 'PujiSansExpandedHeavy';src: url('../fonts/PujiSans-ExpandedHeavy.eot'); /* IE9 Compat Modes */src: url('../fonts/PujiSans-ExpandedHeavy.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */url('../fonts/PujiSans-ExpandedHeavy.woff2') format('woff2'), /* Modern Browsers */url('../fonts/PujiSans-ExpandedHeavy.woff') format('woff'), /* Modern Browsers */url('../fonts/PujiSans-ExpandedHeavy.ttf') format('truetype'); /* Safari, Android, iOS */font-style: normal;font-weight: normal;text-rendering: optimizeLegibility;}
配置:
module.exports = {...module: {rules: [// 配置字体文件{test: /\.(woff|woff2|eot|ttf|otf)$/,// asset/resource可以帮助我们载入任何类型type: 'asset/resource'}]} }
Node API 方式
webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin'); const webpack = require('webpack'); // 访问内置的插件 const path = require('path'); module.exports = {entry: './path/to/my/entry/file.js',output: {filename: 'my-first-webpack.bundle.js',path: path.resolve(__dirname, 'dist'),},module: {rules: [{test: /\.(js|jsx)$/,use: 'babel-loader',},],},plugins: [new webpack.ProgressPlugin(),new HtmlWebpackPlugin({ template: './src/index.html' }),], };
在使用 Node API 时,还可以通过配置中的 plugins
属性传入插件。
some-node-script.js
const webpack = require('webpack'); // 访问 webpack 运行时(runtime) const configuration = require('./webpack.config.js');let compiler = webpack(configuration);new webpack.ProgressPlugin().apply(compiler);compiler.run(function (err, stats) {// ... });
webpack打包成的dist启动运行
安装express-generator生成器
npm install express-generator -g
创建一个express项目 执行express expressDemo
(expressDemo是项目名)
expressDemo项目目录如下图:
进入expressDemo目录,安装项目依赖 执行npm install
把dist目录下的所有文件复制到express项目的public文件夹下
运行npm start
启动expressDemo项目,打开浏览器,输入http://localhost:3000即可访问。
相关文章:

webpack使用
一、简介 概述 本次使用webpack4进行构建打包 二、webpack 安装webpack、webpack-cli npm install webpack4.2.0 webpack-cli4.2.0 -D 三、loader 加载器概述 raw-loader:加载文件原始内容(utf-8) file-loader:把文件输出…...
高通Android 12 音量API设置相关代码
// 获取当前音量大小public static int getCurrentVolume(Context context) {AudioManager audioManager (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);return audioManager.getStreamVolume(AudioManager.STREAM_MUSIC); // 使用 STREAM_MUSIC 作为示例…...

Qt开发第一讲
一、Qt项目里面有什么? 对各个文件的解释: Empty.pro文件 QT core gui # 要引入的Qt模块,后面学习到一些内容的时候可能会修改这里 #这个文件相当于Linux里面的makefile文件。makefile其实是一个非常古老的技术了。 #qmake搭配.pr…...

详细指南:如何有效解决Windows系统中msvcp140.dll丢失的解决方法
如果你在使用Windows系统时遇到“msvcp140.dll丢失”的错误提示,通常是因为你的计算机上缺少或损坏了msvcp140.dll文件。msvcp140.dll是Microsoft Visual C Redistributable包的一部分,许多应用程序和游戏需要它来正常运行。以下是几种解决msvcp140.dll丢…...
【RabbitMQ】幂等性、顺序性
幂等性 概述 幂等性是数学和计算机科学中某些运算的性质,他们可以被多次应用,而不会改变初始应用的结果。RabbitMQ的幂等性则是指同一条消息,多次消费,对系统的影响是相同的。 一般消息中间件的消息传输保障分为三个层级&#…...
FFmpeg源码:avio_skip函数分析
AVIOContext结构体和其相关的函数分析: FFmpeg源码:avio_r8、avio_rl16、avio_rl24、avio_rl32、avio_rl64函数分析 FFmpeg源码:read_packet_wrapper、fill_buffer函数分析 FFmpeg源码:avio_read函数分析 FFmpeg源码ÿ…...

Llama 3.1 技术研究报告-6
6 推理 我们研究了两种主要技术,以使 Llama 3 405B 模型的推理⾼效:(1) 流⽔线并⾏和 (2) FP8 量化。我们已经公开发布了我们的 FP8 量化实现。 6.1 流⽔线并⾏ 当使⽤ BF16 数字表⽰模型参数时,Llama 3 405B 不适合在装有 8 个 Nvidia H1…...
更新日志-Python OS
这么久没更新全是因为这段时间的事情很多,只能一点一点的更新代码,不过好在,也是成功更新出来啦! 更新日志(2024/9/29) 代码全文更新,将所有的绝对路径替换为相对路径,这样在各位大…...

Chrome浏览器的C++内存管理技术揭秘
Chrome浏览器作为全球最流行的网络浏览器之一,其高效的内存管理技术功不可没。本文将深入探讨Chrome浏览器在C中的内存管理技术,并介绍如何通过调整网页加载时间、优化视频播放体验和解决谷歌浏览器占用CPU过高的问题来提升浏览器性能。 (本…...

Redis --- redis事务和分布式事务锁
redis事务基本实现 Redis 可以通过 MULTI,EXEC,DISCARD 和 WATCH 等命令来实现事务(transaction)功能。 > MULTI OK > SET USER "Guide哥" QUEUED > GET USER QUEUED > EXEC 1) OK 2) "Guide哥"使用 MULTI命令后可以输入…...
SQL,将多对多的关联记录按行输出
数据库的Primary表和Secondary表有相同的结构,其中W、H、D是主键。Primary表:NameWHDPrimary item 1100500300Primary item 2100600300Primary item 3200500300Primary item 4100500300Primary item 5100600300Primary item 6200500300 Secondary表&…...

【SQL】筛选字符串与正则表达式
目录 语法 需求 示例 分析 代码 语法 SELECT column1, column2, ... FROM table_name WHERE condition; WHERE 子句用于指定过滤条件,以限制从数据库表中检索的数据。当你执行一个查询时,WHERE 子句允许你筛选出满足特定条件的记录。如果记录满…...

【Redis入门到精通五】Java如何像使用MySQL一样使用Redis(jedis安装及使用)
目录 Jedis 1.jedis是什么 2.jedis的安装配置 3.jedis的基础命令操作展示 1.set和get操作: 2.exists和del操作: 3.keys和type操作: 4. expire和ttl: Jedis Java 操作 redis 的客⼾端有很多,其中最知名的是 jedi…...

【 微信机器人+ AI 搭建】
摘要: 各种大模型已经出来好久了,各类app也已经玩腻了,接下来,就在考虑,怎么让大模型,利益最大化。 本人没有显著的家世,没有富婆包养,只能自己抽点时间,研究下技术&…...

VGG16网络介绍及代码撰写详解(总结1)
可以从本人以前的文章中可以看出作者以前从事的是嵌入式控制方面相关的工作,是一个机器视觉小白,之所以开始入门机器视觉的学习只要是一个idea,想把机器视觉与控制相融合未来做一点小东西。废话不多说开始正题。 摘要:本文是介绍V…...
多个excel表数据比对操作
多个excel表数据比对操作 本文主要使用两种方法进行比对,分别使用了openpyxl第三方库和pandas第三方库进行数据比对 两种方法优缺点: openpyxy: 优点:主要是处理xlsx的文件,里面方法简单,易懂 缺点:当数据量大的时候,速度很慢,之前我一条一条数据拿出来比较,两百多条…...
golang学习笔记32——哪些是用golang实现的热门框架和工具
推荐学习文档 golang应用级os框架,欢迎stargolang应用级os框架使用案例,欢迎star案例:基于golang开发的一款超有个性的旅游计划app经历golang实战大纲golang优秀开发常用开源库汇总想学习更多golang知识,这里有免费的golang学习笔…...

ZYNQ:开发环境搭建
资料下载 http://47.111.11.73/docs/boards/fpga/zdyz_qimxing(V2).html Vivado软件是什么? Vivado软件是Xilinx(赛灵思)公司推出的一款集成设计环境(IDE),主要用于FPGA(现场可编程门阵列&am…...
一步一步丰富生成式语言模型系统
以下是这套生成式语言模型解决任务的流程图概述: #mermaid-svg-sRHDSMUMV1utrg2F {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-sRHDSMUMV1utrg2F .error-icon{fill:#552222;}#mermaid-svg-sRHDSMUMV1u…...
Python中元组的常用方法
# 在Python中,元组(tuple)是一种不可变的序列类型,用于存储多个元素。元组的特点包括: # # 不可变性:一旦创建,元组的元素不能改变。这意味着不能添加、删除或修改元组中的元素。 # 可以包含任何…...

铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...
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任务 三、…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放
简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...

如何将联系人从 iPhone 转移到 Android
从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...

七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...

【JVM面试篇】高频八股汇总——类加载和类加载器
目录 1. 讲一下类加载过程? 2. Java创建对象的过程? 3. 对象的生命周期? 4. 类加载器有哪些? 5. 双亲委派模型的作用(好处)? 6. 讲一下类的加载和双亲委派原则? 7. 双亲委派模…...

并发编程 - go版
1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...