如何用vite打包出非esmodule格式的资源文件
一、如果你只是想对低版本浏览器进行兼容
直接使用官方提供的 @vitejs/plugin-legacy 插件即可。
参考官方文档:https://cn.vitejs.dev/guide/
【使用步骤】
1、安装插件
npm i @vitejs/plugin-legacy -D
2、修改vite.config.js
import { defineConfig } from 'vite';
import legacy from '@vitejs/plugin-legacy';
export default defineConfig({
plugins: [
legacy({
targets: ['defaults', 'not IE 11']
})
]
})
【注】
targets用于标明,你想兼容的浏览器版本范围。具体可配置项,详见:
https://github.com/browserslist/browserslist#queries
二、如果你只想打包出非esmoudle格式的资源文件,无论什么浏览器,都要用这种格式
先说结论:笔者翻阅网上各种资料,并未找到直接实现的方案,如有,辛苦留言指教,十分感谢!
整体解决方案,依然是基于 @vitejs/plugin-legacy,同时,额外对打包后得到的html进行手动处理,使得所有浏览器全部加载 legacy 版本的资源文件。
手动处理内容:
1)删除 script 标签里面的 nomodule,crossorigin 属性
2)删除 含有 type="module" 的 script 标签
3)删除 含有 rel="modulepreload" 的 link 标签
4)删除 id="vite-legacy-entry" 所在 script 标签里的所有内容,并将 data-src 属性换成 src
【实现步骤】
1、安装插件
npm i @vitejs/plugin-legacy -D
2、修改vite.config.js
import { defineConfig } from 'vite';
import legacy from '@vitejs/plugin-legacy';
export default defineConfig({
plugins: [legacy()]
})
3、创建自动格式化html的脚本
bin/htmlFormat.js
import fs from 'fs';
const htmlPath = './dist/index.html'; // 打包后的html文件路径
const htmlText = fs.readFileSync(htmlPath, 'utf8');
const htmlArr = htmlText.match(/.*\n/g) || [];
let result = '';
htmlArr.forEach((v) => {
v = v
.replace(/script ?nomodule\s?/g, 'script ')
.replace(/\s?crossorigin\s?/g, ' ')
.replace(/<link rel="modulepreload" href="[^"]+\.js">/g, '')
.replace("System.import(document.getElementById('vite-legacy-entry').getAttribute('src'))", '')
.replace(/data-src/g, 'src');
if (!v.includes(`script type="module"`)) {
result += v;
}
});
fs.writeFileSync(htmlPath, result, 'utf8');
console.log('处理完成');
4、package.json创建 htmlFormat 脚本
"scripts": {
"htmlFormat": "node ./bin/htmlFormat.js"
}
5、执行 yarn build
6、执行 yarn htmlFormat
7、本地启动,验证能否正常访问
// 没有 serve 的,先执行 npm install -g serve。相关文档:https://github.com/vercel/serve
serve dist
访问 http://localhost:3000/,确认页面能否正常打开。同时,观察浏览器加载的静态资源包,如果包含 legacy 字样,则符合预期。
#参考文档: