feat(global): support vite inline import#2570
Conversation
✅ Deploy Preview for unocss ready!
To edit notification comments on pull requests, go to your Netlify site settings. |
|
#2419 may relate to this, maybe BTW, we are streaming chat for review your pr🤣 |
| const layer = resolveLayer(getPath(id)) | ||
| if (layer) { | ||
| vfsLayers.add(layer) | ||
| return ` ${getLayerPlaceholder(layer)}` |
There was a problem hiding this comment.
@antfu hello, Could you explain to me why revert this line ?
There was a problem hiding this comment.
I add a head space because I found
unocss/packages/vite/src/modes/global/build.ts
Lines 270 to 276 in 22340d3
will replace
const xxx = ("#--unocss--{layer:__ALL__} balaba")to
const xxx = ( *,::before balabal")more about it can see lisonge/vite-plugin-monkey#45 (comment)
There was a problem hiding this comment.
I was about to ask why a space it added - I think adding a space is not the correct solution. Instead we should fix it in replacing.
|
|
||
| // Reload full page when using `?inline` - any better solution? | ||
| if (isInlineCssMod) | ||
| hmr += '\nimport.meta.hot.accept(() => location.reload())\n' |
There was a problem hiding this comment.
import unocssText from 'virtual:uno.css?inline';
const unocssStyle = document.createElement('style');
unocssStyle.dataset.source = 'unocss'
unocssStyle.textContent = unocssText;
export default unocssStyle;
if (import.meta.hot) {
import.meta.hot.accept('/__uno.css?inline', (newModule) => {
const text2 = newModule?.default as string;
unocssStyle.textContent = text2 ?? ``;
});
}hmr not working, it will always reload page,
What is the disadvantage of server.reloadModule ?
There was a problem hiding this comment.
reloadModule is a very new API and does not available in all Vite versions. + we should avoid making side-effects inside .map whenever possible. If it's necessary, we should
- Check if
reloadModuleexists on server, and fallback to custom logic when using with lower version - Move the calls outside of
.map, using.forEachor others.
I actually found either solution works for HMR. Did you manually write the HMR handling?
|
I think the solution is incomplete, and I need to find another time to do a full revisit. Marked as a draft for now. Feel free to push any changes you think making sense. |
|
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
|
A simple way to customize unocss global style side effect it work well with hmr and shadow-dom Although there may be defects, it meets my needs import { build } from '@unocss/cli';
import fs from 'node:fs/promises';
import unocss from 'unocss/vite';
import type { ConfigEnv, Plugin } from 'vite';
const iframeTemplate = /* html */ `
<script type="module">
// base must be '/'
import '/@vite/client';
import '/__uno.css';
const unoStyle = document.querySelector(
'head style[data-vite-dev-id="/__uno.css"]',
);
const update = ()=>{
parent.postMessage(
{
type: '__unocss_update',
textContent: unoStyle?.textContent,
},
'*',
);
}
if (window != parent) {
update();
new MutationObserver(update).observe(unoStyle, {
childList: true,
attributes: true,
});
}
</script>
`.trim();
const moduleTemplate = /* js */ `
const style = document.createElement('style');
style.textContent = __UNOCSS_TEXT__;
export default style;
if (import.meta.env.DEV) {
const origin = new URL(import.meta.url).origin;
window.addEventListener('message', (event) => {
const data = event.data || {};
if (data.type == '__unocss_update') {
style.textContent = data.textContent;
}
});
const iframe = document.createElement('iframe');
iframe.src = origin + '/__unocss_iframe';
iframe.style.display = 'none';
document.head.append(iframe);
}
`.trim();
export const unocssStyle = async (env: ConfigEnv): Promise<Plugin[]> => {
const dev = env.command == 'serve';
const unocss_text = await (async () => {
if (!dev) {
// or use createGenerator({},{}).generate(code)
await build({
cwd: process.cwd(),
config: './unocss.config.ts',
patterns: ['./src/**/*.{js,mjs,ts,jsx,tsx,vue,svelte}'],
stdout: false,
minify: true,
outFile: './uno-prebuilt.css',
});
const text = (await fs.readFile('./uno-prebuilt.css', 'utf-8')).trim();
await fs.unlink('./uno-prebuilt.css');
return text;
} else {
return '';
}
})();
return [
{
name: 'unocss:style',
resolveId(source) {
if (source == `unocss?style`) return `__unocss_style`;
},
async load(id) {
if (id == `__unocss_style`) {
return moduleTemplate.replace(
'__UNOCSS_TEXT__',
JSON.stringify(unocss_text),
);
}
},
configureServer(server) {
server.middlewares.use(async (req, res, next) => {
if (req.url?.startsWith(`/__unocss_iframe`)) {
res.setHeader('content-type', 'text/html');
res.end(iframeTemplate);
return;
}
next();
});
},
},
...(dev ? unocss() : []),
];
};// main.tsx
import { render, Portal } from 'solid-js/web';
import style from 'unocss?style';
import App from './App';
render(
() => (
<Portal useShadow>
<App />
{style}
</Portal>
),
(() => {
const div = document.createElement('div');
document.body.append(div);
return div;
})(),
); |
|
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
|
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |


fix #2533
because of vitejs/vite#12912, the HMR of the virtual module is unavailable by default at the moment
Before it is fixed, it is also working by
/__uno.css?inline