1,Webpack有什么作用,谈谈你对它的了解
当初的前端网页功能丰富,特地是SPA(single page web application 单页利用)技术风行后,JavaScript的复杂度减少和须要一大堆依赖包,还须要解决Scss、Less……新增款式的扩大写法的编译工作。Webpack 最外围的性能就是实现动态模块打包,当Webpack 解决应用程序时,会递归构建一个依赖关系图,其中蕴含应用程序须要的每个模块,而后将这些模块打包成一个或多个bundle资源包。
事实上,当初市面上最风行的三个前端框架,能够说和webpack都曾经严密相连,官网框架都推出了对应的webpack构建工具,常见的组合为React+WebPack、Vue+WebPack以及Angluar+WebPack。
2,前端我的项目为什么要进行打包和构建
之所以要进行打包和构建,是从代码开发层面和部署层面来思考的:
代码层面
- 打包能够使体积更小(Tree-shaking、压缩、合并),加载更快
- 编译高级语言和语法(TS、ES6、模块化、scss)
- 兼容性和谬误查看(polyfill、postcss、eslint)
研发流程层面
- 对立、高效的开发环境
- 对立的构建流程和产出规范
- 集成公司构建标准(提测、上线)
3,gulp/grunt与Webpack有哪些区别
三者都是前端构建工具,grunt和gulp在晚期比拟风行,当初webpack相对来说比拟支流,不过一些轻量化的工作还是会用gulp来解决,比方独自打包CSS文件等。
grunt和gulp是基于工作和流(Task、Stream)的。相似jQuery,找到一个(或一类)文件,对其做一系列链式操作,更新流上的数据, 整条链式操作形成了一个工作,多个工作就形成了整个web的构建流程。
而webpack的我的项目构建则是基于入口的,webpack会主动地递归解析入口所须要加载的所有资源文件,而后用不同的Loader来解决不同的文件,用Plugin来扩大webpack性能。
从构建规定上来说,gulp和grunt须要开发者将前端构建过程拆分多个Task,并正当管制所有Task的调用关系,webpack须要开发者找到入口,并须要分明对于不同的资源应该应用什么Loader 做何种解析和加工的。
4,Webpack提供的基本功能有哪些
目前,Webpack反对如下一些常见的性能(具体视版本而定):
- 代码转换:TypeScript 编译成 JavaScript、SCSS 编译成 CSS 等等
- 文件优化:压缩 JavaScript、CSS、html 代码,压缩合并图片等
- 代码宰割:提取多个页面的公共代码、提取首屏不须要执行局部的代码让其异步加载
- 模块合并:在采纳模块化的我的项目有很多模块和文件,须要构建性能把模块分类合并成一个文件
- 主动刷新:监听本地源代码的变动、主动构建、刷新浏览器
- 代码校验:在代码被提交到仓库前须要检测代码是否符合规范,以及单元测试是否通过
- 主动公布:更新完代码后,主动构建出线上公布代码并传输给公布零碎。
5,简略形容下webpack的构建流程
Webpack的运行流程是一个串行的过程,从启动到完结会会顺次执行以下流程:
- 初始化编译参数:从配置文件和shell命令中读取与合并参数;
- 开始编译:依据上一步失去的参数初始化Compiler对象,加载所有配置的Plugin,执行对象的 run 办法开始执行编译;
- 确定入口:依据配置中的 entry 找出所有的入口文件;
- 编译模块:从入口文件触发,调用所有配置的Loader对模块进行翻译,再找出该模块依赖的模块,而后递归本步骤直到所有入口依赖的文件都进行翻译;
- 实现模块编译:在通过第4步应用 Loader 翻译完所有模块后,失去了每个模块被翻译后的最终内容以及它们之间的依赖关系图。
- 输入资源:依据依赖关系图,组装成一个个蕴含多个模块的Chunk,再把每个Chunk转化成一个独自的文件退出到输入列表,依据配置确定输入的门路和文件名,输入。
- 输入实现:在确定好输入内容后,依据配置确定输入的门路和文件名,把文件内容写入到文件系统。
在以上过程中,Webpack 会在特定的工夫点播送出特定的事件,插件在监听到感兴趣的事件后会执行特定的逻辑,并且插件能够调用 Webpack 提供的 API 扭转 Webpack 的运行后果。整体过程如下图所示。
6,简略介绍下Webpack的基本概念
- Entry:入口,Webpack 执行构建的第一步将从 Entry 开始,通知webpack要应用哪个模块作为构建我的项目的入口,默认为./src/index.js。
- output :进口,通知webpack在哪里输入它打包好的代码以及如何命名,默认为./dist
- Module:模块,在 Webpack 里所有皆模块,一个模块对应着一个文件。Webpack 会从配置的 Entry 开始递归找出所有依赖的模块。
- Chunk:代码块,一个 Chunk 由多个模块组合而成,用于代码合并与宰割。
- Loader:模块转换器,用于把模块原内容依照需要转换成新内容。
- Plugin:扩大插件,在 Webpack 构建流程中的特定时机会播送出对应的事件,插件能够监听这些事件的产生,在特定机会做对应的事件。
7,简略形容下Webpack的工作原理
webpack通过入口文件逐层遍历到模块依赖,进行代码剖析、代码转换,最终生成可在浏览器运行的打包后代码。实质上,webpack 是一个古代 JavaScript 应用程序的动态模块打包器。当 webpack 解决应用程序时,它会递归地构建一个依赖关系图,其中蕴含应用程序须要的每个模块,而后将所有这些模块打包成一个或多个bundle包。并且在3.0版本之后,Webpack还肩负起了优化我的项目的责任。
8,如何进步Webpack的构建速度
随着前端我的项目波及到的页面越来越多,性能和业务代码也会随着减少,相应的webpack的构建工夫也会越来越久,如果构建工夫过长,会大大降低工作效率。以下是常见的进步Webpack我的项目构建的措施:
- 多入口状况下,应用CommonsChunkPlugin来提取公共代码。
- 通过externals配置来提取罕用库。
- 利用DllPlugin和DllReferencePlugin预编译资源模块通过DllPlugin来对那些咱们援用然而相对不会批改的npm包来进行预编译,再通过DllReferencePlugin将预编译的模块加载进来。
- 应用Happypack 实现多线程减速编译。
- 应用webpack-uglify-paralle来晋升uglifyPlugin的压缩速度,webpack-uglify-parallel采纳了多核并行压缩来晋升压缩速度。
- 应用Tree-shaking和Scope Hoisting来剔除多余代码
- 优化Loader配置
9,Webpack是怎么配置单页利用和多页面利用的
单页利用能够了解为Webpack的规范模式,间接在entry中指定单页利用的入口即可。多页利用的话,能够应用webpack的 AutoWebPlugin来实现简略自动化的构建,然而前提是我的项目的目录构造必须恪守他预设的标准。多页利用中须要留神以下几点:
- 每个页面都有公共的代码,能够将这些代码抽离进去,防止反复的加载。比方,每个页面都援用了同一套css样式表。
- 随着业务的一直扩大,页面可能会一直的追加,所以肯定要让入口的配置足够灵便,防止每次增加新页面还须要批改构建配置。
事实上,单页应用程序和多页应用程序的 webpack配置文件其实绝大部分都还是雷同的,只不过多页的配置须要在单页配置的根底上顾及到多个页面罢了,loader、output、plugins这些根本都不须要改变,须要改变的个别都是入口文件 entry,如果你用到了 抽离css款式的插件 extract-text-webpack-plugin、主动模板插件 html-webpack-plugin的话,那么还须要对这两个插件进行额定的改写。
10,Webpack中Loader的作用是什么,有哪些常见的Loader
Loader 是webpack中提供了一种解决多种文件格式的机制,因为Webpack默认只反对辨认JS和JSON,然而Webpack打造的概念是“所有皆模块”,想要实现这个概念,就须要应用Loader。Loader相当于翻译官,能够将其余类型资源进行预处理,并对模块的"源代码"进行转换。
常见的Loader有如下一些:
- less-loader:将less文件编译成css文件
- css-loader:将css文件变成commonjs模块加载到js中,模块内容是款式字符串
- style-loader:创立style标签,将js中的款式资源插入标签内,并将标签增加到head中失效
- ts-loader:打包编译Typescript文件
- url-loader:将文件转换为base64 URI
- source-map-loader:加载额定的 Source Map ⽂件,以⽅便断点调试
- babel-loader:将ES6转化为ES5
- file-loader:把⽂件输入到⼀个⽂件夹中,在代码中通过绝对 URL 去引⽤输入的⽂件
11,Plugin有什么作用,有哪些常见的Plugin
Plugin的次要做用就是为了解决Loader 无奈实现的事件,比方打包优化和代码压缩等。通过扩大 Webpack 性能,在构建流程里注入钩子来解决很多Loader无奈解决的工作,给 Webpack 带来了很大的灵活性。
通常,Webpack通过plugins属性来配置须要应用的插件列表。plugins属性是一个数组,外面的每一项都是插件的一个实例,在实例化一个组件时能够通过构造函数传入这个组件反对的配置属性。
常见的Plugin插件有如下一些:
- html-webpack-plugin:解决html资源,默认会创立一个空的HTML,主动引入打包输入的所有资源(js/css)。
- mini-css-extract-plugin:打包过后的css在js文件里,该插件能够把css独自抽出来。
- clean-webpack-plugin:每次打包时候,CleanWebpackPlugin插件就会主动把上一次打的包删除。
12,简述下Webpack sourceMap的作用
当咱们应用webpack打包代码出错的时候, 如果不应用sourceMap,咱们只能晓得打包后的代码第几行出错,并不知道对应源代码哪里出了错,所以须要它来做源代码和指标代码的映射,而sourceMap的次要作用就是灾打包后将文件映射到源代码,用于定位谬误地位。sourceMap的配置如下所示:
module.exports = { devtool: 'source-map', // 应用sourceMap ...}
同时,加不同前缀的意义也不同:
- inline:不生成映射关系文件,打包进main.js
- cheap:只准确到行,不准确到列,打包速度快;只管业务代码,不论第三方模块
- module:不仅管业务代码,而且管第三方代码
- eval:执行效率最快,性能最好
同时,依据官网文档介绍,配置source-map形式打包后,我的项目打包速度会变慢,因为打包过程中会构建映射关系,比拟消耗性能。因而,咱们须要对开发环境和线上环境进行辨别:
- 开发者模式下(development):去应用sourceMap的话,倡议应用cheap-module-eval-source-map的模式,这种形式提醒谬误比拟全,同时打包速度也是比拟快的。
- 生产者模式下(production):应用cheap-module-source-map能够疾速定位问题。
同时,sourceMap还能够通过nginx设置将.map文件只对白名单凋谢。
13,什么是模热更新,如何配置模块热更新
模块热更新是webpack的一个性能,它能够使得代码批改之后,不必刷新浏览器就能够更新。在利用过程中替换增加删出模块,无需从新加载整个页面,是高级版的主动刷新浏览器。长处是只更新变更内容,以节俭贵重的开发工夫。调整款式更加疾速,简直相当于在浏览器中更改款式。
开启Webpack热更新须要借助webpack.HotModuleReplacementPlugin(),devServer开启hot。比方,实现热更新,只更新指定的js模块。
if (module.hot) { module.hot.accept(’./library.js’, function() { // Do something with the updated library module… });}
热更新的原理图下图所示。
14,什么是模块懒加载
懒加载或者按需加载,是一种很好的优化网页或利用的形式。实际上是先把代码在一些逻辑断点处罚来到,而后在一些代码块中实现某些操作后,立刻援用或援用另外一些新的代码块。这样放慢了利用的初始加载速度,加重了加载的体积。
在WebPack中,实现模块/文件的懒加载须要用到prefetch和preloading等关键字。比方,先加载主业务文件,而后利用网络闲暇工夫异步加载其余组件。
import(/* webpackPrefetch: true / ‘LoginModal’);
如果须要和主业务文件一起加载,异步加载组件,能够应用上面的形式。
import(/ webpackPreload: true */ ‘ChartingLibrary’);
15,什么是长缓存,在webpack中如何实现长缓存优化
Webpack打包的资源,最终都是在浏览器上出现给用户,浏览器在用户拜访页面的时候,为了放慢加载速度,会对用户拜访的动态资源进行存储。浏览器缓存能够分为强缓存和协商缓存两种。
强缓存是指在不拜访服务器的状况下,间接从浏览器获取前端资源。读取资源的形式能够从缓存中读取,也能够从磁盘中读取。实现的形式是在响应头设置Expires字段或者Cache-Control字段。
协商缓存是指在拜访服务器的状况下,服务器告知浏览器文件没变动,这时服务器会返回304,能够间接利用缓存中的资源。实现协商缓存的形式是两对组合(响应头/申请头):Last-Modified/If-Modified-Since ;ETag/If-None-Match。
对于长缓存,能够在output给出输入的文件制订chunkhash,并且拆散常常更新的代码和框架代码,通过NameModulesPlugin或者HashedModulesPlugin使再次打包文件名不变。
参考:webpack4配置浏览器长缓存
16,polyfill和runtime有什么区别
babel-polyfill 的原理是当运行环境中并没有实现的一些办法,babel-polyfill会做兼容。babel-runtime 它是将es6编译成es5去执行。通常,咱们应用es6的语法来编写利用,最终都会通过babel-runtime编译成es5。也就是说,不论浏览器是否反对ES6,只有是ES6的语法,它都会进行转码成ES5,所以就会产生很多冗余的代码。
babel-polyfill 它是通过向全局对象和内置对象的prototype上增加办法来实现的。比方运行环境中不反对Array.prototype.find 办法,引入polyfill, 咱们就能够应用es6办法来编写了,然而毛病就是会造成全局空间净化。
babel-runtime它不会净化全局对象和内置对象的原型,比如说咱们须要Promise,咱们只须要import Promise from 'babel-runtime/core-js/promise’即可,这样不仅防止净化全局对象,而且能够缩小不必要的代码。