前端面试|webpack

Webpack 对webpack的理解
webpack是一个用于现代JS应用程序的静态模块打包工具。webpack的目的是实现前端项目的模块化,皆在更高效的管理和维护项目中的每一个资源。webpack可以很好的管理、打包开发中使用的HTML、CSS、JS和静态文件(图片、字体)等,让开发更高效

webpack解决了什么问题(基本功能)

  • 代码转化:可以把ts转化为js;less、scss转换为css
  • 文件优化:压缩HTML、CSS、JS文件,压缩图片等
  • 代码分割:提取首屏不需要执行的代码,让其异步执行,实现按需加载
  • 代码校验:会检查代码是否合规,检测单元测试是否通过
webpack的构建
  1. 初始化流程:从配置文件中读取并合并参数,初始化需要使用的插件和插件执行所需要的参数
  2. 编译构建流程:从Entry发出,针对每个Moudule串行调用对应的Loader编译文件,再找到该Module以来的Module,递归地进行编译处理
  3. 输出流程:对编译后的Module组合成Chunk,把Chunk转换成文件,输出到文件系统
Webpack和grunt、gulp的区别
Grunt和Gulp是基于任务运行的工具
:他们会自动执行指定的任务,就像流水线,把资源放上去然后通过不同的插件进行加工。
Webpack是基于模块化打包的工具:自动化处理模块,webpack把一切都当作模块,当webpack处理应用程序时,他会递归地构建一个依赖关系图,其中包含应用程序需要的每个模块,然后将这些模块打包成一个或多个bundle。
loader
在遇到import或require加载模块时,webpack只能支持对js和json文件的打包,其他类型的文件都需要经过loader处理。loader可以做语言翻译(将TS转化为JS)、格式转换(将内联图像转换为data URL)、样式编译(允许直接在JS模块中import
CSS文件)

plugin
plugin的作用比loader更大,webpack在生命周期内会广播出许多事情,plugin可以监听这些事情,在合适的时机处理事务,例如打包优化和压缩、重新定义环境中的变量、按需加载等。
loader和plugin的区别
  1. 作用不同
    loader是文件加载器,能够加载资源文件,并对这些文件进行编译、压缩,最终打包到指定的文件中。将A文件转化为B文件,单纯的进行文件转化。
    plugin扩展了webpack的功能,例如:打包优化、重新定义环境中的变量、按需加载等。
  2. 运行时机不同
前端面试|webpack
文章图片

loader运行在打包文件之前;plugin在整个webpack生命周期都起作用。
有哪些常见的loader
  • file-loader:把文件输出到每一个文件夹中,在代码中通过相对URL去引用输出的文件
  • url-loader:把文件内容以base64的方式注入到代码中
  • source-map-loader:加载额外的Source Map文件,以方便断点调试
  • image-loader:加载并压缩图片文件
  • babel-loader:把ES6代码转化为ES5代码
  • css-loader:加载CSS,支持模块化、压缩、文件导入等特性
  • style-loader:把CSS代码注入到JS中,通过DOM操作去加载CSS
  • eslint-loader:通过ESlint检查JS代码
【前端面试|webpack】通常css-loader配合style-loader使用,因为css-loader只是用来解析css,而不会将解析后的css文件插入到DOM中,这时要用style-loader将css挂载到中
常见的plugin
  • define-plugin:定义环境变量
  • html-webpack-plugin:简化html文件创建
  • uglifyjs-webpack-plugin:通过UglifyES压缩ES6代码
  • webpack-parallel-uglify-plugin:多核压缩,提高压缩效率
  • webpack-bundlde-analyzer:可视化webpack输出文件和体积
  • mini-css-extract-plugin:CSS提取到单独的文件中,支持按需加载
bundle、chunk、module是什么?
  • bundle:由webpack打包出来的文件
  • chunk:代码块,一个chunk由多个模块组合而成,用于代码的合并和分割
  • module:是开发中的单个模块,在webpack的世界中一切皆模块,一个模块对应一个文件,webpack会从配置的entry中递归开始找出所有依赖的模块
loader和plugin的区别
不同的作用:
  • Loader:webpack将以切换文件都看作模块,但webpack只能加载和解析js文件和JSON文件,如果想要将其他文件打包的话,就必须要使用loader。所以loader的作用是让webpack有了加载和解析非JS文件的能力
  • Plugin:plugin可以扩展webpack的功能,让webpack具有更多的灵活性。在webpack运行的生命周期中会广播许多事件,plugin可以监听这些事件、在合适的时机通过webpack提供的API改变输出结果。
webpack热更新的实现原理
热更新又称为热替换(HMR),可以做到不刷新浏览器就将更新的内容替换就内容。
前端面试|webpack
文章图片

如何利用webpack优化前端性能
  • 压缩代码:删除多余的代码、注释,简化代码写法。利用webpack的 UglifyJsPlugin 和 ParallelUglifyPlugin 来压缩JS?件
  • Tree Shanking:将代码永远不会走到的片段删除
  • Code Splitting:将代码按组件分块、做到按需加载,同时充分利用浏览器缓存
  • 提取公共第三方库:将公共模块抽取,利用浏览器缓存可以长期缓存这些无需变动的代码
webpack优化前端的手段有:
  • 图片压缩
  • Tree Shaking:删除项目中未被引用的代码和被走到的分支
  • 代码分离:将代码分离到不同的bundle中,按需加载。代码分离可以使bundle更小,以控制资源加载的优先级
  • 优化loader(在配置loader中设置属性):对于Loader来说,影响打包效率的首先肯定是babel,因为babel会将代码转换成字符串,再转换成AST,对AST进行词法分析后再进行转变生成新的代码。项目越大,转换代码越多,效率就越低。所以我们在配置babel中可以在excludes属性中添加不需要被babel转译的代码,例如node_modules。还可以设置将babel编译过的文件缓存起来,下次只需要编译更改过的代码文件即可。
  • HappyPack(插件):因为webpack在打包过程中也是单线程的,而HappyPack可以将Loader的同步执行转换为并行的,开启多个线程,并行执行loader,这样就能充分利用系统资源来加快打包效率了。
  • 代码压缩:在weboack中使用UglifyJS来压缩代码,但这个插件也是单线程运行的,可以使用webpack-parallel-uglify-plugin来并行运行UglifyJS从而提高效率;在webpack4直接将mode设置为production即可开启代码压缩的功能。
  • 设置别名来映射一个路径
  • 按需加载:在开发SPA应用时,项目中都会存在很多路由页面,将这些页面全部打包到一个js文件中,但这样同时也加载了很多不需要的代码。为了首页能够更快的呈现给用户,希望页面能加载的文件体积越小越好,这时就可以使用按需加载,将每个路由页面单独打包为一个文件,在使用当前页面时再去加载。
  • 利用CDN加速:将引用的静态资源路径修改为CDN上对应的路径
Babel
Babel可以让我们在开发中使用TS、JSX、ES6语法而不用担心浏览器兼容性问题,它可以将这些语法特性转换为浏览器可以识别的语言。
Babel的原理是将代码转换为AST,对AST应用各种插件进行处理,最终输出编译后的JS代码

    推荐阅读