@unocss/svelte-scoped 0.52.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/vite.mjs ADDED
@@ -0,0 +1,163 @@
1
+ import { createGenerator } from '@unocss/core';
2
+ import { loadConfig } from '@unocss/config';
3
+ import UnocssSveltePreprocess from './preprocess.mjs';
4
+ import { readFileSync, existsSync, statSync } from 'node:fs';
5
+ import { dirname, resolve } from 'node:path';
6
+ import { fileURLToPath } from 'node:url';
7
+ import '@unocss/preset-uno';
8
+ import 'magic-string';
9
+ import 'css-tree';
10
+
11
+ function PassPreprocessToSveltePlugin(options = {}, ctx) {
12
+ return {
13
+ name: "unocss:svelte-scoped:pass-preprocess",
14
+ enforce: "pre",
15
+ configResolved(viteConfig) {
16
+ options = { ...options, combine: viteConfig.command === "build" };
17
+ },
18
+ api: {
19
+ sveltePreprocess: UnocssSveltePreprocess(options, ctx)
20
+ }
21
+ };
22
+ }
23
+
24
+ const PLACEHOLDER_USER_SETS_IN_INDEX_HTML = "%unocss-svelte-scoped.global%";
25
+ const GLOBAL_STYLES_PLACEHOLDER = "unocss_svelte_scoped_global_styles";
26
+ const DEV_GLOBAL_STYLES_DATA_TITLE = "unocss-svelte-scoped global styles";
27
+
28
+ const _dirname = typeof __dirname !== "undefined" ? __dirname : dirname(fileURLToPath(import.meta.url));
29
+ function getReset(injectReset) {
30
+ if (injectReset.startsWith("@unocss/reset")) {
31
+ const resolvedPNPM = resolve(resolve(_dirname, `../node_modules/${injectReset}`));
32
+ if (isFile(resolvedPNPM))
33
+ return readFileSync(resolvedPNPM, "utf-8");
34
+ const resolvedNPM = resolve(process.cwd(), "node_modules", injectReset);
35
+ if (isFile(resolvedNPM))
36
+ return readFileSync(resolvedNPM, "utf-8");
37
+ throw new Error(`"${injectReset}" given as your injectReset value is not found. Please make sure it is one of the five supported @unocss/reset options. If it is, file a bug report detailing your environment and package manager`);
38
+ }
39
+ if (injectReset.startsWith(".")) {
40
+ const resolved = resolve(process.cwd(), injectReset);
41
+ if (!isFile(resolved))
42
+ throw new Error(`"${injectReset}" given as your injectReset value is not a valid file path relative to the root of your project, where your vite config file sits. To give an example, if you placed a reset.css in your src directory, "./src/reset.css" would work.`);
43
+ return readFileSync(resolved, "utf-8");
44
+ }
45
+ if (injectReset.startsWith("/"))
46
+ throw new Error(`Your injectReset value: "${injectReset}" is not a valid file path. To give an example, if you placed a reset.css in your src directory, "./src/reset.css" would work.`);
47
+ const resolvedFromNodeModules = resolve(process.cwd(), "node_modules", injectReset);
48
+ if (!isFile(resolvedFromNodeModules))
49
+ throw new Error(`"${injectReset}" given as your injectReset value is not a valid file path relative to your project's node_modules folder. Can you confirm that you've installed "${injectReset}"?`);
50
+ return readFileSync(resolvedFromNodeModules, "utf-8");
51
+ }
52
+ function isFile(path) {
53
+ return existsSync(path) && statSync(path).isFile();
54
+ }
55
+
56
+ function isServerHooksFile(path) {
57
+ return path.includes("hooks") && path.includes("server");
58
+ }
59
+ function replaceGlobalStylesPlaceholder(code, stylesTag) {
60
+ const captureQuoteMark = "([\"'`])";
61
+ const matchCapturedQuoteMark = "\\1";
62
+ const QUOTES_WITH_PLACEHOLDER_RE = new RegExp(captureQuoteMark + GLOBAL_STYLES_PLACEHOLDER + matchCapturedQuoteMark);
63
+ const escapedStylesTag = stylesTag.replaceAll(/`/g, "\\`");
64
+ return code.replace(QUOTES_WITH_PLACEHOLDER_RE, `\`${escapedStylesTag}\``);
65
+ }
66
+ async function generateGlobalCss(uno, injectReset) {
67
+ const { css } = await uno.generate("", { preflights: true, safelist: true, minify: true });
68
+ const reset = injectReset ? getReset(injectReset) : "";
69
+ return reset + css;
70
+ }
71
+ const SVELTE_ERROR = `[unocss] You have not setup the svelte-scoped global styles correctly. You must place '${PLACEHOLDER_USER_SETS_IN_INDEX_HTML}' in your index.html file.
72
+ `;
73
+ const SVELTE_KIT_ERROR = `[unocss] You have not setup the svelte-scoped global styles correctly. You must place '${PLACEHOLDER_USER_SETS_IN_INDEX_HTML}' in your app.html file. You also need to have a transformPageChunk hook in your server hooks file with: \`html.replace('${PLACEHOLDER_USER_SETS_IN_INDEX_HTML}', '${GLOBAL_STYLES_PLACEHOLDER}')\`. You can see an example of the usage at https://github.com/unocss/unocss/tree/main/examples/sveltekit-scoped.`;
74
+ function checkTransformPageChunkHook(server, isSvelteKit) {
75
+ server.middlewares.use((req, res, next) => {
76
+ const originalWrite = res.write;
77
+ res.write = function(chunk, ...rest) {
78
+ const str = chunk instanceof Buffer ? chunk.toString() : Array.isArray(chunk) || "at" in chunk ? Buffer.from(chunk).toString() : `${chunk}`;
79
+ if (str.includes("<head>") && !str.includes(DEV_GLOBAL_STYLES_DATA_TITLE))
80
+ server.config.logger.error(isSvelteKit ? SVELTE_KIT_ERROR : SVELTE_ERROR, { timestamp: true });
81
+ return originalWrite.call(this, chunk, ...rest);
82
+ };
83
+ next();
84
+ });
85
+ }
86
+
87
+ function GlobalStylesPlugin({ ready, uno }, injectReset) {
88
+ let isSvelteKit;
89
+ let viteConfig;
90
+ let unoCssFileReferenceId;
91
+ let unoCssHashedLinkTag;
92
+ return {
93
+ name: "unocss:svelte-scoped:global-styles",
94
+ async configResolved(_viteConfig) {
95
+ viteConfig = _viteConfig;
96
+ await ready;
97
+ isSvelteKit = viteConfig.plugins.some((p) => p.name.includes("sveltekit"));
98
+ },
99
+ configureServer: (server) => checkTransformPageChunkHook(server, isSvelteKit),
100
+ async transform(code, id) {
101
+ if (isSvelteKit && viteConfig.command === "serve" && isServerHooksFile(id)) {
102
+ const css = await generateGlobalCss(uno, injectReset);
103
+ return {
104
+ code: replaceGlobalStylesPlaceholder(code, `<style type="text/css" data-title="${DEV_GLOBAL_STYLES_DATA_TITLE}">${css}</style>`)
105
+ };
106
+ }
107
+ },
108
+ async buildStart() {
109
+ if (viteConfig.command === "build") {
110
+ const css = await generateGlobalCss(uno, injectReset);
111
+ unoCssFileReferenceId = this.emitFile({
112
+ type: "asset",
113
+ name: "unocss-svelte-scoped-global.css",
114
+ source: css
115
+ });
116
+ }
117
+ },
118
+ renderStart() {
119
+ const unoCssFileName = this.getFileName(unoCssFileReferenceId);
120
+ const base = viteConfig.base ?? "/";
121
+ unoCssHashedLinkTag = `<link href="${base}${unoCssFileName}" rel="stylesheet" />`;
122
+ },
123
+ renderChunk(code, chunk) {
124
+ if (isSvelteKit && chunk.moduleIds.some((id) => isServerHooksFile(id)))
125
+ return replaceGlobalStylesPlaceholder(code, unoCssHashedLinkTag);
126
+ },
127
+ async transformIndexHtml(html) {
128
+ if (!isSvelteKit) {
129
+ if (viteConfig.command === "build")
130
+ return html.replace(PLACEHOLDER_USER_SETS_IN_INDEX_HTML, unoCssHashedLinkTag);
131
+ if (viteConfig.command === "serve") {
132
+ const css = await generateGlobalCss(uno, injectReset);
133
+ return html.replace(PLACEHOLDER_USER_SETS_IN_INDEX_HTML, `<style type="text/css" data-title="${DEV_GLOBAL_STYLES_DATA_TITLE}">${css}</style>`);
134
+ }
135
+ }
136
+ }
137
+ };
138
+ }
139
+
140
+ function UnocssSvelteScopedVite(options = {}) {
141
+ const context = createSvelteScopedContext(options.configOrPath);
142
+ const plugins = [
143
+ GlobalStylesPlugin(context, options.injectReset)
144
+ ];
145
+ if (!options.onlyGlobal)
146
+ plugins.push(PassPreprocessToSveltePlugin(options, context));
147
+ return plugins;
148
+ }
149
+ function createSvelteScopedContext(configOrPath) {
150
+ const uno = createGenerator();
151
+ const ready = reloadConfig();
152
+ async function reloadConfig() {
153
+ const { config } = await loadConfig(process.cwd(), configOrPath);
154
+ uno.setConfig(config);
155
+ return config;
156
+ }
157
+ return {
158
+ uno,
159
+ ready
160
+ };
161
+ }
162
+
163
+ export { UnocssSvelteScopedVite as default };
package/package.json ADDED
@@ -0,0 +1,69 @@
1
+ {
2
+ "name": "@unocss/svelte-scoped",
3
+ "type": "module",
4
+ "version": "0.52.0",
5
+ "description": "Use UnoCSS in a modular fashion with styles being stored only in the Svelte component they are used in: Vite plugin for apps, preprocessor for component libraries",
6
+ "author": "Jacob Bowdoin",
7
+ "license": "MIT",
8
+ "homepage": "https://github.com/unocss/unocss/tree/main/packages/svelte-scoped#readme",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/unocss/unocss.git",
12
+ "directory": "packages/svelte-scoped"
13
+ },
14
+ "bugs": {
15
+ "url": "https://github.com/unocss/unocss/issues"
16
+ },
17
+ "keywords": [
18
+ "sveltekit",
19
+ "svelte",
20
+ "unocss",
21
+ "utility-styles",
22
+ "component-scoped",
23
+ "component-library"
24
+ ],
25
+ "sideEffects": false,
26
+ "exports": {
27
+ "./preprocess": {
28
+ "types": "./dist/preprocess.d.ts",
29
+ "require": "./dist/preprocess.cjs",
30
+ "import": "./dist/preprocess.mjs"
31
+ },
32
+ "./vite": {
33
+ "types": "./dist/vite.d.ts",
34
+ "require": "./dist/vite.cjs",
35
+ "import": "./dist/vite.mjs"
36
+ }
37
+ },
38
+ "main": "./dist/vite.cjs",
39
+ "module": "./dist/vite.mjs",
40
+ "types": "./dist/vite.d.ts",
41
+ "typesVersions": {
42
+ ">4.0": {
43
+ "preprocess": [
44
+ "./dist/preprocess.d.ts"
45
+ ],
46
+ "vite": [
47
+ "./dist/vite.d.ts"
48
+ ]
49
+ }
50
+ },
51
+ "files": [
52
+ "dist"
53
+ ],
54
+ "dependencies": {
55
+ "css-tree": "^2.3.1",
56
+ "magic-string": "^0.30.0",
57
+ "@unocss/config": "0.52.0",
58
+ "@unocss/reset": "0.52.0"
59
+ },
60
+ "devDependencies": {
61
+ "prettier-plugin-svelte": "^2.10.0",
62
+ "svelte": "^3.58.0"
63
+ },
64
+ "scripts": {
65
+ "build": "unbuild",
66
+ "stub": "unbuild --stub",
67
+ "bench": "vitest bench"
68
+ }
69
+ }