webpack 小知识

写在前面的:说实话,平时项目的 webpack 配置几乎我没有参与过。然后觉着还是有必要整理相关的一些题目巩固一下。首先呢,我推荐还是去官网稍微了解一下基础知识。

webpack 与 grunt、gulp 的不同?


三者都是构建工具,但是侧重点不同。

  • grunt & gulp
    基于任务和流的。找到一个(或一类)文件,对其做一系列链式操作,更新流上的数据, 整条链式操作构成了一个任务,多个任务就构成了整个 web 的构建流程。
  • webpack
    基于入口的。webpack 会自动地递归解析入口所需要加载的所有资源文件,然后用不同的 loader 来处理不同的文件,用 plugin 来扩展 webpack 功能。


有哪些常见的 loader?他们是解决什么问题的?


  • babel-loader:把 ES6 转换成 ES5
  • ts-loader: 将 ts 转换成 js
  • css-loader:加载 CSS,支持模块化、压缩、文件导入等特性
  • style-loader:把 CSS 代码注入到 JavaScript 中,通过 DOM 操作去加载 CSS
  • less-loader:将 Less 编译为 CSS 的 loader
  • sass-loader:加载 Sass/SCSS 文件并将他们编译为 CSS
  • file-loader:将一个文件中的 import/require() 解析为 url,并且将文件发送到输出文件夹。
  • eslint-loader:使用 eslint 对代码进行格式化


有哪些常见的 plugin?他们是解决什么问题的?


  • HtmlWebpackPlugin:简化了 HTML 文件的创建
  • MiniCssExtractPlugin:将 CSS 提取到单独的文件中,为每个包含 CSS 的 JS 文件创建一个 CSS 文件,并且支持 CSS 和 SourceMaps 的按需加载。
  • DefinePlugin:在编译时创建配置的全局常量
  • ProgressPlugin:提供编译进度
  • BundleAnalyzerPlugin:可视化 Webpack 输出文件的体积


loader 和 plugin 的不同?


(1)定义

  • loader 直译为"加载器"。Webpack将一切文件视为模块,但是 webpack 原生是只能解析 js 文件,如果想将其他文件也打包的话,就会用到 loader。 所以 loader 的作用是让 webpack 拥有了加载和解析非 js 文件的能力。
  • plugin 直译为"插件"。plugin可以扩展 webpack 的功能,让 webpack 具有更多的灵活性。 在 webpack 运行的生命周期中会广播出许多事件,plugin 可以监听这些事件,在合适的时机通过 webpack 提供的 API 改变输出结果。

(2)用法

  • loader 在 module.rules 中配置,也就是说他作为模块的解析规则而存在。 类型为数组,每一项都是一个 Object,里面描述了对于什么类型的文件(test),使用什么加载(loader)和使用的参数(options)
  • plugin 在 plugins 中单独配置。 类型为数组,每一项是一个 plugin 的实例,参数都通过构造函数传入。


css-loader 和 style-loader 区别?


  • css-loader:处理 css 文件;会对 @import 和 url() 进行处理。
  • style-loader:把 CSS 插入到 DOM 中。


file-loader 和 url-loader 区别?


  • file-loader:将一个文件中的 import/require() 解析为 url,并且将文件发送到输出文件夹,最终返回 url。
  • url-loader:可以通过 limit(单位:byte) 属性对图片分情况处理,当图片小于 limit 时转 base64,大于等于 limit 时调用 file-loader 处理。


什么是bundle,什么是chunk,什么是module


  • bundle:是由 webpack 打包出来的文件
  • chunk: 是指 webpack 在进行模块的依赖分析的时候代码分割出来的代码块
  • module:是开发中的单个模块


什么是entry,output?


  • entry:指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始。默认为 ./src/index.js
  • output:告诉 webpack 在哪里输出它所创建的 bundle,以及如何命名这些文件。主要输出文件的默认值是 ./dist/main.js,其他生成文件默认放置在 ./dist 文件夹中。


什么是Tree-shaking?CSS可以Tree-shaking?


Tree-shaking 是指在打包中取出那些引入了但在代码中没有被用到的死代码。webpack中通过 uglifysPlugin 来Tree-shaking JS。CSS需要使用 purify-CSS


webpack 基本功能?


(1)代码转换:TypeScript 编译成 JavaScript、SCSS 编译成 CSS 等等
(2)文件优化:压缩 JavaScript、CSS、HTML 代码,压缩合并图片等
(3)代码分割:提取多个页面的公共代码、提取首屏不需要执行部分的代码让其异步加载
(4)模块合并:在采用模块化的项目有很多模块和文件,需要构建功能把模块分类合并成一个文件
(5)自动刷新:监听本地源代码的变化,自动构建,刷新浏览器
(6)代码校验:在代码被提交到仓库前需要检测代码是否符合规范,以及单元测试是否通过
(7)自动发布:更新完代码后,自动构建出线上发布代码并传输给发布系统。


webpack 构建流程?(介绍一下webpack 的整个生命周期?)


Webpack 的运行流程是一个串行的过程,从启动到结束会依次执行以下流程:

(1)初始化参数:从配置文件和 Shell 语句中读取与合并参数,得出最终的参数;
(2)开始编译:用上一步得到的参数初始化 Compiler 对象,加载所有配置的插件,执行对象的 run 方法开始执行编译;
(3)确定入口:根据配置中的 entry 找出所有的入口文件;
(4)编译模块:从入口文件出发,调用所有配置的 Loader 对模块进行翻译,再找出该模块依赖的模块,再递归本步骤直到所有入口依赖的文件都经过了本步骤的处理;
(5)完成模块编译:在经过第4步使用 Loader 翻译完所有模块后,得到了每个模块被翻译后的最终内容以及它们之间的依赖关系;
(6)输出资源:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的 Chunk,再把每个 Chunk 转换成一个单独的文件加入到输出列表,这步是可以修改输出内容的最后机会;
(7)输出完成:在确定好输出内容后,根据配置确定输出的路径和文件名,把文件内容写入到文件系统。

在以上过程中,Webpack 会在特定的时间点广播出特定的事件,插件在监听到感兴趣的事件后会执行特定的逻辑,并且插件可以调用 Webpack 提供的 API 改变 Webpack 的运行结果。

简单说

(1)初始化:启动构建,读取与合并配置参数,加载 Plugin,实例化 Compiler
(2)编译:从 Entry 出发,针对每个 Module 串行调用对应的 Loader 去翻译文件的内容,再找到该 Module 依赖的 Module,递归地进行编译处理
(3)输出:将编译后的 Module 组合成 Chunk,将 Chunk 转换成文件,输出到文件系统中


如何提高webpack的构建速度?


  • 使用高版本的 webpack

  • 多线程/多实例构建

  • 缩小打包作用域
    exclude/include(确定 loader 规则范围)
    resolve.modules(指明第三方模块的绝对路径,减少不必要的查找)
    resolve.extensions(减少后缀尝试的可能性)
    noParse(对不需要解析的库进行忽略,虽然不必解析但依旧会被打包到 bundle 中,被忽略的文件不应该包含 import、require、define等模块化语句)
    IgnorePlugin(完全排除模块)
    合理使用 alias

  • 充分利用缓存提升二次构建速度
    babel-loader 开启缓存
    terser-webpack-plugin 开启缓存
    cache-loader 或者 hard-source-webpack-plugin 开启缓存

  • DLL
    使用 DllPlugin 进行分包,使用 DllReferencePlugin(索引链接)对 manifest.json 引用,让一些基本不会改动的代码先打包成静态资源,避免反复编译浪费时间。


如何优化打包大小?


  • 压缩代码
    通过 mini-css-extract-plugin 插件提取 css 到单独文件中;等

  • 提取页面公共资源
    利用 cdn 加速

  • Tree Shaking
    删除死代码,尽可能多使用 es6 模块;

  • 优化图片
    对于小图可以使用 base64 的方式写入文件中,
    配置 image-webpack-plugin 等;

  • scope hoisting
    将所有模块的代码按照引用顺序放在一个函数作用域里,然后适当重命名以防止变量名冲突。

  • 动态 polyfill
    只给用户返回需要的 polyfill;


了解哪些模块化标准?


(1) CommonJS
  • 介绍
    所有代码都运行在模块作用域,不会污染全局作用域。
    模块可以多次加载,但是只会在第一次加载时运行一次,然后运行结果就被缓存了,以后再加载,就直接读取缓存结果。要想让模块再次运行,必须清除缓存。
    模块加载的顺序,按照其在代码中出现的顺序。
    同步的模块加载方式不适合在浏览器环境中,因为会阻塞加载,浏览器资源多是异步加载的。
  • 基本语法
    暴露模块:module.exports = valueexports.xxx = value
    引入模块:require(xxx)
(2) AMD

AMD规范则是非同步加载模块,允许指定回调函数。

(3) CMD

CMD规范专门用于浏览器端,模块的加载是异步的,模块使用时才会加载执行。

(4) UMD

规范类似于兼容 CommonJS 和 AMD 的语法糖,是模块定义的跨平台解决方案。

(5) ES6模块

编译时能确定模块的依赖关系,以及输入和输出的变量。

  • 基本语法
    暴露模块:export {}
    引入模块:import {} from XXX
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容

  • 随着现代前端开发的复杂度和规模越来越庞大,已经不能抛开工程化来独立开发了,如react的jsx代码必须编译后才能在...
    coderfl阅读 250评论 0 0
  • 1、什么是webpack webpack是一个打包模块化javascript的工具,在webpack里一切文件皆模...
    没糖_cristalle阅读 346评论 0 0
  • webpack插件安装经历: 插件安装前 自行百度其官网及论坛上的利弊介绍生产环境用到的插件: --save-d...
    codingHi阅读 1,148评论 0 0
  • 1、 Loader是什么? 1、我们之前打包的都是js文件,下面试试打包一个图片文件。 首先将一个图片文件放进sr...
    无争公子__阅读 497评论 0 0
  • webpack相关 什么是webpack webpack是一个打包模块化javascript的工具,在webpac...
    木头就是我呀阅读 400评论 0 1