-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat:
sharedDuringBuild
unocss plugin (#57)
- Loading branch information
Showing
13 changed files
with
843 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -35,4 +35,5 @@ pnpm cf-release | |
- [x] css | ||
- [x] client | ||
- [x] server | ||
- [x] unocss | ||
- [ ] code split |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
import { debounce, objectHas, tinyassert } from "@hiogawa/utils"; | ||
import vitePluginUnocss, { type UnocssVitePluginAPI } from "@unocss/vite"; | ||
import { DevEnvironment, type Plugin } from "vite"; | ||
import { invalidateModule } from "../style/plugin"; | ||
import { createVirtualPlugin } from "../utils/plugin"; | ||
|
||
// cf. | ||
// https://github.com/unocss/unocss/tree/47eafba27619ed26579df60fe3fdeb6122b5093c/packages/vite/src/modes/global | ||
// https://github.com/tailwindlabs/tailwindcss/blob/719c0d488378002ff752e8dc7199c843930bb296/packages/%40tailwindcss-vite/src/index.ts | ||
|
||
// TODO: | ||
// - content hash not changing? | ||
// - unocss transform plugin? | ||
// - non global mode? | ||
// - source map? | ||
|
||
export function vitePluginSharedUnocss(): Plugin { | ||
const ctx = getUnocssContext(); | ||
|
||
return { | ||
name: vitePluginSharedUnocss.name, | ||
sharedDuringBuild: true, | ||
create(environment) { | ||
const plugins: Plugin[] = []; | ||
|
||
// [dev, build] | ||
// extract tokens by intercepting transform | ||
plugins.push({ | ||
name: vitePluginSharedUnocss.name + ":extract", | ||
transform(code, id) { | ||
if (ctx.filter(code, id)) { | ||
ctx.extract(code, id); | ||
} | ||
}, | ||
}); | ||
|
||
// Following plugins are naturally applied to the environments | ||
// which import "virtual:unocss.css". | ||
// So, even though we only need to handle "client" environment case, | ||
// such artificial restriction is not necessary. | ||
|
||
// [dev] | ||
if (environment.mode === "dev") { | ||
// transform virtual module directly | ||
plugins.push( | ||
createVirtualPlugin("unocss.css", async () => { | ||
await ctx.flushTasks(); | ||
const result = await ctx.uno.generate(ctx.tokens); | ||
return result.css; | ||
}), | ||
); | ||
|
||
// HMR | ||
function hotUpdate() { | ||
tinyassert(environment instanceof DevEnvironment); | ||
const mod = invalidateModule(environment, "\0virtual:unocss.css"); | ||
if (mod) { | ||
environment.hot.send({ | ||
type: "update", | ||
updates: [ | ||
{ | ||
type: `${mod.type}-update`, | ||
path: "/@id/__x00__virtual:unocss.css", | ||
acceptedPath: "/@id/__x00__virtual:unocss.css", | ||
timestamp: Date.now(), | ||
}, | ||
], | ||
}); | ||
} | ||
} | ||
const debounced = debounce(() => hotUpdate(), 50); | ||
ctx.onInvalidate(debounced); | ||
ctx.onReload(debounced); | ||
} | ||
|
||
// [build] | ||
// transform virtual module during renderChunk | ||
if (environment.mode === "build") { | ||
const cssPlugins = environment.config.plugins.filter( | ||
(p) => p.name === "vite:css" || p.name === "vite:css-post", | ||
); | ||
|
||
plugins.push( | ||
createVirtualPlugin("unocss.css", () => "/*** tmp unocss ***/"), | ||
{ | ||
name: vitePluginSharedUnocss.name + ":render", | ||
async renderChunk(_code, chunk, _options) { | ||
if (chunk.moduleIds.includes("\0virtual:unocss.css")) { | ||
await ctx.flushTasks(); | ||
let { css } = await ctx.uno.generate(ctx.tokens); | ||
// [feedback] environment in renderChunk context? | ||
const pluginCtx = { ...this, environment }; | ||
for (const plugin of cssPlugins) { | ||
tinyassert(typeof plugin.transform === "function"); | ||
const result = await plugin.transform.apply( | ||
pluginCtx as any, | ||
[css, "\0virtual:unocss.css"], | ||
); | ||
tinyassert( | ||
objectHas(result, "code") && | ||
typeof result.code === "string", | ||
); | ||
css = result.code; | ||
} | ||
} | ||
}, | ||
}, | ||
); | ||
} | ||
|
||
return plugins; | ||
}, | ||
}; | ||
} | ||
|
||
// grab internal unocss instance | ||
function getUnocssContext() { | ||
const plugins = vitePluginUnocss(); | ||
const plugin = plugins.find((p) => p.name === "unocss:api"); | ||
tinyassert(plugin); | ||
return (plugin.api as UnocssVitePluginAPI).getContext(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import { defineConfig, presetUno } from "unocss"; | ||
|
||
export default defineConfig({ | ||
presets: [presetUno()], | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.