# fed-e-task-02-02 **Repository Path**: mxydl2009/fed-e-task-02-02 ## Basic Information - **Project Name**: fed-e-task-02-02 - **Description**: 拉勾教育大前端高薪训练营 002 期作业仓库,阶段二,模块二,模块化开发,打包工具webpack + Rollup + parcel,代码标准化规范化工具,ESLint + Stylelint + prettier + GitHooks + Husky + lint-staged - **Primary Language**: JavaScript - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-07-14 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # fed-e-task-02-02 #### 介绍 拉勾教育大前端高薪训练营 002 期作业仓库,阶段二,模块二,模块化开发,打包工具webpack + Rollup + parcel,代码标准化规范化工具,ESLint + Stylelint + prettier + GitHooks + Husky + lint-staged #### 简答题 #### 1. webpack的构建流程主要有哪些环节?如果可以请尽可能详尽地描述webpack打包的整个过程。 ###### webpack的构建流程主要包括如下的环节 1. 从入口文件出发,分析模块的依赖关系,构建依赖树。 2. 递归依赖树,按依赖关系,通过loader加载资源文件。 3. 将经过loader加载的资源文件放入独立函数(模块)中,由webpack的加载函数来加载。 4. 将打包的整体代码统一放到独立文件,使用IIFE的方式来加载模块。 5. 在整个构建流程中,会有构建生命周期的hooks任务参与,也就是插件来实现对打包中文件的额外处理。 #### 2. Loader和Plugin有哪些不同?请描述一下开发Loader和Plugin的思路。 ###### Loader: - Loader面向的是资源,负责的是加载资源,并对资源做一定的转换处理,再交给webpack去打包资源。 - Loader一般处理的是特定类型的资源,不同的资源要经过不同的Loader来转换。 - Loader通常用来处理webpack无法直接加载的资源,当然也可以处理webpack能够加载的资源,只是在webpack加载之前做一下资源的转换工作,如babel-loader。 ###### 开发Loader的思路 - Loader是一个webpack用来调用的模块,用来转换资源,即Loader是一个模块,导出一个用于资源转换的函数。函数的参数为资源文件的内容,函数的返回值为资源文件转换后的结果。 - 对于loader而言,不管是单个loader,还是loader数组,最后交给webpack打包的转换结果要求一定是JavaScript代码。如果资源需要有导出成员,转换后的JavaScript代码要求有导出语法。 - loader函数的签名为(source) => result, 其中source为资源文件的内容。 ###### Plugin: - Plugin是挂载到webpack Hook上的任务,存在于整个打包编译生命周期内。 - Plugin不是针对特定类型资源,而是为了实现特定目的,比如压缩代码、提供HMR功能、给HTML文件注入代码等等功能。 - Plugin用于弥补Loader的功能,也就是在打包中,除了转换资源外,需要额外添加的功能,使用Plugin来完成。 ###### 开发Plugin的思路 - webpack的插件机制是在打包编译生命周期中的某个时间点上调用函数来做额外的一些工作。 - 插件是具有apply方法的类,使用apply方法注册一个处理函数到编译过程中某个事件点,通过事件来触发处理函数的执行。在处理函数调用时,可以访问到整个编译过程中的compilation对象,从而获取编译信息。 - compilation: 打包过程中的上下文,其中compilation.assets包含了此次打包过程中的所有资源,用key-value来保存资源信息,其中key是资源名,value是资源内容。 - 插件的apply方法签名: (compiler) => { compiler.hooks.emit.tap('pluginName', (compilation) => {}) }, 由compiler对象将要运行的函数挂载到某个事件上,这里用emit.tap示例,还可以用run.tap等等,hooks的各种属性表示各种事件对象,事件对象的tap用来注册处理函数。 - 处理函数的签名: (compilation) => { // 具体要做的工作 } ### Vue项目打包说明见fed-e-task-02-02/vue-app-base/README.md