@base-web-kits/base-tools-web 1.3.6 → 1.3.10
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 +79 -0
- package/dist/base-tools-web.umd.global.js +20 -7
- package/dist/base-tools-web.umd.global.js.map +1 -1
- package/dist/index.cjs +20 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +20 -7
- package/dist/index.mjs.map +1 -1
- package/dist/network/request.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/web/network/request.ts +628 -609
package/README.md
CHANGED
|
@@ -98,3 +98,82 @@ setBaseToolsConfig({
|
|
|
98
98
|
</body>
|
|
99
99
|
</html>
|
|
100
100
|
```
|
|
101
|
+
|
|
102
|
+
## 🤖 AI 智能助手 (Skill)
|
|
103
|
+
|
|
104
|
+
本项目提供了强大的 AI Skill,可让 Cursor、Trae、Claude Code 等 AI 助手深度理解 `@base-web-kits` 的能力,为您精准推荐最佳实践函数,并自动处理依赖安装。
|
|
105
|
+
|
|
106
|
+
### 安装方式
|
|
107
|
+
|
|
108
|
+
在项目根目录下执行以下命令:
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
npx skills add gancao-web/base-tools
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### 验证生效
|
|
115
|
+
|
|
116
|
+
安装完成后,可以在对话框中输入以下问题进行测试。如果 AI 推荐了 `@base-web-kits` 下的相关包或函数,说明配置已生效。
|
|
117
|
+
|
|
118
|
+
| 测试场景 | 推荐提问 | 预期 AI 回答 |
|
|
119
|
+
| :-- | :-- | :-- |
|
|
120
|
+
| **JS工具库** | "我需要深拷贝一个对象,请编写或推荐一个函数,优先考虑已配置的skill" | 推荐使用 `base-tools-ts` 的 `cloneDeep` |
|
|
121
|
+
| **JS正则验证** | "我需要校验邮箱格式,请编写或推荐一个函数,优先考虑已配置的skill" | 推荐使用 `base-tools-ts` 的 `isEmail` |
|
|
122
|
+
| **通用web** | "我需要复制文本到剪贴板,请编写或推荐一个函数,优先考虑已配置的skill" | 推荐使用 `base-tools-web` 的 `copyText` |
|
|
123
|
+
| **React项目** | "我需要监听dom元素的尺寸变化,请编写或推荐一个函数,优先考虑已配置的skill" | 推荐使用 `base-tools-react` 的 `useSize` |
|
|
124
|
+
| **Vue项目** | "我需要监听元素外部点击事件,请编写或推荐一个函数,优先考虑已配置的skill" | 推荐使用 `base-tools-vue` 的 `onClickOutside` |
|
|
125
|
+
| **UniApp项目** | "我需要保存网络图片到系统相册,请编写或推荐一个函数,优先考虑已配置的skill" | 推荐使用 `base-tools-uni` 的 `saveImageToPhotosAlbum` 函数 |
|
|
126
|
+
|
|
127
|
+
## 兼容性
|
|
128
|
+
|
|
129
|
+
本工具库和相关依赖可能涉及的新特性及其最低兼容版本:
|
|
130
|
+
|
|
131
|
+
| 特性 | ES 版本 | 最低兼容版本 (Browser/OS) |
|
|
132
|
+
| :--------------------------------------- | :------ | :---------------------------------- |
|
|
133
|
+
| **Object.values / entries** | ES2017 | Chrome 54+, iOS 10.3+, Android 7.0+ |
|
|
134
|
+
| **String.prototype.padStart / padEnd** | ES2017 | Chrome 57+, iOS 10.3+, Android 8.0+ |
|
|
135
|
+
| **Object.getOwnPropertyDescriptors** | ES2017 | Chrome 54+, iOS 10.3+, Android 7.0+ |
|
|
136
|
+
| **Promise.prototype.finally** | ES2018 | Chrome 63+, iOS 11.3+, Android 9.0+ |
|
|
137
|
+
| **Symbol.asyncIterator** | ES2018 | Chrome 63+, iOS 12.0+, Android 9.0+ |
|
|
138
|
+
| **Object.fromEntries** | ES2019 | Chrome 73+, iOS 12.2+, Android 10+ |
|
|
139
|
+
| **Array.prototype.flat / flatMap** | ES2019 | Chrome 69+, iOS 12.0+, Android 9.0+ |
|
|
140
|
+
| **String.prototype.trimStart / trimEnd** | ES2019 | Chrome 66+, iOS 12.0+, Android 9.0+ |
|
|
141
|
+
| **Promise.allSettled** | ES2020 | Chrome 76+, iOS 13.0+, Android 10+ |
|
|
142
|
+
| **String.prototype.matchAll** | ES2020 | Chrome 80+, iOS 13.0+, Android 10+ |
|
|
143
|
+
| **BigInt** | ES2020 | Chrome 67+, iOS 14.0+, Android 11+ |
|
|
144
|
+
| **globalThis** | ES2020 | Chrome 71+, iOS 12.2+, Android 9.0+ |
|
|
145
|
+
| **String.prototype.replaceAll** | ES2021 | Chrome 85+, iOS 13.4+, Android 11+ |
|
|
146
|
+
| **Promise.any** | ES2021 | Chrome 85+, iOS 14.0+, Android 11+ |
|
|
147
|
+
| **WeakRef / FinalizationRegistry** | ES2021 | Chrome 84+, iOS 14.5+, Android 11+ |
|
|
148
|
+
| **Array/String.prototype.at** | ES2022 | Chrome 92+, iOS 15.4+, Android 12+ |
|
|
149
|
+
| **Error.prototype.cause** | ES2022 | Chrome 93+, iOS 15.0+, Android 12+ |
|
|
150
|
+
| **Object.hasOwn** | ES2022 | Chrome 93+, iOS 15.4+, Android 12+ |
|
|
151
|
+
|
|
152
|
+
本工具库构建目标为 **ES2015+**。但不内置 Polyfill, 如需支持低版本浏览器, 请务必在项目中配置 Polyfill。
|
|
153
|
+
|
|
154
|
+
### 配置 Polyfill
|
|
155
|
+
|
|
156
|
+
以 Vite 项目为例, 使用 `@vitejs/plugin-legacy` 插件自动按需注入 Polyfill。
|
|
157
|
+
|
|
158
|
+
```ts
|
|
159
|
+
// vite.config.ts
|
|
160
|
+
import legacy from '@vitejs/plugin-legacy'; // 安装命令: npm install -D @vitejs/plugin-legacy
|
|
161
|
+
|
|
162
|
+
export default {
|
|
163
|
+
plugins: [
|
|
164
|
+
legacy({
|
|
165
|
+
// 与antd4兼容性对齐 https://4x-ant-design.antgroup.com/docs/react/introduce-cn
|
|
166
|
+
// targets: ['defaults', 'not IE 11'],
|
|
167
|
+
|
|
168
|
+
// 与vant4兼容性对齐 https://vant4.ylhtest.com/#/zh-CN/home
|
|
169
|
+
// targets: ['chrome >= 51', 'android >= 5', 'ios >= 10'],
|
|
170
|
+
|
|
171
|
+
// 与Element对齐: https://element-plus.org/zh-CN/guide/installation
|
|
172
|
+
targets: ['Chrome >= 64', 'Edge >= 79', 'Firefox >= 78', 'Safari >= 12', 'not IE 11'],
|
|
173
|
+
|
|
174
|
+
// 按需自动引入polyfill (需使用vite3以上版本,因为vite2.x缺少新的ES特性,如Object.hasOwn)
|
|
175
|
+
modernPolyfills: true,
|
|
176
|
+
}),
|
|
177
|
+
],
|
|
178
|
+
};
|
|
179
|
+
```
|
|
@@ -2064,7 +2064,7 @@ var baseToolsWeb = (() => {
|
|
|
2064
2064
|
onTaskReady == null ? void 0 : onTaskReady(task);
|
|
2065
2065
|
return new Promise((resolve, reject) => {
|
|
2066
2066
|
const execute = () => __async(null, null, function* () {
|
|
2067
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
2067
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
2068
2068
|
const isGet = method === "GET";
|
|
2069
2069
|
const isObjectData = isPlainObject(data);
|
|
2070
2070
|
const isArrayData = !isObjectData && Array.isArray(data);
|
|
@@ -2118,7 +2118,7 @@ var baseToolsWeb = (() => {
|
|
|
2118
2118
|
controller.abort();
|
|
2119
2119
|
}, timeout);
|
|
2120
2120
|
try {
|
|
2121
|
-
|
|
2121
|
+
let response = yield fetch(fillUrl, {
|
|
2122
2122
|
method,
|
|
2123
2123
|
headers: fillHeader,
|
|
2124
2124
|
body: fillBody,
|
|
@@ -2126,9 +2126,20 @@ var baseToolsWeb = (() => {
|
|
|
2126
2126
|
});
|
|
2127
2127
|
if (!response.ok) {
|
|
2128
2128
|
if (showLoading) (_b = appConfig2.hideLoading) == null ? void 0 : _b.call(appConfig2);
|
|
2129
|
-
|
|
2129
|
+
let errorText;
|
|
2130
|
+
try {
|
|
2131
|
+
errorText = yield response.text();
|
|
2132
|
+
JSON.parse(errorText);
|
|
2133
|
+
} catch (e) {
|
|
2134
|
+
throw new Error(`HTTP Error ${response.status}`);
|
|
2135
|
+
}
|
|
2136
|
+
response = new Response(errorText, {
|
|
2137
|
+
status: response.status,
|
|
2138
|
+
statusText: response.statusText,
|
|
2139
|
+
headers: response.headers
|
|
2140
|
+
});
|
|
2130
2141
|
}
|
|
2131
|
-
if (enableChunked) {
|
|
2142
|
+
if (enableChunked && response.ok) {
|
|
2132
2143
|
if (showLoading) (_c = appConfig2.hideLoading) == null ? void 0 : _c.call(appConfig2);
|
|
2133
2144
|
const res2 = yield handleStreamResponse(response, sseTask);
|
|
2134
2145
|
logRequestInfo({ status: "success", config: logConfig, startTime, res: res2 });
|
|
@@ -2155,16 +2166,18 @@ var baseToolsWeb = (() => {
|
|
|
2155
2166
|
reject(res);
|
|
2156
2167
|
}
|
|
2157
2168
|
} catch (e) {
|
|
2169
|
+
if (showLoading) (_g = appConfig2.hideLoading) == null ? void 0 : _g.call(appConfig2);
|
|
2158
2170
|
const status = "fail";
|
|
2159
2171
|
const isAbortError = e instanceof DOMException && e.name === "AbortError";
|
|
2160
2172
|
if (isAbortError && isTimeout) {
|
|
2161
|
-
if (toastError) (
|
|
2173
|
+
if (toastError) (_h = appConfig2.toast) == null ? void 0 : _h.call(appConfig2, { status, msg: "\u8BF7\u6C42\u8D85\u65F6" });
|
|
2162
2174
|
const timeoutError = new Error("Request Timeout");
|
|
2163
2175
|
logRequestInfo({ status, config: logConfig, startTime, e: timeoutError });
|
|
2164
2176
|
reject(timeoutError);
|
|
2165
2177
|
return;
|
|
2166
2178
|
}
|
|
2167
|
-
if (!isAbortError && toastError)
|
|
2179
|
+
if (!isAbortError && toastError)
|
|
2180
|
+
(_i = appConfig2.toast) == null ? void 0 : _i.call(appConfig2, { status, msg: `\u8BF7\u6C42\u5931\u8D25,${String(e)}` });
|
|
2168
2181
|
logRequestInfo({ status, config: logConfig, startTime, e });
|
|
2169
2182
|
reject(e);
|
|
2170
2183
|
} finally {
|
|
@@ -2214,7 +2227,7 @@ var baseToolsWeb = (() => {
|
|
|
2214
2227
|
info.res = cloneDeep(res);
|
|
2215
2228
|
log("info", info);
|
|
2216
2229
|
} else {
|
|
2217
|
-
info.e = e;
|
|
2230
|
+
info.e = e instanceof Error ? { name: e.name, message: e.message, stack: e.stack } : String(e);
|
|
2218
2231
|
log("error", info);
|
|
2219
2232
|
}
|
|
2220
2233
|
}
|