714 lines
17 KiB
Markdown
714 lines
17 KiB
Markdown
|
|
# chunk-vendors.4d47960d.js 详细分析
|
|||
|
|
|
|||
|
|
## 文件信息
|
|||
|
|
- **文件名**: chunk-vendors.4d47960d.js
|
|||
|
|
- **大小**: 1.18MB (1,181,721 bytes)
|
|||
|
|
- **类型**: Webpack第三方依赖打包文件
|
|||
|
|
- **压缩**: 高度压缩,约26行
|
|||
|
|
- **模块数**: 约200+个模块
|
|||
|
|
|
|||
|
|
## 文件用途
|
|||
|
|
|
|||
|
|
这是Webpack打包的第三方依赖库文件,包含应用所需的所有外部库和polyfills。主要包括:
|
|||
|
|
- uni-simple-router(完整路由库)
|
|||
|
|
- 加密库(HMAC, SHA, MD5等)
|
|||
|
|
- Buffer实现
|
|||
|
|
- 各种Polyfills
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 主要库分类
|
|||
|
|
|
|||
|
|
### 1. uni-simple-router 路由库
|
|||
|
|
|
|||
|
|
这是核心依赖,占据了大部分代码量。
|
|||
|
|
|
|||
|
|
#### 核心模块
|
|||
|
|
|
|||
|
|
| 模块ID | 名称 | 功能 |
|
|||
|
|
|--------|------|------|
|
|||
|
|
| **607** | 主入口 | 导出createRouter, RouterMount等 |
|
|||
|
|
| **366** | 常量定义 | hookToggle, navtypeToggle等 |
|
|||
|
|
| **309** | 类型定义 | TypeScript类型声明 |
|
|||
|
|
| **169** | 钩子调用 | loopCallHook, transitionTo等 |
|
|||
|
|
| **890** | 导航跳转 | navjump, lockNavjump, createRoute |
|
|||
|
|
| **845** | 页面钩子 | proxyPageHook, createFullPath |
|
|||
|
|
| **99** | 查询参数 | queryPageToMap, parseQuery |
|
|||
|
|
| **314** | 方法重写 | rewriteMethod |
|
|||
|
|
| **963** | 路由创建 | createRouter, RouterMount |
|
|||
|
|
| **809** | 原生跳转 | uniOriginJump |
|
|||
|
|
| **662** | 钩子注册 | registerEachHooks |
|
|||
|
|
| **460** | Mixins | initMixins, getMixins |
|
|||
|
|
| **789** | 工具函数 | deepClone, getDataType等 |
|
|||
|
|
| **883** | 日志工具 | err, warn, log |
|
|||
|
|
| **282** | 配置常量 | baseConfig, proxyHookName |
|
|||
|
|
| **801** | 路由映射 | createRouteMap |
|
|||
|
|
| **814** | 加载页面 | registerLoddingPage |
|
|||
|
|
| **334** | 路径获取 | getEnterPath |
|
|||
|
|
| **779** | 路径匹配 | pathToRegexp |
|
|||
|
|
|
|||
|
|
#### 功能详解
|
|||
|
|
|
|||
|
|
##### 路由创建 (模块 963)
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
function createRouter(options) {
|
|||
|
|
return {
|
|||
|
|
// 配置
|
|||
|
|
options,
|
|||
|
|
mount: [],
|
|||
|
|
Vue: null,
|
|||
|
|
routesMap: {},
|
|||
|
|
|
|||
|
|
// 导航方法
|
|||
|
|
push(location) { ... },
|
|||
|
|
replace(location) { ... },
|
|||
|
|
replaceAll(location) { ... },
|
|||
|
|
pushTab(location) { ... },
|
|||
|
|
back(delta, options) { ... },
|
|||
|
|
|
|||
|
|
// 守卫
|
|||
|
|
beforeEach(fn) { ... },
|
|||
|
|
afterEach(fn) { ... },
|
|||
|
|
|
|||
|
|
// 安装
|
|||
|
|
install(Vue) { ... }
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
##### 导航跳转 (模块 890)
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
// 核心导航函数
|
|||
|
|
function navjump(rule, router, NAVTYPE, forceNav, uniActualData, callback, passthrough) {
|
|||
|
|
// 1. 处理back类型
|
|||
|
|
if (NAVTYPE === "back") {
|
|||
|
|
// 构建返回参数
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 2. 解析路由
|
|||
|
|
var query = queryPageToMap(rule, router).rule;
|
|||
|
|
query.type = navtypeToggle[NAVTYPE];
|
|||
|
|
|
|||
|
|
// 3. 处理params到query
|
|||
|
|
var finalRule = paramsToQuery(router, query);
|
|||
|
|
var resolvedRule = resolveQuery(finalRule, router);
|
|||
|
|
|
|||
|
|
// 4. H5平台特殊处理
|
|||
|
|
if (router.options.platform === "h5") {
|
|||
|
|
if (NAVTYPE !== "push") NAVTYPE = "replace";
|
|||
|
|
|
|||
|
|
if (forceNav != null) {
|
|||
|
|
forceNav.next({ replace: NAVTYPE !== "push", ...resolvedRule });
|
|||
|
|
} else {
|
|||
|
|
router.$route[NAVTYPE](resolvedRule);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
// 5. 小程序/App平台
|
|||
|
|
else {
|
|||
|
|
// 创建to和from
|
|||
|
|
var to = createToFrom(resolvedRule, router);
|
|||
|
|
var from = getCurrentRoute(router);
|
|||
|
|
|
|||
|
|
createFullPath(resolvedRule, from);
|
|||
|
|
|
|||
|
|
if (!passthrough) {
|
|||
|
|
return resolvedRule;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 触发守卫
|
|||
|
|
transitionTo(router, resolvedRule, from, NAVTYPE, HOOKLIST, function(next) {
|
|||
|
|
uni[navtypeToggle[NAVTYPE]](resolvedRule, true, next, callback);
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 带锁的导航
|
|||
|
|
function lockNavjump(rule, router, NAVTYPE, forceNav, uniActualData) {
|
|||
|
|
lockDetectWarn(router, rule, NAVTYPE, function() {
|
|||
|
|
// H5不锁定
|
|||
|
|
if (router.options.platform !== "h5") {
|
|||
|
|
router.$lockStatus = true;
|
|||
|
|
}
|
|||
|
|
navjump(rule, router, NAVTYPE, void 0, forceNav, uniActualData);
|
|||
|
|
}, uniActualData);
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
##### 路由守卫 (模块 169)
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
// 守卫钩子列表
|
|||
|
|
var HOOKLIST = [
|
|||
|
|
// 1. 全局前置守卫
|
|||
|
|
function(router, to, from, route, next) {
|
|||
|
|
callHook(router.lifeCycle.routerBeforeHooks[0], to, from, router, next);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 2. 组件beforeRouteLeave
|
|||
|
|
function(router, to, from, route, next) {
|
|||
|
|
callBeforeRouteLeave(router, to, from, next);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 3. 路由beforeHooks
|
|||
|
|
function(router, to, from, route, next) {
|
|||
|
|
callHook(router.lifeCycle.beforeHooks[0], to, from, router, next);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 4. 路由独享守卫beforeEnter
|
|||
|
|
function(router, to, from, route, next) {
|
|||
|
|
callHook(route.beforeEnter, to, from, router, next);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 5. 路由afterHooks
|
|||
|
|
function(router, to, from, route, next) {
|
|||
|
|
router.$lockStatus = false;
|
|||
|
|
|
|||
|
|
if (router.options.platform === "h5") {
|
|||
|
|
proxyH5Mount(router);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
callHook(router.lifeCycle.afterHooks[0], to, from, router, next, false);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 6. 全局后置守卫
|
|||
|
|
function(router, to, from, route, next) {
|
|||
|
|
router.$lockStatus = false;
|
|||
|
|
|
|||
|
|
if (router.options.platform === "h5") {
|
|||
|
|
proxyH5Mount(router);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
callHook(router.lifeCycle.routerAfterHooks[0], to, from, router, next, false);
|
|||
|
|
}
|
|||
|
|
];
|
|||
|
|
|
|||
|
|
// 循环调用钩子
|
|||
|
|
function loopCallHook(hooks, index, next, router, to, from, NAVTYPE) {
|
|||
|
|
// 如果所有钩子都执行完了
|
|||
|
|
if (hooks.length - 1 < index) {
|
|||
|
|
return next();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var hook = hooks[index];
|
|||
|
|
var errorHook = ERRORHOOK[0];
|
|||
|
|
|
|||
|
|
// 调用钩子
|
|||
|
|
hook(router, to, from, route, function(nextRule) {
|
|||
|
|
// App平台tab切换特殊处理
|
|||
|
|
if (router.options.platform === "app-plus") {
|
|||
|
|
if (nextRule !== false &&
|
|||
|
|
typeof nextRule !== "string" &&
|
|||
|
|
typeof nextRule !== "object") {
|
|||
|
|
tabIndexSelect(to, from);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 1. next(false) - 终止导航
|
|||
|
|
if (nextRule === false) {
|
|||
|
|
if (router.options.platform === "h5") {
|
|||
|
|
next(false);
|
|||
|
|
}
|
|||
|
|
errorHook({
|
|||
|
|
type: 0,
|
|||
|
|
msg: "管道函数传递 false 导航被终止!",
|
|||
|
|
matTo: to,
|
|||
|
|
matFrom: from,
|
|||
|
|
nextTo: nextRule
|
|||
|
|
}, router);
|
|||
|
|
}
|
|||
|
|
// 2. next(string|object) - 重定向
|
|||
|
|
else if (typeof nextRule === "string" || typeof nextRule === "object") {
|
|||
|
|
var redirectNAVTYPE = NAVTYPE;
|
|||
|
|
var redirectRule = nextRule;
|
|||
|
|
|
|||
|
|
if (typeof nextRule === "object") {
|
|||
|
|
var NAVTYPE_OVERRIDE = nextRule.NAVTYPE;
|
|||
|
|
redirectRule = objectWithoutProperties(nextRule, ["NAVTYPE"]);
|
|||
|
|
|
|||
|
|
if (NAVTYPE_OVERRIDE != null) {
|
|||
|
|
redirectNAVTYPE = NAVTYPE_OVERRIDE;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
navjump(redirectRule, router, redirectNAVTYPE, { from, next });
|
|||
|
|
}
|
|||
|
|
// 3. next() - 继续
|
|||
|
|
else if (nextRule == null) {
|
|||
|
|
index++;
|
|||
|
|
loopCallHook(hooks, index, next, router, to, from, NAVTYPE);
|
|||
|
|
}
|
|||
|
|
// 4. 其他 - 错误
|
|||
|
|
else {
|
|||
|
|
errorHook({
|
|||
|
|
type: 1,
|
|||
|
|
msg: "管道函数传递未知类型,无法被识别。导航被终止!",
|
|||
|
|
matTo: to,
|
|||
|
|
matFrom: from,
|
|||
|
|
nextTo: nextRule
|
|||
|
|
}, router);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 转换导航
|
|||
|
|
function transitionTo(router, to, from, NAVTYPE, hooks, finalCallback) {
|
|||
|
|
var formattedRoutes = forMatNextToFrom(router, to, from);
|
|||
|
|
var matTo = formattedRoutes.matTo;
|
|||
|
|
var matFrom = formattedRoutes.matFrom;
|
|||
|
|
|
|||
|
|
// H5平台
|
|||
|
|
if (router.options.platform === "h5") {
|
|||
|
|
loopCallHook(hooks, 0, finalCallback, router, matTo, matFrom, NAVTYPE);
|
|||
|
|
}
|
|||
|
|
// 小程序/App平台
|
|||
|
|
else {
|
|||
|
|
// 分两步执行钩子
|
|||
|
|
// 第一步:前4个钩子
|
|||
|
|
loopCallHook(hooks.slice(0, 4), 0, function() {
|
|||
|
|
// 第二步:后2个钩子(在导航完成后)
|
|||
|
|
finalCallback(function() {
|
|||
|
|
loopCallHook(hooks.slice(4), 0, voidFun, router, matTo, matFrom, NAVTYPE);
|
|||
|
|
});
|
|||
|
|
}, router, matTo, matFrom, NAVTYPE);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
##### 页面钩子代理 (模块 845)
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
// 代理页面生命周期钩子
|
|||
|
|
function proxyPageHook(vueInstance, router, mpType) {
|
|||
|
|
var proxyHookDeps = router.proxyHookDeps;
|
|||
|
|
var options = vueInstance.$options;
|
|||
|
|
|
|||
|
|
var proxyHookNames = [
|
|||
|
|
"onLoad", "onShow", "onReady", "onHide",
|
|||
|
|
"onUnload", "onPullDownRefresh", "onReachBottom"
|
|||
|
|
];
|
|||
|
|
|
|||
|
|
for (var i = 0; i < proxyHookNames.length; i++) {
|
|||
|
|
var hookName = proxyHookNames[i];
|
|||
|
|
var hooks = options[hookName];
|
|||
|
|
|
|||
|
|
if (hooks) {
|
|||
|
|
for (var j = 0; j < hooks.length; j++) {
|
|||
|
|
// 跳过已代理的钩子
|
|||
|
|
if (hooks[j].toString().includes("UNI-SIMPLE-ROUTER")) {
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var hookId = Object.keys(proxyHookDeps.hooks).length + 1;
|
|||
|
|
|
|||
|
|
// 创建代理函数
|
|||
|
|
var proxyHook = function() {
|
|||
|
|
var args = Array.prototype.slice.call(arguments);
|
|||
|
|
proxyHookDeps.resetIndex.push(hookId);
|
|||
|
|
proxyHookDeps.options[hookId] = args;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 保存原始钩子
|
|||
|
|
var originalHook = hooks.splice(j, 1, proxyHook)[0];
|
|||
|
|
|
|||
|
|
// 保存钩子信息
|
|||
|
|
proxyHookDeps.hooks[hookId] = {
|
|||
|
|
proxyHook: proxyHook,
|
|||
|
|
callHook: function(path) {
|
|||
|
|
// 只在匹配路径时调用
|
|||
|
|
if (router.enterPath.replace(/^\//, "") === path.replace(/^\//, "") ||
|
|||
|
|
mpType === "app") {
|
|||
|
|
var args = proxyHookDeps.options[hookId];
|
|||
|
|
originalHook.apply(vueInstance, args);
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
resetHook: function() {
|
|||
|
|
hooks.splice(j, 1, originalHook);
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 重置并调用页面钩子
|
|||
|
|
function resetAndCallPageHook(router, path, reset) {
|
|||
|
|
if (reset === void 0) reset = true;
|
|||
|
|
|
|||
|
|
// 解析路径
|
|||
|
|
var match = path.trim().match(/^(\/?[^\?\s]+)(\?[\s\S]*$)?$/);
|
|||
|
|
if (match == null) {
|
|||
|
|
throw new Error("还原hook失败。请检查 【" + path + "】 路径是否正确。");
|
|||
|
|
}
|
|||
|
|
path = match[1];
|
|||
|
|
|
|||
|
|
var proxyHookDeps = router.proxyHookDeps;
|
|||
|
|
var resetIndex = proxyHookDeps.resetIndex;
|
|||
|
|
|
|||
|
|
// 调用所有钩子
|
|||
|
|
for (var i = 0; i < resetIndex.length; i++) {
|
|||
|
|
var hookId = resetIndex[i];
|
|||
|
|
proxyHookDeps.hooks[hookId].callHook(path);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 重置钩子
|
|||
|
|
if (reset) {
|
|||
|
|
resetPageHook(router);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 2. 加密库
|
|||
|
|
|
|||
|
|
#### HMAC (模块 0116)
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
/**
|
|||
|
|
* HMAC - Hash-based Message Authentication Code
|
|||
|
|
*
|
|||
|
|
* 算法:
|
|||
|
|
* HMAC(K, m) = H((K ⊕ opad) || H((K ⊕ ipad) || m))
|
|||
|
|
*
|
|||
|
|
* 其中:
|
|||
|
|
* - K: 密钥
|
|||
|
|
* - m: 消息
|
|||
|
|
* - H: 哈希函数
|
|||
|
|
* - ⊕: XOR运算
|
|||
|
|
* - ||: 连接
|
|||
|
|
* - ipad: 0x36重复blocksize次
|
|||
|
|
* - opad: 0x5C重复blocksize次
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
function Hmac(alg, key) {
|
|||
|
|
// 1. 如果key是字符串,转为Buffer
|
|||
|
|
if (typeof key === "string") {
|
|||
|
|
key = Buffer.from(key);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 2. 确定blocksize
|
|||
|
|
var blocksize = (alg === "sha512" || alg === "sha384") ? 128 : 64;
|
|||
|
|
|
|||
|
|
// 3. 处理key长度
|
|||
|
|
if (key.length > blocksize) {
|
|||
|
|
// key太长,先hash
|
|||
|
|
var hash = (alg === "rmd160") ? new rmd160() : sha(alg);
|
|||
|
|
key = hash.update(key).digest();
|
|||
|
|
} else if (key.length < blocksize) {
|
|||
|
|
// key太短,填充0
|
|||
|
|
key = Buffer.concat([key, zeroBuffer], blocksize);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 4. 计算ipad和opad
|
|||
|
|
var ipad = Buffer.allocUnsafe(blocksize);
|
|||
|
|
var opad = Buffer.allocUnsafe(blocksize);
|
|||
|
|
|
|||
|
|
for (var i = 0; i < blocksize; i++) {
|
|||
|
|
ipad[i] = key[i] ^ 0x36;
|
|||
|
|
opad[i] = key[i] ^ 0x5C;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 5. 初始化内部hash
|
|||
|
|
this._hash = (alg === "rmd160") ? new rmd160() : sha(alg);
|
|||
|
|
this._hash.update(ipad);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Hmac.prototype._final = function() {
|
|||
|
|
// 1. 计算内部hash
|
|||
|
|
var innerHash = this._hash.digest();
|
|||
|
|
|
|||
|
|
// 2. 计算外部hash
|
|||
|
|
var hash = (this._alg === "rmd160") ? new rmd160() : sha(this._alg);
|
|||
|
|
return hash.update(this._opad).update(innerHash).digest();
|
|||
|
|
};
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
支持的算法:
|
|||
|
|
- MD5
|
|||
|
|
- SHA1, SHA256, SHA384, SHA512
|
|||
|
|
- RIPEMD160
|
|||
|
|
|
|||
|
|
#### Cipher (模块 0168)
|
|||
|
|
|
|||
|
|
加密/解密基类,提供:
|
|||
|
|
- 缓冲区管理
|
|||
|
|
- 分块处理
|
|||
|
|
- 填充处理
|
|||
|
|
|
|||
|
|
#### Buffer (模块 5f79)
|
|||
|
|
|
|||
|
|
Node.js Buffer在浏览器环境的实现。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 3. 核心Polyfills
|
|||
|
|
|
|||
|
|
#### Object方法
|
|||
|
|
|
|||
|
|
| 模块ID | 方法 | 说明 |
|
|||
|
|
|--------|------|------|
|
|||
|
|
| **00ca** | getOwnPropertyNames | 获取对象自身属性名 |
|
|||
|
|
| **036b** | indexOf | 数组indexOf |
|
|||
|
|
| **338c** | hasOwnProperty | 检查自身属性 |
|
|||
|
|
| **f660** | toIndexedObject | 转为索引对象 |
|
|||
|
|
|
|||
|
|
#### Array方法
|
|||
|
|
|
|||
|
|
| 模块ID | 方法 | 说明 |
|
|||
|
|
|--------|------|------|
|
|||
|
|
| **bb80** | push | 数组push |
|
|||
|
|
| **00c2** | keys | 对象键名 |
|
|||
|
|
|
|||
|
|
#### 工具函数
|
|||
|
|
|
|||
|
|
| 模块ID | 功能 | 说明 |
|
|||
|
|
|--------|------|------|
|
|||
|
|
| **2c2e** | inherits | 继承工具 |
|
|||
|
|
| **cfef** | Transform | 流转换 |
|
|||
|
|
| **d3c2** | assert | 断言 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 4. uni-simple-router 详细功能
|
|||
|
|
|
|||
|
|
#### 路由配置选项
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
{
|
|||
|
|
// 平台类型
|
|||
|
|
platform: "h5" | "app-plus" | "mp-weixin" | "mp-alipay" | ...,
|
|||
|
|
|
|||
|
|
// 路由表
|
|||
|
|
routes: [
|
|||
|
|
{
|
|||
|
|
path: "/pages/index/index",
|
|||
|
|
name: "index",
|
|||
|
|
aliasPath: "/",
|
|||
|
|
meta: {},
|
|||
|
|
beforeEnter: function(to, from, next) {}
|
|||
|
|
}
|
|||
|
|
],
|
|||
|
|
|
|||
|
|
// H5配置
|
|||
|
|
h5: {
|
|||
|
|
vueRouterDev: false,
|
|||
|
|
vueNext: false,
|
|||
|
|
paramsToQuery: false
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 小程序配置
|
|||
|
|
applet: {
|
|||
|
|
animationDuration: 300
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// App配置
|
|||
|
|
APP: {
|
|||
|
|
animation: {
|
|||
|
|
animationType: "pop-in",
|
|||
|
|
animationDuration: 300
|
|||
|
|
},
|
|||
|
|
launchedHook: function() {}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 调试
|
|||
|
|
debugger: false | true | { err: true, warn: true, log: false },
|
|||
|
|
|
|||
|
|
// 守卫
|
|||
|
|
routerBeforeEach: function(to, from, next) {},
|
|||
|
|
routerAfterEach: function(to, from) {},
|
|||
|
|
routerErrorEach: function(error, router) {},
|
|||
|
|
|
|||
|
|
// 查询处理
|
|||
|
|
resolveQuery: function(query) { return query; },
|
|||
|
|
parseQuery: function(query) { return query; },
|
|||
|
|
|
|||
|
|
// 检测锁
|
|||
|
|
detectBeforeLock: function(router, to, navType) {}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 路由对象结构
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
{
|
|||
|
|
name: "index", // 路由名称
|
|||
|
|
path: "/pages/index/index", // 路径
|
|||
|
|
fullPath: "/pages/index/index?id=1", // 完整路径
|
|||
|
|
query: { id: "1" }, // 查询参数
|
|||
|
|
params: {}, // 路由参数
|
|||
|
|
meta: {}, // 元信息
|
|||
|
|
NAVTYPE: "push", // 导航类型
|
|||
|
|
BACKTYPE: "" // 返回类型
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### API方法
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
// 导航方法
|
|||
|
|
router.push(location)
|
|||
|
|
router.replace(location)
|
|||
|
|
router.replaceAll(location)
|
|||
|
|
router.pushTab(location)
|
|||
|
|
router.back(delta, options)
|
|||
|
|
|
|||
|
|
// 守卫方法
|
|||
|
|
router.beforeEach(fn)
|
|||
|
|
router.afterEach(fn)
|
|||
|
|
|
|||
|
|
// 强制触发
|
|||
|
|
router.forceGuardEach(NAVTYPE, passthrough)
|
|||
|
|
|
|||
|
|
// Vue实例访问
|
|||
|
|
this.$Router // 路由器实例
|
|||
|
|
this.$Route // 当前路由
|
|||
|
|
this.$AppReady // App准备完成Promise
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 原生方法重写
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
// 重写uni原生导航方法
|
|||
|
|
uni.navigateTo(options) → router.push()
|
|||
|
|
uni.redirectTo(options) → router.replace()
|
|||
|
|
uni.reLaunch(options) → router.replaceAll()
|
|||
|
|
uni.switchTab(options) → router.pushTab()
|
|||
|
|
uni.navigateBack(options) → router.back()
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 模块依赖关系
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
607 (主入口)
|
|||
|
|
├── 366 (常量)
|
|||
|
|
├── 309 (类型)
|
|||
|
|
├── 814 (加载页面)
|
|||
|
|
└── 963 (创建路由)
|
|||
|
|
├── 282 (配置)
|
|||
|
|
├── 789 (工具)
|
|||
|
|
├── 662 (钩子注册)
|
|||
|
|
├── 460 (Mixins)
|
|||
|
|
│ ├── 801 (路由映射)
|
|||
|
|
│ ├── 844 (Vue路由)
|
|||
|
|
│ ├── 147 (代理)
|
|||
|
|
│ └── 814 (加载页面)
|
|||
|
|
├── 890 (导航)
|
|||
|
|
│ ├── 366 (常量)
|
|||
|
|
│ ├── 99 (查询)
|
|||
|
|
│ ├── 789 (工具)
|
|||
|
|
│ ├── 169 (钩子调用)
|
|||
|
|
│ └── 845 (页面钩子)
|
|||
|
|
└── 314 (方法重写)
|
|||
|
|
└── 809 (原生跳转)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 性能优化
|
|||
|
|
|
|||
|
|
### 1. 代码分割
|
|||
|
|
- 将第三方库独立打包
|
|||
|
|
- 减少主bundle大小
|
|||
|
|
- 利用浏览器缓存
|
|||
|
|
|
|||
|
|
### 2. 懒加载
|
|||
|
|
- 页面组件按需加载
|
|||
|
|
- 减少首屏加载时间
|
|||
|
|
|
|||
|
|
### 3. 压缩
|
|||
|
|
- UglifyJS压缩
|
|||
|
|
- 变量名混淆
|
|||
|
|
- 移除注释和空格
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 建议
|
|||
|
|
|
|||
|
|
### 1. 优化建议
|
|||
|
|
- ✅ 使用CDN加载常用库
|
|||
|
|
- ✅ 启用Gzip/Brotli压缩
|
|||
|
|
- ✅ 考虑按需引入uni-simple-router功能
|
|||
|
|
- ✅ 分析是否所有加密库都需要
|
|||
|
|
|
|||
|
|
### 2. 调试建议
|
|||
|
|
- 使用Source Map调试
|
|||
|
|
- 启用路由debugger选项
|
|||
|
|
- 查看原始源代码
|
|||
|
|
|
|||
|
|
### 3. 升级建议
|
|||
|
|
- 检查依赖库版本
|
|||
|
|
- 及时更新安全补丁
|
|||
|
|
- 关注性能优化
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 总结
|
|||
|
|
|
|||
|
|
`chunk-vendors.4d47960d.js` 是一个包含所有第三方依赖的大型文件:
|
|||
|
|
|
|||
|
|
**主要内容**:
|
|||
|
|
1. ✅ uni-simple-router (约70%代码量)
|
|||
|
|
2. ✅ 加密库 (HMAC, SHA, MD5等)
|
|||
|
|
3. ✅ Buffer实现
|
|||
|
|
4. ✅ Polyfills (Object, Array方法)
|
|||
|
|
5. ✅ 工具函数
|
|||
|
|
|
|||
|
|
**特点**:
|
|||
|
|
- 📦 高度压缩(1.18MB → 约26行)
|
|||
|
|
- 🔒 变量混淆
|
|||
|
|
- ⚡ 模块化设计
|
|||
|
|
- 🎯 独立打包
|
|||
|
|
|
|||
|
|
**用途**:
|
|||
|
|
- 提供路由功能
|
|||
|
|
- 提供加密功能
|
|||
|
|
- 兼容性支持
|
|||
|
|
- 工具函数库
|
|||
|
|
|
|||
|
|
由于文件过大且高度压缩,完整反编译需要原始源代码和构建配置。建议查看:
|
|||
|
|
- uni-simple-router GitHub仓库
|
|||
|
|
- 项目的package.json
|
|||
|
|
- Webpack配置文件
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 附录:模块ID速查表
|
|||
|
|
|
|||
|
|
### uni-simple-router核心模块
|
|||
|
|
- 607: 主入口
|
|||
|
|
- 366: 常量定义
|
|||
|
|
- 963: 创建路由器
|
|||
|
|
- 890: 导航跳转
|
|||
|
|
- 169: 钩子调用
|
|||
|
|
- 845: 页面钩子
|
|||
|
|
- 789: 工具函数
|
|||
|
|
- 99: 查询参数
|
|||
|
|
- 314: 方法重写
|
|||
|
|
- 662: 钩子注册
|
|||
|
|
- 460: Mixins
|
|||
|
|
- 282: 配置常量
|
|||
|
|
|
|||
|
|
### 加密相关
|
|||
|
|
- 0116: HMAC
|
|||
|
|
- 0168: Cipher
|
|||
|
|
- 5f79: Buffer
|
|||
|
|
- 1177: MD5
|
|||
|
|
- 2d81: RMD160
|
|||
|
|
- 25a4: SHA
|
|||
|
|
|
|||
|
|
### Polyfills
|
|||
|
|
- 00c2: indexOf
|
|||
|
|
- 00ca: getOwnPropertyNames
|
|||
|
|
- bb80: array push
|
|||
|
|
- 338c: hasOwnProperty
|
|||
|
|
- f660: toIndexedObject
|
|||
|
|
|
|||
|
|
完整模块列表约200+个,这里仅列出主要模块。
|
|||
|
|
|
|||
|
|
|
|||
|
|
|