@yangyongtao/gaea 1.1.30 → 1.1.32
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/CHANGELOG.md +14 -0
- package/package.json +1 -1
- package/src/GaeaMethods.js +26 -4
- package/src/vite-plugin.js +65 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.1.32] - 2026-09-09
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
- 引擎大文件(`Gaea.pck` / `Gaea.wasm`)改为从外部资源服务器加载:默认 `executable` 指向 `http://172.20.176.100:7072/gaea/Gaea`。可通过宿主站点 `config.js` 设置 `window.__GAEA_ASSETS_URL__`(运行时覆盖,换地址无需重新打包),或构建环境变量 `VITE_GAEA_EXECUTABLE` 覆盖
|
|
7
|
+
- Vite 插件 `closeBundle` 默认不再把 `Gaea.pck` / `Gaea.wasm` 复制到输出目录(引擎从外部服务器加载,dist 体积大幅减小);可用 `gaeaVitePlugin({ skipEngineFiles: [...] })` 覆盖
|
|
8
|
+
- 屏幕图标(`.gaea-iconGif` / `.gaea-iconscreen` / `.gaea-locationLineStyle`)z-index 统一改为 `11`
|
|
9
|
+
|
|
10
|
+
## [1.1.31] - 2026-09-09
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- Vite 插件 `transformIndexHtml` 自动给外部跨域 `<script src="http(s)://...">` 补 `crossorigin="anonymous"`:解决跨域隔离(COEP: require-corp)下第三方脚本因缺少 CORP 响应头被拦截(`NotSameOriginAfterDefaultedToSameOriginByCoep`)并阻塞页面加载的问题(如 `live.dcyun.com` 的 DcVideo.js 视频库)
|
|
14
|
+
- 注入前置脚本 hook `Node.prototype.appendChild/insertBefore`:第三方脚本内部 `document.createElement('script')` 动态加载的跨域子脚本自动补 `crossorigin`(DcVideo.js 内部的 jquery / DCHls / EasyWasmPlayer / ezuikit 等均可正常加载)
|
|
15
|
+
- 新增 `gaeaVitePlugin({ skipExternalScripts: [...] })` 配置:构建期移除匹配的外部脚本(字符串子串或正则),用于跳过跨域隔离下无法正常工作且当前未使用的第三方脚本
|
|
16
|
+
|
|
3
17
|
## [1.1.30] - 2026-09-09
|
|
4
18
|
|
|
5
19
|
### Added
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yangyongtao/gaea",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.32",
|
|
4
4
|
"description": "Gaea 3D visualization component library - Vue 3 components based on Godot WASM engine. Includes WMTS layer loading, camera view control, Vite plugin auto-injection, etc.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.cjs",
|
package/src/GaeaMethods.js
CHANGED
|
@@ -56,7 +56,7 @@ import Gaea from '../public/index.js';
|
|
|
56
56
|
#gaea-layertree-btn:hover { background: rgba(0,0,0,0.7); }
|
|
57
57
|
/* 屏幕图标样式(对齐 ht_3dview) */
|
|
58
58
|
.gaea-locationLineStyle {
|
|
59
|
-
position: absolute; overflow: hidden; z-index:
|
|
59
|
+
position: absolute; overflow: hidden; z-index: 11; pointer-events: auto;
|
|
60
60
|
user-select: none; -webkit-user-select: none;
|
|
61
61
|
}
|
|
62
62
|
.gaea-locationLineStyle .text-wrapper {
|
|
@@ -75,7 +75,7 @@ import Gaea from '../public/index.js';
|
|
|
75
75
|
}
|
|
76
76
|
.gaea-iconscreen {
|
|
77
77
|
position: absolute; overflow: hidden; width: 169px; height: 55px;
|
|
78
|
-
user-select: none; -webkit-user-select: none; z-index:
|
|
78
|
+
user-select: none; -webkit-user-select: none; z-index: 11; pointer-events: auto;
|
|
79
79
|
}
|
|
80
80
|
.gaea-iconscreen img {
|
|
81
81
|
position: absolute; width: 100%; height: 100%;
|
|
@@ -92,7 +92,7 @@ import Gaea from '../public/index.js';
|
|
|
92
92
|
}
|
|
93
93
|
.gaea-iconGif {
|
|
94
94
|
position: absolute; overflow: hidden; width: 48px; height: 48px;
|
|
95
|
-
user-select: none; -webkit-user-select: none; z-index:
|
|
95
|
+
user-select: none; -webkit-user-select: none; z-index: 11; pointer-events: auto;
|
|
96
96
|
}
|
|
97
97
|
.gaea-iconGif img {
|
|
98
98
|
width: 100%; height: 100%; object-fit: contain; display: block;
|
|
@@ -119,11 +119,33 @@ function hideLoading() {
|
|
|
119
119
|
|
|
120
120
|
// ==================== 配置 ====================
|
|
121
121
|
|
|
122
|
+
/** 默认引擎资源服务器地址(Gaea.pck / Gaea.wasm 等大文件),可在运行时/环境变量覆盖 */
|
|
123
|
+
const DEFAULT_ENGINE_ASSETS_URL = 'http://172.20.176.100:7072/gaea/Gaea';
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* 解析默认 executable:
|
|
127
|
+
* 优先级:运行时全局变量 window.__GAEA_ASSETS_URL__(宿主站点 config.js 可设置,
|
|
128
|
+
* 换地址无需重新打包)> 构建环境变量 VITE_GAEA_EXECUTABLE > 内置默认地址。
|
|
129
|
+
*/
|
|
130
|
+
function resolveDefaultExecutable() {
|
|
131
|
+
if (typeof window !== 'undefined' && window.__GAEA_ASSETS_URL__) {
|
|
132
|
+
return window.__GAEA_ASSETS_URL__;
|
|
133
|
+
}
|
|
134
|
+
try {
|
|
135
|
+
if (import.meta.env && import.meta.env.VITE_GAEA_EXECUTABLE) {
|
|
136
|
+
return import.meta.env.VITE_GAEA_EXECUTABLE;
|
|
137
|
+
}
|
|
138
|
+
} catch (e) {
|
|
139
|
+
/* 非 vite 环境忽略 */
|
|
140
|
+
}
|
|
141
|
+
return DEFAULT_ENGINE_ASSETS_URL;
|
|
142
|
+
}
|
|
143
|
+
|
|
122
144
|
const defaultConfig = {
|
|
123
145
|
serveUrl: '',
|
|
124
146
|
serveLocal: '',
|
|
125
147
|
// Engine 配置
|
|
126
|
-
executable:
|
|
148
|
+
executable: resolveDefaultExecutable(),
|
|
127
149
|
fileSizes: { 'Gaea.pck': 450751936, 'Gaea.wasm': 16580215 },
|
|
128
150
|
canvasResizePolicy: 2,
|
|
129
151
|
experimentalVK: false,
|
package/src/vite-plugin.js
CHANGED
|
@@ -55,7 +55,42 @@ const COEP_HEADERS = {
|
|
|
55
55
|
'Cross-Origin-Embedder-Policy': 'require-corp',
|
|
56
56
|
};
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
/**
|
|
59
|
+
* 给外部跨域 <script src="http(s)://..."> 自动补 crossorigin="anonymous"。
|
|
60
|
+
*
|
|
61
|
+
* 背景:Gaea 引擎要求跨域隔离(COEP: require-corp)。在 COEP 下,普通 no-cors
|
|
62
|
+
* 跨域脚本因缺少 Cross-Origin-Resource-Policy 响应头会被浏览器拦截(
|
|
63
|
+
* NotSameOriginAfterDefaultedToSameOriginByCoep),且同步脚本会挂起阻塞页面加载。
|
|
64
|
+
* 补上 crossorigin 后改为 CORS 模式加载,只要服务器返回 Access-Control-Allow-Origin
|
|
65
|
+
* 即可通过 COEP 检查。
|
|
66
|
+
*/
|
|
67
|
+
function addCrossOriginToExternalScripts(html) {
|
|
68
|
+
return html.replace(/<script\b([^>]*?)>/g, (match, attrs) => {
|
|
69
|
+
if (!/\bsrc="https?:\/\//.test(attrs)) return match;
|
|
70
|
+
if (/\bcrossorigin(=|[\s>])/i.test(attrs)) return match;
|
|
71
|
+
return match.replace(/^<script/, '<script crossorigin="anonymous"');
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* 移除 HTML 中匹配的外部 <script src="http(s)://..."> 标签。
|
|
77
|
+
* 用于跳过某些在跨域隔离(COEP)下无法正常工作、且当前项目并未使用的第三方脚本
|
|
78
|
+
* (如第三方视频播放库),避免它们拖慢首屏、产生无意义报错。
|
|
79
|
+
* @param {string} html
|
|
80
|
+
* @param {Array<string|RegExp>} rules 匹配规则:字符串按子串匹配 src,正则直接 test
|
|
81
|
+
*/
|
|
82
|
+
function skipExternalScriptTags(html, rules) {
|
|
83
|
+
if (!rules?.length) return html;
|
|
84
|
+
return html.replace(/<script\b([^>]*?src="(https?:\/\/[^"]+)"[^>]*)>[\s\S]*?<\/script>/g, (match, attrs, src) => {
|
|
85
|
+
const hit = rules.some((rule) => (rule instanceof RegExp ? rule.test(src) : String(src).includes(rule)));
|
|
86
|
+
return hit ? '' : match;
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export default function gaeaVitePlugin(options = {}) {
|
|
91
|
+
const skipScripts = options.skipExternalScripts || [];
|
|
92
|
+
// 构建时不复制到输出目录的引擎大文件(引擎默认从外部资源服务器加载,可配置 skipEngineFiles 覆盖)
|
|
93
|
+
const skipEngineFiles = options.skipEngineFiles || ['Gaea.pck', 'Gaea.wasm'];
|
|
59
94
|
let resolvedOutDir = '';
|
|
60
95
|
|
|
61
96
|
return {
|
|
@@ -155,6 +190,7 @@ export default function gaeaVitePlugin() {
|
|
|
155
190
|
|
|
156
191
|
fs.mkdirSync(outRoot, { recursive: true });
|
|
157
192
|
for (const name of BUILD_TOP_FILES) {
|
|
193
|
+
if (skipEngineFiles.includes(name)) continue;
|
|
158
194
|
const src = path.join(pkgPublic, name);
|
|
159
195
|
if (fs.existsSync(src)) copyFile(src, path.join(outRoot, name));
|
|
160
196
|
}
|
|
@@ -166,6 +202,12 @@ export default function gaeaVitePlugin() {
|
|
|
166
202
|
},
|
|
167
203
|
|
|
168
204
|
transformIndexHtml(html) {
|
|
205
|
+
// 跳过配置中匹配的外部脚本(如项目未使用的第三方视频库)
|
|
206
|
+
html = skipExternalScriptTags(html, skipScripts);
|
|
207
|
+
|
|
208
|
+
// 外部跨域脚本自动补 crossorigin(绕过 COEP 拦截,避免阻塞页面)
|
|
209
|
+
html = addCrossOriginToExternalScripts(html);
|
|
210
|
+
|
|
169
211
|
// 自动注入 Gaea.js(消费者无需在 HTML 中手动写 <script src="/Gaea.js">)
|
|
170
212
|
if (!html.includes('/Gaea.js')) {
|
|
171
213
|
html = html.replace(
|
|
@@ -174,10 +216,31 @@ export default function gaeaVitePlugin() {
|
|
|
174
216
|
);
|
|
175
217
|
}
|
|
176
218
|
|
|
177
|
-
// 跨域隔离检测
|
|
219
|
+
// 跨域隔离检测 + 动态跨域脚本自动补 crossorigin(必须在 body 脚本执行前注入到 head)
|
|
178
220
|
html = html.replace(
|
|
179
221
|
'</head>',
|
|
180
222
|
`<script>
|
|
223
|
+
// 动态创建的跨域 <script> 自动补 crossorigin="anonymous":
|
|
224
|
+
// 跨域隔离(COEP)下,第三方脚本内部 document.createElement('script') 动态加载的子脚本
|
|
225
|
+
// 若不带 crossorigin 会被拦截(NotSameOriginAfterDefaultedToSameOriginByCoep)并阻塞页面。
|
|
226
|
+
(function () {
|
|
227
|
+
if (!window.crossOriginIsolated) return;
|
|
228
|
+
function fix(el) {
|
|
229
|
+
if (el && el.tagName === 'SCRIPT' && el.src && !el.crossOrigin) {
|
|
230
|
+
try {
|
|
231
|
+
if (new URL(el.src, location.href).origin !== location.origin) {
|
|
232
|
+
el.crossOrigin = 'anonymous';
|
|
233
|
+
}
|
|
234
|
+
} catch (e) {}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
var oa = Node.prototype.appendChild;
|
|
238
|
+
var oi = Node.prototype.insertBefore;
|
|
239
|
+
Node.prototype.appendChild = function (el) { fix(el); return oa.call(this, el); };
|
|
240
|
+
Node.prototype.insertBefore = function (el, ref) { fix(el); return oi.call(this, el, ref); };
|
|
241
|
+
})();
|
|
242
|
+
</script>
|
|
243
|
+
<script>
|
|
181
244
|
if (!window.crossOriginIsolated) {
|
|
182
245
|
if (!location.search.includes('gaea_isolated=1')) {
|
|
183
246
|
location.replace(location.href.split('?')[0] + '?gaea_isolated=1');
|