From d34b94a2e53affc475ffcf07381775318da97072 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=AF=9B=E7=91=9E?= Date: Wed, 18 Sep 2019 12:41:38 +0800 Subject: [PATCH] =?UTF-8?q?Fix:=20=E7=BB=86=E8=8A=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 17 ++--- package.json | 2 +- public/index.html | 4 +- public/other.html | 4 +- scripts/figure.js | 117 +++++++++++++++------------------ scripts/insertPreload.js | 74 +++++++++------------ src/components/Error.vue | 15 ++--- src/components/Loading.vue | 9 +-- src/pages/index/App.vue | 6 ++ src/pages/index/router.ts | 9 ++- src/pages/other/router.ts | 9 ++- src/pages/other/scss/main.scss | 6 +- src/scss/var.scss | 6 -- src/utils/highOrder.ts | 23 ++----- vue.config.js | 14 +--- yarn.lock | 8 +-- 16 files changed, 145 insertions(+), 178 deletions(-) diff --git a/README.md b/README.md index f3242fc..ac3d5fb 100644 --- a/README.md +++ b/README.md @@ -221,8 +221,7 @@ yarn vue-cli-service help # [命令] : 比如 yarn vue-cli-service help test:e2e > 推荐使用 [TypeScript](https://www.tslang.cn) -- CSS Modules class 名使用 `camelCase` (global 可以 kebab-case), 选择器嵌套**不应超过三层** -- JavaScript 代码风格为 [**JavaScript standard**](https://standardjs.com/rules-zhcn.html),除了以下区别: +- JavaScript/TypeScript 代码风格为 [**JavaScript standard**](https://standardjs.com/rules-zhcn.html),除了以下区别: - 使用单引号 - 不要句尾分号 @@ -232,7 +231,7 @@ yarn vue-cli-service help # [命令] : 比如 yarn vue-cli-service help test:e2e (.vscode 文件夹为 VSCode 的工作区设置,只在本项目生效,已包含相关设置) - 另请参考: [vue 风格指南](https://cn.vuejs.org/v2/style-guide/) **推荐(C)及以上** 和 [stylelint](https://github.com/stylelint/stylelint/blob/master/docs/user-guide/rules.md) [配置](.stylelintrc.js) -- 引用 vue 单文件组件**不要加文件扩展名**,有利于重构代码 +- 引用 `vue/tsx/ts/js/jsx` **不要加文件扩展名**,有利于重构代码 - 在`tsx/jsx`中使用全局注册的组件时可以使用`kebab-case`, 否则会在控制台输出错误 ┐(:´ ゞ`)┌ ```TypeScript @@ -253,6 +252,9 @@ yarn vue-cli-service help # [命令] : 比如 yarn vue-cli-service help test:e2e ``` - 先定义再`export`(IDE 提示更友好), 并且`export`语句放到最后 +- 不要使用 `$` 作为组件事件名,该名字已被[异步组件刷新](src/utils/highOrder.ts)占用 +- 路由请**全部**使用异步组件(`@utils/highOrder getAsync`),以使路由及其**子(异步)组件**可以局部刷新 +- CSS Modules class 名使用 `camelCase` (global 可以 kebab-case), 选择器嵌套**不应超过三层** - **全局 sccs** _(包含各别名下[.env](.env) `GLOBAL_SCSS`变量指定的文件)_ 中不要出现具体样式, 也不要有[`:export{}`](https://github.com/css-modules/icss#export)(应在 `export*.scss` 中使用); 为保证`ts/js`中引入时 scss 变量注入正确, 应在合适的 scss 文件中引入目标样式源码: ```scss @@ -330,7 +332,7 @@ yarn vue-cli-service help # [命令] : 比如 yarn vue-cli-service help test:e2e ### 其他 -- 规范优雅正确适当的各种**注释**,比如方法注释及必要的变量注释: +- 正确规范简洁优雅适当的各种**注释**,比如方法注释及必要的变量注释: ```TypeScript /** 二维点 @@ -396,13 +398,12 @@ yarn vue-cli-service help # [命令] : 比如 yarn vue-cli-service help test:e2e } ``` -- [异步 chunk](https://webpack.docschina.org/api/module-methods) 使用入口层级命名(方便排查问题和碎文件合并),比如: index 页面下的 home 视图命名为 `index_home`, 其下的用户视图命名为 `index_home_my`, 用户基础信息命名为 `index_home_my_baseinfo` 。为避免文件名太长,每个层级可以缩写: `iHome`, `ihMy`, `ihmBaseInfo`。 -- 路由请**全部**使用异步组件(`@utils/highOrder getAsync`),以使路由及其**子(异步)组件**可以局部刷新 -- libs 下的库文件需要按需加载的,应提供引入方法(只会成功加载一次),比如(模块化, 全局的类似): +- [异步 chunk](https://webpack.docschina.org/api/module-methods) 使用入口层级命名(方便排查问题和碎文件合并),比如: index 页面下的 home 视图命名为 `index_home`, 其下的用户视图命名为 `index_home_my`, 用户基础信息命名为 `index_home_my_baseinfo` 。为避免文件名太长,每个层级可以缩写: `iHome`, `ihMy`, `ihmBaseInfo` +- libs 下的库文件需要按需加载的,应提供引入方法(只会成功加载一次),比如: ```TypeScript // src/libs/somelib/index.ts - /** 异步引入somelib(模块化)及其插件 + /** 模块化异步引入somelib及其插件(全局类似) * @param {Array} plugins 需要加载的somelib插件名列表: * * plugin1: 插件1 diff --git a/package.json b/package.json index 4b7df40..18d423a 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "@babel/core": "^7.6.0", "@types/crypto-js": "^3.1.43", "@types/d3": "^5.7.2", - "@types/echarts": "^4.1.12", + "@types/echarts": "^4.1.13", "@types/jest": "^24.0.18", "@vue/cli-plugin-babel": "^4.0.0-rc.3", "@vue/cli-plugin-e2e-nightwatch": "^4.0.0-rc.3", diff --git a/public/index.html b/public/index.html index 78c79dc..5fe0d29 100644 --- a/public/index.html +++ b/public/index.html @@ -81,9 +81,9 @@ -

加载中,请稍候...

+

加载中,请稍候...

<%= isProd ? '' : '' %> - \ No newline at end of file + diff --git a/public/other.html b/public/other.html index 78c79dc..5fe0d29 100644 --- a/public/other.html +++ b/public/other.html @@ -81,9 +81,9 @@ -

加载中,请稍候...

+

加载中,请稍候...

<%= isProd ? '' : '' %> - \ No newline at end of file + diff --git a/scripts/figure.js b/scripts/figure.js index 285f6c2..0ef4844 100644 --- a/scripts/figure.js +++ b/scripts/figure.js @@ -4,53 +4,8 @@ * @Date: 2019-06-05 09:15:13 */ -/// 通用 /// -const COM = { - c1: ` - _ooOoo_ - o8888888o - 88" . "88 - (| -_- |) - O\\ = /O - ____/\`---'\\____ - . ' \\\\| |// \`. - / \\\\||| : |||// \\ - / _||||| -:- |||||- \\ - | | \\\\\\ - /// | | - | \\_| ''\\---/'' | | - \\ .-\\__ \`-\` ___/-. / - ___\`. .' /--.--\\ \`. . __ - ."" '< \`.___\\_<|>_/___.' >'"". - | | : \`- \\\`.;\`\\ _ /\`;.\`/ - \` : | | - \\ \\ \`-. \\_ __\\ /__ _/ .-\` / / -======\`-.____\`-.___\\_____/___.-\`____.-'====== - \`=---=' -`, - c2: ` - _ooOoo_ - o8888888o - 88" . "88 - (| -_- |) - O\\ = /O - ___/\`---'\\____ - . ' \\\\| |// \`. - / \\\\||| : |||// \\ - / _||||| -:- |||||- \\ - | | \\\\\\ - /// | | - | \\_| ''\\---/'' | | - \\ .-\\__ \`-\` ___/-. / - ___\`. .' /--.--\\ \`. . __ - ."" '< \`.___\\_<|>_/___.' >'"". - | | : \`- \\\`.;\`\\ _ /\`;.\`/ - \` : | | - \\ \\ \`-. \\_ __\\ /__ _/ .-\` / / - ======\`-.____\`-.___\\_____/___.-\`____.-'====== - \`=---=' -`, -} - -module.exports = { - /// 开发环境 /// - d1: ` +module.exports = [ + ` ┌─┐ ┌─┐ ┌──┘ ┴───────┘ ┴──┐ │ │ @@ -90,7 +45,7 @@ module.exports = { ██████╔╝╚██████╔╝╚██████╔╝ ╚═════╝ ╚═════╝ ╚═════╝ `, - d2: ` + ` ,s555SB@@& :9H####@@@@@Xi 1@@@@@@@@@@@@@@8 @@ -120,7 +75,7 @@ module.exports = { ,,,rHAri1h1rh&@#353Sh: 8@@@@@@@@@@@@@@@@@@@@@@@@@#: .A3hH@#5S553&@@#h i:i9S #@@@@@@@@@@@@@@@@@@@@@@@@@A. `, - d3: ` + ` ┌───┐ ┌───┬───┬───┬───┐ ┌───┬───┬───┬───┐ ┌───┬───┬───┬───┐ ┌───┬───┬───┐ │Esc│ │ F1│ F2│ F3│ F4│ │ F5│ F6│ F7│ F8│ │ F9│F10│F11│F12│ │P/S│S L│P/B│ ┌┐ ┌┐ ┌┐ └───┘ └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┘ └┘ └┘ └┘ @@ -136,11 +91,47 @@ module.exports = { │ Ctrl│ │Alt │ Space │ Alt│ │ │Ctrl│ │ ← │ ↓ │ → │ │ 0 │ . │←─┘│ └─────┴────┴────┴───────────────────────┴────┴────┴────┴────┘ └───┴───┴───┘ └───────┴───┴───┘ `, - d4: COM.c1, - d5: COM.c2, - - /// 生产环境 /// - p1: ` + ` + _ooOoo_ + o8888888o + 88" . "88 + (| -_- |) + O\\ = /O +____/\`---'\\____ +. ' \\\\| |// \`. +/ \\\\||| : |||// \\ +/ _||||| -:- |||||- \\ +| | \\\\\\ - /// | | +| \\_| ''\\---/'' | | +\\ .-\\__ \`-\` ___/-. / +___\`. .' /--.--\\ \`. . __ +."" '< \`.___\\_<|>_/___.' >'"". +| | : \`- \\\`.;\`\\ _ /\`;.\`/ - \` : | | +\\ \\ \`-. \\_ __\\ /__ _/ .-\` / / +======\`-.____\`-.___\\_____/___.-\`____.-'====== + \`=---=' +`, + ` + _ooOoo_ + o8888888o + 88" . "88 + (| -_- |) + O\\ = /O + ___/\`---'\\____ + . ' \\\\| |// \`. + / \\\\||| : |||// \\ + / _||||| -:- |||||- \\ + | | \\\\\\ - /// | | + | \\_| ''\\---/'' | | + \\ .-\\__ \`-\` ___/-. / + ___\`. .' /--.--\\ \`. . __ + ."" '< \`.___\\_<|>_/___.' >'"". + | | : \`- \\\`.;\`\\ _ /\`;.\`/ - \` : | | + \\ \\ \`-. \\_ __\\ /__ _/ .-\` / / + ======\`-.____\`-.___\\_____/___.-\`____.-'====== + \`=---=' + `, + ` _______________#########_______________________ ______________############_____________________ ______________#############____________________ @@ -165,7 +156,7 @@ _____#####________####______#####_____###______ ______#####______;###________###______#________ ________##_______####________####______________ `, - p2: ` + ` 瓦瓦 十 十齱龠己 亅瓦車己 乙龍龠毋日丶 丶乙己毋毋丶 @@ -201,7 +192,7 @@ ________##_______####________####______________ 丶亅亅丶 亅日瓦日 丶 `, - p3: ` + ` .::::. .::::::::. ::::::::::: @@ -221,7 +212,7 @@ ________##_______####________####______________ \`\`\`\` ':. ':::::::::' ::::.. '.:::::' ':'\`\`\`\`.. `, - p4: ` + ` ___====-_ _-====___ _--^^^#####// \\\\#####^^^--_ _-^##########// ( ) \\\\##########^-_ @@ -239,7 +230,7 @@ _#/|##########/\\######( /\\ )######/\\##########|\\#_ __\\ | | | | /__ (vvv(VVV)(VVV)vvv) `, - p5: ` + ` __----~~~~~~~~~~~------___ . . ~~//====...... __--~ ~~ -. \\_|// |||\\\\ ~~~~~~::::... /~ @@ -259,7 +250,7 @@ _-~~ .=~ | \\\\-_ '-~7 /- / || \\ / //.-~~~-~_--~- |-------~~~~~~~~ //.-~~~--\\ `, - p6: ` + ` _._ _..._ .-', _.._(\`)) '-. \` ' /-._.-' ',/ ) \\ '. @@ -274,7 +265,7 @@ _._ _..._ .-', _.._(\`)) /,_| | /,_/ / /,_/ '\`-' `, - p7: ` + ` .=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-. | ______ | | .-" "-. | @@ -293,7 +284,7 @@ _._ _..._ .-', _.._(\`)) | | '-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=' `, - p8: ` + ` .--, .--, ( ( \\.---./ ) ) '.__/o o\\__.' @@ -307,6 +298,4 @@ _._ _..._ .-', _.._(\`)) ___)( )(___ (((__) (__))) `, - p9: COM.c1, - p10: COM.c2, -} +] diff --git a/scripts/insertPreload.js b/scripts/insertPreload.js index f5416b3..1e97ab3 100644 --- a/scripts/insertPreload.js +++ b/scripts/insertPreload.js @@ -1,5 +1,5 @@ /* - * @description: 插入 preload 的资源 + * @description: 插入 preload 的资源(js defer) * 依赖: * https://github.com/jantimon/html-webpack-plugin * @vue/preload-webpack-plugin (fork:https://github.com/GoogleChromeLabs/preload-webpack-plugin) @@ -37,82 +37,72 @@ module.exports = class { // 补充缺失的资源 insert(htmlPluginData) { - // 标签对象结构: 只需要关心: head 里的 link, body 里的 script - // { - // tagName: String, - // attributes: { - // /// link /// - // href: String, - // rel: String, // 只需要关心: stylesheet 用于去重 - // as: String, // rel:preload 时存在 - // // ... - - // /// script /// - // src: String, - // }, - // } const head = htmlPluginData.head const body = htmlPluginData.body // 考虑只有script const styles = [] // 待插入样式 const scripts = [] // 待插入脚本 + const script = 'script' const relStyle = 'stylesheet' const REG_RUNTIME = this._REG_REMOVE - // 找到缺的标签 - // 样式插入位置(最后一个样式/preload标签后) - let index = 0 - for (let len = head.length, tmp; index < len; index++) { - tmp = head[index].attributes // 当前属性 + let el + for (el of body) { + el.tagName === script && (el.attributes.defer = true) + } + + let temp + let index = -1 + let len = head.length + while (++index < len) { + temp = head[index].attributes // 当前属性 // preload 只认 as 属性吧 - if (tmp.as || tmp.rel === relStyle) { - switch (tmp.as) { + if (temp.as || temp.rel === relStyle) { + switch (temp.as) { case 'style': // css styles.push({ tagName: 'link', attributes: { rel: relStyle, - href: tmp.href, + href: temp.href, }, }) break - case 'script': // js + case script: // js + // 去掉runtime + if (REG_RUNTIME && REG_RUNTIME.test(temp.href)) { + head.splice(index--, 1) + len-- + } // 去重 - for (let el of body) { - if (tmp.href === el.attributes.src) { - tmp.href = 0 + for (el of body) { + if (temp.href === el.attributes.src) { + el = false // 兼职 break } } - if (tmp.href) { + el === false || scripts.push({ - tagName: 'script', + tagName: script, closeTag: true, attributes: { defer: true, - src: tmp.href, + src: temp.href, type: - tmp.rel === 'modulepreload' ? 'module' : 'text/javascript', + temp.rel === 'modulepreload' ? 'module' : 'text/javascript', }, }) - // 去掉runtime - if (REG_RUNTIME && REG_RUNTIME.test(tmp.href)) { - head.splice(index--, 1) - len-- - continue - } - } break default: // 样式标签 去重 - tmp = styles.findIndex(el => el.attributes.href === tmp.href) - tmp >= 0 && styles.splice(tmp, 1) + temp = styles.findIndex(el => el.attributes.href === temp.href) + temp >= 0 && styles.splice(temp, 1) } // 下一个不是样式则把样式放在下一个 - tmp = (head[index + 1] || {}).attributes || {} - if (!(tmp.as || tmp.rel === relStyle)) { + temp = (head[index + 1] || {}).attributes || {} + if (!(temp.as || temp.rel === relStyle)) { ++index break } diff --git a/src/components/Error.vue b/src/components/Error.vue index 5f71aef..5b6bf55 100644 --- a/src/components/Error.vue +++ b/src/components/Error.vue @@ -31,25 +31,24 @@ export default class extends Vue { diff --git a/src/pages/index/router.ts b/src/pages/index/router.ts index 018f750..f8bde4d 100644 --- a/src/pages/index/router.ts +++ b/src/pages/index/router.ts @@ -49,14 +49,17 @@ const router = new Router({ let timer = 0 const REG_REDIRECT = /\/r\//i const PATH_HOME = `/${ROUTE.home.name}` -const forceUpdate = () => refreshRoute(router.currentRoute.matched) +const forceUpdate = () => { + refreshRoute(router.currentRoute.matched) + NProgress.done() +} router.beforeEach((to, from, next) => { NProgress.start() // 开始进度条 /// 重定向到并刷新目标路由: this.$router.replace('/r' + this.$route.fullPath) /// let toFullPath = to.redirectedFrom || to.fullPath if (REG_REDIRECT.test(toFullPath)) { toFullPath = toFullPath.replace(REG_REDIRECT, '/') - toFullPath === from.fullPath ? NProgress.done() : next(toFullPath) + toFullPath === from.fullPath || next(toFullPath) clearTimeout(timer) timer = setTimeout(forceUpdate) return @@ -77,7 +80,7 @@ router.afterEach((to, from) => { let tmp: any for (key in ROUTE) { tmp = ROUTE[key] - if (tmp && tmp.name === name) { + if (tmp && name === tmp.name && tmp.title) { document.title = tmp.title break } diff --git a/src/pages/other/router.ts b/src/pages/other/router.ts index ef8f1bf..5826a8b 100644 --- a/src/pages/other/router.ts +++ b/src/pages/other/router.ts @@ -49,14 +49,17 @@ const router = new Router({ let timer = 0 const REG_REDIRECT = /\/r\//i const PATH_HOME = `/${ROUTE.home.name}` -const forceUpdate = () => refreshRoute(router.currentRoute.matched) +const forceUpdate = () => { + refreshRoute(router.currentRoute.matched) + NProgress.done() +} router.beforeEach((to, from, next) => { NProgress.start() // 开始进度条 /// 重定向到并刷新目标路由: this.$router.replace('/r' + this.$route.fullPath) /// let toFullPath = to.redirectedFrom || to.fullPath if (REG_REDIRECT.test(toFullPath)) { toFullPath = toFullPath.replace(REG_REDIRECT, '/') - toFullPath === from.fullPath ? NProgress.done() : next(toFullPath) + toFullPath === from.fullPath || next(toFullPath) clearTimeout(timer) timer = setTimeout(forceUpdate) return @@ -77,7 +80,7 @@ router.afterEach((to, from) => { let tmp: any for (key in ROUTE) { tmp = ROUTE[key] - if (tmp && tmp.name === name) { + if (tmp && name === tmp.name && tmp.title) { document.title = tmp.title break } diff --git a/src/pages/other/scss/main.scss b/src/pages/other/scss/main.scss index 1452802..8ebeef6 100644 --- a/src/pages/other/scss/main.scss +++ b/src/pages/other/scss/main.scss @@ -1,5 +1,7 @@ -@import '~@/scss/reset'; // 浏览器样式重置 -@import '~@/scss/transitions'; // 过渡动画 +/// 全局样式 /// +@import '~@/scss/reset'; +@import '~@/scss/icons'; +@import '~@/scss/transitions'; /// 全局注册的element-ui组件样式 /// @import '~element-ui/packages/theme-chalk/src/base'; diff --git a/src/scss/var.scss b/src/scss/var.scss index 6def417..3a2266f 100644 --- a/src/scss/var.scss +++ b/src/scss/var.scss @@ -47,9 +47,3 @@ overflow: hidden; word-break: break-word; } - -/* ---------------------- 我还是一条分割线 ㄟ( ▔, ▔ )ㄏ ---------------------- */ - -/// 共享给js的变量(import VAR from '@/scss/var.scss') /// -// https://github.com/css-modules/icss#export 不支持嵌套 -// :export {} diff --git a/src/utils/highOrder.ts b/src/utils/highOrder.ts index 81da68f..fc58ada 100644 --- a/src/utils/highOrder.ts +++ b/src/utils/highOrder.ts @@ -56,34 +56,21 @@ function getAsync( const asyncComponentFactory = (): AsyncComponent => () => ({ error, // 加载失败时 loading, // 加载时 - component: promiseFactory() as any, - + component: promiseFactory() as any, // 目标 timeout: CONFIG.timeout, // 加载超时(默认Infinity) }) const observe = Vue.observable({ c: asyncComponentFactory() }) - let timer = 0 - let orginHandler: any - const update = function(this: Vue) { - // parent.$forceUpdate() + const update = () => { observe.c = asyncComponentFactory() - - if (orginHandler) { - clearTimeout(timer) - timer = setTimeout(() => orginHandler.apply(this, arguments)) - } } return { functional: true, render(createElement, { data, children }) { - // event: $ 用于 hack 加载失败时点击重新加载 - if (data.on ? !data.on.$ : (data.on = {})) { - if (update !== data.on.$) { - orginHandler = data.on.$ - data.on.$ = update - } - } + // 保留 event: $ 用于 hack 加载失败时点击重新加载 + data.on || (data.on = {}) + data.on.$ = update return createElement(observe.c, data, children) }, diff --git a/vue.config.js b/vue.config.js index 4e7e253..e62d346 100644 --- a/vue.config.js +++ b/vue.config.js @@ -4,28 +4,20 @@ * @Date: 2019-06-18 16:18:18 */ -// TODO: 环境变量/入口文件 改变热更新 - -const path = require('path') - const environment = process.env // 环境变量 const isProd = environment.NODE_ENV === 'production' // 是否生产环境 const pages = require('./scripts/pages')(isProd) // 自动检测并返回页面入口设置 - const ALIAS = {} // 别名字典 + // 输出图形 +const FIGURE = require('./scripts/figure') // eslint-disable-next-line no-console console.log( '\033[3' + // eslint-disable-line no-octal-escape Math.ceil(Math.random() * 6) + 'm' + - // eslint-disable-next-line standard/computed-property-even-spacing - require('./scripts/figure')[ - isProd - ? 'd' + Math.ceil(Math.random() * 5) - : 'p' + Math.ceil(Math.random() * 10) - ] + + FIGURE[(Math.random() * FIGURE.length) | 0] + '\33[0m' // eslint-disable-line no-octal-escape ) diff --git a/yarn.lock b/yarn.lock index 621bb4c..a3dda11 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1714,10 +1714,10 @@ "@types/d3-voronoi" "*" "@types/d3-zoom" "*" -"@types/echarts@^4.1.12": - version "4.1.12" - resolved "https://registry.yarnpkg.com/@types/echarts/-/echarts-4.1.12.tgz#5d013096301cd696b098f7ff3a1cd96d7ea1a680" - integrity sha512-J+hC+Zjo+NAq0Xu9yk4A7WI55W8VOpIyWdMhhzv+w+ZooFuhAt1p2y9T4l2ajWNZBRRmsebRjgX51oddrY/qew== +"@types/echarts@^4.1.13": + version "4.1.13" + resolved "https://registry.yarnpkg.com/@types/echarts/-/echarts-4.1.13.tgz#5e1279b722dfec49b8aef5cb678b0ace5bc2d75f" + integrity sha512-eimS5NYLnzuJ002rScM4IctFioh3riEo/160KcK911xHnv1dek3pA1nRxrLOfTQQ9kP5o/0LIH6irRK0zQFDpA== dependencies: "@types/zrender" "*"