vite-plugin-shopify-theme-islands 0.3.0 → 0.4.1
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/README.md +5 -0
- package/dist/__tests__/plugin.test.d.ts +1 -0
- package/dist/__tests__/runtime.test.d.ts +1 -0
- package/dist/__tests__/setup-dom.d.ts +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +34 -7
- package/dist/runtime.js +5 -1
- package/package.json +11 -3
- package/revive.d.ts +1 -1
package/README.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# vite-plugin-shopify-theme-islands
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/vite-plugin-shopify-theme-islands)
|
|
4
|
+
[](https://www.npmjs.com/package/vite-plugin-shopify-theme-islands)
|
|
5
|
+
[](./LICENSE)
|
|
6
|
+
|
|
3
7
|
Island architecture for Shopify themes. Lazily hydrate custom elements using loading directives — only load the JavaScript when it's actually needed.
|
|
4
8
|
|
|
5
9
|
## Installation
|
|
@@ -146,6 +150,7 @@ Directives can be combined — the element will wait for all conditions to be me
|
|
|
146
150
|
| `directiveVisible` | `string` | `'client:visible'` | Attribute name for the visible directive |
|
|
147
151
|
| `directiveMedia` | `string` | `'client:media'` | Attribute name for the media directive |
|
|
148
152
|
| `directiveIdle` | `string` | `'client:idle'` | Attribute name for the idle directive |
|
|
153
|
+
| `debug` | `boolean` | `false` | Log discovered islands and active directives at startup |
|
|
149
154
|
|
|
150
155
|
### Multiple island directories
|
|
151
156
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/index.d.ts
CHANGED
|
@@ -8,5 +8,7 @@ export interface ShopifyThemeIslandsOptions {
|
|
|
8
8
|
directiveMedia?: string;
|
|
9
9
|
/** Attribute for "load when idle". Default: `'client:idle'` */
|
|
10
10
|
directiveIdle?: string;
|
|
11
|
+
/** Log discovered islands and generated virtual module. Default: `false` */
|
|
12
|
+
debug?: boolean;
|
|
11
13
|
}
|
|
12
14
|
export default function shopifyThemeIslands(options?: ShopifyThemeIslandsOptions): Plugin;
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
2
|
import { readFileSync, readdirSync } from "node:fs";
|
|
3
3
|
import { join, relative } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
4
5
|
var VIRTUAL_ID = "vite-plugin-shopify-theme-islands/revive";
|
|
5
6
|
var RESOLVED_ID = "\x00" + VIRTUAL_ID;
|
|
6
7
|
var ISLAND_ID = "vite-plugin-shopify-theme-islands/island";
|
|
7
|
-
var runtimePath = new URL("./runtime.js", import.meta.url)
|
|
8
|
-
var islandPath = new URL("./island.js", import.meta.url)
|
|
8
|
+
var runtimePath = fileURLToPath(new URL("./runtime.js", import.meta.url));
|
|
9
|
+
var islandPath = fileURLToPath(new URL("./island.js", import.meta.url));
|
|
9
10
|
var ISLAND_IMPORT_RE = /from\s+['"]vite-plugin-shopify-theme-islands\/island['"]/;
|
|
10
11
|
var TS_JS_RE = /\.(ts|js)$/;
|
|
11
12
|
var defaults = {
|
|
@@ -56,10 +57,19 @@ function shopifyThemeIslands(options = {}) {
|
|
|
56
57
|
const directiveVisible = options.directiveVisible ?? defaults.directiveVisible;
|
|
57
58
|
const directiveMedia = options.directiveMedia ?? defaults.directiveMedia;
|
|
58
59
|
const directiveIdle = options.directiveIdle ?? defaults.directiveIdle;
|
|
60
|
+
const debug = options.debug ?? false;
|
|
61
|
+
const log = (...args) => {
|
|
62
|
+
if (debug)
|
|
63
|
+
console.log("[islands]", ...args);
|
|
64
|
+
};
|
|
59
65
|
let resolvedDirs = rawDirs;
|
|
60
66
|
let root = process.cwd();
|
|
61
67
|
const islandFiles = new Set;
|
|
62
68
|
let scanned = false;
|
|
69
|
+
const inDirectory = (file) => resolvedDirs.some((dir) => {
|
|
70
|
+
const absDir = dir.startsWith(root) ? dir : join(root, dir.replace(/^\//, ""));
|
|
71
|
+
return file.startsWith(absDir);
|
|
72
|
+
});
|
|
63
73
|
return {
|
|
64
74
|
name: "vite-plugin-shopify-theme-islands",
|
|
65
75
|
enforce: "pre",
|
|
@@ -72,28 +82,45 @@ function shopifyThemeIslands(options = {}) {
|
|
|
72
82
|
return;
|
|
73
83
|
scanned = true;
|
|
74
84
|
scanForIslandFiles(root, islandFiles);
|
|
85
|
+
for (const f of islandFiles)
|
|
86
|
+
if (inDirectory(f))
|
|
87
|
+
islandFiles.delete(f);
|
|
88
|
+
if (debug) {
|
|
89
|
+
log("Scanning directories:", resolvedDirs.map((d) => d + "**/*.{ts,js}").join(", "));
|
|
90
|
+
log("Directives:", { visible: directiveVisible, media: directiveMedia, idle: directiveIdle });
|
|
91
|
+
if (islandFiles.size) {
|
|
92
|
+
log(`Found ${islandFiles.size} island file(s) via mixin import:`);
|
|
93
|
+
for (const f of islandFiles)
|
|
94
|
+
log(" ", relative(root, f));
|
|
95
|
+
}
|
|
96
|
+
}
|
|
75
97
|
},
|
|
76
98
|
transform(code, id) {
|
|
77
99
|
if (!id.endsWith(".ts") && !id.endsWith(".js"))
|
|
78
100
|
return;
|
|
79
|
-
if (code.includes("shopify-theme-islands/island") && ISLAND_IMPORT_RE.test(code)) {
|
|
101
|
+
if (code.includes("shopify-theme-islands/island") && ISLAND_IMPORT_RE.test(code) && !inDirectory(id)) {
|
|
80
102
|
islandFiles.add(id);
|
|
103
|
+
log("Detected island:", relative(root, id));
|
|
81
104
|
} else {
|
|
82
|
-
islandFiles.delete(id)
|
|
105
|
+
if (islandFiles.delete(id))
|
|
106
|
+
log("Removed island:", relative(root, id));
|
|
83
107
|
}
|
|
84
108
|
},
|
|
85
109
|
watchChange(id, { event }) {
|
|
86
110
|
if (!TS_JS_RE.test(id))
|
|
87
111
|
return;
|
|
88
112
|
if (event === "delete") {
|
|
89
|
-
islandFiles.delete(id)
|
|
113
|
+
if (islandFiles.delete(id))
|
|
114
|
+
log("Removed island (deleted):", relative(root, id));
|
|
90
115
|
} else {
|
|
91
116
|
try {
|
|
92
117
|
const content = readFileSync(id, "utf-8");
|
|
93
|
-
if (ISLAND_IMPORT_RE.test(content)) {
|
|
118
|
+
if (ISLAND_IMPORT_RE.test(content) && !inDirectory(id)) {
|
|
94
119
|
islandFiles.add(id);
|
|
120
|
+
log("Detected island (watchChange):", relative(root, id));
|
|
95
121
|
} else {
|
|
96
|
-
islandFiles.delete(id)
|
|
122
|
+
if (islandFiles.delete(id))
|
|
123
|
+
log("Removed island (watchChange):", relative(root, id));
|
|
97
124
|
}
|
|
98
125
|
} catch {}
|
|
99
126
|
}
|
package/dist/runtime.js
CHANGED
|
@@ -37,7 +37,11 @@ function revive(islands, options) {
|
|
|
37
37
|
const islandMap = new Map;
|
|
38
38
|
for (const [key, loader] of Object.entries(islands)) {
|
|
39
39
|
const tagName = key.split("/").pop().replace(/\.(ts|js)$/, "");
|
|
40
|
-
if (tagName.includes("-")
|
|
40
|
+
if (!tagName.includes("-")) {
|
|
41
|
+
console.warn(`[islands] Skipping "${key.split("/").pop()}" — filename must contain a hyphen to match a valid custom element tag name (e.g. rename to "${tagName}-island.ts")`);
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
if (!islandMap.has(tagName))
|
|
41
45
|
islandMap.set(tagName, loader);
|
|
42
46
|
}
|
|
43
47
|
const queued = new Set;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vite-plugin-shopify-theme-islands",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "Vite plugin for island architecture in Shopify themes",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"packageManager": "bun@1.3.10",
|
|
@@ -23,7 +23,9 @@
|
|
|
23
23
|
"dist",
|
|
24
24
|
"revive.d.ts"
|
|
25
25
|
],
|
|
26
|
-
"sideEffects":
|
|
26
|
+
"sideEffects": [
|
|
27
|
+
"./dist/runtime.js"
|
|
28
|
+
],
|
|
27
29
|
"keywords": [
|
|
28
30
|
"vite",
|
|
29
31
|
"shopify",
|
|
@@ -52,12 +54,18 @@
|
|
|
52
54
|
"build:types": "tsc --declaration --emitDeclarationOnly --outDir dist",
|
|
53
55
|
"build": "rm -rf dist && bun run build:js && bun run build:types",
|
|
54
56
|
"check": "tsc --noEmit",
|
|
55
|
-
"prepublishOnly": "bun run build"
|
|
57
|
+
"prepublishOnly": "bun run build",
|
|
58
|
+
"test:plugin": "bun test src/__tests__/plugin.test.ts",
|
|
59
|
+
"test:runtime": "bun test ./src/__tests__/runtime.test.ts",
|
|
60
|
+
"test": "bun test",
|
|
61
|
+
"test:watch": "bun test --watch"
|
|
56
62
|
},
|
|
57
63
|
"peerDependencies": {
|
|
58
64
|
"vite": ">=6"
|
|
59
65
|
},
|
|
60
66
|
"devDependencies": {
|
|
67
|
+
"@happy-dom/global-registrator": "^20.8.3",
|
|
68
|
+
"@types/bun": "latest",
|
|
61
69
|
"@types/node": "^25.3.3",
|
|
62
70
|
"typescript": "^5.0.0",
|
|
63
71
|
"vite": "^6.0.0"
|
package/revive.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
declare module "vite-plugin-shopify-theme-islands/revive" {}
|