asma-qiankun-plugin-vite
Version:
vite for qiankun with some adjustments for hmr
153 lines (150 loc) • 6.42 kB
JavaScript
/*!
* asma-qiankun-plugin-vite.js v0.2.3
* (c) 2022-2023 IE
* Released under the MIT License.
* Inspired by vite-plugin-qiankun (https://github.com/tengmaoqing/vite-plugin-qiankun).
*/
import { load } from 'cheerio';
const createQiankunHelper = (qiankunName) => `
const createDeffer = (hookName) => {
const d = new Promise((resolve, reject) => {
window.proxy && (window.proxy[\`vite\${hookName}\`] = resolve)
})
return props => d.then(fn => fn(props));
}
const bootstrap = createDeffer('bootstrap');
const mount = createDeffer('mount');
const unmount = createDeffer('unmount');
const update = createDeffer('update');
;(global => {
global.qiankunName = '${qiankunName}';
global['${qiankunName}'] = {
bootstrap,
mount,
unmount,
update
};
})(window);
`;
/* const _replaceSomeScript = ($: CheerioAPI, findStr: string, replaceStr = '') => {
$('script').each((i, el) => {
if ($(el).html()?.includes(findStr)) {
$(el).html(replaceStr)
}
})
} */
const createImportFinallyResolve = (qiankunName) => {
return `
const global_concurrent_qiankun = window.proxy?.__GLOBAL_CONCURRENT_QIANKUN__?.['${qiankunName}']
if(global_concurrent_qiankun){
window.proxy = global_concurrent_qiankun
}
const qiankunLifeCycle = window.moduleQiankunAppLifeCycles && window.moduleQiankunAppLifeCycles['${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));
}
`;
};
const createImport = (src, callback) => {
const appendBase = "(window.proxy ? (window.proxy?.__INJECTED_PUBLIC_PATH_BY_QIANKUN__ + '..') : '') + ";
return `import(${appendBase}'${src}').then(${callback})`;
};
const createEntry = (entryScript) => `
let RefreshRuntime;
window.$RefreshReg$ = () => {};
window.$RefreshSig$ = () => (type) => type;
window.__vite_plugin_react_preamble_installed__ = true;
${createImport('/@react-refresh', `(module) => {
RefreshRuntime=module.default
RefreshRuntime.injectIntoGlobalHook(window)
${entryScript}
}
`)}`;
const qiankun = (qiankunName, microOption = {}) => {
let isProduction;
let base = '';
const module2DynamicImport = ($, scriptTag) => {
if (!scriptTag) {
return;
}
const script$ = $(scriptTag);
const moduleSrc = script$.attr('src');
let appendBase = '';
if (microOption.useDevMode && !isProduction) {
appendBase = "(window.proxy ? (window.proxy?.__INJECTED_PUBLIC_PATH_BY_QIANKUN__ + '..') : '') + ";
}
script$.removeAttr('src');
script$.removeAttr('type');
script$.html(`import(${appendBase}'${moduleSrc}')`);
return script$;
};
return {
name: 'qiankun-html-transform',
configResolved(config) {
isProduction = config.command === 'build' || config.isProduction;
base = config.base;
},
configureServer(server) {
return () => {
server.middlewares.use((_req, res, next) => {
if (isProduction || !microOption.useDevMode) {
next();
return;
}
const end = res.end.bind(res);
res.end = (...args) => {
let [htmlStr] = args;
const [_, ...rest] = args;
if (typeof htmlStr === 'string') {
const $ = load(htmlStr);
//const $ = load(htmlStr)
module2DynamicImport($, $(`script[src=${base}@vite/client]`).get(0));
//module2DynamicImport($, $('script[src=/@vite/client]').get(0))
const reactRefreshScript = $('script[type=module]');
//const reactRefreshScriptStr = reactRefreshScript.toString()
// console.log('==============reactRefreshScriptStr===============')
//console.log(reactRefreshScriptStr)
// console.log('==============reactRefreshScriptStr===============')
reactRefreshScript.removeAttr('type').empty();
const entryScript = $('#entry');
entryScript.html(createEntry(entryScript.html()));
// console.log('==============entryScript===============')
// console.log(entryScript.html())
// console.log('==============entryScript===============')
htmlStr = $.html();
// console.log('==============start===============')
//console.log(htmlStr)
// console.log('================end===============')
//htmlStr = $.html()
}
return end(htmlStr, ...rest);
};
next();
});
};
},
transformIndexHtml(html) {
const $ = load(html);
const moduleTags = $('body script[type=module], head script[crossorigin=""]');
if (!moduleTags || !moduleTags.length) {
return;
}
const len = moduleTags.length;
moduleTags.each((i, moduleTag) => {
const script$ = module2DynamicImport($, moduleTag);
if (len - 1 === i) {
script$ === null || script$ === void 0 ? void 0 : script$.html(`${script$.html()}.finally(() => {
${createImportFinallyResolve(qiankunName)}
})`);
}
});
$('body').append(`<script>${createQiankunHelper(qiankunName)}</script>`);
const output = $.html();
return output;
},
};
};
export { qiankun };