背景
微前端项目是这个样子:
主应用是 qiankun+webpack+react
子应用 vite+react 之前没考虑兼容性,用的 vite-plugin-qiankun 集成子项目的,再开发环境和生产环境都是没有任何问题的
直到客户现场黑屏.......
历程
在电脑上下载了 chrome 59版本的浏览器
一、@vitejs/plugin-legacy
直接在项目里引入 官方推荐的插件,在vite添加配置
legacy({
targets: ['defaults', 'ie >= 11', 'chrome 52'], //需要兼容的目标列表,可以设置多个
additionalLegacyPolyfills: ['regenerator-runtime/runtime'],
}),
然后。。。然后还是不行,浏览器报错
很纳闷,为啥做了兼容,代码里还有
import,难道 @vitejs/plugin-legacy,有问题???
后来看 vite-plugin-qiankun 源代码
const createImportFinallyResolve = (qiankunName: string) => {
return `
const qiankunLifeCycle = window.moudleQiankunAppLifeCycles && window.moudleQiankunAppLifeCycles['${qiankunName}'];
if (qiankunLifeCycle) {
window.proxy.vitemount((props) => qiankunLifeCycle.mount(props));
window.proxy.viteunmount((props) => qiankunLifeCycle.unmount(props));
window.proxy.vitebootstrap(() => qiankunLifeCycle.bootstrap());
window.proxy.viteupdate((props) => qiankunLifeCycle.update(props));
}
`
}
···
script$.html(`import(${appendBase}'${moduleSrc}')`)
···
script$?.html(`${script$.html()}.finally(() => {
${createImportFinallyResolve(qiankunName)}
})`)
这里有个 import
二、lib库模式? umd
阅读了 在微前端qiankun中使用Vite你踩坑了吗? - 掘金 (juejin.cn) 添加如下代码
import html from '@rollup/plugin-html';
plugins:[..., html({
template: ({ attributes, files, meta, publicPath, title }) => {
const makeHtmlAttributes = (attributes) => {
if (!attributes) {
return '';
}
const keys = Object.keys(attributes);
return keys.reduce((result, key) => (result += ` ${key}="${attributes[key]}"`), '');
};
const scripts = (files.js || [])
.map(({ fileName }) => {
const attrs = makeHtmlAttributes(attributes.script);
return `<script src="${publicPath}${fileName}"${attrs}></script>`;
})
.join('\n');
const links = (files.css || [])
.map(({ fileName }) => {
const attrs = makeHtmlAttributes(attributes.link);
return `<link href="${publicPath}${fileName}" rel="stylesheet"${attrs}>`;
})
.join('\n');
const metas = meta
.map((input) => {
const attrs = makeHtmlAttributes(input);
return `<meta${attrs}>`;
})
.join('\n');
return `<!doctype html>
<html${makeHtmlAttributes(attributes.html)}>
<head>
${metas}
<title>${title}</title>
${links}
<link href="./style.css" rel="stylesheet"></link>
</head>
<body>
<div id="app"></div>
${scripts}
</body>
</html>`;
}
})],
···
build: {
target: "es2015",
lib: {
name: 'web-soar',
entry: 'src/main.tsx',
formats: ['umd'],
},
},
首先运行时,报错如下
plugin-legacy overrode 'build.target'. You should pass 'targets' as an option to this plugin with the list of legacy browsers
to support instead.
error during build:
Error: @vitejs/plugin-legacy does not support library mode
那先去掉 @vitejs/plugin-legacy
又报
51:
52: BrowserRouter.prototype.componentDidMount = function () {
53: process.env.NODE_ENV !== "production" ? warning(!this.props.history, "<BrowserRouter> ignores the history prop. To use a custom history, " + "use `import { Router }` instead of `import { BrowserRouter as Router }`.") : void 0;
^
54: };
55: }
error during build:
SyntaxError: Unexpected token (53:19)
网上也没找到相应的解决办法,所以换方案吧
三、vite-plugin-legacy-qiankun
如何让 vite 完美接入 qiankun - 掘金 (juejin.cn) 话不多说,试试先,改造代码
// main.tsx
import { createLifecyle, getMicroApp } from 'vite-plugin-legacy-qiankun'
const render = () => {
ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<App />
</React.StrictMode>
)
}
const microApp = getMicroApp(pkg.name)
if (microApp.__POWERED_BY_QIANKUN__) {
createLifecyle(pkg.name, {
mount(props) {
console.log('mount', pkg.name);
render();
},
bootstrap() {
console.log('bootstrap', pkg.name);
},
unmount() {
console.log('unmount', pkg.name)
}
})
} else {
render();
}
// vite.config.ts
import { legacyQiankun } from 'vite-plugin-legacy-qiankun'
...
plugins: [
react({ fastRefresh: false }),
legacy(),
legacyQiankun({ name: 'your micro app name' })
]
build 一切正常,但是浏览器报错
有一说一,看不懂,可能是我使用姿势不对,此时心态有点崩溃了
四、迁移回webpack
没办法,已经快周五了,找不到解决,只能从vite回到webpack,因为有现成的webpack子项目,模仿着改就行了,比较麻烦的点是,svg和img资源的引入吧,过程就不赘述了,方案可行的
五、心有不甘
确实喜欢vite开发,突然换有点不是滋味,还是在继续找解决办法,直到vite子应用接入微前端框架qiankun - 掘金 (juejin.cn) 先试着改造生产模式方案,确实可行,就不贴代码了。