webpack

230 阅读12分钟

1.初识webpack

Webpack简介

webpack是什么

*Webpack是一种前端资源构建工具,一个静态模块打包器(module bundler)。
	在Webpack看来,前端的所有资源文件(js/ css/ sass/ less/ img/ ,,,)都会作为模块处理
	它将格局模块的依赖关系进行静态分析,打包生成对应的静态资源(bundle)。*

在这里插入图片描述
webpack能干什么

代码转换文件优化:{
	将sass,less转换为css
	将es6转换为es5
}
文件优化: {
	压缩代码体积
	多入口打包
}
代码分割:{
	将所有分拣单独分离到指定的文件目录下
}
模块合并: {
	把多个模块合并成一个模块
}
自动刷新: {
	在修改代码之后自动刷新页面
}
代码校验: {
	自动检测代码,精准判断源码错误信息,并且可以自动修复某些格式错误
}
自动发布: {
	在代码构建完,之后会自动进行发布
}

2.五个核心概念

  1. 入口(entry)

    入口(entry)指示Webpack以哪个文件为入口起点开始打包,分析构建内部依赖图
    
  2. 出口(output)

    输出指示 Webpack 打包后的资源bundles 输出到哪里去
    
  3. 配置(module)

    Loader让Webpack能够去处理那些非js文件(webpack自身只理解js)
    
  4. 插件(plugins)

    插件(plugins)可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量等。
    
  5. 模式(mode)

    ## 开发模式: development 本地调试
    开发环境会将DefinePlugin中process.env.NODE_ENV的值设置为development。启动NamedChunksPlugin 和 NamedModulesPlugin。
    
    生产模式: production	优化上线
    会将DefinePlugin中process.env.NODE_ENV的值设置为production。启动FlagDependencyUsagePlugin,FlagIncludedChunksPliugin,ModuleConcatenationPlugin,NoEmitOnErrorsPlugin,OccurrenceOrderPlugin,SideEffectsFlagPlugin 和 terserPlugin
    

3.webpack 初体验

  • 初始化配置 初始化package.json

     输入指令
     Npm init
    
  • 下载并安装 webpack 输入指令

     Npm install webpack webpack-cli -g		
     Npm install webpack webpack-cli -D
    
  • 编译打包应用 1. 创建webpack.config.js文件 2. 运行指令

     开发环境指令: webpack src/js/index.js -o build/js/built.js -mode=development
     功能:webpack能够编译打包js和json文件,并且能将es6的模块化语法转换成浏览器能识别的语法
    
     
     生产环境指令: webpack src/js/index.js -o build/js/built.js -mode=production
     功能:在开发配置功能上多一个功能,压缩代码。
    
  • 结论

Webpack能够编译打包js和json文件

	能将es6的模块化语法转换成浏览器能识别的语法能压缩代码
	问题
	不能编译打包css,img等文件
	不能将js的es6基本语法转化为es5以下语
  • 开发环境配置

    1. 创建webpack.config.js文件

    2. 配置内容如下

      在这里插入图片描述

  • 打包样式文件

     将css文件变成commonjs模块加载js中,里面内容是样式字符串创建style标签,将js中的字符样式插入style标签中,放入head中
    
test: \/.css$\, //正则匹配css结尾的文件
use:['style-loader','css-loader'] // 这样就是最基本的打包css文件,他会打包到你的入口文件里
  • 打包html文件

    下载一个插件包 引入到plugins中

     Npm install --save-dev html-webpack-plugin	
    

    修改配置文件

    在这里插入图片描述
    在这里插入图片描述
    这样就会将template路径下的html文件,复制并打包到bundle中,最后会引入js,css。。。

  • 打包图片资源

在这里插入图片描述

	Name就是把hash值只取十位但是解决不了html中的img图片就要利用html-loader了

在这里插入图片描述

此时html-loader是处理html里的img图片的,而不是html文件,然后再转换为url-loader,但是我们的html-loader默认使用commonjs,不认识我们的es6模块,所以要在url-loader中设置esModule = false配置
  • 打包其他资源

    在这里插入图片描述
    exclude就是除了上述文件类型,的文件,那就用file-loader。

  • devServer

在这里插入图片描述

创建一个本地服务器,用来调试,

运行指令:npx webpack-dev-server

/*

生产环境来了

*/

生产环境配置

1. 抽离css

将css从js中抽离出

下载安装包: npm install --save-dev mini-css-extract-plugin

在这里插入图片描述
这样就会把打包到js中的css单独抽离出来了

Minicssextractplugin.loader替换style-loader

在这里插入图片描述
再在我们的plugins中写入这个配置
在这里插入图片描述

2. css兼容性

Npm install --save-dev postcss-loader postcss-preset-env
 引入css压缩变量(写成变量好使用)	
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200412115247188.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ1MTU3MTk3,size_16,color_FFFFFF,t_70)
 然后添加到use里
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200412115334752.png)

放在最后是最先执行,这是loader的执行顺序,从下往上执行

再到package.json中使用“browserslist”,development开发环境配置,最近一个版本,production生产版本 百分比控制兼容性,not dead删除以及死掉的浏览器,not op_mini all删除欧朋mini

在这里插入图片描述

但默认使用生产模式,所以你可以在webpack配置文件里设置

在这里插入图片描述

3. 压缩css

在这里插入图片描述
在插件中引入optimizecssassetswebpackplugin
在这里插入图片描述

4.js语法检查

下载安装包

Npm install --save-dev eslint-loader eslint eslint-config-airbnb eslint-plugin-import

配置文件

	在webpack配置文件配置

在这里插入图片描述

再去package.json使用airbnb-base,env和此配置无关

在这里插入图片描述

5.Js兼容性

下载安装包

Npm install --save-dev babel-loader @babel/core @babel/preset-env @babel/polyfill core-js	

修改配置文件

在这里插入图片描述
在这里插入图片描述
这样就配置好babel兼容了,但是babel/preset-env只能兼容像箭头函数这种,promise这种语法就不可兼容

在这里插入图片描述

由于babel/polyfill太暴力了,我只是用部分的兼容性,却把所有的兼容都引入进来,使bundle包边的及其大,所以此时使用core.js来按需加载兼容,上面有详细注释,大家可以仔细参阅,bable/polyfill用不到,所以我就不写了,感兴趣的可以去官网看。

6. js压缩

这是有史以来最简单的配置了,mode设置为生产模式即可,生产会替我们引入UglifyJsPlugin来进行JavaScript的压缩

7. html压缩

在plugins中插件写入下面配置

在这里插入图片描述

开发环境优化

1.MHR

1.认识HMR

1.为什么使用HMR
	使用HMR可以在模块更新时,只更新变动的模块,其他的模块不更新
2.HMR是什么
	HMR就是热加载,就是热更新
3.HMR的好处
	HMR的好处是减少请求,只请求更新的模块

2.使用HMR

1. 在devServer中配置

在这里插入图片描述
但是js就不会自动热加载 所以要手动设置

在这里插入图片描述
你想哪个模块使用HMR就就这样做

2.source-map

1.source-map是什么
	会创建源码和构建后的映射
2.source-map能做什么
	用来调试代码,清晰的提示错误信息
3.为什么用source-map
	Source-map可以直接在控制台使用,利于开发者

4. 配置source-map

在这里插入图片描述
这就是最基本的配置,也是最标准的

下面是详情,所有source-map的环境,以及开发生产使用哪个source-map

在这里插入图片描述
在这里插入图片描述
像vue这种脚手架都是用的第一种,所以大家看到的报错很清晰

生产环境优化

1.OneOf

1.OnfOf是什么
	是一种优化loader配置手段
	
2.Oneof 做了什么
	像之前loader在匹配文件时,会全部走一遍,这样会浪费很多效率,设置oneof他可以只匹配一个,当匹配到合适的loader就会停止继续查找。

3.配置oneof

在这里插入图片描述

注意: 重复文件不会进行匹配所以,要把重复的文件单独写在rules里面,你应该把它单独提取出来

2.Babel缓存

1.缓存能干嘛

加载js,css文件,使其下载打开网页加载速度提高

2.配置缓存

在这里插入图片描述

你需要理解三个hash值

hash

Hash 根据webpack打包生成的hash,即使文件没变,一旦重新打包hash就会变,使缓存找不到

chunkhash

Chunkhash 来自同一个chunk的hash值是一样的,css和js来自同一个chunk

contenthash

Contenthash 基于文件类型创建hash值,但是有一个问题,就是a.js 和 b.js的hash是一样的,所以要使用一个runtime来解决,下面我会介绍。

3. Tree shaking

1.什么是tree shaking

Dom树上会挂载很多js,css,如果当前没有使用哪个模块,改模块就不会被加载,从而节省效率

2.配置文件

开启es6模块化(import),开启production就可以进行树摇了
**在webpack4中树摇不能识别多层引入,所以尽量不要深度导入一个文件,webpack5为我们解决了这一点最后会详细介绍

4.Code split

1.什么是代码分割

	把js拆分成小的js,实行快速打包

2.方法

1.多入口 --》使用多入口
2.Optimization --> node_modules --> 单独文件 --》 大小超过30kb
3.Import (路由常用) --》利用模块化

5.Lazy loading

1.懒加载

懒加载是什么
懒加载是当触发某个条件时,才进行代码的加载(用户稍微卡顿)

2.预加载

预加载
预加载,当主线程的任务队列处于空闲期,程序会进行加载,等到条件允许时,直接执行缓存(使用了缓存)

3.配置

懒加载利用异步函数导入(触发条件就加载),预加载只需在import后加入 /* webpackPrefetch: true */

PWA

1.什么是PWA

PWA就是离线访问技术(像淘宝就用了这种技术)

2.下载安装包

Npm install --save-dev workbox-webpack-plugin

3.配置文件

在这里插入图片描述

在这里插入图片描述

** 还需要在js中注册serviceWorker

在这里插入图片描述

7. 多进程打包

1.下载安装包

Npm install --save-dev thread-loader

2.配置文件

在这里插入图片描述
为什么要写在上面呢,因为loader自下而上,执行的,所以thread-loader算是在babel后面执行 但要注意,如果babel体积大的话可以这么使用,如果babel本身没多少体积,反而实用多进程,无疑是增负担,因为本身开启就需要600ms

8.Externals

功能: 让某些文件不打包

配置

在这里插入图片描述

这样就可以阻止第三方库打包到我们的项目中了,比如你要使用cnd引入某些库,这就很好用了!

9.dll

什么是Dll

让某些程序不打包,进行单独打包,并且输出在html上,优化第二次打包,优化效率

配置

首先配置webpack.dll.js

在这里插入图片描述
然后我们运行 webpack命令 ,但默认webpack会打包webpack.config.js,所以要使用webpack --config webpack-dll.js 指令,这样就可以打包我们的dll.js文件

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

我们要进行独立打包的jq已经成功在dll文件了,并且也做了对jq的映射,下次打包文件再有jq的时候就不会再次打包,从而减少内存

在index.js只引入jq就好了

在这里插入图片描述
有了这个文件还不行,还需要配置我们的webpack.config.js文件

在这里插入图片描述

这样我们下一次打包,只需打包config文件,而不再需要对dll进行打包(除非你加别的库)

让我们看看html是某引入jquery

在这里插入图片描述

可以看到html中以及引入了jq,在让我们看看浏览器

在这里插入图片描述

在这里插入图片描述

可以看到jquery已经打印出来了哦 肯定有人要疑惑了,难道只能打包一个库吗,当然不是

在这里插入图片描述

你要加入哪个库,就添加上,然后再打包dll

在这里插入图片描述
可以看到我们的react才8kb!香啊~

详细配置

1. 入口(entry)

Entry入口分为二种形式、

一种单入口,一种多入口

单入口用于框架的脚手架,用于开发的多,
而多入口有事也需要,下面这幅图详细的介绍入口的配置

在这里插入图片描述

2.出口(output)

配置webpack

在这里插入图片描述
可以再这看到一些output属性,chunkfilename值得重点提一下,使用单入口的时候除非你用import否则你无法把它从bundle中单独抽离出去,在这使用了import引入test.js 并且单独使用了独立的chunk值,你还可以添加hash值

在这里插入图片描述

在这里插入图片描述

添加后的hash值

在这里插入图片描述
在这里插入图片描述

还有两个属性

在这里插入图片描述

还有一些不常用的属性,小伙伴们要多去官方文档上看。

3.module配置

在这里插入图片描述
以上是常用的配置,还有一些在官方文档,大家可以关注下

4. resolve

在这里插入图片描述

简化手写路径名

在这里插入图片描述

你还可以不用输入后缀名就能引入某些文件,用框架的时候就很好用,和帮助webpack寻找需要解析的模块

在这里插入图片描述

5. devServer(本地测试服务器)

在这里插入图片描述

以上是一些常用配置,如果要是用devServer必须开启开发模式(development) 下面还有一些其他属性,更加人性化

在这里插入图片描述

6. Optimization

这个配置基本系统会默认设置好,除非你要更改,下面就带大家看看它到底都做了那些事情

在这里插入图片描述
在这里插入图片描述
以上除了chunks以下的属性都是默认值

但有一个bug,就是虽然contentchunk是由文件类型决定的,但是每次打包都依赖与hash值,并且需要这个hash值来引入到入口文件,并且入口文件里也会包含这个hash值,当引入的文件内容发生改变,那么hash值也会跟着改变,这是必然的,但是这影响了入口文件使得需要重新构建。(入口文件保存了hash值)

这个问题就要用runTime来解决,先来看看问题在解决怕~

首先是利用模块化引入文件,多入口打包test

在这里插入图片描述

然后可以看到打包之后的结果

在这里插入图片描述

再去看看main文件(入口文件)

在这里插入图片描述

记录着这个test的hash值 如果我们改动了test文件,test文件的hash值会变,这是必然,但是随着hash值得变动,main也要再次新生成一个文件

在这里插入图片描述

这样是不好的 所以要利用优化配置来解决

在这里插入图片描述

此时再次打包就会生成一个runtime文件,专门记录非入口文件的hash值 再次重新打包

在这里插入图片描述

然后修改test文件再打包

在这里插入图片描述

然后可以看到只更新了test文件,和runtime文件,而main没有变

是不是so easy too happy!

马上要结束了!!!

初识webpack5

安装webpack5

Npm i webpack@next webpack-cli -D

新特性:

webpack5在开启production,es6模块化之后会自动进行树摇tree shaking
Webpack5会压缩代码体积
自动删除node.js polyfills
自动添加chunk和模块ID,生产环境默认启动
Webpack5 可以进行深度引入(import)
Webpack5能对commonjs进行tree shaking
Webpack4 只能输出es5语法,webpack5能对es版本进行更改 output.ecmaVersion: 2015(es6)
Webpack5 对代码分割 之前只能minSize: 30000,  现在可以对css,js单独设置 minSize : {css:30000, js:50000}
Webpack5 使用caching来缓存
Webpack5 会优化首次打包速度

Webpack5 output新特性

->  output.path : path.resolve(__dirname, ‘dist’)
->  output.filename: [name].js

更多的关注官方文档,官方真的是最好的书籍!!!

未完待续。。。