需求
期望 Vite 打出来一个能直接本地双击打开就能看的页面的包
问题
研究过程中发现很多问题,第一个问题就是 type: 'module'
问题,如果本地双击,这个会导致跨域,js 文件就无法加载
https://github.com/vitejs/vite/blob/main/packages/vite/src/node/plugins/html.ts#L491-L502
vite html 插件代码如下,可以看到 type: 'module'
是写死的,需要额外处理
const toScriptTag = (
chunk: OutputChunk,
isAsync: boolean
): HtmlTagDescriptor => ({
tag: 'script',
attrs: {
...(isAsync ? { async: true } : {}),
type: 'module',
crossorigin: true,
src: toPublicPath(chunk.fileName, config),
},
});
第二个问题就是 @vitejs/plugin-legacy
插件好像不管用,后来才发现这个是为了支持不支持 esm
的浏览器用的插件,如果你的浏览器仍然支持 esm
,那么这个插件就不会生效,本地打开是 file 协议,但是你的浏览器支持 esm
,那么就会加载 module
的 js,从而出现跨域无法加载 js 文件的报错。
- https://blog.csdn.net/qq_37193972/article/details/122535933
- https://github.com/vitejs/vite/tree/main/packages/plugin-legacy
// vite.config.js
import legacy from '@vitejs/plugin-legacy';
export default {
plugins: [
legacy({
targets: ['ie >= 11'],
additionalLegacyPolyfills: ['regenerator-runtime/runtime'],
}),
],
};
不允许跨域问题
- https://blog.csdn.net/muguli2008/article/details/122306515
- https://blog.csdn.net/lan123456_/article/details/116669994
- https://blog.csdn.net/KateCateCake/article/details/79045211
解决
vite-plugin-singlefile 插件
- https://segmentfault.com/q/1010000040094465
- https://github.com/richardtallent/vite-plugin-singlefile
- https://github.com/richardtallent/vite-plugin-singlefile/blob/main/src/index.ts
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import { viteSingleFile } from 'vite-plugin-singlefile';
export default defineConfig({
plugins: [vue(), viteSingleFile()],
build: {
target: 'esnext',
assetsInlineLimit: 100000000,
chunkSizeWarningLimit: 100000000,
cssCodeSplit: false,
brotliSize: false,
rollupOptions: {
inlineDynamicImports: true,
output: {
manualChunks: () => 'everything.js',
},
},
},
});
这个存在一些奇怪的问题,就是有路由的时候,会出问题。看了一下源码:
https://github.com/vitejs/vite/blob/main/packages/vite/src/node/plugins/importAnalysisBuild.ts
if (!true || !deps || deps.length === 0) {
return baseModule();
}
改为
if (
!true ||
!deps ||
deps.length === 0 ||
deps === `__VITE_PRELOAD__`
) {
return baseModule();
}
修复正常
@rollup/plugin-html 插件
感谢群里 @三月 大佬提供方案
这个插件还要配置一下模板,我回头补充一下,马上要吃午饭了。
https://github.com/rollup/plugins/tree/master/packages/html#template
import { fileURLToPath, URL } from 'url';
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import vueJsx from '@vitejs/plugin-vue-jsx';
// import { viteSingleFile } from 'vite-plugin-singlefile';
const html = require('@rollup/plugin-html');
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue(), vueJsx()],
base: './',
build: {
minify: false,
rollupOptions: {
output: {
format: 'umd',
inlineDynamicImports: true,
},
input: 'src/main.ts',
plugins: [
html({
publicPath: './',
}),
],
},
},
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)),
},
},
});
多入口方案
占位,等明白了补充文章和整理
import path from 'path';
import glob from 'glob';
export default {
root: path.join(__dirname, 'src'),
build: {
outDir: path.join(__dirname, 'dist'),
rollupOptions: {
input: glob.sync(path.resolve(__dirname, 'src', '*.html')),
},
},
};
配置 Chrome 浏览器支持 file 协议
Windows:
设置 Chrome 的快捷方式属性,在“目标”后面加上 –allow-file-access-from-files
,注意前面有个空格,重新打开 Chrome 即可。
Mac:
打开终端,输入下面命令:open -a“Google Chrome” –args –disable-web-security
然后就可以屏蔽安全访问了 [ –args
:此参数可有可无]