前端工程化-webpack入门
# 前端工程化-webpack入门
# 前言
在开始介绍webpack之前,先简单带大家回顾下前端的发展简史~
# 前端发展简史
- 原始时代
- 1989 年,任职于欧洲核子研究中心的蒂姆·伯纳斯 - 李(Tim Berners-Lee)提出了在互联网上构建超链接文档系统的构想:可以把超文本系统完美地运行在互联网上,让各地的人们能够自由地共享信息。蒂姆把这个系统称为“万维网”(World Wide Web),也就是我们现在所熟知的 Web。而HTML就一直被用作万维网的信息表示语言。
- 1993年,第一款图文混排的网页浏览器Mosaic诞生;94年网景公司(Netscape)推出网景浏览器(Netscape Navigator),迅速占领市场,成为当时最流行的浏览器。它的初衷是为了方便科研人员查阅资料、文档 index.html页面和它的样式文件a.css,用文本编辑器写代码,无需编译,本地预览,确认OK,丢到服务器,等待用户访问。
纯内容的静态展示:HTML 写写页面模板、CSS 给页面排个好看点的版式
- 1995年,JS出现,HTML 为骨架,CSS 为外貌,JavaScript 为交互。之后1998年,aJax的出现,前端从纯内容的静态展示,发展到了动态网页,富交互,前端数据处理的新时期
由于动态交互、数据交互的需求增多,还衍生出了jQuery(2006) 这样优秀的跨浏览器的 js 工具库,主要用于 DOM 操作,数据交互。
- 08年之后,NodeJs、ReactJs、VueJS相继出现
- 谷歌V8引擎 和 node 的出现,使前端开发人员可以用熟悉的语法糖编写后台系统,为前端提供了使用同一语言的实现全栈开发的机会
- React、Angular、Vue 等 MVVM 前端框架的出现,使前端实现了项目真正的应用化(SPA单页面应用);推动了前后端的彻底分离(前端项目独立部署,不再依赖类似的 template 文件目录)
- 4G 移动网络的普及,使得前端从单一的基于的 PC 浏览器 展示的 web 应用,开始向手机、平板覆盖;前端不再仅仅是 PC web 方面的开发,手机配置,与 app 进行 hybird 开发,变成了常态。
# 前端工程化的发展
前端越来越复杂,设计的问题和环节也越来越多,不采用工程化管理,就无法很好的实现团队协同和降低复杂性:
- 前端范畴不断扩大
- 前后端分离
- 模块化开发的出现
- 转码器的盛行
- 开发流程和团队
# 前端工程化的发展
目前来说,Web业务日益复杂化和多元化,前端开发已经由以WebPage模式为主转变为以WebApp模式为主了。现在随便找个前端项目,都已经不是过去的拼个页面+搞几个jQuery插件就能完成的了。工程复杂了就会产生许多问题,比如:如何进行高效的多人协作?如何保证项目的可维护性?如何提高项目的开发质量?...
前端工程化是前端架构中重要的一环,主要就是为了解决上述大部分问题的。而前端工程本质上是软件工程的一种,因此我们应该从软件工程的角度来研究前端工程。
# 什么是前端工程化?
工程化是一种思想,而不是某种技术。其主要目的为了提高效率和降低成本,即提高开发过程中的开发效率,减少不必要的重复工作时间等
一个工程的生命周期:工程立项、需求分析、产品原型、开发实施、测试部署、上线运行
前端工程化就是通过各种工具和技术,提升前端开发效率的过程。
- 前端工程化的内容:各种工具和技术
- 作用:通过使用工具,提升开发效率
学习前端工程化,就是学习使用各种工具,解决前端开发中的各种问题
前端工程化要解决的问题:
- 项目上线前,压缩代码:减少代码体积,节省带宽或空间
原理:把代码中多余的空格,注释,不需要的内容全部去掉
- 对es6+或css3新特性进行转换:解决浏览器兼容性问题(caniuse)
- 对Less等css预编译语言进行编译处理:想使用Less增强css的编程性,但浏览器不能直接支持Less:支持使用变量
- 格式化代码:多人协作时,代码风格无法统一
- ...
相对应就出现解决这些问题的工具:压缩工具、转换工具、格式化工具、自动化工具、...
前端工程化包含的内容:
- 脚手架工具:创建项目基础结构、提供项目规范和约定
- 专用脚手架:vue-cli(只能创建vue项目)、create-react-app、angular-cli、
- 通用脚手架:Yeoman(可创建vue和react项目)、Plop
- 自动化构建:
- 简单的:npm scripts && script hooks
- 专业的:Grunt、Gulp、FIS、vite
- 模块化打包:Webpack、Rollup、Parcel
- 标准化规范:ESLint、StyleLint、Prettier
- 自动化测试:Mocha、Jest
- 自动化部署:Git Hook、Lint-staged、CI / CD
工程化 不是 某个工具!!!
前端工程化的基础是node.js,现在大部分前端工程化使用的工具都是使用node.js做开发的。
前端工程化需要考虑哪些因素呢?应该从模块化、组件化、规范化、自动化4个方面去思考:
- 模块化:模块化就是把一个大的文件,拆分成多个相互依赖的小文件,按一个个模块来划分;模块化只是在文件层面上,对代码和资源的拆分
- 组件化:页面上所有的东西都可以看成组件,页面是个大型组件,可以拆成若干个中型组件,然后中型组件还可以再拆,拆成若干个小型组件;组件化是在设计层面上,对于UI的拆分
- 规范化:在项目规划初期制定的好坏对于后期的开发有一定影响。 目录结构的制定 编码规范:html规范、CSS规范、JS规范、图片规范、命名规范 前后端接口规范 文档规范 组件管理 Git分支管理 Commit描述规范 定期codeReview 视觉图标规范
- 自动化:也就是简单重复的工作交给机器来做,自动化也就是有很多自动化工具代替我们来完成,例如持续集成、自动化构建、自动化部署、自动化测试等等
# 模块化
- JS的模块化
在ES6之前,JavaScript一直没有模块系统,这对开发大型复杂的前端工程造成了巨大的障碍。对此社区制定了一些模块加载方案,如CommonJS、AMD和CMD、ES6,某些框架也会有自己模块系统,比如Angular1.x。
规范确定了,然后就是模块的打包和加载问题:
- 用Webpack+Babel将所有模块打包成一个文件同步加载,也可以打成多个chunk异步加载;
- 用SystemJS+Babel主要是分模块异步加载;
- 用浏览器的
<script type="module">加载目前Webpack远比SystemJS流行。Safari已经支持用type="module"加载了。
- CSS的模块化
虽然SASS、LESS、Stylus等预处理器实现了CSS的文件拆分,但没有解决CSS模块化的一个重要问题:选择器的全局污染问题。
按道理,一个模块化的文件应该要隐藏内部作用域,只暴露少量接口给使用者。而按照目前预处理器的方式,导入一个CSS模块后,已存在的样式有被覆盖的风险。
CSS Modules仍然使用CSS,只是让JS来管理依赖。它能够最大化地结合CSS生态和JS模块化能力,目前来看是最好的解决方案。Vue的scoped style也算是一种。
- 资源的模块化
Webpack的强大之处不仅仅在于它统一了JS的各种模块系统,取代了Browserify、RequireJS、SeaJS的工作。更重要的是它的万能模块加载理念,即所有的资源都可以且也应该模块化。
资源模块化后,有三个好处:
- 依赖关系单一化。所有CSS和图片等资源的依赖关系统一走JS路线,无需额外处理CSS预处理器的依赖关系,也不需处理代码迁移时的图片合并、字体图片等路径问题;
- 资源处理集成化。现在可以用loader对各种资源做各种事情,比如复杂的vue-loader等等。
- 项目结构清晰化。使用Webpack后,你的项目结构总可以表示成这样的函数:dest = webpack(src, config)
# 组件化
页面上所有的东西都是组件。页面是个大型组件,可以拆成若干个中型组件,然后中型组件还可以再拆,拆成若干个小型组件,小型组件也可以再拆,直到拆成DOM元素为止。DOM元素可以看成是浏览器自身的组件,作为组件的基本单元。
# 规范化
模块化和组件化确定了开发模型,而这些东西的实现就需要规范去落实。
其中编码规范最好采取ESLint和StyleLint等强制措施,配置git hooks可以实现Lint不过不能提交代码等机制
# 自动化
图标合并、持续集成、自动化构建、自动化部署、自动化测试
# 构建工具
- 自动化构建是指将手动构建任务,通过命名自动执行的过程
构建过程:源代码自动转换生产代码
- 实现自动化构建的最简方式:
npm scripts
npm 允许在 package.json文件中,使用scripts字段定义脚本命令:
npm run dev、并行&、串行&&
- Grunt:基于文件读写的方式进行自动化构建
- Gulp:使用内存的方式进行构建
- FIS:百度出的,集成了很多工具,全家桶
- vite2.0
# 打包工具
- 前端为什么需要打包工具?
互联网的发现,前端越来越复杂,随着项目的负责度升级,代码规范和管理必须同步升级,于是出现了模块化规范;服务端出现commonJs,客户端AMD规范;之后出现ES modules规范;模块化很好得解决了复杂应用开发中的代码组织问题,但又产生新的问题:
- ES modules的浏览器兼容性问题
- 模块文件过多导致频繁发送网络请求问题
- 资源文件模块化的问题
转换ES6语法、转换JSX、CSS前缀补全/预处理器、压缩混淆、图片压缩
- rollup、webpack、parcel、vite
- Webpack 的构建主要依赖了插件和 loader,能力比较强大
评价工程化的六个维度
- Code Splitting,即代码分割。这意味着在构建打包时,能够将静态资源拆分,因此在页面加载时,实现最合理的按需加载策略。
- Hashing,即对打包资源进行版本信息映射。这个话题背后的重要技术点是最合理地利用缓存机制。
工程工具进行打包的前提就是对各个模块依赖关系进行分析,并根据依赖关系,支持开发者自行定义哈希策略。比如webpack的:hash/chunkhash/contenthash
- Output Module Formats,工程输出的模块化方式也需要更加灵活,比如开发者可配置 ESM、CommonJS 等规范的构建内容导出。
- Transformations,前端工程化离不开编译/转义过程。比如对 JavaScript 代码的压缩、对无用代码的删除(DCE)等。
- Importing Modules
- Non-JavaScript Resources
# webpack
- 为什么选择webpack?
社区生态丰富、配置灵活和插件扩展、官方更新迭代速度快
- 核心部分:通过loader处理特殊资源(图片、文字等)的加载
- 拓展:通过plugins实现各种自动化的构建任务:自动压缩
核心工作流程:
- 找到打包入口,通过入口的import或require语句解析推断出入口需要依赖的资源模块,然后再分别解析这些资源模块中的依赖,最终得到项目中的依赖关系树;
- 然后webpack就会遍历递归这个依赖树,找到每个节点资源文件,然后交给loader配置里面的对应loader去加载对应模块;
- 最后将加载的结果放在bundle.js中,从而实现整个项目的打包。
# 从0到1搭建一个项目
# 打包流程分析
# webpack编译原理
# 手写loader
# 1.sprite-loader(自动合成雪碧图的loader)
# 2.markdown-loader
将markdown文件转换为html字符串
npm init
npm install webpack webpack-cli
添加命令:npm run build
打包初试:node ./dist/bundle.js
npm install marked