总结之webpack

一、Webpack是什么

webpack是一个用于现代JS应用程序的静态模块打包工具。当webpack处理应用程序时,会在内部构建一个依赖图,此依赖图对应映射到项目所需的每个模块(不再局限JS文件),并生成一个或者多个bundle。

二、 webpack 作用

  • 编译代码能力:提高效率,解决浏览器兼容问题;
  • 模块整合能力:提高性能,可维护性,解决浏览器频繁请求文件的问题;
  • 万物皆可模块能力:项目维护性增强,支持不同种类的前端模块类型,统一的模块化方案,所有资源文件的加载都可以通过代码控制。

三、Webpack的构建流程

webpack的运行流程室一个串行的过程,它的工作流程是将各个插件串联起来,在运行过程中会广播事件,插件只需要监听它所关心的事件,就能加入到这条webpack机制中,去改变webpack的运作,使整个系统扩展性良好。
webpack从启动到结束会依次执行以下流程:

  • 初始化参数:从配置文件和Shell语句中读取与合并参数,得出最终的参数;
  • 开始编译:用上一步得到的参数初始化Compiler对象,加载所有配置的插件,执行对象的run方法开始执行编译;
  • 确定入口:根据配置中的entry找出所有的入口文件;
  • 编译模块:从入口文件出发,调用所有配置的Loader对模块进行翻译,再找出该模块依赖的模块,再递归本步骤直到所有入口依赖的文件都经过了本步骤的处理;
  • 完成模块编译:再经过第4步使用Loader翻译完所有模块后,得到了每个模块被翻译后的最终内容以及它们之间的依赖关系;
  • 输出资源:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的Chunk,再把每个Chunk转换成一个单独的文件加入到输出列表,这步是可以修改输出内容的最后机会;
  • 输出完成:在确定好输出内容后,根据配置确定输出的路径和⽂件名,把⽂件内容写⼊到⽂件系统。

四、webpack API

需要在项目的根目录下创建一个webpackconfig.js文件,这个文件是webpack的默认配置文件
默认导出一个配置对象 ,导出遵循CommonJS规范

1、mode

mode有三个选项,none(不做任何操作),production(生产环境),development(开发环境)

2、entry入口配置

3、 output 出口配置,filename: “bundle.js”, //输出的为文件名,path: path.join(__dirname, ‘dist’), //输出目录

publicPath: "./", //公共文件路径

4、devtool,相当于开发调试工具

eval 文档上解释的很明白,每个模块都封装到 eval 包裹起来,并在后面添加 //# sourceURL

source-map 这是最原始的 source-map 实现方式,其实现是打包代码同时创建一个新的 sourcemap 文件,
并在打包文件的末尾添加 //# sourceURL 注释行告诉 JS 引擎文件在哪儿

hidden-source-map 文档上也说了,就是 soucremap 但没注释,没注释怎么找文件呢?貌似只能靠后缀,
譬如xxx/bundle.js 文件,某些引擎会尝试去找 xxx/bundle.js.map

inline-source-map 为每一个文件添加 sourcemap 的DataUrl,注意这里的文件是打包前的每一个文件而不是最后打包出来的,
同时这个 DataUrl 是包含一个文件完整 souremap信息的 Base64 格式化后的字符串,而不是一个 url。

eval-source-map 这个就是把 eval 的 sourceURL 换成了完整 souremap 信息的 DataUrl

cheap-source-map 不包含列信息,不包含 loader 的 sourcemap,(譬如 babel 的 sourcemap)

cheap-module-source-map 不包含列信息,同时 loader 的 sourcemap 也被简化为只包含对应行的。
最终的 sourcemap 只有一份,它是 webpack 对 loader 生成的 sourcemap 进行简化,然后再次生成的。

5、module:

辅助模块可以使用不同的loader来处理相应的文件,例如使用ES6语法就要使用babel-loader,

处理css文件就要使用css-loader和style-loader,需要注意的是执行顺序是从后往前执行的,
最后的loader最先执行这点需要注意

处理图片就要用file-loader

6、devServe 本地服务器

可以开启本地服务器以及热替换 代码如下,open:true,hot:true,port:8080,

7、resolve:解析模块的规则

(1)、resolve.alias,
resolve.alias 配置项通过别名来把原导入路径映射成一个新的导入路径

(2)、extensions
配置省略文件路径的后缀名

(3)modules
resolve.modules 配置 Webpack 去哪些目录下寻找第三方模块,默认是只会去 node_modules 目录下寻找。
可指定目录,提升速度,默认就是 modules: [“node_modules”],一般可不写

8、plugins: 插件
plugin是用于扩展webpack的功能,各种各样的plugin几乎可以让webpack做任何与构建相关关的事情。
plugin的配置很简单,plugins配置项接收一个数组,数组里的每一项都是一个要使用的plugin的实例,
plugin需要的参数通过构造函数传入。

 使用plugin的难点在于plugin本身的配置项,而不是如何在webpack中引入plugin,
 几乎所有webpack无法直接实现的功能,都能找到开源的plugin去解决,我们要做的就是去找更据自己的需要找出相应的plugin。

五、webpack 热更新

  • 热更新(HMR)全程Hot Module Replacement,可以理解为模块热替换,指在应用程序运行的过程中,替换、添加、删除模块,而无需重新刷新整个应用。
  • 例如在运行过程中修改了某个模块,通过自动刷新会导致整个应用的整体刷新,那页面中的状态信息都会丢失;如果使用的是HMR,就可以实现只将修改的模块实时替换至应用中,不必完全刷新应用。
  • 总结
    • 通过webpack-dev-server创建两个服务器:提供静态资源的服务(express)和Socket服务
    • express server 负责直接提供静态资源的服务(打包后的资源直接被浏览器请求和解析)
    • socket server 是一个 websocket 的长连接,双方可以通信
    • 当 socket server 监听到对应的模块发生变化时,会生成两个文件.json(manifest文件)和.js文件(update chunk)
    • 通过长连接,socket server 可以直接将这两个文件主动发送给客户端(浏览器)
    • 浏览器拿到两个新的文件后,通过HMR runtime机制,加载这两个文件,并且针对修改的模块进行更新

六、webpack 优化

1、JS代码压缩

terser是一个JavaScript的解释、绞肉机、压缩机的工具集,可以帮助我们压缩、丑化我们的代码,让bundle更小。在production模式下,webpack 默认就是使用 TerserPlugin 来处理我们的代码的。

2、CSS代码压缩

CSS压缩通常是去除无用的空格等,因为很难去修改选择器、属性的名称、值等。CSS的压缩我们可以使用另外一个插件:css-minimizer-webpack-plugin

3、HTML文件压缩

使用HtmlWebpackPlugin插件来生成HTML的模板时候,通过配置属性minify进行html优化。

4、HTML文件压缩

使用HtmlWebpackPlugin插件来生成HTML的模板时候,通过配置属性minify进行html优化。

5、文件大小压缩

使用compression-webpack-plugin对文件的大小进行压缩,减少http传输过程中宽带的损耗。

6、Tree Shaking

Tree Shaking是一个术语,在计算机中表示消除死代码,依赖于ES Module的静态语法分析(不执行任何的代码,可以明确知道模块的依赖关系)。在webpack实现Tree Shaking有两种不同的方案:useExports(通过标记某些函数是否被使用,之后通过Terser来进行优化);sideEffects(跳过整个模块/文件),直接查看该文件是否有副作用。

7、代码分离

将代码分离到不同的bundle中,之后可以按需加载,或者并行加载这些文件。默认情况下,所有的JS代码在首页全部加载,会影响到首页的加载速度。代码可以分出更小的bundle,以及控制资源加载的优先级,提供代码的加载性能。通过插件splitChunksPlugin来实现。

8、利用CDN加速以及提取公共第三方库

七、Loader和Plugin都是什么,有什么区别

1、Loader

Loader直译为“加载器”,用于对模块的“源代码”进行转换,在import或“加载”模块时与处理文件。默认情况下,webpack只支持对JS和JSON文件打包,像css , sass , png等这些类型的文件的时候,webpack则无能为力,这时候就需要配置对应的loader进行文件内容的解析。

常见的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 代码
2、Plugin是什么

Plugin直译为“插件”,可以扩展webpack的功能,让webpack具有更多灵活性。在webpack运行的生命周期中会广播许多事件,Plugin可以监听这些事件,在合适的时机通过webpack提供的API改变输出结果。

常见的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提取到单独的⽂件中,⽀持按需加载
3、Loader和Plugin的区别
  • 概念
    • Loader直译为"加载器"。Webpack将⼀切⽂件视为模块,但是webpack原⽣是只能解析js⽂件,如果想将其他⽂件也打包的话,就会⽤到 loader 。 所以Loader的作⽤是让webpack拥有了加载和解析⾮JavaScript⽂件的能⼒。
    • Plugin直译为"插件"。Plugin可以扩展webpack的功能,让webpack具有更多的灵活性。 在 Webpack 运⾏的⽣命周期中会⼴播出许多事件,Plugin 可以监听这些事件,在合适的时机通过 Webpack 提供的 API 改变输出结果。
  • 用法:
    • Loader在 module.rules 中配置,也就是说他作为模块的解析规则⽽存在。 类型为数组,每⼀项都是⼀个 Object ,⾥⾯描述了对于什么类型的⽂件( test ),使⽤什么加载( loader )和使⽤的参数( options )
    • Plugin在 plugins 中单独配置。 类型为数组,每⼀项是⼀个 plugin 的实例,参数都通过构造函数传⼊。
  • 运行时机
    • loader 运行在打包文件之前
    • plugins 在整个编译周期都起作用
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值