frontendmasters webpack-fundamentals

Introduction

本质上就是个命令行工具

  • 沿袭自 npm 的脚本和生态系统

Problems with Script Loading

管理 js

  • 最初用 IIFE
  • 后来的 gulp 等目的只是将文件连接在一起
  • 传统的模块化方式迫使 JavaScript 引擎急于解析代码,从而引起性能浪费。懒加载和摇树才是我们想要的。

History of Modules

模块化

  • CommonJS 和 npm,但没有浏览器支持
  • 需要解决自我引用和循环引用的问题
  • require 实际上是一个可以传递到任何地方的函数,所以 webpack 重新定义了 require
  • 下一个问题是如何异步加载,用 AMD 解决吗?NO,那像是依赖注入,太动态化了。

EcmaScript Modules (ESM)

对模块化问题的解决方案

  • Node 的 ESM 有点悬而未决
  • 浏览器的 ESM 非常慢

Introducing Webpack

所有的资产都有模块

  • Webpack 是一个模块捆绑器
  • Webpack 支持代码分割或静态异步捆绑
  • 之后诞生了热更新功能,甚至是 redux

Configuring Webpack

有三种方法可以使用 Webpack

  • cli
  • 配置
  • node,像 Neutrino 和 joy

Using Webpack for the First Time

  • webpack 只做 barebones,帮助用户定制工作流
  • 使用 npm 脚本封装如 webpack 这样的二进制命令

Adding npm Scripts for Environment Builds

  • webpack 4+ 零配置
  • 为工作流定制环境:开发、线上、构建、调试

Setting Up Debugging

  • node --inspect --debug-brk
"debug":"node --inspect --inspect-brk ./node_modules/webpack/bin/webpack.js",
"dev:debug":"npm run debug -- --env.mode development"

Coding Your First Module

Adding Watch Mode

ES Module Syntax

  • Webpack中 会解析出一个依赖图

CommonJS Export

  • Webpack 支持使用 require,但强烈支持不要尽可能多地使用 CommonJS
  • 像 Bable 和 Typescript 这样的工具可以安全地默认在后台将ESM转换为 CommonJS,然后将其传递给 Webpack。

CommonJS Named Exports

  • 建议将导出保留在文件的底部
  • 使用命名参数而不仅仅是模块或模块点导出

Tree Shaking

  • 增量编译

Webpack Bundle Walkthrough 重要

  • 编译后的每个模块都是 IIFE
  • 会预置一段运行时代码,首先是 installedModules,它是一个模块缓存
  • 还有一个名为 webpack_require 的函数,这就是 require 函数,它需要一个模块 ID 参数,返回 .exports
  • 找到模块后会调用 .call 方法
  • 这个过程叫做动态绑定,为了避免循环依赖,会对对象进行冻结
  • 第一个模块在最后一行被调用,不是 IIFE

Webpack Entry

  • 依赖的切入点
  • 与 output 属性搭配使用

Output & Loaders

  • output 告诉 Webpack 在哪里以及如何分发这些文件
  • loader 需要规则集,从而匹配和转换文件
  • loader 可以组合使用

Chaining Loaders

  • 总是从右到左执行,类似一个组合函数

Webpack Plugins

  • 它只是一个实例。它是一个 JavaScript 对象,在原型链中有一个 apply 属性。它允许您挂钩整个事件的 Webpack 生命周期。
  • 通过监听事件来根据数据的内容进行一些操作。
  • 记得使用的时候 new 一下
  • 80% 的 Webpack 源代码都是由这些插件组成的。Webpack 本身是一个完全由事件驱动的架构。

Webpack Config

  • webpack 可以接受一个对象,作为配置模块的默认导出,但它也可以使用一个返回对象的函数。

Passing Variable to Webpack Config

  • 三套配置
npm run webpack -- --env.mode production

Adding Webpack Plugins

  • 以 html-webpack-plugin 做例子

Setting Up a Local Development Server

  • 以 webpack-dev-server 为例,是基于 Express 的 Web 服务器。只不过写到内存里。

Starting to Code with Webpack

随便写了点代码

Splitting Environment Config Files

  • webpack-merge 合并
  • 在创建 JavaScript 模块时可以对其进行哈希处理,比如说 chunckhash

Webpack Q&A

  • webpack-dev-server 可以进行服务端开发吗?

实际上是 webpack-dev-middleware,当然可以

  • 有没有办法利用多个模板的 HTML webpack 插件?

实际上是多页应用程序架构:multipage-webpack-plugin?为每个条目创建一个新的 html-webpack-plugin 插件实例。

  • 是否存在 webpack 进程遇到内存不足错误以及捕获该异常的情况?

webpack 性能的空间复杂度和模块是线性的,所以需要很多内存。webpack 5 会有一些缓存。如果出现内存泄漏就加哈希。

Using CSS with Webpack

  • 传统的方法是在磁盘文件夹中提供它并在 style 标记中引用。
  • 需要一个合适的加载器来处理这个文件:css-loader

Hot Module Replacement with CSS

  • Webpack 具有以下功能:能够对以增量方式进行的更改进行修补,并在不必重新加载浏览器的情况下应用它们。
  • mini-css-extra 插件可以将 css 提取到一个文件里
  • 代码拆分 CSS 时,将它们分成异步应用程序变得很有价值。所以 CSS 模块出现了。

File Loader & URL Loader

  • 将媒体资源转换成 base64

Loading Images with JavaScript

Limit Filesize Option in URL Loader

  • 各种图像

Implementing Presets

  • 添加一个预设系统,不仅仅是开发和生产环境
  • 有时,肖恩称他们为附加组件。你可以随意调用它。通过传 env 来取出预设选项
  • 将若干个预设选选项对应的配置合并:applyPresets
const webpackMerge = require("webpack-merge");

const loadPresets = (env = { presets: [] }) => {
  const presets = env.presets || [];

  const mergedPresets = [].concat(...[presets]);
  const mergedConfigs = mergedPresets.map(presetName => {
    return require(`./presets/webpack.${presetName}`)(env);
  });

  return webpackMerge({}, ...mergedConfigs);
};

module.exports = loadPresets;

Bundle Analyzer Preset

  • 当 webpack 构建时,它会发出这个 stats 对象。stats 对象要么转换为字符串,要么转换为 JSON
  • WebpackBundleAnalyzer 插件可视化分析

Compression Plugin

  • 压缩所有资产成 gzip

Source Maps

  • 可以通过多种不同的方式生成源映射
  • devtool 是负责创建源映射的属性。
  • sourcemap 有不同的质量:快慢轻重
  • 可以做调试驱动的开发
  • 常见的有 source-map、cheap-module-source-map、eval 等

Q&A and Closing Remarks

  • 如何避免打包文件过大?

代码拆分、关闭缓存、懒加载等。

  • 摇树在 output 独立的函数而不是 class 时都会受益吗?

只需使用 ESM 即可获得依赖注入。所以与导出整个类相比,最好是导出单个函数和值以及基元。

  • 如何找到好插件和坏插件?

Webpack-Contrib,以及看 github 的 pr 和 issue 处理程度

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

推荐阅读更多精彩内容