优化了部分方法实现

This commit is contained in:
2025-08-17 00:15:47 +08:00
parent ebb617bb96
commit 7da191231e
3 changed files with 166 additions and 139 deletions

View File

@@ -76,7 +76,7 @@ wxSDK({
| `sdk` | string | `https://res.wx.qq.com/open/js/jweixin-1.6.0.js` | 否 | 微信 SDK URL | | `sdk` | string | `https://res.wx.qq.com/open/js/jweixin-1.6.0.js` | 否 | 微信 SDK URL |
| `title` | string \| string[] | `['分享至朋友圈', '分享至好友']` | 否 | 分享标题 | | `title` | string \| string[] | `['分享至朋友圈', '分享至好友']` | 否 | 分享标题 |
| `desc` | string | `'万事皆虚,万物皆允'` | 否 | 分享描述 | | `desc` | string | `'万事皆虚,万物皆允'` | 否 | 分享描述 |
| `shareIcon` | string \| string[] | 网站图标 | 否 | 分享图标 URL | | `shareIcon` | string \| string[] | 网站图标 | 否 | 分享图标 URL如果没有使用该属性将自动抓取页面头部类型为icon的资源作为分享图 |
| `shareLinks` | string \| string[] | 当前页面 URL | 否 | 分享链接 | | `shareLinks` | string \| string[] | 当前页面 URL | 否 | 分享链接 |
| `debug` | boolean | `false` | 否 | 启用调试模式 | | `debug` | boolean | `false` | 否 | 启用调试模式 |
| `jsApiList` | string[] | `[]` | 否 | 微信 JS API 列表 | | `jsApiList` | string[] | `[]` | 否 | 微信 JS API 列表 |

301
index.js
View File

@@ -6,7 +6,8 @@
const wxSDK = (options = {}) => { const wxSDK = (options = {}) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
// 环境检测 // 环境检测
const w = typeof window !== 'undefined' ? window : self const globalThis = typeof global !== 'undefined' ? global : self
const w = typeof window !== 'undefined' ? window : globalThis
if (!w.document) { if (!w.document) {
return reject(new Error('wxSDK只能在浏览器环境下使用')) return reject(new Error('wxSDK只能在浏览器环境下使用'))
} }
@@ -30,7 +31,7 @@ const wxSDK = (options = {}) => {
}, },
} }
// 合并配置(深度合并回调函数) // 深度合并配置
const config = { const config = {
...defaultConfig, ...defaultConfig,
...options, ...options,
@@ -44,70 +45,110 @@ const wxSDK = (options = {}) => {
// 参数校验 // 参数校验
if (!apiUrl) { if (!apiUrl) {
return reject(new Error('apiUrl is required')) return reject(new Error('apiUrl为必填参数'))
} }
// 处理分享图标(使用 let 声明) // 处理分享图标
let { shareIcon } = config let { shareIcon } = config
try { try {
const favicon = document.querySelector('link[rel="shortcut icon"], link[rel="icon"]') const favicon = document.querySelector('link[rel*="icon"]')
if (favicon && favicon.href) { if (favicon && favicon.href) {
shareIcon = favicon.href shareIcon = favicon.href
} }
} catch (e) { } catch (e) {
console.warn('Favicon detection failed:', e) console.warn('网站图标检测失败:', e)
} }
// SDK 加载管理 // 常量定义
const scriptId = 'wxShare' const SCRIPT_ID = 'wxShareSDK'
let scriptTag = document.getElementById(scriptId) const BASE_API_LIST = ['updateTimelineShareData', 'updateAppMessageShareData']
let loadTimeout const DEFAULT_OPEN_TAGS = ['wx-open-launch-app']
// 清理资源
let scriptTag = document.getElementById(SCRIPT_ID)
let timeoutId
const cleanup = () => { const cleanup = () => {
clearTimeout(loadTimeout) clearTimeout(timeoutId)
if (scriptTag) { if (scriptTag) {
scriptTag.onload = null scriptTag.onload = null
scriptTag.onerror = null scriptTag.onerror = null
} }
} }
// 加载微信SDK
const loadSDK = () => { const loadSDK = () => {
cleanup() cleanup()
scriptTag = document.createElement('script') scriptTag = document.createElement('script')
scriptTag.id = scriptId scriptTag.id = SCRIPT_ID
scriptTag.src = sdk scriptTag.src = sdk
scriptTag.async = true scriptTag.async = true
scriptTag.defer = true scriptTag.defer = true
// 超时处理 return new Promise((loadResolve, loadReject) => {
loadTimeout = setTimeout(() => { // 加载超时处理
cleanup() timeoutId = setTimeout(() => {
document.head.removeChild(scriptTag) cleanup()
reject(new Error(`微信JSSDK加载超时 ${timeout}ms`)) document.head.removeChild(scriptTag)
}, timeout) loadReject(new Error(`微信JSSDK加载超时 (${timeout}ms)`))
}, timeout)
scriptTag.onload = () => { scriptTag.onload = () => {
cleanup() cleanup()
initWeChat() loadResolve()
} }
scriptTag.onerror = err => { scriptTag.onerror = err => {
cleanup() cleanup()
document.head.removeChild(scriptTag) document.head.removeChild(scriptTag)
reject(new Error('微信JSSDK加载错误')) loadReject(new Error('微信JSSDK加载失败'))
} }
document.head.appendChild(scriptTag) document.head.appendChild(scriptTag)
})
} }
// 微信初始化 // 获取微信签名
const initWeChat = () => { const fetchSignature = async () => {
if (!w.wx) { const controller = new AbortController()
return reject(new Error('微信JSSDK加载不正确')) const fetchTimeout = setTimeout(() => controller.abort(), timeout)
try {
const response = await fetch(`${apiUrl}${encodeURIComponent(w.location.href.split('#')[0])}`, {
signal: controller.signal,
})
clearTimeout(fetchTimeout)
if (!response.ok) {
throw new Error(`网络请求失败 (${response.status})`)
}
const res = await response.json()
const { appId, timestamp, nonceStr, signature } = res || {}
if (!appId || !timestamp || !nonceStr || !signature) {
throw new Error('接口响应格式错误')
}
return { appId, timestamp, nonceStr, signature }
} catch (err) {
clearTimeout(fetchTimeout)
throw new Error(`签名接口请求错误: ${err.message}`)
}
}
// 配置微信分享
const configureWeChat = async () => {
if (!w.wx || typeof w.wx.config !== 'function') {
throw new Error('微信JSSDK未正确加载')
} }
// 参数处理 // 获取签名
const signatureData = await fetchSignature()
// 准备分享配置
const timelineConfig = { const timelineConfig = {
title: Array.isArray(title) ? title[0] : title, title: Array.isArray(title) ? title[0] : title,
link: Array.isArray(shareLinks) ? shareLinks[0] : shareLinks.split('#')[0], link: Array.isArray(shareLinks) ? shareLinks[0] : shareLinks.split('#')[0],
@@ -121,119 +162,105 @@ const wxSDK = (options = {}) => {
desc, desc,
} }
// API 列表处理 // 合并API列表
const baseApiList = ['updateTimelineShareData', 'updateAppMessageShareData'] const fullApiList = [...new Set([...BASE_API_LIST, ...jsApiList])]
const fullApiList = [...new Set([...baseApiList, ...jsApiList])] const fullOpenTagList = [...new Set([...DEFAULT_OPEN_TAGS, ...openTagList])]
const fullOpenTagList = ['wx-open-launch-app', ...openTagList]
// 获取签名 // 初始化微信配置
fetch(`${apiUrl}${w.location.href.split('#')[0]}`) w.wx.config({
.then(response => { debug,
if (!response.ok) { ...signatureData,
throw new Error(`网络请求失败 (${response.status})`) jsApiList: fullApiList,
} openTagList: fullOpenTagList,
return response.json() })
})
.then(res => { // 返回封装后的wx对象
const { appId, timestamp, nonceStr, signature } = res || {} return new Promise((wxResolve, wxReject) => {
if (!appId || !timestamp || !nonceStr || !signature) { w.wx.error(wxReject)
throw new Error('接口响应格式错误')
w.wx.ready(() => {
const shareOperations = []
// 配置朋友圈分享
if (w.wx.updateTimelineShareData) {
shareOperations.push(
new Promise(shareResolve => {
w.wx.updateTimelineShareData({
...timelineConfig,
success: () => {
callback.success?.('timeline')
shareResolve()
},
fail: err => {
callback.error?.(err)
shareResolve() // 不阻断流程
},
})
})
)
} }
// 微信配置 // 配置好友分享
w.wx.config({ if (w.wx.updateAppMessageShareData) {
debug, shareOperations.push(
appId, new Promise(shareResolve => {
timestamp, w.wx.updateAppMessageShareData({
nonceStr, ...messageConfig,
signature, success: () => {
jsApiList: fullApiList, callback.success?.('message')
openTagList: fullOpenTagList, shareResolve()
}) },
fail: err => {
w.wx.error(err => { callback.error?.(err)
callback.error?.(err) shareResolve() // 不阻断流程
reject(err) },
})
w.wx.ready(() => {
try {
const shareOperations = []
// 朋友圈分享
if (w.wx.updateTimelineShareData) {
shareOperations.push(
new Promise(shareResolve => {
w.wx.updateTimelineShareData({
...timelineConfig,
success: () => {
callback.success?.('timeline')
shareResolve()
},
fail: err => {
callback.error?.(err)
shareResolve() // 不阻断流程
},
})
})
)
}
// 好友分享
if (w.wx.updateAppMessageShareData) {
shareOperations.push(
new Promise(shareResolve => {
w.wx.updateAppMessageShareData({
...messageConfig,
success: () => {
callback.success?.('message')
shareResolve()
},
fail: err => {
callback.error?.(err)
shareResolve() // 不阻断流程
},
})
})
)
}
// 等待所有分享配置完成
Promise.all(shareOperations)
.then(() => {
callback.ready?.()
resolve(w.wx)
}) })
.catch(e => { })
console.error('分享设置失败:', e) )
callback.ready?.() }
resolve(w.wx) // 仍返回wx对象
}) // 等待所有分享配置完成
} catch (e) { Promise.all(shareOperations)
reject(e) .then(() => {
} callback.ready?.()
}) wxResolve(w.wx)
}) })
.catch(err => { .catch(e => {
reject(new Error(`签名接口请求错误: ${err.message}`)) console.error('分享设置部分失败:', e)
callback.ready?.()
wxResolve(w.wx) // 仍返回wx对象
})
}) })
})
} }
// 加载SDK // 主执行流程
if (typeof w.wx === 'object' && w.wx.config) { const initialize = async () => {
// 已加载SDK try {
initWeChat() // 加载SDK如果需要
} else if (scriptTag) { if (!w.wx || typeof w.wx.config !== 'function') {
// 正在加载中 if (scriptTag && scriptTag.parentNode) {
scriptTag.onload = initWeChat // 等待正在加载的SDK
scriptTag.onerror = err => { await new Promise((resolve, reject) => {
cleanup() scriptTag.onload = resolve
reject(new Error('微信JSSDK加载失败')) scriptTag.onerror = () => reject(new Error('SDK加载失败'))
})
} else {
await loadSDK()
}
}
// 配置微信功能
const wxInstance = await configureWeChat()
resolve(wxInstance)
} catch (err) {
callback.error?.(err)
reject(err)
} }
} else {
// 全新加载
loadSDK()
} }
// 启动初始化
initialize()
}) })
} }

View File

@@ -1,6 +1,6 @@
{ {
"name": "wxsdk-pure", "name": "wxsdk-pure",
"version": "1.0.3", "version": "1.0.4",
"description": "微信分享 SDK 封装", "description": "微信分享 SDK 封装",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {