前端工程化是指:在企业级的前端项目开发中,把前端开发所需的工具、技术、流程、经验等进行规范化、标准化。
一、版本管理
1、概念
版本控制是一种软件工程技巧,借此能在软件开发的过程中,确保由不同人所编辑的同一程序文件都得到同步
2、分类
2.1、本地版本控制系统
优点:
简单,很多系统中都有内置
适合管理文本,如系统配置
缺点:
其不支持远程操作,因此并不适合多人版本开发
2.2、集中式版本控制系统
a、优点:
适合多人团队协作开发
代码集中化管理
b、缺点:
单点故障
必须联网,无法单机工作
c、代表工具:
SVN
CVS
2.3、分布式版本控制系统
分布式版本管理系统每个计算机都有一个完整的仓库,可本地提交,可以做到离线工作,
则不用像集中管理那样因为断网情况而无法工作
2.3.1、优点
适合多人团队协作开发
代码集中化管理
可以离线工作
每个计算机都是一个完整仓库
2.3.2、代表工具
git、HG
二、面试题
1、说说你对webpack的理解?解决了什么问题?
1.1、概念
是一个用于现代JavaScript应用程序的静态模块打包工具
1.2、作用
webpack大而全,很多常用的功能做到开箱即用。有两大最核心的特点:一切皆模块和按需加载
如下:
智能解析:对 CommonJS 、 AMD 、ES6 的语法做了兼容
万物模块:对 js、css、图片等资源文件都支持打包
开箱即用:HRM、Tree-shaking等功能
代码分割:可以将代码切割成不同的 chunk,实现按需加载,降低了初始化时间
插件系统,具有强大的 Plugin 接口,具有更好的灵活性和扩展性
易于调试:支持 SourceUrls 和 SourceMaps
快速运行:webpack 使用异步 IO 并具有多级缓存,这使得 webpack 很快且在增量编译上更加快
2、webpack与grunt、gulp的不同?
Grunt、Gulp是基于任务运行的⼯具:
它们会⾃动执⾏指定的任务,就像流⽔线,把资源放上去然后通过不同插件进⾏加⼯,它们包含活跃的社区,丰富的插件,能⽅便的打造各种⼯作流。
Webpack是基于模块化打包的工具:
自动化处理模块,webpack把一切当成模块,当 webpack 处理应用程序时,它会递归地构建一个依赖关系图 (dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。
3、如何⽤webpack来优化前端性能?
⽤webpack优化前端性能是指优化webpack的输出结果,让打包的最终结果在浏览器运⾏快速⾼效。
通过webpack优化前端的手段:
3.1、代码压缩
a、JS代码压缩
利⽤webpack的 UglifyJsPlugin 和 ParallelUglifyPlugin 来压缩JS⽂件
b、CSS代码压缩
利⽤ cssnano (css-loader?minimize)来压缩css
c、Html文件代码压缩
使用HtmlWebpackPlugin插件来生成HTML的模板时候,通过配置属性minify进行html优化
3.2、文件大小压缩
对文件的大小进行压缩,减少http传输过程中宽带的损耗
3.3、图片压缩
3.4、Tree Shaking
将代码中永远不会⾛到的⽚段删除掉(消除死代码)。可以通过在启动webpack时追加参数 --optimize-minimize 来实现;
3.5、代码分离
代码按路由维度或者组件分块(chunk),这样做到按需加载,同时可以充分利⽤浏览器缓存
3.6、提取公共第三⽅库
SplitChunksPlugin插件来进⾏公共模块抽取,利⽤浏览器缓存可以⻓期缓存这些⽆需频繁变动的公共代码
4、webpack的构建流程
Webpack 的运⾏流程是⼀个串⾏的过程,从启动到结束会依次执⾏以下流程,
并在这个过程中,Webpack 会在特定的时间点⼴播出特定的事件,
插件在监听到感兴趣的事件后会执⾏特定的逻辑,并且插件可以调⽤ Webpack 提供的 API 改变 Webpack 的运⾏结果。
1. 初始化参数:从配置⽂件和 Shell 语句中读取与合并参数,得出最终的参数;
2. 开始编译:⽤上⼀步得到的参数初始化 Compiler 对象,加载所有配置的插件,执⾏对象的 run ⽅法开始执⾏编译;
3. 确定⼊⼝:根据配置中的 entry 找出所有的⼊⼝⽂件;
4. 编译模块:从⼊⼝⽂件出发,调⽤所有配置的 Loader 对模块进⾏翻译,再找出该模块依赖的模块,再递归本步骤直到所有⼊⼝依赖的⽂件都经过了本步 骤的处理;
5. 完成模块编译:在经过第4步使⽤ Loader 翻译完所有模块后,得到了每个模块被翻译后的最终内容以及它们之间的依赖关系;
6. 输出资源:根据⼊⼝和模块之间的依赖关系,组装成⼀个个包含多个模块的 Chunk,再把每个 Chunk 转换成⼀个单独的⽂件加⼊到输出列表,这步是可以修改输出内容的最后机会;
7. 输出完成:在确定好输出内容后,根据配置确定输出的路径和⽂件名,把⽂件内容写⼊到⽂件系统。
5、如何提⾼webpack的构建速度?
优化webpack构建的方式有很多,主要可以从优化搜索时间、缩小文件搜索范围、减少不必要的编译、
提高压缩速度,优化代码等方面入手
a、优化loader配置
在使用loader时,可以通过配置include、exclude、test属性来匹配文件,缩小文件的搜索范围,优化搜索时间
b、通过 externals 配置来提取常⽤库,脱离webpack打包,不被打⼊bundle中,从⽽减少打包时间
c、利⽤ DllPlugin 和 DllReferencePlugin 预编译资源模块 ,让⼀些基本不会改动的代码先打包成静态资源,避免反复编译浪费时间
d、使⽤ Happypack 实现多线程加速编译
e、使⽤ webpack-uglify-parallel 来提升 uglifyPlugin 的压缩速度。
f、使⽤ Tree-shaking 和 Scope Hoisting 来剔除多余代码
g、利⽤缓存提⾼rebuild效率
6、如何提⾼webpack的打包速度?
a、优化loader
对于 Loader 来说,影响打包效率首当其冲必属 Babel 了。因为 Babel 会将代码转为字符串生成 AST,然后对 AST 继续进行转变最后再生成新的代码,项目越大,转换代码越多,效率就越低。
b、HappyPack
受限于 Node 是单线程运行的,所以 Webpack 在打包的过程中也是单线程的,特别是在执行 Loader 的时候,长时间编译的任务很多,这样就会导致等待的情况。HappyPack 可以将 Loader 的同步执行转换为并行的,这样就能充分利用系统资源来加快打包效率了
c、DllPlugin
DllPlugin 可以将特定的类库提前打包然后引入。这种方式可以极大的减少打包类库的次数,只有当类库更新版本才有需要重新打包,并且也实现了将公共代码抽离成单独文件的优化方案。
d、代码压缩
在 Webpack3 中,一般使用 UglifyJS 来压缩代码,但是这个是单线程运行的,为了加快效率,可以使用 webpack-parallel-uglify-plugin 来并行运行 UglifyJS,从而提高效率。在 Webpack4 中,不需要以上这些操作了,只需要将 mode 设置为 production 就可以默认开启以上功能。代码压缩也是我们必做的性能优化方案,当然我们不止可以压缩 JS 代码,还可以压缩 HTML、CSS 代码,并且在压缩 JS 代码的过程中,我们还可以通过配置实现比如删除 console.log 这类代码的功能。
e、其他
resolve.extensions:
用来表明文件后缀列表,默认查找顺序是 ['.js', '.json'],如果你的导入文件没有添加后缀就会按照这个顺序查找文件。我们应该尽可能减少后缀列表长度,然后将出现频率高的后缀排在前面
resolve.alias:
可以通过别名的方式来映射一个路径,能让 Webpack 更快找到路径
module.noParse:
如果你确定一个文件下没有其他依赖,就可以使用该属性让 Webpack 不扫描该文件,这种方式对于大型的类库很有帮助
7、Loader和Plugin的不同?
7.1、不同的作用
Loader直译为"加载器"。loader 是文件加载器,能够加载资源文件,并对这些文件进行一些处理,诸如编译、压缩等,最终一起打包到指定的文件中。Webpack将一切文件视为模块,但是webpack原生是只能解析js文件,如果想将其他文件也打包的话,就会用到 loader 。 所以Loader的作用是让webpack拥有了加载和解析非JavaScript文件的能力。
Plugin直译为"插件"。Plugin可以扩展webpack的功能,让webpack具有更多的灵活性。 在 Webpack 运行的生命周期中会广播出许多事件,Plugin 可以监听这些事件,在合适的时机通过 Webpack 提供的 API 改变输出结果。
7.2、不同的运行时机
loader 运行在打包文件之前
plugins 在整个编译周期都起作用
7.3、不同的用法
Loader在 module.rules 中配置,也就是说他作为模块的解析规则⽽存在。 类型为数组,每⼀项都是⼀个 Object ,⾥⾯描述了对于什么类型的⽂件( test ),使⽤什么加载( loader )和使⽤的参数( options )
Plugin在 plugins 中单独配置。 类型为数组,每⼀项是⼀个 plugin 的实例,参数都通过构造函数传⼊。
8、webpack有哪些常⻅的Loader?
8.1、什么是loader
loader 用于对模块的"源代码"进行转换,在 import 或"加载"模块时预处理文件。
webpack做的事情,仅仅是分析出各种模块的依赖关系,然后形成资源列表,最终打包生成到指定的文件中。
在webpack内部中,任何文件都是模块,不仅仅只是js文件。
默认情况下,在遇到import或者require加载模块的时候,webpack只支持对js 和 json 文件打包,像css、sass、png等这些类型的文件的时候,webpack则无能为力,这时候就需要配置对应的loader进行文件内容的解析,
当 webpack 碰到不识别的模块的时候,webpack 会在配置的中查找该文件解析规则。
关于loader的配置,我们是写在module.rules属性中
8.2、webpack有哪些常用的Loader
file-loader:把文件输出到一个文件夹中,在代码中通过相对 URL 去引用输出的文件
url-loader:和 file-loader 类似,但是能在文件很小的情况下以 base64 的方式把文件内容注入到代码中去
source-map-loader:加载额外的 Source Map 文件,以方便断点调试
image-loader:加载并且压缩图片文件
babel-loader:把 ES6 转换成 ES5
css-loader:加载 CSS,支持模块化、压缩、文件导入等特性
style-loader:把 CSS 代码注入到 JavaScript 中,通过 DOM 操作去加载 CSS。
eslint-loader:通过 ESLint 检查 JavaScript 代码
less-loader:通过less-loader将less转换为css
9、webpack有哪些常⻅的Plugin?
9.1、什么是Plugin
定义:webpack中的plugin赋予其各种灵活的功能,例如打包优化、资源管理、环境变量注入等,
它们会运行在 webpack 的不同阶段(钩子 / 生命周期),贯穿了webpack整个编译周期,
目的在于解决loader 无法实现的其他事
配置方式:
9.2、webpack有哪些常⻅的Plugin
● define-plugin:定义环境变量
● html-webpack-plugin:简化html文件创建
● uglifyjs-webpack-plugin:通过 UglifyES 压缩 ES6 代码
● webpack-parallel-uglify-plugin: 多核压缩,提升压缩速度
● webpack-bundle-analyzer: 可视化webpack输出文件的体积
● mini-css-extract-plugin: CSS提取到单独的文件中,支持按需加载
10、编写loader或plugin的思路?
10.1、loader
Loader像⼀个"翻译官"把读到的源文件内容转义成新的文件内容,并且每个Loader通过链式操作,将源⽂件⼀步步翻译成想要的样⼦。
编写Loader时要遵循单一原则,每个Loader只做一种"转义"工作。
每个Loader的拿到的是源文件内容(source),可以通过返回值的⽅式将处理后的内容输出,也可以调⽤ this.callback() ⽅法,将内容返回给webpack。 还可以通过this.async() 生成一个 callback 函数,再将这个callback将处理后的内容输出出去。 此外 webpack 还为开发者准备了开发loader的⼯具函数集——loader-utils 。
10.2、Plugin的编写灵活了许多。
webpack在运⾏的⽣命周期中会⼴播出许多事件,Plugin 可以监听这些事件,
在合适的时机通过 Webpack 提供的 API 改变输出结果。
11、bundle,chunk,module是什么?
bundle:
是由webpack打包出来的⽂件;
chunk:
代码块,⼀个chunk由多个模块组合⽽成,⽤于代码的合并和分割;
module:
是开发中的单个模块,在webpack的世界,⼀切皆模块,⼀个模块对应⼀个⽂件,webpack会从配置的 entry中递归开始找出所有依赖的模块。
12、怎么配置单⻚应⽤?怎么配置多⻚应⽤?
12.1、单⻚应⽤可以理解为webpack的标准模式,直接在 entry 中指定单⻚应⽤的⼊⼝即可
12.2、多⻚应⽤可以使⽤webpack的 AutoWebPlugin 来完成简单⾃动化的构建,但是前提是项⽬的⽬录结构必须遵守他预设的规范。 多⻚应⽤中要注意的是:
a、每个⻚⾯都有公共的代码,可以将这些代码抽离出来,避免重复的加载。
例如,每个⻚⾯都引⽤了同⼀套css样式表
b、随着业务的不断扩展,⻚⾯可能会不断的追加,所以⼀定要让⼊⼝的配置⾜够灵活,
避免每次添加新⻚⾯还需要修改构建配置
13、webpack 热更新的实现原理? [ HMR ]
13.1、热更新概念
HMR全称 Hot Module Replacement,可以理解为模块热替换,指在应用程序运行过程中,替换、添加、删除模块,而无需重新刷新整个应用,
例如,我们在应用运行过程中修改了某个模块,通过自动刷新会导致整个应用的整体刷新,那页面中的状态信息都会丢失,如果使用的是 HMR,就可以实现只将修改的模块实时替换至应用中,不必完全刷新整个应用
13.2、配置
如果我们修改并保存css文件,确实能够以不刷新的形式更新到页面中,但是,当我们修改并保存js文件之后,页面依旧自动刷新了,这里并没有触发热模块,HMR并不像 Webpack 的其他特性一样可以开箱即用,需要有一些额外的操作,需要去指定哪些模块发生更新时进行HRM
13.3、实现原理
通过webpack-dev-server创建两个服务器:提供静态资源的服务(express)和Socket服务
express server 负责直接提供静态资源的服务(打包后的资源直接被浏览器请求和解析)
socket server 是一个 websocket 的长连接,双方可以通信
当 socket server 监听到对应的模块发生变化时,会生成两个文件.json(manifest文件)和.js文件(update chunk)
通过长连接,socket server 可以直接将这两个文件主动发送给客户端(浏览器)
浏览器拿到两个新的文件后,通过HMR runtime机制,加载这两个文件,并且针对修改的模块进行更新
14、webpack proxy工作原理?为什么能解决跨域?
14.1、概念
webpack proxy,即webpack提供的代理服务,基本行为就是接收客户端发送的请求后转发给其他服务器,其目的是为了便于开发者在开发模式下解决跨域问题(浏览器安全策略限制),想要实现代理首先需要一个中间服务器,webpack中提供服务器的工具为webpack-dev-server,是 webpack 官方推出的一款开发工具,将自动编译和自动刷新浏览器等一系列对开发友好的功能全部集成在了一起。
关于配置方面,在webpack配置对象属性中通过devServer属性提供:
devServetr里面proxy则是关于代理的配置,该属性为对象的形式,对象中每一个属性就是一个代理的规则匹配,
属性的名称是需要被代理的请求路径前缀,一般为了辨别都会设置前缀为/api,值为对应的代理匹配规则:target:表示的是代理到的目标地址
pathRewrite:默认情况下,我们的 /api-hy 也会被写入到URL中,如果希望删除,可以使用pathRewrite
14.2、工作原理及为什么能解决跨域问题
在开发阶段中,webpack-dev-server会启动一个本地开发的服务器,即跨域所使用的代理服务器,通过利用http-proxy-middleware代理中间件,代理服务器会响应本地请求,继而转发到目标服务器,目标服务器响应数据后再将数据返回给代理服务器,代理服务器再将数据返回给本地。在此阶段中不涉及任何跨域问题,因为代理服务器跟本地同源,而服务器之间不存在跨域问题,跨域问题是浏览器安全策略限制。
14.3、总结
webpack通过配置webpack proxy这个代理服务器(本地服务器),接受客户端的请求继而转发给目标服务器,解决跨域问题。因为跨域问题是由于浏览器同源安全策略限制所导致的,服务器与服务器之间并不存在跨域问题,浏览器和本地服务器(代理服务器)不存在跨域问题
标签:文件,前端,loader,webpack,模块,工程化,代码,打包 From: https://www.cnblogs.com/gs-top/p/16886185.html