沐游虞笔记
  • 前端面试题

    • HTML面试题汇总(无答案)
    • HTML面试题汇总
    • CSS 面试题汇总(无答案)
    • CSS 面试题汇总
    • javascript 面试题汇总(无答案)
    • javascript 面试题汇总
    • promise 面试题(无答案)
    • promise 面试题
    • 浏览器面试题汇总(无答案)
    • 浏览器面试题汇总
    • 网络面试题汇总(无答案)
    • 网络面试题汇总
    • 工程化面试题汇总(无答案)
    • 工程化面试题汇总
    • VUE面试题汇总(无答案)
    • VUE面试题汇总
  • 直播课文件

    • 静态页面学习指导
    • 属性的计算过程
    • 层叠继承规则总结
    • BFC
    • JS基础知识回顾
    • DOM 事件的传播机制
    • DOM 事件的注册和移除
    • 阻止事件默认行为
    • 基础领航考试题
    • 基础领航考试题(答案)
    • 2024前端发展
    • JS核心概念学习指导
    • 第三方库与工程化学习指导
    • Vue入门学习指导
    • vue进阶学习指导
    • 前端性能优化
  • 笔面试环节知识讲解

    • 目录
    • 图像处理
    • 图像处理(面试)
    • Webpack构建优化
    • Webpack构建优化(面试)
    • TTS性能优化
    • TTS性能优化(面试)
    • 实时协作
    • 实时协作(面试)
    • 网页复制图片到剪贴板
    • 网页复制图片到剪贴板(面试)
    • vite插件
    • vite插件(面试)
    • 表单数据同步与保持
    • 表单数据同步与保持(面试)
    • 优化虚拟列表
    • 优化虚拟列表(面试)
    • 微前端解决巨石应用
    • 微前端解决巨石应用(面试)
    • DNS解析与优化
    • DNS解析与优化(面试)
    • 前端监控
    • 前端监控(面试)
    • 12.跨标签页通信
    • 12.跨标签页通信(面试)
    • 13.Vite相关优化
    • 13.Vite相关优化(面试)
    • 14.计时器节流问题
    • 14.计时器节流问题(面试)
    • 15.多文件预览支持
    • 15.多文件预览支持(面试)
    • 16.defer优化白屏时间
    • 16.defer优化白屏时间(面试)
  • Vue3整体变化
  • Vue2响应式回顾
  • Vue3响应式变化
  • nextTick实现原理
  • 两道代码题
  • Vue运行机制
  • 渲染器核心功能
  • 事件绑定与更新
  • computed面试题
  • watch面试题
  • 图解双端diff
  • 图解快速dff
  • 最长递增子序列
  • 模板编译器
  • 模板编译提升
  • 组件name作用
  • 路由传参方式
  • 基础篇

    • 序章React介绍
    • JSX基础语法
    • React基本介绍
    • 表单
    • 生命周期
    • 组件与事件绑定
    • 组件状态与数据传递
    • Hooks
    • React--redux介绍
    • React-router介绍
  • 就业篇

    • 属性默认值和类型验证
    • 高阶组件
    • Ref
    • Context
    • Render Props
    • Portals
    • 错误边界
    • 组件渲染性能优化
    • 前端框架的理解
    • Reacti和Vue描述页面的区别
    • 前端框架的分类
    • 虚拟DoM
    • React整体架构
    • React渲染流程
    • Fiber双缓冲
    • MessageChannel
    • Scheduleri调度普通任务
    • Scheduleri调度延时任务
    • 最小堆
    • React中的位运算
    • beginWork工作流程
    • completeWork工作流程
    • 图解diff算法
    • commit工作流程
    • lane模型
    • React中的事件
    • Hooks原理
    • useStateuseReducer.
    • effect相关hook
    • useCallbackuseMemo
    • useRef
    • Update
    • 性能优化策略之eagerState
    • 性能优化策略之bailout
    • bailoutContextAPl
    • 性能优化对日常开发启示
  • 前端监控概述
  • 错误监控
  • 数据上报
  • 页面性能监控
  • 用户行为收集与埋点
  • CSS3手册
  • HTML5手册
  • JavaScript语言提升

    • es补充
    • 事件循环
    • promise基础
    • Promise的链式调用
    • Promise的静态方法
    • async和await
    • Promise相关面试题
  • 网络

    • 客户端与服务器
    • 关于 Apifox 的使用
  • git文档
  • 工程化

    • CommonJS
    • ES module
    • npm文档(包管理)
    • Lass笔记
    • webpack工具
  • canvas详解
  • uinapp笔记
  • 自动化测试
  • oauth2令牌

    • 认识Oauth2
    • 三方应用实现github授权
    • 微信三方应用登录实现
    • 支付宝沙箱支付功能
  • 前端面试题

    • HTML面试题汇总(无答案)
    • HTML面试题汇总
    • CSS 面试题汇总(无答案)
    • CSS 面试题汇总
    • javascript 面试题汇总(无答案)
    • javascript 面试题汇总
    • promise 面试题(无答案)
    • promise 面试题
    • 浏览器面试题汇总(无答案)
    • 浏览器面试题汇总
    • 网络面试题汇总(无答案)
    • 网络面试题汇总
    • 工程化面试题汇总(无答案)
    • 工程化面试题汇总
    • VUE面试题汇总(无答案)
    • VUE面试题汇总
  • 直播课文件

    • 静态页面学习指导
    • 属性的计算过程
    • 层叠继承规则总结
    • BFC
    • JS基础知识回顾
    • DOM 事件的传播机制
    • DOM 事件的注册和移除
    • 阻止事件默认行为
    • 基础领航考试题
    • 基础领航考试题(答案)
    • 2024前端发展
    • JS核心概念学习指导
    • 第三方库与工程化学习指导
    • Vue入门学习指导
    • vue进阶学习指导
    • 前端性能优化
  • 笔面试环节知识讲解

    • 目录
    • 图像处理
    • 图像处理(面试)
    • Webpack构建优化
    • Webpack构建优化(面试)
    • TTS性能优化
    • TTS性能优化(面试)
    • 实时协作
    • 实时协作(面试)
    • 网页复制图片到剪贴板
    • 网页复制图片到剪贴板(面试)
    • vite插件
    • vite插件(面试)
    • 表单数据同步与保持
    • 表单数据同步与保持(面试)
    • 优化虚拟列表
    • 优化虚拟列表(面试)
    • 微前端解决巨石应用
    • 微前端解决巨石应用(面试)
    • DNS解析与优化
    • DNS解析与优化(面试)
    • 前端监控
    • 前端监控(面试)
    • 12.跨标签页通信
    • 12.跨标签页通信(面试)
    • 13.Vite相关优化
    • 13.Vite相关优化(面试)
    • 14.计时器节流问题
    • 14.计时器节流问题(面试)
    • 15.多文件预览支持
    • 15.多文件预览支持(面试)
    • 16.defer优化白屏时间
    • 16.defer优化白屏时间(面试)
  • Vue3整体变化
  • Vue2响应式回顾
  • Vue3响应式变化
  • nextTick实现原理
  • 两道代码题
  • Vue运行机制
  • 渲染器核心功能
  • 事件绑定与更新
  • computed面试题
  • watch面试题
  • 图解双端diff
  • 图解快速dff
  • 最长递增子序列
  • 模板编译器
  • 模板编译提升
  • 组件name作用
  • 路由传参方式
  • 基础篇

    • 序章React介绍
    • JSX基础语法
    • React基本介绍
    • 表单
    • 生命周期
    • 组件与事件绑定
    • 组件状态与数据传递
    • Hooks
    • React--redux介绍
    • React-router介绍
  • 就业篇

    • 属性默认值和类型验证
    • 高阶组件
    • Ref
    • Context
    • Render Props
    • Portals
    • 错误边界
    • 组件渲染性能优化
    • 前端框架的理解
    • Reacti和Vue描述页面的区别
    • 前端框架的分类
    • 虚拟DoM
    • React整体架构
    • React渲染流程
    • Fiber双缓冲
    • MessageChannel
    • Scheduleri调度普通任务
    • Scheduleri调度延时任务
    • 最小堆
    • React中的位运算
    • beginWork工作流程
    • completeWork工作流程
    • 图解diff算法
    • commit工作流程
    • lane模型
    • React中的事件
    • Hooks原理
    • useStateuseReducer.
    • effect相关hook
    • useCallbackuseMemo
    • useRef
    • Update
    • 性能优化策略之eagerState
    • 性能优化策略之bailout
    • bailoutContextAPl
    • 性能优化对日常开发启示
  • 前端监控概述
  • 错误监控
  • 数据上报
  • 页面性能监控
  • 用户行为收集与埋点
  • CSS3手册
  • HTML5手册
  • JavaScript语言提升

    • es补充
    • 事件循环
    • promise基础
    • Promise的链式调用
    • Promise的静态方法
    • async和await
    • Promise相关面试题
  • 网络

    • 客户端与服务器
    • 关于 Apifox 的使用
  • git文档
  • 工程化

    • CommonJS
    • ES module
    • npm文档(包管理)
    • Lass笔记
    • webpack工具
  • canvas详解
  • uinapp笔记
  • 自动化测试
  • oauth2令牌

    • 认识Oauth2
    • 三方应用实现github授权
    • 微信三方应用登录实现
    • 支付宝沙箱支付功能
  • HTML+CSS语言提升

    • CSS3视觉

      • CSS3手册
    • HTML5文档

      • HTML5手册
  • JavaScript语言提升

    • 零碎的改动

      • ES语言提升
    • 数组

    • 事件循环

      • 课件
    • Promise基础

      • 笔记
    • Promise的链式调用

      • 笔记
    • Promise的静态方法

      • 笔记
    • async和await

      • 笔记
    • Promise相关面试题

      • 笔记
  • 网络

    • 基本概念-客户端和服务器

      • 网络课件
    • 关于 Apifox 的使用

      • 关于 Apifox 的使用
  • git

    • git基本概念

      • git文档
    • git分支

  • 工程化

    • CommonJS

      • 课堂笔记
    • ES Module

      • 模块化手册
    • 包管理器

      • npm文档
    • Less

      • 课堂笔记
    • 构建工具的使用

      • 课堂笔记
        • 自动厂商前缀
        • css module
          • 真正的webpack没有那么神奇
          • 对我们开发的影响
          • 作业
        • 回顾和总结1
        • 回顾和总结2
    • 分页电影列表案例

  • 技术应用
  • 工程化
  • 构建工具的使用
luzhichang
2023-10-23
目录

课堂笔记

技能树

工程化,为复杂应用而生

本文为保持简单,牺牲了某些语言的准确性

# 核心

webpack是用来搭建前端工程的

它运行在node环境中,它所做的事情,简单来说,就是打包

image-20210508172953979

具体来说,就是以某个模块作为入口,根据入口分析出所有模块的依赖关系,然后对各种模块进行合并、压缩,形成最终的打包结果

在webpack的世界中,一切皆是模块

# 体验

老师提供的工程,以src/main.js作为入口文件

按照习惯,所有的模块均放置在src目录中

  1. 安装依赖

  2. 编写多个模块

    随意编写一些模块,可以是js、图片、音视频,以入口模块为起点,形成依赖关系

  3. 运行npm run build命令,进行打包

  4. 查看打包结果

    打包结果放置在dist目录中

通过上面的体验,可以发现,webpack给我们带来了至少以下好处:

  • 可以大胆的使用任意模块化标准

    无须担心兼容性问题,因为webpack完成打包后,已经没有了任何模块化语句

  • 可以将一些非JS代码也视为模块

    这样可以对css、图片等资源进行更加细粒度的划分

  • 在前端开发中,也可以使用npm

    webpack不会运行你的源代码,无论是你自己写的模块,还是通过npm安装的模块,webpack一视同仁,统统视为依赖,最终合并到打包结果中

  • 非常适合开发单页应用

    单页应用是前端用户体验最好的web应用

    所谓单页应用,是指只有一个html页面,页面中没有任何内容,所有的内容均靠js生成

    要优雅的实现单页应用,最好依托于前端框架,比如vue、react

webpack给我们开发带来的变化远不止于此,接下来一一体验

# 页面模板

对于单页应用而言,只有一个空白的页面,所有内容都靠JS代码创建

webpack会自动生成一个页面,并且在页面中会自动加入对js和css的引用

它生成页面时,参考的是public/index.html,其称之为页面模板

# public目录

webpack会非常暴力的将public目录中的所有文件(除页面模板外),复制到打包结果中

# 开发服务器

如果每次修改完代码,都要经过打包->运行,未免太过麻烦

在开发阶段,我们可以运行npm run serve命令获得更好的打包体验

该命令会让webpack启动一个开发服务器。

在这个阶段,webpack并不会形成打包结果文件,而是把打包的内容放到内存中,当我们请求服务器时,服务器从内存中给予我们打包结果

与此同时,当源码发生变动时,webpack会自动重新打包,同时刷新页面以访问到最新的打包结果

image-20210508194442940

# 文件缓存

可以看到,除了页面外,其他的资源在打包完成后,文件名多了一些奇奇怪怪的字符

例如:js/app-9ea93.js

其中,9ea93这样的字符称之为hash,它会随着模块内容的变化而变化

源码内容不变,hash不变;源码内容变化,hash变化

之所以这样做,是因为生产环境中,浏览器会对除页面外的静态资源进行缓存

如果不设置hash值,一旦代码更新,浏览器还会使用之前缓存的结果,无法使用最新的代码

image-20210508183135487

有了hash值之后,即可解决此问题

image-20210508183454385

webpack会在打包时自动处理hash值,并不会对我们写代码造成任何影响,但作为一个前端开发者,有必要了解这一点

# 资源路径

除代码和样式模块外,其他模块被视为资源模块

值得特别注意的是,资源模块在源代码中的路径和打包后的路径是不一样的,这就导致我们在编写代码的时候,根本无法知晓最终的路径

最常见的例子,就是在css中使用背景图片

.container{
  /* 背景图使用了源码中的路径 */
  backgroud: url('../assets/1.png'); 
}

它能正常工作吗?

它能!

因为webpack非常智能的发现了这一点,对于css中的路径,webpack在打包时,会将其自动转换为打包结果的路径,比如,上面的代码在打包完成后,可能被转换为下面的格式

.container{
  /* css中的资源路径会被自动替换,我们无须关心 */
  background: url(/img/1492ea.png);
}

但如果我们要通过js动态的使用路径,webpack是无法识别的

// 打包前
const url = './assets/1.png'; // 该路径无法被转换
img.src = url;

// 打包后
const url = './assets/1.png'; // ❌
img.src = url;

正确的做法是,通过模块化的方式导入资源,并获取资源路径

// 打包前
import url from './assets/1.png'; // 打包后,url得到的将是真实的路径
img.src = url;

// 打包后
const url = '/img/1492ea.png'; // ✅
img.src = url;

# 缺省的文件和后缀名

导入模块时,所有js模块均可省略.js,若导入的模块文件名为index.js,可省略文件名

import './home'; // 若存在home.js,可省略js
import './movie'; // 若movie是一个目录,此次导入的是 ./movie/index.js

# 路径别名

随着体量的增长,不可避免的,会形成层级极深的目录

root
	|- src
		|- a
				|- a1
						|- a2
							 |- index.js
		|- b
				|- b1
						|- index.js

如果需要在./src/a/a1/a2/index.js中导入./src/b/b1/index.js,则可能产生下面特别恶心的代码

import '../../../b/b1/index.js';

webpack提供了别名供我们快速定位到./src目录,通常,该别名为@

上面的导入代码可简化为

import '@/b/b1'; // @表示src目录,同时省略了index.js

# js兼容性

当webpack读取到js代码时,会自动对其进行兼容性处理

具体的处理方案涉及到两个配置文件:

  • babel.config.js:通过配置该文件,可以设置对哪些js代码进行降级处理
  • .browserslistrc:通过配置该文件,可以设置在降级时,要兼容哪些浏览器,兼容的范围越光,降级产生的代码就越多,自然,打包后的体积就越大

你无须知晓具体的配置方式

# 打包压缩

webpack在打包时,会对所有js和css代码进行压缩

对于js,除了压缩之外,还会对其中的各种名称进行混淆

(self.webpackChunkmovie_list=self.webpackChunkmovie_list||[]).push([[587],{3587:(r,t,n)=>{"use strict";n.r(t),n(5666),n(1539),n(8674),n(9600),n(1249),n(2222);var e=n(9755),a=n.n(e);var o;function i(r){o.html(r.map((function(r){return'<li>\n  <a href="'.concat(r.url,'" target="_blank">\n    <img src="').concat(r.cover,'" title="').concat(r.title,'">\n  </a>\n  <a href="').concat(r.url,'" target="_blank" class="').concat("qmUYQv1xlJhGMQKz-kfAp",'">').concat(r.title,'</a>\n  <p class="').concat("_3yV5wC-URYTUP0sPvaE0ZR",'">').concat(r.rate,"</p>\n  </li>")})).join(""))}o=a()("<ul>").addClass("_1fsrc5VinfYHBXCF1s58qS").appendTo("#app");var c=n(8138);const u=

混淆的作用一方面是为了进一步压缩包体积,另一方面是为了让我们的代码更难被其他人理解利用

# 源码地图 source map

我们运行的是webpack打包后的结果,而打包后的结果是很难阅读的

但这样一来会带来新的问题,如果代码报错,我们就难以知道到底是那一行代码写的有问题

此时源码地图就发挥了作用

可以发现,js代码打包后都会跟上一个同名的、后缀为.map的文件,该文件就保存了原始代码的内容

请放心,这个内容人类是看不懂的,但浏览器可以看懂

当代码报错时,浏览器会定位到源码地图中的对应代码,而不是把真实报错的代码展示给我们

你无须关心这一点,但可以自然的从其中获得巨大的便利

# css工程化

webpack能够识别所有的样式代码,包括css、less、sass、stylus

在打包时,会将它们转换成纯正的css

除此之外,它还具备以下的神奇能力

# 自动厂商前缀

css有很多兼容性问题,解决这些兼容性问题的最常见办法,就是加上厂商前缀。

比如:

/* 兼容性不好的代码 */
.container{
	display: flex;
  transition: 1s;
}

/* 兼容性好的代码 */
.container {
  display: -webkit-box;
  display: -webkit-flex;
  display: flex;
  -webkit-transition: 1s;
  transition: 1s;
}

webpack会根据.browserlistrc中指定的浏览器范围,按需、自动加上厂商前缀

我们开发无须关心

# css module

css文件多了后,你怎么保证它们里面没有冲突的类样式?

靠层级选择器?就不担心效率?

靠命名规范?就不担心脑袋爆炸?

要靠就靠css module

当样式文件以xxx.mdoule.xxx的方式命名时,webpack会将该文件当成一个开启了css module的文件

比如:index.module.less、movie.module.css,都是开启了css module的文件

文件中的所有类名都会被hash化

// 源码
.container{}
.list{}
.item{}

// 打包结果,绝无可能重名
._2GFVidHvoHtfgtrdifua24{}
._1fsrc5VinfYHBXCF1s58qS{}
.urPUKUukdS_UTSuWRI5-5{}

现在就一个问题,我们在使用类名时,如何知道它打包结果的类名呢?

import './index.module.less';
dom.classList.add('container'); // ❌ 最终的类名可不是这个

正确的方式如下:

// styles 是一个对象,里面映射了源码类名和打包类名的关系
import styles from './index.module.less';
dom.classList.add(styles.container); // ✅ 属性container中记录的就是container转换后的类名

# 真正的webpack没有那么神奇

实际上,webpack没有做这么多事,我们不能把功劳(怨念)全归结于它

它只是站在巨人(其他流氓)肩膀上而已

下图可以看个热闹

image-20210508203658298

webpack通过插件(plugin)和加载器(loader)将这些技术整合在一起

上图的技术 + 乱七八糟一大堆其他技术 + 老师的配置 = 呈现给你的工程

目前,你无须理解这一些,保持敬畏即可

最后,说明一下工程中看不懂的文件:

  • .browserslistrc,表达适配的浏览器范围,会被工程化中的其他技术所使用
  • babel.config.js,babel的配置文件,做js降级处理
  • postcss.config.js,postcss的配置文件,做css代码转换
  • webpack.config.js,webpack的配置文件,整合其他工程化技术,以及配置打包细节、开发服务器、路径别名等等

# 对我们开发的影响

  1. 学会访问开发服务器查看效果

  2. 学会动态获取资源文件路径

    import url from './assets/1.png'; 
    img.src = url;
    
  3. 学会省略文件和后缀名

    import './home'; // 若存在home.js,可省略js
    import './movie'; // 若movie是一个目录,此次导入的是 ./movie/index.js
    
  4. 学会使用别名简化导入代码

    import '@/b/b1'; // 实际导入: src/b/b1/index.js  (若b1是目录)
    
  5. 学会使用css module

    // styles 是一个对象,里面映射了源码类名和打包类名的关系
    import styles from './index.module.less';
    dom.classList.add(styles.container); 
    

# 作业

# 回顾和总结1

看着此笔记的目录,大声说出每个目录标题板块的内容

# 回顾和总结2

脱离此文档,能够说出整个文档的大致内容

课堂笔记

← 课堂笔记

Theme by Vdoing | Copyright © 2021-2024 蜀ICP备2024068710号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式