@allior/wmake-cli 0.0.4 → 0.0.6
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/index.d.ts +0 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -4
- package/dist/vite-config.d.ts +16 -21
- package/dist/vite-config.d.ts.map +1 -1
- package/dist/vite-config.js +129 -119
- package/dist/widget.d.ts.map +1 -1
- package/dist/widget.js +38 -1
- package/package.json +6 -1
- package/src/vite-config.ts +142 -127
- package/src/widget.ts +41 -4
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Библиотека экспортов для использования в других пакетах (например, в Vite конфигах).
|
|
3
|
-
* ВАЖНО: Не запускает CLI автоматически при импорте.
|
|
4
|
-
*/
|
|
5
1
|
export * from "./vite-config.js";
|
|
6
2
|
export { buildWidget } from "./widget.js";
|
|
7
3
|
export { runGenerateFields } from "./generate-fields.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Библиотека экспортов для использования в других пакетах (например, в Vite конфигах).
|
|
3
|
-
* ВАЖНО: Не запускает CLI автоматически при импорте.
|
|
4
|
-
*/
|
|
5
1
|
export * from "./vite-config.js";
|
|
6
2
|
export { buildWidget } from "./widget.js";
|
|
7
3
|
export { runGenerateFields } from "./generate-fields.js";
|
package/dist/vite-config.d.ts
CHANGED
|
@@ -1,22 +1,17 @@
|
|
|
1
|
-
import { PluginOption } from "vite";
|
|
2
|
-
|
|
3
|
-
export declare
|
|
4
|
-
|
|
5
|
-
export declare
|
|
6
|
-
|
|
7
|
-
export declare function
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
"@allior/wmake-streamelements": string;
|
|
18
|
-
};
|
|
19
|
-
export declare function getWmakeOptimizeDeps(): {
|
|
20
|
-
include: string[];
|
|
21
|
-
};
|
|
1
|
+
import type { PluginOption } from "vite";
|
|
2
|
+
/** Генерирует карту глобалов для Rollup. Используем чистые имена. */
|
|
3
|
+
export declare function getWmakeGlobals(cwd?: string): Record<string, string>;
|
|
4
|
+
/** Вспомогательная функция для получения ЧИСТЫХ имен глобалов (без window.) для проверок */
|
|
5
|
+
export declare function getRawWmakeGlobals(cwd?: string): Record<string, string>;
|
|
6
|
+
/** Получает Set внешних зависимостей для CDN режима */
|
|
7
|
+
export declare function getExternalForCdn(cwd?: string): Set<string>;
|
|
8
|
+
/** Реактивная настройка алиасов для разработки (локальные пути) */
|
|
9
|
+
export declare function getWmakeAliases(root: string, cwd?: string): Record<string, string>;
|
|
10
|
+
/** Оптимизация Vite (чтобы он не пересобирал их сто раз) */
|
|
11
|
+
export declare function getWmakeOptimizeDeps(cwd?: string): string[];
|
|
12
|
+
/** Плагин для вставки тегов <script> из CDN в HTML.txt */
|
|
13
|
+
export declare function wmakeScriptCdnPlugin(options: {
|
|
14
|
+
useCdn: boolean;
|
|
15
|
+
projectDir?: string;
|
|
16
|
+
}): PluginOption;
|
|
22
17
|
//# sourceMappingURL=vite-config.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vite-config.d.ts","sourceRoot":"","sources":["../src/vite-config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"vite-config.d.ts","sourceRoot":"","sources":["../src/vite-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AA0CzC,qEAAqE;AACrE,wBAAgB,eAAe,CAAC,GAAG,GAAE,MAAsB,0BAQ1D;AAED,4FAA4F;AAC5F,wBAAgB,kBAAkB,CAAC,GAAG,GAAE,MAAsB,0BAQ7D;AAED,uDAAuD;AACvD,wBAAgB,iBAAiB,CAAC,GAAG,GAAE,MAAsB,GAAG,GAAG,CAAC,MAAM,CAAC,CAQ1E;AAED,mEAAmE;AACnE,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,GAAE,MAAsB,0BASxE;AAED,4DAA4D;AAC5D,wBAAgB,oBAAoB,CAAC,GAAG,GAAE,MAAsB,YAO/D;AAED,0DAA0D;AAC1D,wBAAgB,oBAAoB,CAAC,OAAO,EAAE;IAC5C,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,YAAY,CAsDf"}
|
package/dist/vite-config.js
CHANGED
|
@@ -1,127 +1,137 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
1
|
import fs from "node:fs";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
"react",
|
|
8
|
-
"react/
|
|
9
|
-
"react-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
"
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
(
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
/** Базовые зависимости, которые всегда выносим в CDN (IIFE) */
|
|
4
|
+
const BASE_GLOBALS = {
|
|
5
|
+
react: "React",
|
|
6
|
+
"react-dom": "ReactDOM",
|
|
7
|
+
"react-dom/client": "ReactDOM",
|
|
8
|
+
"react/jsx-runtime": "React",
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Преобразует @allior/wmake-something в WmakeSomething
|
|
12
|
+
* @allior/wmake-something/react -> WmakeSomethingReact
|
|
13
|
+
*/
|
|
14
|
+
function toGlobalName(pkg) {
|
|
15
|
+
if (pkg.endsWith("/react")) {
|
|
16
|
+
return toGlobalName(pkg.replace("/react", "")) + "React";
|
|
17
|
+
}
|
|
18
|
+
const name = pkg
|
|
19
|
+
.replace("@allior/", "")
|
|
20
|
+
.replace(/\//g, "-")
|
|
21
|
+
.split("-")
|
|
22
|
+
.map((s) => s.charAt(0).toUpperCase() + s.slice(1))
|
|
23
|
+
.join("");
|
|
24
|
+
return name;
|
|
25
|
+
}
|
|
26
|
+
/** Получает список @allior/wmake-* пакетов из депенденси текущего проекта */
|
|
27
|
+
function getWmakeDeps(cwd) {
|
|
28
|
+
const pkgPath = path.join(cwd, "package.json");
|
|
29
|
+
if (!fs.existsSync(pkgPath))
|
|
30
|
+
return [];
|
|
31
|
+
try {
|
|
32
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
|
|
33
|
+
const deps = { ...pkg.dependencies };
|
|
34
|
+
return Object.keys(deps).filter((d) => d.startsWith("@allior/wmake-") && d !== "@allior/wmake-cli");
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return [];
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/** Генерирует карту глобалов для Rollup. Используем чистые имена. */
|
|
41
|
+
export function getWmakeGlobals(cwd = process.cwd()) {
|
|
42
|
+
const deps = getWmakeDeps(cwd);
|
|
43
|
+
const res = { ...BASE_GLOBALS };
|
|
44
|
+
for (const pkg of deps) {
|
|
45
|
+
res[pkg] = toGlobalName(pkg);
|
|
46
|
+
res[`${pkg}/react`] = toGlobalName(pkg) + "React";
|
|
47
|
+
}
|
|
48
|
+
return res;
|
|
49
|
+
}
|
|
50
|
+
/** Вспомогательная функция для получения ЧИСТЫХ имен глобалов (без window.) для проверок */
|
|
51
|
+
export function getRawWmakeGlobals(cwd = process.cwd()) {
|
|
52
|
+
const deps = getWmakeDeps(cwd);
|
|
53
|
+
const res = { ...BASE_GLOBALS };
|
|
54
|
+
for (const pkg of deps) {
|
|
55
|
+
res[pkg] = toGlobalName(pkg);
|
|
56
|
+
res[`${pkg}/react`] = toGlobalName(pkg) + "React";
|
|
57
|
+
}
|
|
58
|
+
return res;
|
|
59
|
+
}
|
|
60
|
+
/** Получает Set внешних зависимостей для CDN режима */
|
|
61
|
+
export function getExternalForCdn(cwd = process.cwd()) {
|
|
62
|
+
const deps = getWmakeDeps(cwd);
|
|
63
|
+
const res = new Set(Object.keys(BASE_GLOBALS));
|
|
64
|
+
for (const pkg of deps) {
|
|
65
|
+
res.add(pkg);
|
|
66
|
+
res.add(`${pkg}/react`);
|
|
67
|
+
}
|
|
68
|
+
return res;
|
|
69
|
+
}
|
|
70
|
+
/** Реактивная настройка алиасов для разработки (локальные пути) */
|
|
71
|
+
export function getWmakeAliases(root, cwd = process.cwd()) {
|
|
72
|
+
const deps = getWmakeDeps(cwd);
|
|
73
|
+
const aliases = {};
|
|
74
|
+
for (const pkg of deps) {
|
|
75
|
+
const name = pkg.replace("@allior/wmake-", "");
|
|
76
|
+
aliases[pkg] = path.join(root, `${name}/dist/root/index.js`);
|
|
77
|
+
aliases[`${pkg}/react`] = path.join(root, `${name}/dist/react/index.js`);
|
|
78
|
+
}
|
|
79
|
+
return aliases;
|
|
80
|
+
}
|
|
81
|
+
/** Оптимизация Vite (чтобы он не пересобирал их сто раз) */
|
|
82
|
+
export function getWmakeOptimizeDeps(cwd = process.cwd()) {
|
|
83
|
+
const deps = getWmakeDeps(cwd);
|
|
84
|
+
const res = [];
|
|
85
|
+
for (const pkg of deps) {
|
|
86
|
+
res.push(pkg, `${pkg}/react`);
|
|
87
|
+
}
|
|
88
|
+
return res;
|
|
89
|
+
}
|
|
90
|
+
/** Плагин для вставки тегов <script> из CDN в HTML.txt */
|
|
91
|
+
export function wmakeScriptCdnPlugin(options) {
|
|
92
|
+
const { useCdn, projectDir = process.cwd() } = options;
|
|
73
93
|
return {
|
|
74
|
-
name: "
|
|
94
|
+
name: "wmake-script-cdn",
|
|
75
95
|
transformIndexHtml: {
|
|
76
96
|
order: "post",
|
|
77
|
-
handler(html
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
97
|
+
handler(html) {
|
|
98
|
+
if (!useCdn)
|
|
99
|
+
return html;
|
|
100
|
+
// По требованию пользователя используем React 18.2.0 по умолчанию для совместимости
|
|
101
|
+
const reactVer = "18.2.0";
|
|
102
|
+
const CDN_BASE = "https://cdn.jsdelivr.net/npm";
|
|
103
|
+
// Скрипты реакта - ВСЕГДА В НАЧАЛО
|
|
104
|
+
const reactTags = [
|
|
105
|
+
`<script src="${CDN_BASE}/react@${reactVer}/umd/react.production.min.js"></script>`,
|
|
106
|
+
`<script src="${CDN_BASE}/react-dom@${reactVer}/umd/react-dom.production.min.js"></script>`
|
|
107
|
+
].join("\n ");
|
|
108
|
+
// Шим для JSX Runtime, чтобы не падал на React.createElement
|
|
109
|
+
const shim = `
|
|
110
|
+
<script>
|
|
111
|
+
(function() {
|
|
112
|
+
var r = function() { return window.React; };
|
|
113
|
+
window.ReactJSXRuntime = {
|
|
114
|
+
get jsx() { return r().createElement; },
|
|
115
|
+
get jsxs() { return r().createElement; },
|
|
116
|
+
get Fragment() { return r().Fragment; }
|
|
117
|
+
};
|
|
118
|
+
})();
|
|
119
|
+
</script>`;
|
|
120
|
+
// Остальные библиотеки @allior/wmake-*
|
|
121
|
+
const deps = getWmakeDeps(projectDir);
|
|
122
|
+
const otherTags = deps.map(pkg => {
|
|
123
|
+
return [
|
|
124
|
+
`<script src="${CDN_BASE}/${pkg}@latest/dist/root/index.iife.js"></script>`,
|
|
125
|
+
`<script src="${CDN_BASE}/${pkg}@latest/dist/react/index.iife.js"></script>`
|
|
126
|
+
].join("\n ");
|
|
127
|
+
}).join("\n ");
|
|
128
|
+
// Вставляем В НАЧАЛО <head>, чтобы зависимости были первыми
|
|
129
|
+
let res = html.replace(/(<head[^>]*>)/i, `$1\n ${reactTags}${shim ? "\n " + shim : ""}\n ${otherTags}`);
|
|
130
|
+
// Для работы в Streamelements нам НЕ НУЖЕН тег основного скрипта в HTML,
|
|
131
|
+
// так как код живет во вкладке JS. Удаляем его вместе с атрибутами type="module" и crossorigin.
|
|
132
|
+
res = res.replace(/<script(?=[^>]*src=["']\/assets\/index\.js["'])[\s\S]*?><\/script>/gi, '');
|
|
133
|
+
return res;
|
|
84
134
|
},
|
|
85
135
|
},
|
|
86
|
-
writeBundle(options) {
|
|
87
|
-
const outDir = options.dir ?? "dist";
|
|
88
|
-
const htmlPath = path.join(outDir, "index.html");
|
|
89
|
-
if (!fs.existsSync(htmlPath))
|
|
90
|
-
return;
|
|
91
|
-
let html = fs.readFileSync(htmlPath, "utf-8");
|
|
92
|
-
const scriptTagMatch = html.match(/<script(?=[^>]*type=["']module["'])(?=[^>]*src=)[^>]*src=["']([^"']+)["'][^>]*>\s*<\/script>/);
|
|
93
|
-
if (!scriptTagMatch)
|
|
94
|
-
return;
|
|
95
|
-
const mainScriptSrc = scriptTagMatch[1];
|
|
96
|
-
html = html
|
|
97
|
-
.replace(BOOTSTRAP_PLACEHOLDER_VER, WMAKE_VER)
|
|
98
|
-
.replace(BOOTSTRAP_PLACEHOLDER_SRC, mainScriptSrc)
|
|
99
|
-
.replace(scriptTagMatch[0], "");
|
|
100
|
-
fs.writeFileSync(htmlPath, html);
|
|
101
|
-
},
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
export function getWmakeAliases(root) {
|
|
105
|
-
return {
|
|
106
|
-
"@allior/wmake-streamelements-events/react": path.join(root, "streamelements-events/dist/react/index.js"),
|
|
107
|
-
"@allior/wmake-streamelements-events": path.join(root, "streamelements-events/dist/root/index.js"),
|
|
108
|
-
"@allior/wmake-utils/react": path.join(root, "utils/dist/react/index.js"),
|
|
109
|
-
"@allior/wmake-utils": path.join(root, "utils/dist/root/index.js"),
|
|
110
|
-
"@allior/wmake-emotes/react": path.join(root, "emotes/dist/react/index.js"),
|
|
111
|
-
"@allior/wmake-emotes/7tv": path.join(root, "emotes/dist/7tv/index.js"),
|
|
112
|
-
"@allior/wmake-emotes": path.join(root, "emotes/dist/root/index.js"),
|
|
113
|
-
"@allior/wmake-streamelements/react": path.join(root, "streamelements/dist/react/index.js"),
|
|
114
|
-
"@allior/wmake-streamelements/fields": path.join(root, "streamelements/dist/fields/index.js"),
|
|
115
|
-
"@allior/wmake-streamelements": path.join(root, "streamelements/dist/root/index.js"),
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
export function getWmakeOptimizeDeps() {
|
|
119
|
-
return {
|
|
120
|
-
include: [
|
|
121
|
-
"@allior/wmake-streamelements-events",
|
|
122
|
-
"@allior/wmake-utils",
|
|
123
|
-
"@allior/wmake-emotes/7tv",
|
|
124
|
-
"@allior/wmake-streamelements",
|
|
125
|
-
],
|
|
126
136
|
};
|
|
127
137
|
}
|
package/dist/widget.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"widget.d.ts","sourceRoot":"","sources":["../src/widget.ts"],"names":[],"mappings":"AAwCA,wBAAsB,WAAW,CAAC,OAAO,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"widget.d.ts","sourceRoot":"","sources":["../src/widget.ts"],"names":[],"mappings":"AAwCA,wBAAsB,WAAW,CAAC,OAAO,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA+K5E"}
|
package/dist/widget.js
CHANGED
|
@@ -85,7 +85,44 @@ export async function buildWidget(options) {
|
|
|
85
85
|
if (jsFiles.length === 0 || cssFiles.length === 0) {
|
|
86
86
|
throw new Error("Expected .js and .css in dist/assets");
|
|
87
87
|
}
|
|
88
|
-
|
|
88
|
+
let finalJs = fs.readFileSync(jsFiles[0], "utf-8");
|
|
89
|
+
// Если мы НЕ в FULL режиме, оборачиваем в проверку готовности глобалов
|
|
90
|
+
if (!options.full) {
|
|
91
|
+
const { getRawWmakeGlobals } = await import("./vite-config.js");
|
|
92
|
+
const rawGlobals = getRawWmakeGlobals(projectDir);
|
|
93
|
+
const requiredGlobals = JSON.stringify(Array.from(new Set(Object.values(rawGlobals))));
|
|
94
|
+
finalJs = `(function() {
|
|
95
|
+
var req = ${requiredGlobals};
|
|
96
|
+
function check() {
|
|
97
|
+
var missing = [];
|
|
98
|
+
for (var i = 0; i < req.length; i++) {
|
|
99
|
+
if (!window[req[i]]) { missing.push(req[i]); }
|
|
100
|
+
}
|
|
101
|
+
if (missing.length === 0) {
|
|
102
|
+
console.log("[WMAKE] All dependencies confirmed: " + req.join(", "));
|
|
103
|
+
var run = function() {
|
|
104
|
+
// Принудительно гарантируем наличие переменных в глобальной области
|
|
105
|
+
${Array.from(new Set(Object.values(rawGlobals))).map(g => `if (!window.${g}) window.${g} = undefined; var ${g} = window.${g};`).join(" ")}
|
|
106
|
+
try {
|
|
107
|
+
${finalJs}
|
|
108
|
+
} catch (e) {
|
|
109
|
+
console.error("[WMAKE] Runtime error during widget execution:", e);
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
run();
|
|
113
|
+
} else {
|
|
114
|
+
if (window.__WMAKE_LOG_MISSING !== missing.join(",")) {
|
|
115
|
+
console.warn("[WMAKE] Waiting for dependencies: " + missing.join(", "));
|
|
116
|
+
window.__WMAKE_LOG_MISSING = missing.join(",");
|
|
117
|
+
}
|
|
118
|
+
setTimeout(check, 100);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
console.log("[WMAKE] Initializing dependency check...");
|
|
122
|
+
check();
|
|
123
|
+
})();`;
|
|
124
|
+
}
|
|
125
|
+
fs.writeFileSync(path.join(buildDir, "js.txt"), finalJs);
|
|
89
126
|
fs.writeFileSync(path.join(buildDir, "css.txt"), fs.readFileSync(cssFiles[0], "utf-8"));
|
|
90
127
|
const fieldsJsonPath = path.join(projectDir, "fields.json");
|
|
91
128
|
if (fs.existsSync(fieldsJsonPath)) {
|
package/package.json
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@allior/wmake-cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.6",
|
|
4
4
|
"description": "Streamiby/wmake CLI: build widgets, base64 encode assets, generate fields",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": "./dist/index.js",
|
|
9
|
+
"./vite-config": "./dist/vite-config.js",
|
|
10
|
+
"./vite-plugin": "./dist/vite-config.js"
|
|
11
|
+
},
|
|
7
12
|
"bin": {
|
|
8
13
|
"wmake-cli": "dist/bin.js",
|
|
9
14
|
"@allior/wmake-cli": "dist/bin.js"
|
package/src/vite-config.ts
CHANGED
|
@@ -1,141 +1,156 @@
|
|
|
1
|
-
import
|
|
1
|
+
import type { PluginOption } from "vite";
|
|
2
2
|
import fs from "node:fs";
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
export const CDN_BASE = "https://cdn.jsdelivr.net/npm";
|
|
6
|
-
export const REACT_VER = "19.0.0";
|
|
7
|
-
export const WMAKE_VER = "1.0.0";
|
|
8
|
-
|
|
9
|
-
export const EXTERNAL_FOR_CDN = new Set([
|
|
10
|
-
"react",
|
|
11
|
-
"react/jsx-runtime",
|
|
12
|
-
"react-dom",
|
|
13
|
-
"react-dom/client",
|
|
14
|
-
"@allior/wmake-utils",
|
|
15
|
-
"@allior/wmake-utils/react",
|
|
16
|
-
"@allior/wmake-streamelements-events",
|
|
17
|
-
"@allior/wmake-streamelements-events/react",
|
|
18
|
-
"@allior/wmake-emotes/7tv",
|
|
19
|
-
"@allior/wmake-streamelements",
|
|
20
|
-
]);
|
|
21
|
-
|
|
22
|
-
const BOOTSTRAP_PLACEHOLDER_SRC = "__MAIN_SCRIPT_SRC__";
|
|
23
|
-
const BOOTSTRAP_PLACEHOLDER_VER = "__DEFAULT_WMAKE_VER__";
|
|
24
|
-
|
|
25
|
-
const bootstrapScript = `
|
|
26
|
-
(function(){
|
|
27
|
-
var CDN_BASE='${CDN_BASE}';
|
|
28
|
-
var REACT_VER='${REACT_VER}';
|
|
29
|
-
var defaultVer='${BOOTSTRAP_PLACEHOLDER_VER}';
|
|
30
|
-
var mainScriptSrc='${BOOTSTRAP_PLACEHOLDER_SRC}';
|
|
31
|
-
function run(ver){
|
|
32
|
-
var v=ver||defaultVer;
|
|
33
|
-
var map={imports:{
|
|
34
|
-
'react':CDN_BASE+'/react@'+REACT_VER+'/+esm',
|
|
35
|
-
'react/jsx-runtime':CDN_BASE+'/react@'+REACT_VER+'/jsx-runtime.js',
|
|
36
|
-
'react-dom':CDN_BASE+'/react-dom@'+REACT_VER+'/+esm',
|
|
37
|
-
'react-dom/client':CDN_BASE+'/react-dom@'+REACT_VER+'/client.js',
|
|
38
|
-
'@allior/wmake-utils':CDN_BASE+'/@allior/wmake-utils@'+v+'/dist/root/index.js',
|
|
39
|
-
'@allior/wmake-utils/react':CDN_BASE+'/@allior/wmake-utils@'+v+'/dist/react/index.js',
|
|
40
|
-
'@allior/wmake-streamelements-events':CDN_BASE+'/@allior/wmake-streamelements-events@'+v+'/dist/root/index.js',
|
|
41
|
-
'@allior/wmake-streamelements-events/react':CDN_BASE+'/@allior/wmake-streamelements-events@'+v+'/dist/react/index.js',
|
|
42
|
-
'@allior/wmake-emotes/7tv':CDN_BASE+'/@allior/wmake-emotes@'+v+'/dist/7tv/index.js',
|
|
43
|
-
'@allior/wmake-streamelements':CDN_BASE+'/@allior/wmake-streamelements@'+v+'/dist/root/index.js'
|
|
44
|
-
}};
|
|
45
|
-
var s=document.createElement('script');
|
|
46
|
-
s.type='importmap';
|
|
47
|
-
s.textContent=JSON.stringify(map);
|
|
48
|
-
document.head.appendChild(s);
|
|
49
|
-
var m=document.createElement('script');
|
|
50
|
-
m.type='module';
|
|
51
|
-
m.src=mainScriptSrc;
|
|
52
|
-
document.body.appendChild(m);
|
|
53
|
-
}
|
|
54
|
-
if(typeof window.addEventListener==='function'){
|
|
55
|
-
window.addEventListener('onWidgetLoad',function(obj){
|
|
56
|
-
var fd=obj.detail&&obj.detail.fieldData;
|
|
57
|
-
run(fd&&fd.wmakeVersion);
|
|
58
|
-
});
|
|
59
|
-
setTimeout(function(){if(!document.querySelector('script[type="importmap"]'))run(defaultVer);},100);
|
|
60
|
-
}else{run(defaultVer);}
|
|
61
|
-
})();
|
|
62
|
-
`;
|
|
63
|
-
|
|
64
|
-
export function wmakeImportMapPlugin(): PluginOption {
|
|
65
|
-
const imports: Record<string, string> = {
|
|
66
|
-
react: `${CDN_BASE}/react@${REACT_VER}/+esm`,
|
|
67
|
-
"react/jsx-runtime": `${CDN_BASE}/react@${REACT_VER}/jsx-runtime.js`,
|
|
68
|
-
"react-dom": `${CDN_BASE}/react-dom@${REACT_VER}/+esm`,
|
|
69
|
-
"react-dom/client": `${CDN_BASE}/react-dom@${REACT_VER}/client.js`,
|
|
70
|
-
"@allior/wmake-utils": `${CDN_BASE}/@allior/wmake-utils@${WMAKE_VER}/dist/root/index.js`,
|
|
71
|
-
"@allior/wmake-utils/react": `${CDN_BASE}/@allior/wmake-utils@${WMAKE_VER}/dist/react/index.js`,
|
|
72
|
-
"@allior/wmake-streamelements-events": `${CDN_BASE}/@allior/wmake-streamelements-events@${WMAKE_VER}/dist/root/index.js`,
|
|
73
|
-
"@allior/wmake-streamelements-events/react": `${CDN_BASE}/@allior/wmake-streamelements-events@${WMAKE_VER}/dist/react/index.js`,
|
|
74
|
-
"@allior/wmake-emotes/7tv": `${CDN_BASE}/@allior/wmake-emotes@${WMAKE_VER}/dist/7tv/index.js`,
|
|
75
|
-
"@allior/wmake-streamelements": `${CDN_BASE}/@allior/wmake-streamelements@${WMAKE_VER}/dist/root/index.js`,
|
|
76
|
-
};
|
|
3
|
+
import path from "node:path";
|
|
77
4
|
|
|
78
|
-
|
|
79
|
-
|
|
5
|
+
/** Базовые зависимости, которые всегда выносим в CDN (IIFE) */
|
|
6
|
+
const BASE_GLOBALS: Record<string, string> = {
|
|
7
|
+
react: "React",
|
|
8
|
+
"react-dom": "ReactDOM",
|
|
9
|
+
"react-dom/client": "ReactDOM",
|
|
10
|
+
"react/jsx-runtime": "React",
|
|
11
|
+
};
|
|
80
12
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
if (!fs.existsSync(htmlPath)) return;
|
|
13
|
+
/**
|
|
14
|
+
* Преобразует @allior/wmake-something в WmakeSomething
|
|
15
|
+
* @allior/wmake-something/react -> WmakeSomethingReact
|
|
16
|
+
*/
|
|
17
|
+
function toGlobalName(pkg: string): string {
|
|
18
|
+
if (pkg.endsWith("/react")) {
|
|
19
|
+
return toGlobalName(pkg.replace("/react", "")) + "React";
|
|
20
|
+
}
|
|
21
|
+
const name = pkg
|
|
22
|
+
.replace("@allior/", "")
|
|
23
|
+
.replace(/\//g, "-")
|
|
24
|
+
.split("-")
|
|
25
|
+
.map((s) => s.charAt(0).toUpperCase() + s.slice(1))
|
|
26
|
+
.join("");
|
|
27
|
+
return name;
|
|
28
|
+
}
|
|
98
29
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
30
|
+
/** Получает список @allior/wmake-* пакетов из депенденси текущего проекта */
|
|
31
|
+
function getWmakeDeps(cwd: string): string[] {
|
|
32
|
+
const pkgPath = path.join(cwd, "package.json");
|
|
33
|
+
if (!fs.existsSync(pkgPath)) return [];
|
|
34
|
+
try {
|
|
35
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
|
|
36
|
+
const deps = { ...pkg.dependencies };
|
|
37
|
+
return Object.keys(deps).filter((d) => d.startsWith("@allior/wmake-") && d !== "@allior/wmake-cli");
|
|
38
|
+
} catch {
|
|
39
|
+
return [];
|
|
40
|
+
}
|
|
41
|
+
}
|
|
103
42
|
|
|
104
|
-
|
|
105
|
-
|
|
43
|
+
/** Генерирует карту глобалов для Rollup. Используем чистые имена. */
|
|
44
|
+
export function getWmakeGlobals(cwd: string = process.cwd()) {
|
|
45
|
+
const deps = getWmakeDeps(cwd);
|
|
46
|
+
const res: Record<string, string> = { ...BASE_GLOBALS };
|
|
47
|
+
for (const pkg of deps) {
|
|
48
|
+
res[pkg] = toGlobalName(pkg);
|
|
49
|
+
res[`${pkg}/react`] = toGlobalName(pkg) + "React";
|
|
50
|
+
}
|
|
51
|
+
return res;
|
|
52
|
+
}
|
|
106
53
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
54
|
+
/** Вспомогательная функция для получения ЧИСТЫХ имен глобалов (без window.) для проверок */
|
|
55
|
+
export function getRawWmakeGlobals(cwd: string = process.cwd()) {
|
|
56
|
+
const deps = getWmakeDeps(cwd);
|
|
57
|
+
const res: Record<string, string> = { ...BASE_GLOBALS };
|
|
58
|
+
for (const pkg of deps) {
|
|
59
|
+
res[pkg] = toGlobalName(pkg);
|
|
60
|
+
res[`${pkg}/react`] = toGlobalName(pkg) + "React";
|
|
61
|
+
}
|
|
62
|
+
return res;
|
|
63
|
+
}
|
|
111
64
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
65
|
+
/** Получает Set внешних зависимостей для CDN режима */
|
|
66
|
+
export function getExternalForCdn(cwd: string = process.cwd()): Set<string> {
|
|
67
|
+
const deps = getWmakeDeps(cwd);
|
|
68
|
+
const res = new Set(Object.keys(BASE_GLOBALS));
|
|
69
|
+
for (const pkg of deps) {
|
|
70
|
+
res.add(pkg);
|
|
71
|
+
res.add(`${pkg}/react`);
|
|
72
|
+
}
|
|
73
|
+
return res;
|
|
115
74
|
}
|
|
116
75
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
"@allior/wmake-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
"@allior/wmake-streamelements/fields": path.join(root, "streamelements/dist/fields/index.js"),
|
|
128
|
-
"@allior/wmake-streamelements": path.join(root, "streamelements/dist/root/index.js"),
|
|
129
|
-
};
|
|
76
|
+
/** Реактивная настройка алиасов для разработки (локальные пути) */
|
|
77
|
+
export function getWmakeAliases(root: string, cwd: string = process.cwd()) {
|
|
78
|
+
const deps = getWmakeDeps(cwd);
|
|
79
|
+
const aliases: Record<string, string> = {};
|
|
80
|
+
for (const pkg of deps) {
|
|
81
|
+
const name = pkg.replace("@allior/wmake-", "");
|
|
82
|
+
aliases[pkg] = path.join(root, `${name}/dist/root/index.js`);
|
|
83
|
+
aliases[`${pkg}/react`] = path.join(root, `${name}/dist/react/index.js`);
|
|
84
|
+
}
|
|
85
|
+
return aliases;
|
|
130
86
|
}
|
|
131
87
|
|
|
132
|
-
|
|
88
|
+
/** Оптимизация Vite (чтобы он не пересобирал их сто раз) */
|
|
89
|
+
export function getWmakeOptimizeDeps(cwd: string = process.cwd()) {
|
|
90
|
+
const deps = getWmakeDeps(cwd);
|
|
91
|
+
const res = [];
|
|
92
|
+
for (const pkg of deps) {
|
|
93
|
+
res.push(pkg, `${pkg}/react`);
|
|
94
|
+
}
|
|
95
|
+
return res;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** Плагин для вставки тегов <script> из CDN в HTML.txt */
|
|
99
|
+
export function wmakeScriptCdnPlugin(options: {
|
|
100
|
+
useCdn: boolean;
|
|
101
|
+
projectDir?: string;
|
|
102
|
+
}): PluginOption {
|
|
103
|
+
const { useCdn, projectDir = process.cwd() } = options;
|
|
104
|
+
|
|
133
105
|
return {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
"
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
106
|
+
name: "wmake-script-cdn",
|
|
107
|
+
transformIndexHtml: {
|
|
108
|
+
order: "post",
|
|
109
|
+
handler(html) {
|
|
110
|
+
if (!useCdn) return html;
|
|
111
|
+
|
|
112
|
+
// По требованию пользователя используем React 18.2.0 по умолчанию для совместимости
|
|
113
|
+
const reactVer = "18.2.0";
|
|
114
|
+
|
|
115
|
+
const CDN_BASE = "https://cdn.jsdelivr.net/npm";
|
|
116
|
+
|
|
117
|
+
// Скрипты реакта - ВСЕГДА В НАЧАЛО
|
|
118
|
+
const reactTags = [
|
|
119
|
+
`<script src="${CDN_BASE}/react@${reactVer}/umd/react.production.min.js"></script>`,
|
|
120
|
+
`<script src="${CDN_BASE}/react-dom@${reactVer}/umd/react-dom.production.min.js"></script>`
|
|
121
|
+
].join("\n ");
|
|
122
|
+
|
|
123
|
+
// Шим для JSX Runtime, чтобы не падал на React.createElement
|
|
124
|
+
const shim = `
|
|
125
|
+
<script>
|
|
126
|
+
(function() {
|
|
127
|
+
var r = function() { return window.React; };
|
|
128
|
+
window.ReactJSXRuntime = {
|
|
129
|
+
get jsx() { return r().createElement; },
|
|
130
|
+
get jsxs() { return r().createElement; },
|
|
131
|
+
get Fragment() { return r().Fragment; }
|
|
132
|
+
};
|
|
133
|
+
})();
|
|
134
|
+
</script>`;
|
|
135
|
+
|
|
136
|
+
// Остальные библиотеки @allior/wmake-*
|
|
137
|
+
const deps = getWmakeDeps(projectDir);
|
|
138
|
+
const otherTags = deps.map(pkg => {
|
|
139
|
+
return [
|
|
140
|
+
`<script src="${CDN_BASE}/${pkg}@latest/dist/root/index.iife.js"></script>`,
|
|
141
|
+
`<script src="${CDN_BASE}/${pkg}@latest/dist/react/index.iife.js"></script>`
|
|
142
|
+
].join("\n ");
|
|
143
|
+
}).join("\n ");
|
|
144
|
+
|
|
145
|
+
// Вставляем В НАЧАЛО <head>, чтобы зависимости были первыми
|
|
146
|
+
let res = html.replace(/(<head[^>]*>)/i, `$1\n ${reactTags}${shim ? "\n " + shim : ""}\n ${otherTags}`);
|
|
147
|
+
|
|
148
|
+
// Для работы в Streamelements нам НЕ НУЖЕН тег основного скрипта в HTML,
|
|
149
|
+
// так как код живет во вкладке JS. Удаляем его вместе с атрибутами type="module" и crossorigin.
|
|
150
|
+
res = res.replace(/<script(?=[^>]*src=["']\/assets\/index\.js["'])[\s\S]*?><\/script>/gi, '');
|
|
151
|
+
|
|
152
|
+
return res;
|
|
153
|
+
},
|
|
154
|
+
},
|
|
140
155
|
};
|
|
141
156
|
}
|
package/src/widget.ts
CHANGED
|
@@ -102,10 +102,47 @@ export async function buildWidget(options: { full?: boolean }): Promise<void> {
|
|
|
102
102
|
throw new Error("Expected .js and .css in dist/assets");
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
-
fs.
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
)
|
|
105
|
+
let finalJs = fs.readFileSync(jsFiles[0], "utf-8");
|
|
106
|
+
|
|
107
|
+
// Если мы НЕ в FULL режиме, оборачиваем в проверку готовности глобалов
|
|
108
|
+
if (!options.full) {
|
|
109
|
+
const { getRawWmakeGlobals } = await import("./vite-config.js");
|
|
110
|
+
const rawGlobals = getRawWmakeGlobals(projectDir);
|
|
111
|
+
const requiredGlobals = JSON.stringify(Array.from(new Set(Object.values(rawGlobals))));
|
|
112
|
+
|
|
113
|
+
finalJs = `(function() {
|
|
114
|
+
var req = ${requiredGlobals};
|
|
115
|
+
function check() {
|
|
116
|
+
var missing = [];
|
|
117
|
+
for (var i = 0; i < req.length; i++) {
|
|
118
|
+
if (!window[req[i]]) { missing.push(req[i]); }
|
|
119
|
+
}
|
|
120
|
+
if (missing.length === 0) {
|
|
121
|
+
console.log("[WMAKE] All dependencies confirmed: " + req.join(", "));
|
|
122
|
+
var run = function() {
|
|
123
|
+
// Принудительно гарантируем наличие переменных в глобальной области
|
|
124
|
+
${Array.from(new Set(Object.values(rawGlobals))).map(g => `if (!window.${g}) window.${g} = undefined; var ${g} = window.${g};`).join(" ")}
|
|
125
|
+
try {
|
|
126
|
+
${finalJs}
|
|
127
|
+
} catch (e) {
|
|
128
|
+
console.error("[WMAKE] Runtime error during widget execution:", e);
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
run();
|
|
132
|
+
} else {
|
|
133
|
+
if (window.__WMAKE_LOG_MISSING !== missing.join(",")) {
|
|
134
|
+
console.warn("[WMAKE] Waiting for dependencies: " + missing.join(", "));
|
|
135
|
+
window.__WMAKE_LOG_MISSING = missing.join(",");
|
|
136
|
+
}
|
|
137
|
+
setTimeout(check, 100);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
console.log("[WMAKE] Initializing dependency check...");
|
|
141
|
+
check();
|
|
142
|
+
})();`;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
fs.writeFileSync(path.join(buildDir, "js.txt"), finalJs);
|
|
109
146
|
fs.writeFileSync(
|
|
110
147
|
path.join(buildDir, "css.txt"),
|
|
111
148
|
fs.readFileSync(cssFiles[0], "utf-8"),
|