-
-
Notifications
You must be signed in to change notification settings - Fork 857
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
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🤣 |
@@ -100,7 +101,7 @@ export function GlobalModeBuildPlugin(ctx: UnocssPluginContext<VitePluginConfig> | |||
const layer = resolveLayer(getPath(id)) | |||
if (layer) { | |||
vfsLayers.add(layer) | |||
return ` ${getLayerPlaceholder(layer)}` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@antfu hello, Could you explain to me why revert this line ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I add a head space because I found
unocss/packages/vite/src/modes/global/build.ts
Lines 270 to 276 in 22340d3
chunk.code = await replaceAsync(js, LAYER_PLACEHOLDER_RE, async (_, __, layer) => { | |
replaced = true | |
const css = getLayer(layer, js) | |
return css | |
.replace(/\n/g, '') | |
.replace(/(?<!\\)(['"])/g, '\\$1') | |
}) |
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
@@ -197,13 +216,16 @@ try { | |||
if (!import.meta.url.includes('?')) | |||
await new Promise(resolve => setTimeout(resolve, 100))` | |||
|
|||
// 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
reloadModule
exists on server, and fallback to custom logic when using with lower version - Move the calls outside of
.map
, using.forEach
or 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