资源模块类型(asset module type)
上一篇说了webpack5打包其他资源已经可以不用到file-loader与url-loader了。
webpack5可以使用 资源模块类型(asset module type),替代file-loader等。
资源模块类型通过添加四种新的模块类型,来代替Loader
1 asset/resource 发送一个单独的文件并导出URL,替代file-loader
2asset/inline 导出一个资源的data URL,替代url-loader
3asset/source 到处资源的源代码,之前通过使用raw-loader实现。
4 asset在导出一个data URL和发送一个单独的文件之间做选择,之前通过url-loader+limit属性实现。
这样说较为抽象,看具体实现。为了验证我们这个资源模块类型可用
我们先删掉两个loader,先试第一个,asset/resource
看看效果是不是跟file-loader一样
可以看到打包成功,效果跟file-loader类似。但是打包到的都在build里面了。我们想通过打包到一个文件可以这么样设置,在Output属性里面的assetModuleFilname属性设置你的资源打包后要放在哪,还可以设置像options里面的name,outputPath属性一样设置文件夹名字以及文件名字。打包如图
可以看到里面有两个点,assetModuleFilename的ext跟我们之前设置的ext不一样,默认是会拿到后缀并且包括那个点,所以这里我们可以不加点。
但我们设置的assetModuleFilename属性是会将所有通过assetModule处理的资源都生成在img里面,但我们要的是对应的asset module type生成在不同的位置,就可以这么做了。
在每一个type值后面配置geneator属性,生成的意识,里面是个对象,配置下filename即可。效果同上面设置assetModuleFilename一样。
试试第二个 asset/inline,同url-loader 转64,因为不生成文件,所以没有generator属性
打包成功并且转为base64了。
要实现limit的效果,就得用第四个了asset
asset类型又多一个属性,parser,表示解析,是个对象,里面有个固定的属性,叫dataUrlCondition,顾名思义,data转成url的条件,也就是转成bas64的条件,maxSize是就相当于Limit了,当大于100kb才不转换,所以
打包完没转换。
当大于10kb转换时,已经转换了而且生成的位置名字符合generator。
非常方便,使用asset module type来替代url,file-loader。
加载字体文件
特殊的字体,字体图标。下载了阿里的一个图标
把它放到关系依赖图
build后报错
缺少loader。css为什么缺少loader
# 因为icon。css文件里面又引入了其他文件,webpack将它们作为模块打包,又因为缺少合适的loader,所以webpack5并不认识他们,就会报错。
在webpack5之前是直接通过url-loader,file-loader来处理,webpack5后就不用了。
一般的操作都是将字体文件复制到build下面。
也是通过assets module type处理
打包成功,注意test后面跟着的是正则,不能加“”。
MP3 MP4文件也是一样这样处理即可
认识Plugin(插件)
每次打包都要手动删除build,不然会冲突。其次,最主要的原因是打包后的文件一定要有Index.html。
之前每次打包的build都没有index.html。
plugin就可以帮我们生成。
什么是plugin呢,loader是用于特定的模块进行转换,而plugin可以用于更加广泛的任务,比如打包优化,资源管理,环境变量注入等等。
看一幅图,css-loader可以加载css文件,csso-loader优化,而要打包成style.css就得通过Plugin。
基本的plugin使用
自动删除build,新打包的文件覆盖旧的文件。
cleanWebpackPlugin
cnpm install clean-webpack-plugin -D
使用也是非常简单
先看下cleanWebpackPlugin源码
是一个类,并且导出了。
plugin与loader不同,使用的时候需要require引入
在plugin属性里面,直接生成一个实例,源码里cleanWebpacjPlugin是一个类,所以我们使用的时候是new一个实例就行。以后自定义plugin都是类的形式。
打包下看看
打包成功并且帮我们删除了原来的build文件了。
plugin的基本使用就是require,在plugins属性设置,然后直接new一个实例即可使用。
HtmlWebpackPlugin
顾名思义就是对html文件的处理,因为我们之前打包,html是没有打包到build的。
生成html有两种方式,一种是使用默认的,他自己的ejs模板,一种是我们给他一个ejs模板
试试这插件的威力,直接把Index.html除掉
cnpm install html-webpack-plugin -D
因为html-webpack-plugin是通过module.exports来到出的,使用也是很简单,直接new就完事了,看看打包
打包成功,压缩是因为Mode为上苍模式,后续再讲。这样html就生成了。
可以看到也帮我们引入打包后的js文件,而且用的是defer延迟异步加载,这个属性的script是异步加载,并且等到DOM树加载完再执行。
可以看到源码里面是有这个模板的,我们的Index.html就是根据这个模板生成的。
ejs模板学过Node的应该熟悉,里面的《%= %>是准备给值替代的。
可以看到里面是个options.title,我们可以传值进去。
已经被替换了。
虽然这个帮我们生成了图片了,但有时候他的模板不是我们要的,所以我们要配置自己的模板
像vue的写法就是,学过vue的一般都知道,有个Public文件,里面有Index.html,那就是vue的模板。
使用也很简单,只要在
设置template属性即可。build一下试试
可以看到已经打包成功了。
但这个我们如果要使用全局变量时,但是现在我们没有BASE_URL,那么打包就会报错。
所以我们要配置全局变量。
所以要借助一个插件,DefinePlugin。这个插件允许在编译时创建全局的常量。webpack已经内置这个插件了。
使用也非常简单
打包一下
报错了
因为我们这个是外面包裹一层字符串的,因为如果
baseUrl: ‘/’ => 内部编译 const baseUrl = ./
这样就会报错,所以我们得再添加一层字符串包裹。打包一下
很明显看到,BASE_URL已经被替换了。
Vue还有一点就是他放在public的文件,是会直接复制到dist里面的,也就是直接复制到打包后的文件夹,我们要怎么实现这个效果呢。
使用另外一个插件 copyWebpackPlugin
cnpm install copy-webpack-plugin -D
老规矩,先导入,再去new
可以看到我们new的时候可以传参数过去,第一个就是patterns,匹配的意思,里面的from表示会复制的文件夹。而to可以忽略,默认会使用output的path的,最后就是我们要忽略的文件了,比如Index.html是要生成的,不是我们传的,所以使用globOptions里面的ignore属性,而且忽略要注意用法,加**/才表示是在public里面忽略。看看效果
可以看到Css文件被忽略了,index.html不是复制过来的,是生成的。
这样看上去有点别扭,因为我们生成的js文件,或者复制过去的css文件,icon文件想放在相对应的文件夹,如js文件夹, css文件夹等等。
我们来设置budle.js放到Js文件里去,
output配置就行了。
看到生效了。