【vite】plugin介绍与手写压缩HTML-plugin
Vite
在介绍vite plugin之前,先介绍一下vite:
- Vite,一个基于浏览器原生ES模块的开发服务器。利用浏览器去解析模块,在服务器端按需编译返回,完全跳过了打包这个概念,服务器随起随用。同时另有有Vue文件支持,还搞定了热更新,而且热更新的速度不会随着模块增加而变慢。
- Vite要求项目完全由ES模块模块组成,common.js模块不能直接在Vite上使用。因此不能直接在生产环境中使用。在打包上依旧还是使用rollup等传统打包工具。
- Vite的基本实现原理,就是启动一个koa服务器拦截浏览器请求ES模块的请求。通过路径查找目录下对应文件的文件做一定的处理最终以ES模块格式返回给客户端。
相对于传统的webpack它的优势主要为以下两点:
- 无需打包:只有浏览器请求某个模块时,再根据需要对模块内容进行编译,webpack则需要全部模块编译完成之后再启动开发服务器;
- 热更新(HMR):当改动了一个模块后,vite仅需让浏览器重新请求该模块即可,不像webpack那样需要把该模块的相关依赖模块全部编译一次;
Plugin
webpack插件插件由一个构造函数实例化出来,与webpack插件申明方式不同,vite的插件通常以function来定义:
webpack
注册插件
// plugin.js
class WaylonWebpackPlugin {
// 参数
constructor(options) {
this.options = options;
}
// 构造函数定义 apply 方法,在安装插件时,apply 方法会被 Webpack compiler 调用一次
apply(compiler) {
// 准备开始构建
compiler.hooks.beforeRun.tap('begin', () => {
console.log('开始编译🚀');
});
// 编译完成
compiler.hooks.done.tap('end', () => {
console.log('恭喜你,没有bug,编译完成~ 🚀');
});
}
}
module.exports = WaylonWebpackPlugin;
使用插件
// webpack.config.js
const WaylonWebpackPlugin = require('./plugin.js');
plugins: [new WaylonWebpackPlugin()]
vite
注册插件
// plugin.js
const WaylonVitePlugin = () => {
return {
name: 'WaylonVitePlugin', // 必须的,将会在 warning 和 error 中显示
buildStart() {
console.log('开始编译🚀');
},
buildEnd() {
console.log('恭喜你,没有bug,编译完成~ 🚀');
},
};
};
export default WaylonVitePlugin;
使用插件
// vite.config.js
import WaylonVitePlugin from './plugin.js';
plugins: [WaylonVitePlugin()];
vite钩子介绍
Vite的插件可以有两种形式,一种是vite插件,仅供vite使用;另一种则是rollup通用插件,它不使用 Vite 特有的钩子,让我们简单介绍一下关于这两种插件的生命周期:
通用钩子
以下钩子在服务器启动时被调用:
以下钩子会在每个传入模块请求时被调用:
以下钩子在服务器关闭时被调用:
vite专属钩子
详细介绍可以直接点击进入官网查阅,这里我们简单介绍几个常用的钩子:
下面的钩子会在服务启动时调用一次(文件更新也不会调用)
- options:替换或操纵
rollup
选项 - buildStart:开始创建
vite特有的钩子
- config: 修改Vite配置
- configResolved:Vite配置确认
- configureServer:用于配置dev server,可以进行中间件操作
- transformIndexHtml:用于转换宿主页
- handleHotUpdate:自定义HMR更新时调用
下面钩子每次有模块请求时都会被调用:(核心hook)
- resolveId:创建自定义确认函数,常用语定位第三方依赖(找到对应的文件)
- load:创建自定义加载函数,可用于返回自定义的内容(加载文件源码)
- transform:可用于转换已加载的模块内容(转变源码为需要的代码)
开发一个压缩HTML的vite plugin
插件功能: 由于vite编译出来的HTML存在换行符、注释、空格等,这里我们简单做一个插件将HTML中的换行符、注释、空格去掉以压缩HTML文件;
首先我们所要使用到的是vite插件中transformIndexHtml
这个钩子,具体实现方式如下:
// utils.ts
// 清除类 采用构建者模式进行开发 每次执行方法后将this返回 链式调用
export class Clear {
htmlStr: string;
constructorrting) {
this.htmlStr = str;
};
clear(reg:RegExp) {
if (!reg) {
return this;
}
this.htmlStr = this.htmlStr.replace(reg, '');
// 每次清除完毕后将this放回, 供下一次清除其他目标
return this;
};
replace(reg:RegExp, text:string) {
if (!reg) {
return this;
}
this.htmlStr = this.htmlStr.replace(reg, text);
// 每次清除完毕后将this放回, 供下一次清除其他目标
return this;
}
}
// plugin.ts
import { Clear } from "./utils";
const uglifyHtmlPlugin = () => {
return {
name: 'uglifyHtmlPlugin', // 必须的,将会在 warning 和 error 中显示
transformIndexHtml(html: string) {
const replaceObj = new Clear(html);
// 构建者模式: 先去除空格与换行符 再去除注释
replaceObj.clear(/[\r\n]*/g).clear(/<!--[\w\W\r\n]*?-->/gmi);
// 放回处理完毕以后的html字符串
return replaceObj.htmlStr;
},
};
};
export default uglifyHtmlPlugin;
// vite.config.js
import uglifyHtmlPlugin from '@waylonzheng/vite-uglify-html-plugin'; // 这里我已经发npm包了,直接引
plugins: [uglifyHtmlPlugin()];
效果对比:
最后
这个插件已经发布在npm上了,目前还有一点待优化的地方,比如说如何将没用的双标签修改为单标签等等,后续会优化;
GitHub: github.com/waylonzheng… npm: www.npmjs.com/package/@wa…
转载自:https://juejin.cn/post/7211745375920586813