静态文件包含(vite打包静态文件打开显示空白)
vite 打包生成静态文件打开显示空白
需求场景 本地调试访问打包的文件看是否有啥问题 ,方便定位线上问题 安卓手机需要去直接访问静态文件 ,而不是访问域名的情况vite 打包生成的文件如果直接放在服务器中是可以正常访问的 ,但是本地直接访问打包生成index.html文件就会提示以下问题 。
访问的文件不存在 ,主要是因为路径配置问题 。
提示跨域问题 ,不支持files协议 ,主要是因为esModule问题 。
问题1:访问的文件不存在 ,主要是因为路径配置问题 。
解决:在 vite.config.js文件中配置
主要:打包静态文件必须是根路径 ,否则放到服务器找不到静态资源(同理于webpack中的publicPath 的配置) export default defineConfig({ ... base: "./", ... })验证路径是否正常看浏览器中的network看文件是否加载正常
问题2. 提示跨域问题 ,不支持files协议,主要是因为esModule问题
对比webpack 打包静态文件是否可以正常访问答案:正常
在vue.config.js 文件中配置 module.exports = { outputDir: dist, publicPath: baseUrl,原理:开始通过file协议直接访问index.html ,在index.html中静态引入index.js ,在index.js中import test.js 。在import的过程中需要http服务器去解析es6语法并添加header头信息去跨域引入test.js,但是file协议相当于通过资源管理器静态访问index.html ,中间的过程没有http服务器参与解析 ,所以无法识别es6的import语法 。
解决:将打包生成的文件改成为没有moudle的文件
step1:安装
$ npm install @vitejs/plugin-legacystep2: 配置vite.config.js
import legacy from @vitejs/plugin-legacy; export default defineConfig({ .... plugins: [legacy({ targets: [defaults, not IE 11] }),vue()], build:{ target: [es2015, chrome63], // 默认是modules,百度说是更改这个会去输出兼容浏览器,尝试没啥作用 ,先配置吧 } .... })step3:
在dist并列的文件夹中创建脚本文件 (用于替换module等关键词 ,省的每次得手动删除)toFile.mjs
创建 toFiles.mjs (为啥格式不是js为了执行命令不报兼容的错误) import fs from fs; console.time(转换耗时); const distPath = ./dist/index.html;//打包路径的index.html let htmlText = fs.readFileSync(distPath, utf8); let resultText = ; let htmlArr = htmlText.match(/.*\n/g) || []; htmlArr.forEach(str => { str = str.replace(/\s?nomodule\s?/g,); str = str.replace(/\s?crossorigin\s?/g,); str = str.replace(/data-src/g,src); if(!/type="module"/i.test(str)) resultText += str; }); fs.writeFileSync(distPath,resultText,utf8); console.timeEnd(转换耗时);step5:
npm install fs // 安装fs node toFile.mjs // 执行脚本step6: 查看 dist 文件夹中的 index.html 文件,查看是否没有module 、 crossorigin 等关键词 ,访问index.html 文件 查看效果
一般执行到这里基本是可以正常访问的 ,但是我的项目还是空白 ,后面观察加载的html结构发现router-view的组件没有加载上去 ,后面尝试将router.js 文件中history模式改成了hash ,然后再重新打包执行上面的操作能够正常打开 。
总结:
vite生成的文件会带有module ,导致存在跨域问题 ,大多数项目开发都是将文件放在服务器中通过域名去访问,但是特殊情况需要直接访问静态资源 。所以要去解决file存在跨域的问题 。
反思:
webpack为啥打包出的文件同样是file直接访问但是不存在跨域。 webpack为啥打包出的文件不带module ,但是file打包会带module 。借鉴其他的博文总结:
1 、给引用文件设置type="module"等于给文件设置了私有作用域 ,xx.js文件成了单独的模块,运行在自己的私有作用域中 ,而不是全局作用域中 。
2 、虽然script标签自带跨域能力(这也是某些场合会通过jsonp结合script来请求资源的原因) ,但是这里的跨域是指的http协议(协议 、域名 、端口一致),file协议是不支持跨域的。
3 、es6声明type=“module ” ,这类使用了模块的script是受限于同源策略的 。
参考:
vue3.0 + vue-router4.0打包后页面空白
https://blog.csdn.net/here962464/article/details/114917147创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!