在使用Vite的过程中,会发现所有不管是CSS,JS还是其他资源文件,都在dist中乱成一堆,不便于管理。
Webpack可以通过简单的配置输出文件的plugin
来实现文件类型分离,而Vite在生产模式下,也应该由输出文件的东西来控制,不过Vite不用plugin
,而是rollup
配置项。
对文件类型初步判断
首先,通过查阅文档可知Vite提供了三种输出的文件类型的路径参数,分别是:
- 资源文件:
assetFileNames
- 生成的chunk:
chunkFileNames
- 入口文件:
entryFileNames
所以直接把它们搬到output
里边:
rollupOptions: {
output: {
assetFileNames: 'static/assets/[name].[hash][extname]',
chunkFileNames: 'static/js/[name].[hash].js',
entryFileNames: 'static/js/[name].[hash].js',
}
}
注:xxxFileNames
不是单纯的文件名,而实际上是文件的路径。
2对资源类型的判断
由于chunk
和entry
都是Javascript文件,所以可以直接输出到JS文件夹。
然而asset
资源除了CSS之外,可能还有各种图片、字体等等,故需要分门别类地将对应的类型的资源,放在对应文件夹下。
现在咱先脱离Vite环境,如果已知资源的文件名,如何通过Javascript判断它的类型呢?
咱很容易地可以想出以下的步骤✓
- 1. 获取文件名为字符串,以 “.” 为界分割成两个或多个字符串。
- 2. 检测这些字符串中是否包含指定的文件扩展名。
- 3. 按照不同的扩展名进行分类并return
接下来以这些代码就可以很简单地实现:
let getType = fileName => {
if(/\.(woff2|woff|ttf)(\?.*)?$/i.test(fileName)){
return "字体";
}
elseif(/\.(jpe?g|webp|png|svg)(\?.*)?$/i.test(fileName)){
return "图片";
}
elseif(/\.(css)(\?.*)?$/i.test(fileName)){
return "样式表";
}
}
let a = getType("iconfont.woff2"); // 字体
let b = getType("banner.jpg"); // 图片
let c = getType("index.css"); // 样式表
资源处理的实践
接下来的步骤,就是将第二步中的函数搬进rollup
的配置项中,其实到这一步已经简单了。
rollup
对1中所提到的这三个fileNames
,实际上不仅可以是固定的值,也可以是返回字符串的函数。而这个函数,只要你写需要传一个参数,不管参数叫什么名,逐个打包文件时rollup
都会传一个关于这个文件的对象。而我们所需要的文件名字,就是它的name
属性。
也就是说,下面这段代码中的asset.name
就相当于咱在2中写的fileName
参数↓
rollupOptions: {
output: {
assetFileNames: asset => {
// 这里的 asset.name 即为 2 中的 fileName
}
}
}
而接下来就是将它们分门别类地放进各个文件夹,有了咱上面的铺垫,这个问题解决起来已经比较容易了 (*´︶`*)
咱目前需要处理的,就是以下的小问题啦
- 1. 通过文件扩展名判断文件类型
- 2. 将文件放到对应文件夹中
rollupOptions: {
output: {
assetFileNames: asset => {
if(/\.(woff2|woff|ttf)(\?.*)?$/i.test(asset.name)){
let extType = "fonts";
}
elseif(/\.(jpe?g|webp|png|svg)(\?.*)?$/i.test(asset.name)){
let extType = "images";
}
elseif(/\.(css)(\?.*)?$/i.test(asset.name)){
let extType = "css";
}
// 2. 将文件放到对应位置
return `static/${extType}/[name].[hash][extname]`;
},
chunkFileNames: 'static/js/[name].[hash].js',
entryFileNames: 'static/js/[name].[hash].js',
}
}
主要代码分两大板块,分别以独立的思想去解决问题,接着再将它们拼接起来,完成!
浅谈 Rollup 和 Vite
所以为毛Vite中会出现 Rollup 的配置项呢?
至于开发模式,Vite由于自己研制了一套推翻Webpack的完全使用ESModule
语法的HMR热更新系统,所以开发模式就跟Rollup没啥关系了。
然而在生产模式下,由于Rollup使用ES2015
的模块化语法,相对于Webpack等所使用的CommonJS
,更符合Vite的需要,编写更简洁,打包体积更小,所以Vite选择使用了它。
总而言之,简单(但不准确地)来说Rollup是生产模式下Vite的打包内核。