之前工作的时候用 vite 项目打包之后后端跟我说用不了,html都打不开,emmm...
vite 默认使用 ES Module 模块是不支持file协议的,需要使用插件来配置之后才可以正常使用file协议打开。
安装 @vitejs/plugin-legacy
yarn add @vitejs/plugin-legacy
vite3 版本以上还需要安装
yarn add terser
在 vite.config.js 里面使用并加上 base:"./"
import legacy from '@vitejs/plugin-legacy';
import vue from '@vitejs/plugin-vue';
import { defineConfig } from 'vite';
export default defineConfig({
base:"./",
plugins: [
vue(),
legacy()
],
});
路由改为哈希模式 createWebHashHistory
打包之后的html文件这样
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" href="./favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vite App</title>
<script type="module" crossorigin src="./assets/index-cd4486e7.js"></script>
<link rel="stylesheet" href="./assets/index-9f3fdf99.css">
<script type="module">import.meta.url;import("_").catch(()=>1);async function* g(){};if(location.protocol!="file:"){window.__vite_is_modern_browser=true}</script>
<script type="module">!function(){if(window.__vite_is_modern_browser)return;console.warn("vite: loading legacy chunks, syntax error above and the same error below should be ignored");var e=document.getElementById("vite-legacy-polyfill"),n=document.createElement("script");n.src=e.src,n.onload=function(){System.import(document.getElementById('vite-legacy-entry').getAttribute('data-src'))},document.body.appendChild(n)}();</script>
</head>
<body>
<div id="app"></div>
<script nomodule>!function(){var e=document,t=e.createElement("script");if(!("noModule"in t)&&"onbeforeload"in t){var n=!1;e.addEventListener("beforeload",(function(e){if(e.target===t)n=!0;else if(!e.target.hasAttribute("nomodule")||!n)return;e.preventDefault()}),!0),t.type="module",t.src=".",e.head.appendChild(t),t.remove()}}();</script>
<script nomodule crossorigin id="vite-legacy-polyfill" src="./assets/polyfills-legacy-f496a5dd.js"></script>
<script nomodule crossorigin id="vite-legacy-entry" data-src="./assets/index-legacy-75662b69.js">System.import(document.getElementById('vite-legacy-entry').getAttribute('data-src'))</script>
</body>
</html>
需要把 script 标签里面的 nomodule,crossorigin 属性删掉
删掉含有 type="module" 的标签
data-src 属性换成 src。
建议写一个node脚本来处理
安装 fs 模块
yarn add fs
新建一个js文件
// 如果运行报错 Cannot use import statement outside a module 换成
// const fs = require("fs");
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(/data-src/g, 'src');
if (!v.includes(`script type="module"`)) {
result += v;
}
});
fs.writeFileSync(htmlPath, result, 'utf8');
console.log("处理完成");
在 package.json 里面配置脚本
执行
yarn html
处理之后的html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" href="./favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vite App</title>
<link rel="stylesheet" href="./assets/index-9f3fdf99.css">
</head>
<body>
<div id="app"></div>
<script >!function(){var e=document,t=e.createElement("script");if(!("noModule"in t)&&"onbeforeload"in t){var n=!1;e.addEventListener("beforeload",(function(e){if(e.target===t)n=!0;else if(!e.target.hasAttribute("nomodule")||!n)return;e.preventDefault()}),!0),t.type="module",t.src=".",e.head.appendChild(t),t.remove()}}();</script>
<script id="vite-legacy-polyfill" src="./assets/polyfills-legacy-f496a5dd.js"></script>
<script id="vite-legacy-entry" src="./assets/index-legacy-75662b69.js">System.import(document.getElementById('vite-legacy-entry').getAttribute('src'))</script>
</body>
</html>
这样就可以双击html打开,使用file协议访问了