@lark-apaas/miaoda-presets 1.0.6 → 1.0.7
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/lib/overlay/index.js
CHANGED
|
@@ -198,6 +198,10 @@ function render() {
|
|
|
198
198
|
const origin = targetOrigin || getPreviewParentOrigin();
|
|
199
199
|
window.parent.postMessage(message, origin);
|
|
200
200
|
};
|
|
201
|
+
// 通知前端,渲染错误页面已准备就绪
|
|
202
|
+
sendPostMessage({
|
|
203
|
+
type: 'PreviewReady'
|
|
204
|
+
});
|
|
201
205
|
// 通知主应用存在自定义 overlay
|
|
202
206
|
sendPostMessage({
|
|
203
207
|
type: 'app-features',
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"useDefineForClassFields": true,
|
|
5
|
+
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
6
|
+
"module": "ESNext",
|
|
7
|
+
"skipLibCheck": true,
|
|
8
|
+
|
|
9
|
+
/* Bundler mode */
|
|
10
|
+
"moduleResolution": "bundler",
|
|
11
|
+
"allowImportingTsExtensions": true,
|
|
12
|
+
"isolatedModules": true,
|
|
13
|
+
"moduleDetection": "force",
|
|
14
|
+
"noEmit": true,
|
|
15
|
+
"jsx": "react-jsx",
|
|
16
|
+
|
|
17
|
+
/* Linting */
|
|
18
|
+
"strict": false,
|
|
19
|
+
"noUnusedLocals": false,
|
|
20
|
+
"noUnusedParameters": false,
|
|
21
|
+
"noImplicitAny": false,
|
|
22
|
+
"noFallthroughCasesInSwitch": false,
|
|
23
|
+
|
|
24
|
+
"sourceMap": true,
|
|
25
|
+
"allowJs": true,
|
|
26
|
+
"strictNullChecks": false,
|
|
27
|
+
|
|
28
|
+
"incremental": false,
|
|
29
|
+
},
|
|
30
|
+
"include": [
|
|
31
|
+
"client/**/*"
|
|
32
|
+
],
|
|
33
|
+
"exclude": [
|
|
34
|
+
"node_modules",
|
|
35
|
+
"dist",
|
|
36
|
+
"public"
|
|
37
|
+
]
|
|
38
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
|
|
5
|
+
"module": "commonjs",
|
|
6
|
+
"moduleResolution": "node",
|
|
7
|
+
|
|
8
|
+
"skipLibCheck": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
|
|
11
|
+
"experimentalDecorators": true,
|
|
12
|
+
"emitDecoratorMetadata": true,
|
|
13
|
+
"importHelpers": true,
|
|
14
|
+
"incremental": true,
|
|
15
|
+
|
|
16
|
+
"strict": false,
|
|
17
|
+
"composite": true,
|
|
18
|
+
"declaration": true,
|
|
19
|
+
"removeComments": false,
|
|
20
|
+
"noEmit": false,
|
|
21
|
+
|
|
22
|
+
"types": ["node"]
|
|
23
|
+
},
|
|
24
|
+
"ts-node": { "require": ["tsconfig-paths/register"] }
|
|
25
|
+
}
|
package/package.json
CHANGED
|
@@ -1,262 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Webpack HMR 耗时计算插件 JavaScript 版本
|
|
4
|
-
* 在浏览器 Console 打印热更文件和耗时信息
|
|
5
|
-
*/
|
|
6
|
-
class HMRTimingPlugin {
|
|
7
|
-
constructor(options = {}) {
|
|
8
|
-
this.options = {
|
|
9
|
-
threshold: options.threshold || 1000
|
|
10
|
-
};
|
|
11
|
-
this.hmrStartTime = null;
|
|
12
|
-
this.changedFiles = new Set();
|
|
13
|
-
this.devServer = null;
|
|
14
|
-
}
|
|
15
|
-
apply(compiler) {
|
|
16
|
-
const pluginName = 'HMRTimingPlugin';
|
|
17
|
-
// 在 devServer 启动后保存引用
|
|
18
|
-
if (compiler.options.devServer) {
|
|
19
|
-
const originalSetupMiddlewares = compiler.options.devServer.setupMiddlewares;
|
|
20
|
-
const self = this;
|
|
21
|
-
compiler.options.devServer.setupMiddlewares = function (middlewares, devServer) {
|
|
22
|
-
// 保存 devServer 实例的引用
|
|
23
|
-
self.devServer = devServer;
|
|
24
|
-
global.__webpack_dev_server__ = devServer;
|
|
25
|
-
if (originalSetupMiddlewares) {
|
|
26
|
-
return originalSetupMiddlewares(middlewares, devServer);
|
|
27
|
-
}
|
|
28
|
-
return middlewares;
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
// 监听文件变化
|
|
32
|
-
compiler.hooks.invalid.tap(pluginName, (fileName) => {
|
|
33
|
-
this.hmrStartTime = Date.now();
|
|
34
|
-
this.changedFiles.clear();
|
|
35
|
-
if (fileName) {
|
|
36
|
-
this.changedFiles.add(fileName);
|
|
37
|
-
}
|
|
38
|
-
});
|
|
39
|
-
// 监听 watch 运行开始
|
|
40
|
-
compiler.hooks.watchRun.tapAsync(pluginName, (compiler, callback) => {
|
|
41
|
-
if (!this.hmrStartTime) {
|
|
42
|
-
this.hmrStartTime = Date.now();
|
|
43
|
-
}
|
|
44
|
-
// 收集变化的文件
|
|
45
|
-
if (compiler.modifiedFiles) {
|
|
46
|
-
compiler.modifiedFiles.forEach(file => this.changedFiles.add(file));
|
|
47
|
-
}
|
|
48
|
-
if (compiler.removedFiles) {
|
|
49
|
-
compiler.removedFiles.forEach(file => this.changedFiles.add(file));
|
|
50
|
-
}
|
|
51
|
-
callback();
|
|
52
|
-
});
|
|
53
|
-
// 监听编译完成
|
|
54
|
-
compiler.hooks.done.tap(pluginName, (stats) => {
|
|
55
|
-
if (this.hmrStartTime === null)
|
|
56
|
-
return;
|
|
57
|
-
const totalTime = Date.now() - this.hmrStartTime;
|
|
58
|
-
// 获取实际更新的模块
|
|
59
|
-
const updatedModules = new Set();
|
|
60
|
-
stats.compilation.modules.forEach(module => {
|
|
61
|
-
const identifier = module.resource || module.identifier?.();
|
|
62
|
-
if (identifier && typeof identifier === 'string') {
|
|
63
|
-
// 过滤掉 node_modules 中的模块
|
|
64
|
-
if (!identifier.includes('node_modules')) {
|
|
65
|
-
updatedModules.add(identifier);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
});
|
|
69
|
-
// 合并文件列表
|
|
70
|
-
const allChangedFiles = new Set([
|
|
71
|
-
...Array.from(this.changedFiles),
|
|
72
|
-
...Array.from(updatedModules)
|
|
73
|
-
]);
|
|
74
|
-
// 简化文件路径
|
|
75
|
-
const simplifiedFiles = Array.from(allChangedFiles)
|
|
76
|
-
.map(file => {
|
|
77
|
-
// 移除项目根路径
|
|
78
|
-
const relativePath = file.replace(compiler.context || '', '');
|
|
79
|
-
// 移除开头的斜杠
|
|
80
|
-
return relativePath.replace(/^[\/\\]/, '');
|
|
81
|
-
})
|
|
82
|
-
.filter(file => file && file.length > 0)
|
|
83
|
-
.slice(0, 10); // 最多显示10个文件
|
|
84
|
-
const timingInfo = {
|
|
85
|
-
totalTime,
|
|
86
|
-
changedFiles: simplifiedFiles,
|
|
87
|
-
modules: stats.compilation.modules.size,
|
|
88
|
-
isOverThreshold: totalTime > this.options.threshold,
|
|
89
|
-
threshold: this.options.threshold
|
|
90
|
-
};
|
|
91
|
-
// 通过 WebSocket 发送到浏览器
|
|
92
|
-
this.sendToBrowser(compiler, timingInfo);
|
|
93
|
-
// 重置
|
|
94
|
-
this.changedFiles.clear();
|
|
95
|
-
});
|
|
96
|
-
// 注入客户端代码
|
|
97
|
-
this.injectClientScript(compiler);
|
|
98
|
-
}
|
|
99
|
-
sendToBrowser(compiler, timingInfo) {
|
|
100
|
-
// 使用 done hook 确保在编译完成后发送
|
|
101
|
-
const server = this.getDevServer(compiler);
|
|
102
|
-
if (server) {
|
|
103
|
-
if (server.sockWrite) {
|
|
104
|
-
// webpack-dev-server 3.x
|
|
105
|
-
server.sockWrite(server.sockets, 'hmr-timing', timingInfo);
|
|
106
|
-
}
|
|
107
|
-
else if (server.sendMessage) {
|
|
108
|
-
// webpack-dev-server 4.x/5.x
|
|
109
|
-
const clients = server.webSocketServer?.clients || server.clients;
|
|
110
|
-
server.sendMessage(clients, 'hmr-timing', timingInfo);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
getDevServer(compiler) {
|
|
115
|
-
// 尝试多种方式获取 devServer 实例
|
|
116
|
-
// 方式1: 从 compiler.options.devServer 存储的引用
|
|
117
|
-
if (compiler.options.devServer && compiler.options.devServer.__instance) {
|
|
118
|
-
return compiler.options.devServer.__instance;
|
|
119
|
-
}
|
|
120
|
-
// 方式2: 从全局变量
|
|
121
|
-
if (global.__webpack_dev_server__) {
|
|
122
|
-
return global.__webpack_dev_server__;
|
|
123
|
-
}
|
|
124
|
-
// 方式3: 从 compiler 上挂载的引用
|
|
125
|
-
if (compiler.__webpack_dev_server__) {
|
|
126
|
-
return compiler.__webpack_dev_server__;
|
|
127
|
-
}
|
|
128
|
-
// 方式4: 在 infrastructure 日志中查找
|
|
129
|
-
if (compiler.infrastructureLogger) {
|
|
130
|
-
const logger = compiler.infrastructureLogger;
|
|
131
|
-
if (logger.__devServer) {
|
|
132
|
-
return logger.__devServer;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
return null;
|
|
136
|
-
}
|
|
137
|
-
injectClientScript(compiler) {
|
|
138
|
-
const clientScript = `
|
|
139
|
-
;(function() {
|
|
140
|
-
if (typeof window === 'undefined' || !module.hot) return;
|
|
141
|
-
|
|
142
|
-
const threshold = ${this.options.threshold};
|
|
143
|
-
|
|
144
|
-
// 显示 HMR 耗时和变化文件
|
|
145
|
-
function logHMRTiming(data) {
|
|
146
|
-
const color = data.isOverThreshold ? '#ff9800' : '#4caf50';
|
|
147
|
-
|
|
148
|
-
// 主要信息
|
|
149
|
-
console.log(
|
|
150
|
-
'%c🔥 HMR 更新完成 - 耗时: %c' + data.totalTime + 'ms',
|
|
151
|
-
'color: ' + color + '; font-weight: bold; font-size: 14px;',
|
|
152
|
-
'color: ' + color + '; font-weight: bold; font-size: 16px;'
|
|
153
|
-
);
|
|
154
|
-
|
|
155
|
-
// 热更文件列表
|
|
156
|
-
if (data.changedFiles && data.changedFiles.length > 0) {
|
|
157
|
-
console.group('📝 热更文件 (' + data.changedFiles.length + ')');
|
|
158
|
-
data.changedFiles.forEach(function(file) {
|
|
159
|
-
console.log(' •', file);
|
|
160
|
-
});
|
|
161
|
-
console.groupEnd();
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// 超过阈值警告
|
|
165
|
-
if (data.isOverThreshold) {
|
|
166
|
-
console.warn('⚠️ HMR 耗时超过阈值 ' + threshold + 'ms');
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
console.log(''); // 空行分隔
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
// 监听 webpack-dev-server 的 WebSocket 消息
|
|
173
|
-
if (typeof __webpack_dev_server_client__ !== 'undefined') {
|
|
174
|
-
// webpack-dev-server 4.x/5.x
|
|
175
|
-
const originalOnMessage = __webpack_dev_server_client__.onMessage;
|
|
176
|
-
__webpack_dev_server_client__.onMessage = function(message) {
|
|
177
|
-
if (message.type === 'hmr-timing') {
|
|
178
|
-
logHMRTiming(message.data);
|
|
179
|
-
}
|
|
180
|
-
if (originalOnMessage) {
|
|
181
|
-
return originalOnMessage.apply(this, arguments);
|
|
182
|
-
}
|
|
183
|
-
};
|
|
184
|
-
} else {
|
|
185
|
-
// 备用方案:监听 WebSocket
|
|
186
|
-
setTimeout(function() {
|
|
187
|
-
const ws = window.__webpack_dev_server_ws__;
|
|
188
|
-
if (ws && ws.addEventListener) {
|
|
189
|
-
ws.addEventListener('message', function(event) {
|
|
190
|
-
try {
|
|
191
|
-
const message = JSON.parse(event.data);
|
|
192
|
-
if (message.type === 'hmr-timing') {
|
|
193
|
-
logHMRTiming(message.data);
|
|
194
|
-
}
|
|
195
|
-
} catch (e) {}
|
|
196
|
-
});
|
|
197
|
-
}
|
|
198
|
-
}, 1000);
|
|
199
|
-
}
|
|
200
|
-
})();
|
|
201
|
-
`;
|
|
202
|
-
compiler.hooks.compilation.tap('HMRTimingPlugin', (compilation) => {
|
|
203
|
-
compilation.hooks.processAssets.tap({
|
|
204
|
-
name: 'HMRTimingPlugin',
|
|
205
|
-
stage: compilation.constructor.PROCESS_ASSETS_STAGE_ADDITIONAL,
|
|
206
|
-
}, () => {
|
|
207
|
-
// 注入到主入口文件
|
|
208
|
-
const mainAssets = Object.keys(compilation.assets).filter(name => name.match(/^(main|index|app|bundle).*\.js$/) && !name.includes('hot-update'));
|
|
209
|
-
if (mainAssets.length > 0) {
|
|
210
|
-
const assetName = mainAssets[0];
|
|
211
|
-
const asset = compilation.assets[assetName];
|
|
212
|
-
const source = asset.source();
|
|
213
|
-
const newSource = clientScript + '\n' + source;
|
|
214
|
-
compilation.assets[assetName] = {
|
|
215
|
-
source: () => newSource,
|
|
216
|
-
size: () => newSource.length,
|
|
217
|
-
map: () => asset.map ? asset.map() : null
|
|
218
|
-
};
|
|
219
|
-
}
|
|
220
|
-
});
|
|
221
|
-
});
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
module.exports = HMRTimingPlugin;
|
|
225
|
-
/**
|
|
226
|
-
* 使用示例:
|
|
227
|
-
*
|
|
228
|
-
* // webpack.config.js
|
|
229
|
-
* const HMRTimingPlugin = require('./HMRTimingPlugin');
|
|
230
|
-
*
|
|
231
|
-
* module.exports = {
|
|
232
|
-
* mode: 'development',
|
|
233
|
-
* devServer: {
|
|
234
|
-
* hot: true,
|
|
235
|
-
* },
|
|
236
|
-
* plugins: [
|
|
237
|
-
* new HMRTimingPlugin({
|
|
238
|
-
* threshold: 1000 // 超过1秒会显示警告
|
|
239
|
-
* })
|
|
240
|
-
* ]
|
|
241
|
-
* };
|
|
242
|
-
*
|
|
243
|
-
* 浏览器控制台输出示例:
|
|
244
|
-
*
|
|
245
|
-
* 🔥 HMR 更新完成 - 耗时: 523ms
|
|
246
|
-
* 📝 热更文件 (2)
|
|
247
|
-
* • src/components/App.jsx
|
|
248
|
-
* • src/styles/main.css
|
|
249
|
-
*
|
|
250
|
-
* 🔥 HMR 更新完成 - 耗时: 1250ms
|
|
251
|
-
* 📝 热更文件 (1)
|
|
252
|
-
* • src/utils/helper.js
|
|
253
|
-
* ⚠️ HMR 耗时超过阈值 1000ms
|
|
254
|
-
*
|
|
255
|
-
* 功能特性:
|
|
256
|
-
* - 显示 HMR 耗时(带颜色提示)
|
|
257
|
-
* - 显示热更新的文件列表(可折叠)
|
|
258
|
-
* - 超过阈值时显示警告
|
|
259
|
-
* - 通过 DevServer WebSocket 通信
|
|
260
|
-
* - 自动过滤 node_modules
|
|
261
|
-
* - 简化文件路径显示
|
|
262
|
-
*/
|