# webapck-study **Repository Path**: NeThunder93/webapck-study ## Basic Information - **Project Name**: webapck-study - **Description**: # 前端知识分享 第一期 doc - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2023-02-24 - **Last Updated**: 2023-02-28 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 前端知识分享 第一期 ## 抛出问题 > JavaScript不是解释型语言吗,为什么需要打包和编译? > Python/Java等语言,只要一个依赖管理器就可以开始敲代码,为什么写前端要配置Webpack那么复杂的配置项? ## Webpack是什么 本质上,webpack 是一个用于现代 JavaScript 应用程序的 静态模块打包工具。当 webpack 处理应用程序时,它会在内部从一个或多个入口点构建一个 依赖图(dependency graph),然后将你项目中所需的每一个模块组合成一个或多个 bundles,它们均为静态资源,用于展示你的内容。 ![webpack](./static/webpack.png) ## JavaScript:一个被不断吐槽的语言 ![rank](./static/rank.png) JavaScript是目前最流行的语言之一,常年稳定在前十,但是又是被吐槽的最狠的语言之一。 ### 不断改变的规范 JavaScript是网景公司开发,目前有ECMA协会进行标准的制定,第一版的JavaScript功能很弱,仅仅是为了给网景浏览器提供简单的交互操作,缺少异常处理,内部函数和继承。而现在的JavaScript已经是一套完整的面向对象语言,但是在这个过程中,ECMA发布了许多版本的标准,而且本身JavaScript运行在所有浏览器中,这些浏览器对标准的跟进是滞后的,导致许多标准版本都在同时生效,十分混乱。 > ECMAScript(ES)发布的版本 - ES1: 1997年 - ES2: 1997年 - ES3: 1999年,增加正则、异常处理等 - ES4: 废弃 - ES5: 2009年,增加"strict mode"(严格模式)、getter、setter、JSON对象等功能 - ES6: 2015年,叫法很多,ECMAScript6(ES6),也被叫做 ECMAScript2015(ES2015)。let、const、class、modules、arrow function、template string、destructuring、default、reset argument、binary data、promise等,都是在这一版加入进来的。 - ES7: 2016年,也被称作ES2016,完善ES6规范,还包括两个新的功能:求幂运算符(*)和array.prototype.includes方法。 - ES8: 2017年,也被称作ES2017,增加新的功能,如并发、原子操作、Object.values/Object.entries、字符串填充、promises await/asyn等等。 ### JavaScript语言充满了迷惑性 > 参考demo-1代码, 这部分描述已过时 - 它有对象,对象里可以包含数据和处理数据的方法,对象也可以嵌套对象 - 它没有类,但是却有构造器可以做类似的事情,例如作为类变量、方法的容器 - 它没有基于类的继承,但是它有基于原型的继承,可以做到类继承的效果 - 它没有模块化,但是有N多实现模块化的方案 ### 层出不穷的“语言”框架 JavaScript可以通过dom对象,可以对html元素进行修改,以实现页面交互和动效,这方面最知名的库是JQuery。但从Angular开始,出现了各种前端“语言”,React、Vue、Taro、UniAPP。每个框架都有自己独特的语法,目前已经很少有公司单纯使用 HTML+CSS+JavaScript 进行开发了。 但无论那种“语言”,最终代码都是要运行在浏览器里,前面说过JavaScript才是浏览器真正运行的语言,浏览器只对ECMA指定的标准进行解析。因此各种语言都要经过“预编译”,变成纯粹的JavaScript,浏览器才能识别。 这个编译过程可以与Java编译成字节码的过程类比。 - Java要进行编译,编译后的字节码被虚拟机解释执行 - Rect/Vue也要进行编译,编译后的JavaScript代码被浏览器解释执行 ### 层出不穷的开源框架 #### Babel - 兼容性方案 > [BabselDoc](https://babeljs.io/setup#installation) Babel是个工具链,主要用来将ES2015+标准的代码,转换为低版本,兼容性更强的版本代码,以便在老版本浏览器中运行。随着IE浏览器彻底退出市场,Babel的热度也逐渐下降了。 ```javascript // Babel Input: ES2015 arrow function [1, 2, 3].map(n => n + 1); // Babel Output: ES5 equivalent [1, 2, 3].map(function(n) { return n + 1; }); ``` #### TypeScript - 类型校验方案 JavaScript是弱类型语言,程序运行的时候,一个变量的类型是可变的。弱类型语言健壮性是不够的,例如21年B站崩溃的故障,就是因为方法入参变量类型的问题导致的。 > ["0"与0导致的全站奔溃故障](https://www.163.com/dy/article/HCFJP6P80511D3QS.html) 为了解决弱类型健壮性问题,微软基于JavaScript做了一个TypeScript语言,[官网](https://www.typescriptlang.org/)对TypeScript的定义是: > 添加了类型系统的 JavaScript ![typescript](./static/typescript.png) #### 模块化方案 > 模块化就是把逻辑代码拆分成独立的块,各自封装,互相独立,每个块自行决定对外暴露什么,同时自行决定引入执行哪些外部代码。 JavaScript模块化这部分是做的最乱的,在ES6标准出现之前,也就是2015年前,并没有官方的模块化实现。一般有两种模块化方案:同步执行依赖、异步执行依赖。 不同的实现方案主要在这两个方面有差异: - 依赖加载时间:提前加载、调用加载 - 依赖执行时间:提前执行、调用执行 ***约定命名空间*** > 参考demo-3 通过命名空间的方式,可以做到变量名的隔离,但是模块化的一些特性是没有的,例如“私有变量”、“依赖关系”等。 ***CommonJS 规范*** > 参考demo-5 由NodeJS实现,符合服务端程序的特点。服务器磁盘读写很快,所以 - 依赖加载时间:延迟加载 - 依赖执行时间:调用执行 ***AMD( Asynchronous Module Definition) 规范*** > 参考demo-4 CommonJS的加载方式不适合浏览器环境,社区提出了一个异步加载的规范,其中最知名的实现库是:[requirejs](https://github.com/requirejs/requirejs)。 - 依赖加载时间:提前加载 - 依赖执行时间:提前执行 ***CMD(Common Module Definition)规范*** > 参考demo_7 同样脱胎与CommonJS规范,最知名的实现库是:[seajs](https://github.com/requirejs/requirejs),由阿里开源出来。作者对于“依赖提前执行”这点很不认同,有可能一个依赖项到代码末尾才用到,但是初始化动作在开始前就要执行完,会导致代码启动速度较慢。 - 依赖加载时间:提前加载 - 依赖执行时间:调用执行 ***ES Module*** > 参考demo_8 最终在2015年,ES6(ES2015)规范发版,更新了大量特性,其中就包括模块化,从此终于结束了对于模块化的争议。作为官方标准,兼容了各种使用方式。其他开源库逐步被废弃,import、export成为了模块化标配。 - 依赖加载时间:提前加载/延迟加载 - 依赖执行时间:提前执行/异步执行 ## CSS:够用,但不完全够用 > [参考文档](https://juejin.cn/post/7064246166396862477#heading-17) ```css // main.css body { color: red; font-size: 14px; } .header { font-size: 14px; } .content { font-size: 14px; } // article.css .content { font-size: 18px; } ``` - 重复代码无法复用 - 样式容易冲突 ![css](./static/CSS.png) ## 总结 问题1:JavaScript不是解释型语言吗,为什么需要打包和编译? - 浏览器兼容性跟不上标准迭代速度,打包和编译主要是为了让代码能跑在低版本浏览器上 问题2:Python/Java等语言,只要一个依赖管理器就可以开始敲代码,为什么写前端要配置Webpack那么复杂的配置项? - 前期的JavaScript设计的太烂了,但随着浏览器的全面普及,使用人数有非常多,因此出现大量开源的解决方案,Webpack就是为了统一这些解决方案的配置,简化开发维护难度。