├── .babelrc ├── .gitignore ├── README.md ├── package-lock.json ├── package.json ├── rollup.config.js ├── src ├── applyReactInVue.js ├── applyReactRouterInVue.js ├── applyRedux.js ├── applyVueInReact.js ├── applyVuex.js ├── cleanStyle.js ├── index.js ├── lazyReactInVue.js ├── lazyVueInReact.js ├── options.js ├── portal-vue.esm.js ├── reactAllHandles.js ├── vueRootInfo.js └── withVueRouter.js └── types └── vuereact.d.ts /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "@babel/preset-env", 4 | "@babel/preset-react" 5 | ], 6 | "plugins": ["@babel/plugin-proposal-object-rest-spread", "@babel/plugin-proposal-class-properties"], 7 | "env": { 8 | "rollup": { 9 | "plugins": ["@babel/plugin-external-helpers"] 10 | }, 11 | "test": { 12 | "presets": ["es2015"], 13 | "plugins": ["@babel/plugin-proposal-class-properties"] 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw? 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Vue和React快捷集成的工具包,并且适合复杂的集成场景 2 |
3 | 4 |
5 | 6 |
7 |

8 |

可以在任何的Vue和React项目中使用另一个类型框架的组件,并且解决了复杂的集成问题

9 |

10 |

11 | 12 | ## 支持Vue3? 13 | Vue3和React的共同开发场景请使用[Veaury](https://github.com/devilwjp/veaury) 14 | 15 | ## 安装 16 | ```` 17 | npm i vuereact-combined -S 18 | ```` 19 | 20 | ## Why? 21 | #### 让vue和react的同学们一起来完成同一个项目同一个页面甚至同一个组件 22 | + 使项目的人员选择性和机动性变得更强,vue和react的技术栈都可以加入项目 23 | + 使项目的第三方插件选择性更强,vue和react的插件都可以通用 24 | + 使研发人员的技术交流性更强,研发人员不应该被技术栈所限制 25 | + 使项目可以集成更多的业务代码,其他vue和react项目的优秀代码可以快速引入 26 | + 使前端研发人员可以更好的学习vue和react,了解两者的精华,促进团队在前端技术栈的广度 27 | + 使用方式极其简便 28 | ## Benchmark 29 | 非常感谢vuera的存在,开辟了Vue和React融合的想法,但是vuera只能解决非常基础的组件融合,并且存在插槽(children)和数据变更后的渲染性能问题,因此无法用于复杂的场景以及生产环境 30 | vuereact-combined将融合做到了极致,支持了大部分的Vue和React组件的功能,并且在渲染更新上使用了和vuera不同的思路,完美解决了渲染性能问题 31 | 32 | 场景/功能 | vuereact-combined | vuera | 33 | | --------- | --------- | --------- | 34 | normal prop (vue / react) | ✔ | ✔ | 35 | event (vue / react) | ✔ | ✔ | 36 | children (vue / react) | ✔ | ✔ | 37 | Provider/Consumer in vue (react) | ✔ | | 38 | Provider/Consumer cross react->vue->...->react | ✔ | | 39 | provide/inject cross vue->react->...->vue | ✔ | | 40 | named slots (vue) | ✔ | | 41 | scope slots (vue) | ✔ | | 42 | v-model (vue) | ✔ | | 43 | sync (vue) | ✔ | | 44 | render props (react) | ✔ | | 45 | node props (react) | ✔ | | 46 | enter & leave 事件委托传递 (react) | ✔ | | 47 | slots & children & node在父组件数据变更后的生命周期表现 | 触发更新 | 每次都触发创建和销毁 | 48 | vuex in react | ✔ | | 49 | vue-router in react | ✔ | | 50 | redux in vue | ✔ | | 51 | react-router in react | ✔ | | 52 | lazyReactInVue | ✔ | | 53 | lazyVueInReact | ✔ | | 54 | 第三方组件跨框架使用(比如antd、element) | 支持所有第三方组件 | 基本不支持 | 55 | 自定义融合包囊层的dom attr | ✔ | | 56 | 57 | ## 只是高阶组件 58 | ````vue 59 | 60 | 65 | 66 | 81 | 82 | 85 | ```` 86 | ````jsx 87 | // React JSX File 88 | import React, { useState } from 'react' 89 | // element-ui DatePicker Vue 90 | import { DatePicker } from 'element-ui' 91 | import { applyVueInReact } from 'vuereact-combined' 92 | 93 | // 使用applyVueInReact高阶组件讲element-ui DatePicker转换成React组件 94 | const ElDatePicker = applyVueInReact(DatePicker) 95 | export default function() { 96 | const [timeValue, setTimeValue] = useState(Date.now()) 97 | return { setTimeValue(val) }, 102 | }} 103 | type="date" 104 | placeholder="选择日期"/> 105 | } 106 | 107 | ```` 108 | ## 使用场景 109 | 最基本的,项目中至少应该存在`vue@^2.6`、`react@^16.3`、`react-dom@^16.3` 110 | ### Vue项目中使用第三方的React组件 111 | 第三方的react组件已经是通过`babel`进行过处理,不包含React的`jsx` 112 | 此情况下,可以直接在项目中使用applyReactInVue对第三方的React组件进行处理 113 | ### React项目中使用第三方的Vue组件 114 | 第三方的Vue组件已经是通过`vue-loader`和`babel`进行过处理,不包含`.vue`文件以及Vue的`jsx` 115 | 此情况下,可以直接在项目中使用applyVueInReact对第三方的Vue组件进行处理 116 | ### 复杂情况(项目中同时安装和配置react和vue的相关环境) 117 | 此情况可以在一个项目中同时开发编写React和Vue的组件代码,由于需要同时具备两种技术栈所依赖的环境,因此需要对项目的构建(一般是`webpack`的配置)和`babel.config.js`进行一些配置上的修改 118 | 可以参考以下案例 119 | + 如果是通过vue-cli3创建的项目 120 | 请参考 https://github.com/devilwjp/vuereact-for-vuecli3-demo 121 | + 如果通过react-create-app创建的项目(react版本需要>=16.3) 122 | 请参考 https://github.com/devilwjp/vuereact-for-cra-demo 123 | 124 | ## 属性传递 125 | 在React中正常的使用React的方式向Vue组件传递属性和children 126 | ````jsx 127 | // React JSX File 128 | import React, { useState } from 'react' 129 | // element-ui Vue 130 | import { Button, ButtonGroup } from 'element-ui' 131 | import { applyVueInReact } from 'vuereact-combined' 132 | 133 | const ElButton = applyVueInReact(Button) 134 | const ElButtonGroup = applyVueInReact(ButtonGroup) 135 | 136 | export default function() { 137 | 138 | const [type, setType] = useState('primary') 139 | const [disabled, setDisabled] = useState(false) 140 | const [content, setContent] = useState('提交') 141 | 142 | return 143 | 提交 144 | 提交 145 | {content} 146 | 147 | } 148 | ```` 149 | 在Vue中正常的使用Vue的方式向React组件传递属性和插槽 150 | ````vue 151 | 152 | 157 | 158 | 177 | 178 | 181 | ```` 182 | ## 在React中使用Vue组件的v-model和sync修饰符 183 | ````jsx 184 | // React JSX File 185 | import React, { useState } from 'react' 186 | // element-ui DatePicker Vue 187 | import { DatePicker } from 'element-ui' 188 | // 一个开放sync修饰符属性的Vue组件 189 | import VueComponent from './VueComponent.vue' 190 | import { applyVueInReact } from 'vuereact-combined' 191 | 192 | const ElDatePicker = applyVueInReact(DatePicker) 193 | const VueComponentInReact = applyVueInReact(VueComponent) 194 | 195 | export default function() { 196 | const [timeValue, setTimeValue] = useState(Date.now()) 197 | const [timeValue1, setTimeValue1] = useState(Date.now()) 198 | // Vue组件的v-model在React中的用法 199 | const $model = { 200 | value: timeValue, 201 | setter: (val) => { setTimeValue(val) }, 202 | } 203 | // Vue组件的sync在React中的用法 204 | const $sync = { 205 | props1: { 206 | value: timeValue1, 207 | setter: (val) => { setTimeValue1(val) }, 208 | } 209 | } 210 | return
211 | 212 | 213 |
214 | } 215 | ```` 216 | 使用`$model`属性传递一个对象 217 | `$model` 218 | **Type:** `{value: state, setter: (val: nextState) => void}` 219 | 其中`value`就是要传入给v-model的状态值,`setter`就是子组件向父组件发出修改状态值的触发函数,这个函数应该是个纯函数,不应该包含其他逻辑,确保函数内容仅仅只用于修改状态值 220 | `$sync` 221 | **Type:** `{[propName: {value: state, setter: (val: nextState) => void}]}` 222 | 223 | ## 在React中使用Vue组件的作用域插槽和具名插槽 224 | ```jsx 225 | // React JSX File 226 | import React, { useState } from 'react' 227 | // 一个开放具名插槽和作用域插槽的vue组件 228 | import VueComponent from './VueComponent.vue' 229 | import { applyVueInReact } from 'vuereact-combined' 230 | 231 | const VueComponentInReact = applyVueInReact(VueComponent) 232 | export default function() { 233 | // 具名插槽 234 | const $slots = { 235 | slotA:
具名插槽A
, 236 | slotB:
具名插槽B
237 | } 238 | // 作用域插槽 239 | const $scopedSlots = { 240 | slotC: (context) =>
我是作用域插槽C:{context.value}
241 | } 242 | return
243 | 244 |

我是普通的插槽

245 |
246 |
247 | } 248 | ``` 249 | `$slots` 具名插槽属性 250 | **Type:** {[slotName: string]: ReactNode} 251 | `$scopedSlots` 作用域插槽属性 252 | **Type:** {[slotName: string]: (context: RenderPropsContext) => ReactElement | ReactComponent} 253 | ## 在Vue组件中向React组件传递ReactNode类型的属性和renderProps类型的属性 254 | ```vue 255 | 256 | 273 | 274 | 284 | ``` 285 | applyReactInVue会将ReactNode类型的属性转会为Vue的具名插槽,将renderProps类型的属性转换为作用域插槽,具名插槽和作用域插槽的插槽名就是属性名 286 | ## 在Vue组件中调用React组件的Context/Provider 287 | ```vue 288 | 289 | 296 | 297 | 317 | ``` 318 | ## VueContainer,在React组件中使用Vue的动态组件 319 | VueContainer是一个高阶组件,通过component属性直接渲染Vue组件 320 | ```jsx 321 | // React JSX File 322 | import React, { useState, useEffect } from 'react' 323 | import VueComponent1 from './VueComponent1.vue' 324 | import VueComponent2 from './VueComponent2.vue' 325 | import { VueContainer } from 'vuereact-combined' 326 | 327 | const ElButton = applyVueInReact(Button) 328 | const ElButtonGroup = applyVueInReact(ButtonGroup) 329 | 330 | export default function() { 331 | const [vueComponent, setVueComponent] = useState(VueComponent1) 332 | useEffect(() => { 333 | // 3秒之后换成VueComponent2组件 334 | setTimeout(() => { 335 | setVueComponent(VueComponent2) 336 | }, 3000) 337 | }, []) 338 | const prop1 = '属性1' 339 | const prop2 = '属性2' 340 | return
341 | 342 | {/* component属性为string类型时,表示使用vue的全局组件,以下的例子表示在react组件中使用vue-router的 */} 343 | 344 |
345 | } 346 | ``` 347 | 348 | ## 在React组件中使用Vue组件的事件 349 | 注意:这里没有使用onEvent的属性传递方法,因为无法排除vue组件有属性与此种用法重名的可能 350 | ```jsx 351 | // React JSX File 352 | import React, { useState } from 'react' 353 | // 一个开放了某些事件的Vue组件 354 | import VueComponent from './VueComponent.vue' 355 | import { applyVueInReact } from 'vuereact-combined' 356 | 357 | const VueComponentInReact = applyVueInReact(VueComponent) 358 | 359 | export default function() { 360 | const click = () => { 361 | console.log('click') 362 | } 363 | const mouseEnter = () => { 364 | console.log('mouseEnter') 365 | } 366 | const customEvent = () => { 367 | console.log('mouseEnter') 368 | } 369 | // 通过on属性传递将事件所对应的函数传递给vue组件 370 | // 以下的代码等于同于vue中v-on="{click, mouseEnter, customEvent}" 371 | return 372 | } 373 | ``` 374 | ## applyRedux 375 | 作用:使得所有的Vue组件可以使用redux的状态管理 376 | 对工具包开启redux状态管理,这个场景一般存在于以React为主的项目中,为了使Vue组件也可以共享到redux,需要在项目的入口文件引入applyRedux方法(整个项目应该只引一次),将redux的store以及redux的context作为参数传入(或者至少在redux的Provider高阶组件引入的地方使用applyRedux方法) 377 | ````js 378 | // 第二个参数是redux的context,之所以需要传第二个参数,是因为有如下场景 379 | // Provider -> ReactCom1 -> VueCom1 -> ReactCom2 380 | // Provider无法直接透过Vue组件传递给之后的React组件,所以applyRedux提供了第二个参数,作用就是可以使通过Vue组件之后的React组件继续可以获取到redux的context 381 | import { ReactReduxContext } from 'react-redux' 382 | import store from '../reactComponents/reduxStore' 383 | applyRedux({ store, ReactReduxContext }) 384 | ```` 385 | #### store.js 386 | ````js 387 | // 原生的redux store的创建方式 388 | import { createStore } from 'redux' 389 | import someCombineReducer from './reducer' // 建议通过react-redux的combineReducer输出 390 | let store = createStore(someCombineReducer) 391 | export default store 392 | ```` 393 | React组件连接redux的方式这里就不再做介绍了,应该使用react-redux的connect方法 394 | 这里介绍Vue组件如何使用redux,工具包尽可能的实现了vue组件使用vuex的方式去使用redux,通过vm.$redux可以在组件实例里获取到redux状态管理 395 | ````html 396 | 401 | 402 | 420 | ```` 421 | 422 | ## applyVuex 423 | 作用:使得所有的Redux组件可以使用Vuex的状态管理 424 | 对工具包开启vuex状态管理,这个场景一般存在于以Vue为主的项目中,为了使React组件也可以共享到vuex,需要在项目的入口文件引入applyVuex方法(整个项目应该只引一次),将vuex的store作为参数传入 425 | ````js 426 | import store from '../store' // vuex的store文件 427 | applyVuex(store) 428 | ```` 429 | 430 | ## connectVuex 431 | 类似react-redux的connect方法,在React组件中使用,由于vuex的关键字比redux多,所以将参数改成了对象,包含了mapStateToProps、mapCommitToProps、mapGettersToProps、mapDispatchToProps,每个都是一个纯函数,返回一个对象(和redux的connect使用方式完全一致) 432 | ````js 433 | export default connectVuex({ 434 | mapStateToProps (state) { 435 | return { 436 | vuexState: state, 437 | state1: state.state1, 438 | moduleAstate: state.moduleA 439 | } 440 | }, 441 | mapCommitToProps (commit) { 442 | return { 443 | vuexCommit: commit 444 | } 445 | }, 446 | // mapGettersToProps = (getters) => {}, 447 | // mapDispatchToProps = (dispatch) => {}, 448 | })(ReactComponent) 449 | ```` 450 | 451 | ## lazyVueInReact 452 | 在React的router里懒加载Vue组件 453 | ````jsx harmony 454 | import React, { lazy, Suspense } from "react" 455 | import { lazyVueInReact } from 'vuereact-combined' 456 | const Hello = lazy(() => import("./react_app/hello")); 457 | //懒加载vue组件 458 | const TestVue = lazyVueInReact(() => import("./vue_app/test.vue")) 459 | 460 | 461 | export default [ 462 | { 463 | path: "/reactHello", 464 | component: () => { 465 | return ( 466 | Loading...}> 467 | 468 | 469 | ); 470 | } 471 | }, 472 | { 473 | path: "/vuetest1", 474 | component: () => { 475 | return ( 476 | Loading...}> 477 |
478 |

我是一个vue组件

479 | 480 |
481 |
482 | ); 483 | } 484 | }] 485 | ```` 486 | 487 | ## lazyReactInVue 488 | 在Vue的router里懒加载React组件 489 | ````js 490 | import Vue from 'vue' 491 | import VueRouter from 'vue-router' 492 | import { lazyReactInVue } from 'vuereact-combined' 493 | Vue.use(VueRouter) 494 | 495 | const routes = [ 496 | { 497 | path: '/', 498 | name: 'home', 499 | component: () => import('../views/Home') 500 | }, 501 | { 502 | path: '/reactInVueDemo', 503 | name: 'reactInVueDemo', 504 | component: lazyReactInVue(() => import('../reactComponents/cc.jsx')) 505 | } 506 | ] 507 | 508 | const router = new VueRouter({ 509 | routes 510 | }) 511 | 512 | export default router 513 | ```` 514 | 515 | ## withVueRouter 516 | 在react组件中获取vue router对象,可以通过props属性获取倒$vueRouter和$vueRoute 517 | ```jsx harmony 518 | import React from 'react' 519 | import { withVueRouter } from 'vuereact-combined' 520 | class Test2 extends React.Component { 521 | constructor (props) { 522 | super(props) 523 | } 524 | componentWillMount () { 525 | 526 | } 527 | componentDidMount () { 528 | // 可以通过props属性获取倒$vueRouter和$vueRoute 529 | console.log(this.props.$vueRouter, this.props.$vueRoute) 530 | } 531 | 532 | render () { 533 | return ( 534 |
535 | test2 536 |

{this.props.$vueRoute.query.b}

537 |
538 | ) 539 | } 540 | } 541 | export default withVueRouter(Test2) 542 | ``` 543 | 544 | ## applyReactRouterInVue 545 | 建议在react项目的app或者main引入,然后再任何一个被转换的vue组件中都可以直接获取到实例属性$reactRouter,其中包含了react router的history、location、match 546 | #### app.jsx 547 | ```jsx harmony 548 | import { applyReactRouterInVue } from 'vuereact-combined' 549 | import { withRouter } from 'react-router-dom' 550 | applyReactRouterInVue(withRouter) 551 | ``` 552 | #### demo.vue 553 | ```vue 554 | 560 | 561 | 567 | ``` 568 | ## 需要注意的包囊性问题 569 | 由于在每一次跨越一个框架进行组件引用时,都会出现一层包囊,这个包囊是默认是以div呈现,并且会被特殊属性标注 570 | React->Vue,会在vue组件的dom元素外包囊一层标识data-use-vue-component-wrap的div 571 | Vue->React,会在react组件的dom元素外包囊一层标识__use_react_component_wrap的div 572 | 如果引发样式问题,可以对applyVueInReact、applyReactInVue方法传入第二个参数`options` 573 | ```jsx 574 | import VueComponent from './VueComponent.vue' 575 | import { applyVueInReact } from 'vuereact-combined' 576 | const VueComponentInReact = applyVueInReact(VueComponent, { 577 | react: { 578 | // react.componentWrapAttrs代表是vue组件在react组件中的组件包囊层的标签设置 579 | // 以下设置将设置组件的包囊层div的display为inline-block 580 | componentWrapAttrs: { 581 | style: { 582 | display: 'inline-block' 583 | }, 584 | class: 'react-wrap-vue-component-1' 585 | }, 586 | // react.slotWrapAttrs代表是vue组件在react组件中的插槽包囊层的标签设置 587 | // 以下设置将设置插槽的包囊层div的display为inline-block 588 | slotWrapAttrs: { 589 | style: { 590 | display: 'inline-block' 591 | } 592 | }, 593 | }, 594 | }) 595 | ``` 596 | 以下是默认配置 597 | ```jsx 598 | // 默认配置 599 | const originOptions = { 600 | react: { 601 | componentWrap: 'div', 602 | slotWrap: 'div', 603 | componentWrapAttrs: { 604 | __use_react_component_wrap: '', 605 | style: { 606 | all: 'unset' 607 | } 608 | }, 609 | slotWrapAttrs: { 610 | __use_react_slot_wrap: '', 611 | style: { 612 | all: 'unset' 613 | } 614 | } 615 | }, 616 | vue: { 617 | // 组件wrapper 618 | componentWrapHOC: (VueComponentMountAt, nativeProps = []) => { 619 | // 传入portals 620 | return function ({ portals = [] } = {}) { 621 | return (
{VueComponentMountAt}{portals.map((Portal, index) => )}
) 622 | } 623 | }, 624 | componentWrapAttrs: { 625 | 'data-use-vue-component-wrap': '', 626 | style: { 627 | all: 'unset', 628 | } 629 | }, 630 | slotWrapAttrs: { 631 | 'data-use-vue-slot-wrap': '', 632 | style: { 633 | all: 'unset' 634 | } 635 | } 636 | } 637 | } 638 | ``` 639 | ## 支持程度 640 | #### 在react组件中引入vue组件 641 | 功能 | 支持程度 | 说明 642 | -|-|- 643 | 普通属性 | 完全支持 | | 644 | html片段属性 | 变向支持 | 通过$slots,在vue中使用具名插槽获取 | 645 | render props | 变向支持 | 通过$scopedSlots,在vue中使用作用域插槽获取 | 646 | children(普通插槽) | 完全支持 | | 647 | 组件合成事件 | 完全支持 | 通过on属性 | 648 | 组件原生事件(.native) | 不支持 | react没有这种感念,可以自己包囊div | 649 | v-model | 变向支持 | 通过$model,并且支持vue组件中随意自定义model属性 | 650 | html片段中使用react或者vue组件 | 完全支持 | react组件直接传入,vue组件继续通过applyVueInReact转换 | 651 | 懒加载vue组件 | 完全支持 | 通过lazyVueInReact | 652 | redux共享 | 完全支持 | 使用applyRedux | 653 | mobx共享 | 变向支持 | mobx本身就有react和vue的连接方式 | 654 | vuex共享 | 完全支持 | 使用applyVuex | 655 | sync装饰 | 变向支持 | 使用$sync | 656 | 事件修饰(key.enter、click.once) | 不支持 | 自行处理 | 657 | 透传 | 变向支持 | 使用data-passed-props | 658 | ref | 变向支持 | ref首先会返回包囊实例的,在包囊实例中的属性vueRef可以获取倒vue组件实例 | 659 | react router(在vue组件中) | 完全支持 | 使用applyReactRouterInVue | 660 | 判断自身是否被转化 | 完全支持 | 通过props属性data-passed-props或者实例属性reactWrapperRef | 661 | 662 | #### 在vue组件中引入react组件 663 | 功能 | 支持程度 | 说明 664 | -|-|- 665 | 普通属性 | 完全支持 | | 666 | 具名插槽 | 完全支持 | 在react中使用属性获取 | 667 | 作用域插槽 | 完全支持 | 在react中使用属性获取,类型是个函数 | 668 | 普通插槽 | 完全支持 | | 669 | 组件合成事件 | 完全支持 | 在react中使用属性获取 | 670 | 组件原生事件(.native) | 暂不支持 | | 671 | v-model | 不支持 | react组件没有这个概念 | 672 | provider/inject传入react | 暂不支持 | 未来会支持 | 673 | sync装饰 | 不支持 | react组件没有这个概念 | 674 | redux共享 | 完全支持 | 使用applyRedux | 675 | mobx共享 | 变向支持 | mobx本身就有react和vue的连接方式 | 676 | vuex共享 | 完全支持 | 使用applyVuex | 677 | 事件修饰(key.enter、click.once) | 不支持 | react组件没有这个概念 | 678 | 懒加载react组件 | 完全支持 | 通过lazyReactInVue | 679 | 透传 | 变向支持 | 使用data-passed-props | 680 | ref | 变向支持 | ref首先会返回包囊实例的,在包囊实例中的属性reactRef可以获取倒react组件实例 | 681 | vue router(在react组件中) | 完全支持 | 使用withVueRouter | 682 | 判断自身是否被转化 | 完全支持 | 通过props属性data-passed-props或者实例属性vueWrapperRef | 683 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vuereact-combined", 3 | "version": "1.2.11", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@babel/code-frame": { 8 | "version": "7.5.5", 9 | "resolved": "http://npm.weimob.com/@babel%2fcode-frame/-/code-frame-7.5.5.tgz", 10 | "integrity": "sha1-vAeC9tafe31JUxIZaZuYj2aaj50=", 11 | "dev": true, 12 | "requires": { 13 | "@babel/highlight": "^7.0.0" 14 | } 15 | }, 16 | "@babel/core": { 17 | "version": "7.7.4", 18 | "resolved": "http://npm.weimob.com/@babel%2fcore/-/core-7.7.4.tgz", 19 | "integrity": "sha1-N+hkUyIAy2tQ7ppARfX4F4QBZqs=", 20 | "dev": true, 21 | "requires": { 22 | "@babel/code-frame": "^7.5.5", 23 | "@babel/generator": "^7.7.4", 24 | "@babel/helpers": "^7.7.4", 25 | "@babel/parser": "^7.7.4", 26 | "@babel/template": "^7.7.4", 27 | "@babel/traverse": "^7.7.4", 28 | "@babel/types": "^7.7.4", 29 | "convert-source-map": "^1.7.0", 30 | "debug": "^4.1.0", 31 | "json5": "^2.1.0", 32 | "lodash": "^4.17.13", 33 | "resolve": "^1.3.2", 34 | "semver": "^5.4.1", 35 | "source-map": "^0.5.0" 36 | } 37 | }, 38 | "@babel/generator": { 39 | "version": "7.7.4", 40 | "resolved": "http://npm.weimob.com/@babel%2fgenerator/-/generator-7.7.4.tgz", 41 | "integrity": "sha1-22UeKEDKmqZvMn3OwdxfX6lhE2k=", 42 | "dev": true, 43 | "requires": { 44 | "@babel/types": "^7.7.4", 45 | "jsesc": "^2.5.1", 46 | "lodash": "^4.17.13", 47 | "source-map": "^0.5.0" 48 | } 49 | }, 50 | "@babel/helper-annotate-as-pure": { 51 | "version": "7.7.4", 52 | "resolved": "http://npm.weimob.com/@babel%2fhelper-annotate-as-pure/-/helper-annotate-as-pure-7.7.4.tgz", 53 | "integrity": "sha1-uz+vHnS3S9VH6Gfkj1UfprCYts4=", 54 | "dev": true, 55 | "requires": { 56 | "@babel/types": "^7.7.4" 57 | } 58 | }, 59 | "@babel/helper-builder-binary-assignment-operator-visitor": { 60 | "version": "7.7.4", 61 | "resolved": "http://npm.weimob.com/@babel%2fhelper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.7.4.tgz", 62 | "integrity": "sha1-X3PysoWA4iS1ub0DFGpAFdYhf18=", 63 | "dev": true, 64 | "requires": { 65 | "@babel/helper-explode-assignable-expression": "^7.7.4", 66 | "@babel/types": "^7.7.4" 67 | } 68 | }, 69 | "@babel/helper-builder-react-jsx": { 70 | "version": "7.7.4", 71 | "resolved": "http://npm.weimob.com/@babel%2fhelper-builder-react-jsx/-/helper-builder-react-jsx-7.7.4.tgz", 72 | "integrity": "sha1-2hiNJHUItlN1ssMM9Z3hh75rDGY=", 73 | "dev": true, 74 | "requires": { 75 | "@babel/types": "^7.7.4", 76 | "esutils": "^2.0.0" 77 | } 78 | }, 79 | "@babel/helper-call-delegate": { 80 | "version": "7.7.4", 81 | "resolved": "http://npm.weimob.com/@babel%2fhelper-call-delegate/-/helper-call-delegate-7.7.4.tgz", 82 | "integrity": "sha1-YhuD5ZZyK1DABm+dw30yMuRhuAE=", 83 | "dev": true, 84 | "requires": { 85 | "@babel/helper-hoist-variables": "^7.7.4", 86 | "@babel/traverse": "^7.7.4", 87 | "@babel/types": "^7.7.4" 88 | } 89 | }, 90 | "@babel/helper-create-class-features-plugin": { 91 | "version": "7.7.4", 92 | "resolved": "http://npm.weimob.com/@babel%2fhelper-create-class-features-plugin/-/helper-create-class-features-plugin-7.7.4.tgz", 93 | "integrity": "sha1-/OYJOf1QYYYQlCMgqNlRs7Y52i0=", 94 | "dev": true, 95 | "requires": { 96 | "@babel/helper-function-name": "^7.7.4", 97 | "@babel/helper-member-expression-to-functions": "^7.7.4", 98 | "@babel/helper-optimise-call-expression": "^7.7.4", 99 | "@babel/helper-plugin-utils": "^7.0.0", 100 | "@babel/helper-replace-supers": "^7.7.4", 101 | "@babel/helper-split-export-declaration": "^7.7.4" 102 | } 103 | }, 104 | "@babel/helper-create-regexp-features-plugin": { 105 | "version": "7.7.4", 106 | "resolved": "http://npm.weimob.com/@babel%2fhelper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.7.4.tgz", 107 | "integrity": "sha1-bVdiNZ/TT02hUA5M/5lVtSmar1k=", 108 | "dev": true, 109 | "requires": { 110 | "@babel/helper-regex": "^7.4.4", 111 | "regexpu-core": "^4.6.0" 112 | } 113 | }, 114 | "@babel/helper-define-map": { 115 | "version": "7.7.4", 116 | "resolved": "http://npm.weimob.com/@babel%2fhelper-define-map/-/helper-define-map-7.7.4.tgz", 117 | "integrity": "sha1-KEG/kuuL2ckGhRVG/mudReFi8XY=", 118 | "dev": true, 119 | "requires": { 120 | "@babel/helper-function-name": "^7.7.4", 121 | "@babel/types": "^7.7.4", 122 | "lodash": "^4.17.13" 123 | } 124 | }, 125 | "@babel/helper-explode-assignable-expression": { 126 | "version": "7.7.4", 127 | "resolved": "http://npm.weimob.com/@babel%2fhelper-explode-assignable-expression/-/helper-explode-assignable-expression-7.7.4.tgz", 128 | "integrity": "sha1-+nAIeOAI2F3FG6Q+n7g1zd/gXIQ=", 129 | "dev": true, 130 | "requires": { 131 | "@babel/traverse": "^7.7.4", 132 | "@babel/types": "^7.7.4" 133 | } 134 | }, 135 | "@babel/helper-function-name": { 136 | "version": "7.7.4", 137 | "resolved": "http://npm.weimob.com/@babel%2fhelper-function-name/-/helper-function-name-7.7.4.tgz", 138 | "integrity": "sha1-q24EHnE11DbY8KPsoV3ltno0Gi4=", 139 | "dev": true, 140 | "requires": { 141 | "@babel/helper-get-function-arity": "^7.7.4", 142 | "@babel/template": "^7.7.4", 143 | "@babel/types": "^7.7.4" 144 | } 145 | }, 146 | "@babel/helper-get-function-arity": { 147 | "version": "7.7.4", 148 | "resolved": "http://npm.weimob.com/@babel%2fhelper-get-function-arity/-/helper-get-function-arity-7.7.4.tgz", 149 | "integrity": "sha1-y0Y0jS+ICOYy8KsEgXITDmNgBfA=", 150 | "dev": true, 151 | "requires": { 152 | "@babel/types": "^7.7.4" 153 | } 154 | }, 155 | "@babel/helper-hoist-variables": { 156 | "version": "7.7.4", 157 | "resolved": "http://npm.weimob.com/@babel%2fhelper-hoist-variables/-/helper-hoist-variables-7.7.4.tgz", 158 | "integrity": "sha1-YSOE49gj/fqvn84xVQ/l1NsPPRI=", 159 | "dev": true, 160 | "requires": { 161 | "@babel/types": "^7.7.4" 162 | } 163 | }, 164 | "@babel/helper-member-expression-to-functions": { 165 | "version": "7.7.4", 166 | "resolved": "http://npm.weimob.com/@babel%2fhelper-member-expression-to-functions/-/helper-member-expression-to-functions-7.7.4.tgz", 167 | "integrity": "sha1-NWQ44lad9zIagyZkTUt5DSEiy3Q=", 168 | "dev": true, 169 | "requires": { 170 | "@babel/types": "^7.7.4" 171 | } 172 | }, 173 | "@babel/helper-module-imports": { 174 | "version": "7.7.4", 175 | "resolved": "https://registry.npm.taobao.org/@babel/helper-module-imports/download/@babel/helper-module-imports-7.7.4.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-module-imports%2Fdownload%2F%40babel%2Fhelper-module-imports-7.7.4.tgz", 176 | "integrity": "sha1-5aklKfiIi/MZpjdqv70c68SRrZE=", 177 | "dev": true, 178 | "requires": { 179 | "@babel/types": "^7.7.4" 180 | } 181 | }, 182 | "@babel/helper-module-transforms": { 183 | "version": "7.7.4", 184 | "resolved": "http://npm.weimob.com/@babel%2fhelper-module-transforms/-/helper-module-transforms-7.7.4.tgz", 185 | "integrity": "sha1-jXzbHh+Oo9jDiwZzRZJKxPjgh5o=", 186 | "dev": true, 187 | "requires": { 188 | "@babel/helper-module-imports": "^7.7.4", 189 | "@babel/helper-simple-access": "^7.7.4", 190 | "@babel/helper-split-export-declaration": "^7.7.4", 191 | "@babel/template": "^7.7.4", 192 | "@babel/types": "^7.7.4", 193 | "lodash": "^4.17.13" 194 | } 195 | }, 196 | "@babel/helper-optimise-call-expression": { 197 | "version": "7.7.4", 198 | "resolved": "http://npm.weimob.com/@babel%2fhelper-optimise-call-expression/-/helper-optimise-call-expression-7.7.4.tgz", 199 | "integrity": "sha1-A0rzE3DSmVJCqk30AsO3eUstzfI=", 200 | "dev": true, 201 | "requires": { 202 | "@babel/types": "^7.7.4" 203 | } 204 | }, 205 | "@babel/helper-plugin-utils": { 206 | "version": "7.0.0", 207 | "resolved": "http://npm.weimob.com/@babel%2fhelper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz", 208 | "integrity": "sha1-u7P77phmHFaQNCN8wDlnupm08lA=", 209 | "dev": true 210 | }, 211 | "@babel/helper-regex": { 212 | "version": "7.5.5", 213 | "resolved": "http://npm.weimob.com/@babel%2fhelper-regex/-/helper-regex-7.5.5.tgz", 214 | "integrity": "sha1-CqaCT3EAouDonBUnwjk2wVLKs1E=", 215 | "dev": true, 216 | "requires": { 217 | "lodash": "^4.17.13" 218 | } 219 | }, 220 | "@babel/helper-remap-async-to-generator": { 221 | "version": "7.7.4", 222 | "resolved": "http://npm.weimob.com/@babel%2fhelper-remap-async-to-generator/-/helper-remap-async-to-generator-7.7.4.tgz", 223 | "integrity": "sha1-xowkBzUNmvDgYe1nJq+0//FtAjQ=", 224 | "dev": true, 225 | "requires": { 226 | "@babel/helper-annotate-as-pure": "^7.7.4", 227 | "@babel/helper-wrap-function": "^7.7.4", 228 | "@babel/template": "^7.7.4", 229 | "@babel/traverse": "^7.7.4", 230 | "@babel/types": "^7.7.4" 231 | } 232 | }, 233 | "@babel/helper-replace-supers": { 234 | "version": "7.7.4", 235 | "resolved": "http://npm.weimob.com/@babel%2fhelper-replace-supers/-/helper-replace-supers-7.7.4.tgz", 236 | "integrity": "sha1-PIgaamp1cSdactguYQcSbsnizdI=", 237 | "dev": true, 238 | "requires": { 239 | "@babel/helper-member-expression-to-functions": "^7.7.4", 240 | "@babel/helper-optimise-call-expression": "^7.7.4", 241 | "@babel/traverse": "^7.7.4", 242 | "@babel/types": "^7.7.4" 243 | } 244 | }, 245 | "@babel/helper-simple-access": { 246 | "version": "7.7.4", 247 | "resolved": "http://npm.weimob.com/@babel%2fhelper-simple-access/-/helper-simple-access-7.7.4.tgz", 248 | "integrity": "sha1-oWmgrbG19BjPwZ8iWGsuv1ipopQ=", 249 | "dev": true, 250 | "requires": { 251 | "@babel/template": "^7.7.4", 252 | "@babel/types": "^7.7.4" 253 | } 254 | }, 255 | "@babel/helper-split-export-declaration": { 256 | "version": "7.7.4", 257 | "resolved": "http://npm.weimob.com/@babel%2fhelper-split-export-declaration/-/helper-split-export-declaration-7.7.4.tgz", 258 | "integrity": "sha1-Vykq9gRDxKNiLPdAQN3Cjmgzb9g=", 259 | "dev": true, 260 | "requires": { 261 | "@babel/types": "^7.7.4" 262 | } 263 | }, 264 | "@babel/helper-wrap-function": { 265 | "version": "7.7.4", 266 | "resolved": "http://npm.weimob.com/@babel%2fhelper-wrap-function/-/helper-wrap-function-7.7.4.tgz", 267 | "integrity": "sha1-N6t/7VFQ4i2dcmboMAcsDN2Lqs4=", 268 | "dev": true, 269 | "requires": { 270 | "@babel/helper-function-name": "^7.7.4", 271 | "@babel/template": "^7.7.4", 272 | "@babel/traverse": "^7.7.4", 273 | "@babel/types": "^7.7.4" 274 | } 275 | }, 276 | "@babel/helpers": { 277 | "version": "7.7.4", 278 | "resolved": "http://npm.weimob.com/@babel%2fhelpers/-/helpers-7.7.4.tgz", 279 | "integrity": "sha1-YsIVuebHEtrcFamg3Kt2ySqUAwI=", 280 | "dev": true, 281 | "requires": { 282 | "@babel/template": "^7.7.4", 283 | "@babel/traverse": "^7.7.4", 284 | "@babel/types": "^7.7.4" 285 | } 286 | }, 287 | "@babel/highlight": { 288 | "version": "7.5.0", 289 | "resolved": "http://npm.weimob.com/@babel%2fhighlight/-/highlight-7.5.0.tgz", 290 | "integrity": "sha1-VtETEr2SSPphlZHQJHK+boyzJUA=", 291 | "dev": true, 292 | "requires": { 293 | "chalk": "^2.0.0", 294 | "esutils": "^2.0.2", 295 | "js-tokens": "^4.0.0" 296 | } 297 | }, 298 | "@babel/parser": { 299 | "version": "7.7.4", 300 | "resolved": "http://npm.weimob.com/@babel%2fparser/-/parser-7.7.4.tgz", 301 | "integrity": "sha1-dastcRDCzy+pSZWa+wX6NG0iMbs=", 302 | "dev": true 303 | }, 304 | "@babel/plugin-external-helpers": { 305 | "version": "7.7.4", 306 | "resolved": "http://npm.weimob.com/@babel%2fplugin-external-helpers/-/plugin-external-helpers-7.7.4.tgz", 307 | "integrity": "sha1-iqeqQC8OLsuSRhHL8wlCpJff0X4=", 308 | "dev": true, 309 | "requires": { 310 | "@babel/helper-plugin-utils": "^7.0.0" 311 | } 312 | }, 313 | "@babel/plugin-proposal-async-generator-functions": { 314 | "version": "7.7.4", 315 | "resolved": "http://npm.weimob.com/@babel%2fplugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.7.4.tgz", 316 | "integrity": "sha1-A1HFrAqeknhF//1bgq9HaUe3zm0=", 317 | "dev": true, 318 | "requires": { 319 | "@babel/helper-plugin-utils": "^7.0.0", 320 | "@babel/helper-remap-async-to-generator": "^7.7.4", 321 | "@babel/plugin-syntax-async-generators": "^7.7.4" 322 | } 323 | }, 324 | "@babel/plugin-proposal-class-properties": { 325 | "version": "7.7.4", 326 | "resolved": "http://npm.weimob.com/@babel%2fplugin-proposal-class-properties/-/plugin-proposal-class-properties-7.7.4.tgz", 327 | "integrity": "sha1-L5ZPDLGLlIRQNidC4z4VIR53wro=", 328 | "dev": true, 329 | "requires": { 330 | "@babel/helper-create-class-features-plugin": "^7.7.4", 331 | "@babel/helper-plugin-utils": "^7.0.0" 332 | } 333 | }, 334 | "@babel/plugin-proposal-dynamic-import": { 335 | "version": "7.7.4", 336 | "resolved": "http://npm.weimob.com/@babel%2fplugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.7.4.tgz", 337 | "integrity": "sha1-3eZKfxJ2kXWMv+1s9w3g+lh51S0=", 338 | "dev": true, 339 | "requires": { 340 | "@babel/helper-plugin-utils": "^7.0.0", 341 | "@babel/plugin-syntax-dynamic-import": "^7.7.4" 342 | } 343 | }, 344 | "@babel/plugin-proposal-json-strings": { 345 | "version": "7.7.4", 346 | "resolved": "http://npm.weimob.com/@babel%2fplugin-proposal-json-strings/-/plugin-proposal-json-strings-7.7.4.tgz", 347 | "integrity": "sha1-dwCmv9p3HY3IGXMknqxBbGtMaX0=", 348 | "dev": true, 349 | "requires": { 350 | "@babel/helper-plugin-utils": "^7.0.0", 351 | "@babel/plugin-syntax-json-strings": "^7.7.4" 352 | } 353 | }, 354 | "@babel/plugin-proposal-object-rest-spread": { 355 | "version": "7.7.4", 356 | "resolved": "http://npm.weimob.com/@babel%2fplugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.7.4.tgz", 357 | "integrity": "sha1-zFeEmJSlx3QhQXjIq2T2M07Ir3E=", 358 | "dev": true, 359 | "requires": { 360 | "@babel/helper-plugin-utils": "^7.0.0", 361 | "@babel/plugin-syntax-object-rest-spread": "^7.7.4" 362 | } 363 | }, 364 | "@babel/plugin-proposal-optional-catch-binding": { 365 | "version": "7.7.4", 366 | "resolved": "http://npm.weimob.com/@babel%2fplugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.7.4.tgz", 367 | "integrity": "sha1-7CHorrCexnEbwKOcpJUgq+4d43k=", 368 | "dev": true, 369 | "requires": { 370 | "@babel/helper-plugin-utils": "^7.0.0", 371 | "@babel/plugin-syntax-optional-catch-binding": "^7.7.4" 372 | } 373 | }, 374 | "@babel/plugin-proposal-unicode-property-regex": { 375 | "version": "7.7.4", 376 | "resolved": "http://npm.weimob.com/@babel%2fplugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.7.4.tgz", 377 | "integrity": "sha1-fCOcyvCUcNvh1FPVAFdGDoRRfrs=", 378 | "dev": true, 379 | "requires": { 380 | "@babel/helper-create-regexp-features-plugin": "^7.7.4", 381 | "@babel/helper-plugin-utils": "^7.0.0" 382 | } 383 | }, 384 | "@babel/plugin-syntax-async-generators": { 385 | "version": "7.7.4", 386 | "resolved": "http://npm.weimob.com/@babel%2fplugin-syntax-async-generators/-/plugin-syntax-async-generators-7.7.4.tgz", 387 | "integrity": "sha1-MxqvMQoQyAxEpmsji25JEyvTyIk=", 388 | "dev": true, 389 | "requires": { 390 | "@babel/helper-plugin-utils": "^7.0.0" 391 | } 392 | }, 393 | "@babel/plugin-syntax-dynamic-import": { 394 | "version": "7.7.4", 395 | "resolved": "http://npm.weimob.com/@babel%2fplugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.7.4.tgz", 396 | "integrity": "sha1-Kco7RBWr/kpew4HpA4Yq0aVMOuw=", 397 | "dev": true, 398 | "requires": { 399 | "@babel/helper-plugin-utils": "^7.0.0" 400 | } 401 | }, 402 | "@babel/plugin-syntax-json-strings": { 403 | "version": "7.7.4", 404 | "resolved": "http://npm.weimob.com/@babel%2fplugin-syntax-json-strings/-/plugin-syntax-json-strings-7.7.4.tgz", 405 | "integrity": "sha1-huY/fS4i+eJxKaxOg+qYmjguhsw=", 406 | "dev": true, 407 | "requires": { 408 | "@babel/helper-plugin-utils": "^7.0.0" 409 | } 410 | }, 411 | "@babel/plugin-syntax-jsx": { 412 | "version": "7.7.4", 413 | "resolved": "http://npm.weimob.com/@babel%2fplugin-syntax-jsx/-/plugin-syntax-jsx-7.7.4.tgz", 414 | "integrity": "sha1-2rK1ajb7bDwiKh+8cfe/l/Mnqew=", 415 | "dev": true, 416 | "requires": { 417 | "@babel/helper-plugin-utils": "^7.0.0" 418 | } 419 | }, 420 | "@babel/plugin-syntax-object-rest-spread": { 421 | "version": "7.7.4", 422 | "resolved": "http://npm.weimob.com/@babel%2fplugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.7.4.tgz", 423 | "integrity": "sha1-R88iDRnW0NexVDBHAfRo/BzG/0Y=", 424 | "dev": true, 425 | "requires": { 426 | "@babel/helper-plugin-utils": "^7.0.0" 427 | } 428 | }, 429 | "@babel/plugin-syntax-optional-catch-binding": { 430 | "version": "7.7.4", 431 | "resolved": "http://npm.weimob.com/@babel%2fplugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.7.4.tgz", 432 | "integrity": "sha1-o+OPWfS2IzhntKktyw7gWywzSqY=", 433 | "dev": true, 434 | "requires": { 435 | "@babel/helper-plugin-utils": "^7.0.0" 436 | } 437 | }, 438 | "@babel/plugin-syntax-top-level-await": { 439 | "version": "7.7.4", 440 | "resolved": "http://npm.weimob.com/@babel%2fplugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.7.4.tgz", 441 | "integrity": "sha1-vX2Pp7n+55OjbkAn/W3RqjL5Rto=", 442 | "dev": true, 443 | "requires": { 444 | "@babel/helper-plugin-utils": "^7.0.0" 445 | } 446 | }, 447 | "@babel/plugin-transform-arrow-functions": { 448 | "version": "7.7.4", 449 | "resolved": "http://npm.weimob.com/@babel%2fplugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.7.4.tgz", 450 | "integrity": "sha1-djCb1Xit3YruOzedgJyAIwWpihI=", 451 | "dev": true, 452 | "requires": { 453 | "@babel/helper-plugin-utils": "^7.0.0" 454 | } 455 | }, 456 | "@babel/plugin-transform-async-to-generator": { 457 | "version": "7.7.4", 458 | "resolved": "http://npm.weimob.com/@babel%2fplugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.7.4.tgz", 459 | "integrity": "sha1-aUy+rm1hOjTvApJxP6QvtFxEcLo=", 460 | "dev": true, 461 | "requires": { 462 | "@babel/helper-module-imports": "^7.7.4", 463 | "@babel/helper-plugin-utils": "^7.0.0", 464 | "@babel/helper-remap-async-to-generator": "^7.7.4" 465 | } 466 | }, 467 | "@babel/plugin-transform-block-scoped-functions": { 468 | "version": "7.7.4", 469 | "resolved": "http://npm.weimob.com/@babel%2fplugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.7.4.tgz", 470 | "integrity": "sha1-0NnVwmnHjq6nYies4hS40B5Ng3s=", 471 | "dev": true, 472 | "requires": { 473 | "@babel/helper-plugin-utils": "^7.0.0" 474 | } 475 | }, 476 | "@babel/plugin-transform-block-scoping": { 477 | "version": "7.7.4", 478 | "resolved": "http://npm.weimob.com/@babel%2fplugin-transform-block-scoping/-/plugin-transform-block-scoping-7.7.4.tgz", 479 | "integrity": "sha1-IAqtDc1ruANy+U2eYo6gYsWL8iQ=", 480 | "dev": true, 481 | "requires": { 482 | "@babel/helper-plugin-utils": "^7.0.0", 483 | "lodash": "^4.17.13" 484 | } 485 | }, 486 | "@babel/plugin-transform-classes": { 487 | "version": "7.7.4", 488 | "resolved": "http://npm.weimob.com/@babel%2fplugin-transform-classes/-/plugin-transform-classes-7.7.4.tgz", 489 | "integrity": "sha1-ySwUvgoTmeFd9yZnBnqPUQyUAOw=", 490 | "dev": true, 491 | "requires": { 492 | "@babel/helper-annotate-as-pure": "^7.7.4", 493 | "@babel/helper-define-map": "^7.7.4", 494 | "@babel/helper-function-name": "^7.7.4", 495 | "@babel/helper-optimise-call-expression": "^7.7.4", 496 | "@babel/helper-plugin-utils": "^7.0.0", 497 | "@babel/helper-replace-supers": "^7.7.4", 498 | "@babel/helper-split-export-declaration": "^7.7.4", 499 | "globals": "^11.1.0" 500 | } 501 | }, 502 | "@babel/plugin-transform-computed-properties": { 503 | "version": "7.7.4", 504 | "resolved": "http://npm.weimob.com/@babel%2fplugin-transform-computed-properties/-/plugin-transform-computed-properties-7.7.4.tgz", 505 | "integrity": "sha1-6FbBYo0yOP/hLWaOtCVZ95qBkQ0=", 506 | "dev": true, 507 | "requires": { 508 | "@babel/helper-plugin-utils": "^7.0.0" 509 | } 510 | }, 511 | "@babel/plugin-transform-destructuring": { 512 | "version": "7.7.4", 513 | "resolved": "http://npm.weimob.com/@babel%2fplugin-transform-destructuring/-/plugin-transform-destructuring-7.7.4.tgz", 514 | "integrity": "sha1-K3E3KeUFShE1CXtqZ9obb+h4kmc=", 515 | "dev": true, 516 | "requires": { 517 | "@babel/helper-plugin-utils": "^7.0.0" 518 | } 519 | }, 520 | "@babel/plugin-transform-dotall-regex": { 521 | "version": "7.7.4", 522 | "resolved": "http://npm.weimob.com/@babel%2fplugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.7.4.tgz", 523 | "integrity": "sha1-98zaYRGMW3olmactXjIQiEoCHpY=", 524 | "dev": true, 525 | "requires": { 526 | "@babel/helper-create-regexp-features-plugin": "^7.7.4", 527 | "@babel/helper-plugin-utils": "^7.0.0" 528 | } 529 | }, 530 | "@babel/plugin-transform-duplicate-keys": { 531 | "version": "7.7.4", 532 | "resolved": "http://npm.weimob.com/@babel%2fplugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.7.4.tgz", 533 | "integrity": "sha1-PSFzGkLj9ZinODUpndAWnDuQrJE=", 534 | "dev": true, 535 | "requires": { 536 | "@babel/helper-plugin-utils": "^7.0.0" 537 | } 538 | }, 539 | "@babel/plugin-transform-exponentiation-operator": { 540 | "version": "7.7.4", 541 | "resolved": "http://npm.weimob.com/@babel%2fplugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.7.4.tgz", 542 | "integrity": "sha1-3TDAGR46G6GbzH44m9/dwHKdXbk=", 543 | "dev": true, 544 | "requires": { 545 | "@babel/helper-builder-binary-assignment-operator-visitor": "^7.7.4", 546 | "@babel/helper-plugin-utils": "^7.0.0" 547 | } 548 | }, 549 | "@babel/plugin-transform-for-of": { 550 | "version": "7.7.4", 551 | "resolved": "http://npm.weimob.com/@babel%2fplugin-transform-for-of/-/plugin-transform-for-of-7.7.4.tgz", 552 | "integrity": "sha1-JIgA46XlB7HxA9i0ypmOd8Y5Mrw=", 553 | "dev": true, 554 | "requires": { 555 | "@babel/helper-plugin-utils": "^7.0.0" 556 | } 557 | }, 558 | "@babel/plugin-transform-function-name": { 559 | "version": "7.7.4", 560 | "resolved": "http://npm.weimob.com/@babel%2fplugin-transform-function-name/-/plugin-transform-function-name-7.7.4.tgz", 561 | "integrity": "sha1-dabTMD1Q22OP+LU4XRJFHIZQJbE=", 562 | "dev": true, 563 | "requires": { 564 | "@babel/helper-function-name": "^7.7.4", 565 | "@babel/helper-plugin-utils": "^7.0.0" 566 | } 567 | }, 568 | "@babel/plugin-transform-literals": { 569 | "version": "7.7.4", 570 | "resolved": "http://npm.weimob.com/@babel%2fplugin-transform-literals/-/plugin-transform-literals-7.7.4.tgz", 571 | "integrity": "sha1-J/6H0rUBeipaNNHEGmufamJiZD4=", 572 | "dev": true, 573 | "requires": { 574 | "@babel/helper-plugin-utils": "^7.0.0" 575 | } 576 | }, 577 | "@babel/plugin-transform-member-expression-literals": { 578 | "version": "7.7.4", 579 | "resolved": "http://npm.weimob.com/@babel%2fplugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.7.4.tgz", 580 | "integrity": "sha1-ruEn8vMzn8NM5eMFXX/796om8Zo=", 581 | "dev": true, 582 | "requires": { 583 | "@babel/helper-plugin-utils": "^7.0.0" 584 | } 585 | }, 586 | "@babel/plugin-transform-modules-amd": { 587 | "version": "7.7.4", 588 | "resolved": "http://npm.weimob.com/@babel%2fplugin-transform-modules-amd/-/plugin-transform-modules-amd-7.7.4.tgz", 589 | "integrity": "sha1-J2s4RcorIo8pleRTrcLm9U1y+3E=", 590 | "dev": true, 591 | "requires": { 592 | "@babel/helper-module-transforms": "^7.7.4", 593 | "@babel/helper-plugin-utils": "^7.0.0", 594 | "babel-plugin-dynamic-import-node": "^2.3.0" 595 | } 596 | }, 597 | "@babel/plugin-transform-modules-commonjs": { 598 | "version": "7.7.4", 599 | "resolved": "http://npm.weimob.com/@babel%2fplugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.7.4.tgz", 600 | "integrity": "sha1-vuQ4blUERjQ91SpXHtpHhR/4V6M=", 601 | "dev": true, 602 | "requires": { 603 | "@babel/helper-module-transforms": "^7.7.4", 604 | "@babel/helper-plugin-utils": "^7.0.0", 605 | "@babel/helper-simple-access": "^7.7.4", 606 | "babel-plugin-dynamic-import-node": "^2.3.0" 607 | } 608 | }, 609 | "@babel/plugin-transform-modules-systemjs": { 610 | "version": "7.7.4", 611 | "resolved": "http://npm.weimob.com/@babel%2fplugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.7.4.tgz", 612 | "integrity": "sha1-zZgVIznT52Pf6Di31Cc+2vUguzA=", 613 | "dev": true, 614 | "requires": { 615 | "@babel/helper-hoist-variables": "^7.7.4", 616 | "@babel/helper-plugin-utils": "^7.0.0", 617 | "babel-plugin-dynamic-import-node": "^2.3.0" 618 | } 619 | }, 620 | "@babel/plugin-transform-modules-umd": { 621 | "version": "7.7.4", 622 | "resolved": "http://npm.weimob.com/@babel%2fplugin-transform-modules-umd/-/plugin-transform-modules-umd-7.7.4.tgz", 623 | "integrity": "sha1-ECfDVaEY3gqun+4ArXgTxYTZBh8=", 624 | "dev": true, 625 | "requires": { 626 | "@babel/helper-module-transforms": "^7.7.4", 627 | "@babel/helper-plugin-utils": "^7.0.0" 628 | } 629 | }, 630 | "@babel/plugin-transform-named-capturing-groups-regex": { 631 | "version": "7.7.4", 632 | "resolved": "http://npm.weimob.com/@babel%2fplugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.7.4.tgz", 633 | "integrity": "sha1-+zvMTuQZjnOFgFAHNz1rb0LJgiA=", 634 | "dev": true, 635 | "requires": { 636 | "@babel/helper-create-regexp-features-plugin": "^7.7.4" 637 | } 638 | }, 639 | "@babel/plugin-transform-new-target": { 640 | "version": "7.7.4", 641 | "resolved": "http://npm.weimob.com/@babel%2fplugin-transform-new-target/-/plugin-transform-new-target-7.7.4.tgz", 642 | "integrity": "sha1-SgdT0tYGOUN74HtZKp5Y7gByAWc=", 643 | "dev": true, 644 | "requires": { 645 | "@babel/helper-plugin-utils": "^7.0.0" 646 | } 647 | }, 648 | "@babel/plugin-transform-object-super": { 649 | "version": "7.7.4", 650 | "resolved": "http://npm.weimob.com/@babel%2fplugin-transform-object-super/-/plugin-transform-object-super-7.7.4.tgz", 651 | "integrity": "sha1-SEiJN6LVhsAUhFG/Ua+dfdpWcmI=", 652 | "dev": true, 653 | "requires": { 654 | "@babel/helper-plugin-utils": "^7.0.0", 655 | "@babel/helper-replace-supers": "^7.7.4" 656 | } 657 | }, 658 | "@babel/plugin-transform-parameters": { 659 | "version": "7.7.4", 660 | "resolved": "http://npm.weimob.com/@babel%2fplugin-transform-parameters/-/plugin-transform-parameters-7.7.4.tgz", 661 | "integrity": "sha1-2kVVyX85tRrAidMcc4DwO8pAdc4=", 662 | "dev": true, 663 | "requires": { 664 | "@babel/helper-call-delegate": "^7.7.4", 665 | "@babel/helper-get-function-arity": "^7.7.4", 666 | "@babel/helper-plugin-utils": "^7.0.0" 667 | } 668 | }, 669 | "@babel/plugin-transform-property-literals": { 670 | "version": "7.7.4", 671 | "resolved": "http://npm.weimob.com/@babel%2fplugin-transform-property-literals/-/plugin-transform-property-literals-7.7.4.tgz", 672 | "integrity": "sha1-I4jWUF74myZhA/RQ+RZ+a9c/mMI=", 673 | "dev": true, 674 | "requires": { 675 | "@babel/helper-plugin-utils": "^7.0.0" 676 | } 677 | }, 678 | "@babel/plugin-transform-react-display-name": { 679 | "version": "7.7.4", 680 | "resolved": "http://npm.weimob.com/@babel%2fplugin-transform-react-display-name/-/plugin-transform-react-display-name-7.7.4.tgz", 681 | "integrity": "sha1-nyuAsU68l+70qbKbYSxY7ZwNEN0=", 682 | "dev": true, 683 | "requires": { 684 | "@babel/helper-plugin-utils": "^7.0.0" 685 | } 686 | }, 687 | "@babel/plugin-transform-react-jsx": { 688 | "version": "7.7.4", 689 | "resolved": "http://npm.weimob.com/@babel%2fplugin-transform-react-jsx/-/plugin-transform-react-jsx-7.7.4.tgz", 690 | "integrity": "sha1-2RIFcX+uTi+E0CDNMFfsAqEPEdo=", 691 | "dev": true, 692 | "requires": { 693 | "@babel/helper-builder-react-jsx": "^7.7.4", 694 | "@babel/helper-plugin-utils": "^7.0.0", 695 | "@babel/plugin-syntax-jsx": "^7.7.4" 696 | } 697 | }, 698 | "@babel/plugin-transform-react-jsx-self": { 699 | "version": "7.7.4", 700 | "resolved": "http://npm.weimob.com/@babel%2fplugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.7.4.tgz", 701 | "integrity": "sha1-gbj7/RSyIV6PHCw637omYSewIxw=", 702 | "dev": true, 703 | "requires": { 704 | "@babel/helper-plugin-utils": "^7.0.0", 705 | "@babel/plugin-syntax-jsx": "^7.7.4" 706 | } 707 | }, 708 | "@babel/plugin-transform-react-jsx-source": { 709 | "version": "7.7.4", 710 | "resolved": "http://npm.weimob.com/@babel%2fplugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.7.4.tgz", 711 | "integrity": "sha1-iZSxv2AUsTP1pG07fR7l9ePnLBA=", 712 | "dev": true, 713 | "requires": { 714 | "@babel/helper-plugin-utils": "^7.0.0", 715 | "@babel/plugin-syntax-jsx": "^7.7.4" 716 | } 717 | }, 718 | "@babel/plugin-transform-regenerator": { 719 | "version": "7.7.4", 720 | "resolved": "http://npm.weimob.com/@babel%2fplugin-transform-regenerator/-/plugin-transform-regenerator-7.7.4.tgz", 721 | "integrity": "sha1-0Y6sAxKnAVLX2RTL7S3DmZYBz8A=", 722 | "dev": true, 723 | "requires": { 724 | "regenerator-transform": "^0.14.0" 725 | } 726 | }, 727 | "@babel/plugin-transform-reserved-words": { 728 | "version": "7.7.4", 729 | "resolved": "http://npm.weimob.com/@babel%2fplugin-transform-reserved-words/-/plugin-transform-reserved-words-7.7.4.tgz", 730 | "integrity": "sha1-anzxI60XW7XGmuyPbwdwOH7T8es=", 731 | "dev": true, 732 | "requires": { 733 | "@babel/helper-plugin-utils": "^7.0.0" 734 | } 735 | }, 736 | "@babel/plugin-transform-shorthand-properties": { 737 | "version": "7.7.4", 738 | "resolved": "http://npm.weimob.com/@babel%2fplugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.7.4.tgz", 739 | "integrity": "sha1-dKCpsvbWemhMb7/V8EWOt7qZiR4=", 740 | "dev": true, 741 | "requires": { 742 | "@babel/helper-plugin-utils": "^7.0.0" 743 | } 744 | }, 745 | "@babel/plugin-transform-spread": { 746 | "version": "7.7.4", 747 | "resolved": "http://npm.weimob.com/@babel%2fplugin-transform-spread/-/plugin-transform-spread-7.7.4.tgz", 748 | "integrity": "sha1-qmc7NW/mt+cNabbjOhf+9kEAhXg=", 749 | "dev": true, 750 | "requires": { 751 | "@babel/helper-plugin-utils": "^7.0.0" 752 | } 753 | }, 754 | "@babel/plugin-transform-sticky-regex": { 755 | "version": "7.7.4", 756 | "resolved": "http://npm.weimob.com/@babel%2fplugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.7.4.tgz", 757 | "integrity": "sha1-/7aMBQkMMHMgdrEoXcFAG0BKEjw=", 758 | "dev": true, 759 | "requires": { 760 | "@babel/helper-plugin-utils": "^7.0.0", 761 | "@babel/helper-regex": "^7.0.0" 762 | } 763 | }, 764 | "@babel/plugin-transform-template-literals": { 765 | "version": "7.7.4", 766 | "resolved": "http://npm.weimob.com/@babel%2fplugin-transform-template-literals/-/plugin-transform-template-literals-7.7.4.tgz", 767 | "integrity": "sha1-HrZBFzbdP+h9vSDMZmjlEhwX1gQ=", 768 | "dev": true, 769 | "requires": { 770 | "@babel/helper-annotate-as-pure": "^7.7.4", 771 | "@babel/helper-plugin-utils": "^7.0.0" 772 | } 773 | }, 774 | "@babel/plugin-transform-typeof-symbol": { 775 | "version": "7.7.4", 776 | "resolved": "http://npm.weimob.com/@babel%2fplugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.7.4.tgz", 777 | "integrity": "sha1-MXRiYhTy1t4yKILkmKOOg3GyFA4=", 778 | "dev": true, 779 | "requires": { 780 | "@babel/helper-plugin-utils": "^7.0.0" 781 | } 782 | }, 783 | "@babel/plugin-transform-unicode-regex": { 784 | "version": "7.7.4", 785 | "resolved": "http://npm.weimob.com/@babel%2fplugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.7.4.tgz", 786 | "integrity": "sha1-o8D2WxF8TIHFtkhPKl57lTRrg64=", 787 | "dev": true, 788 | "requires": { 789 | "@babel/helper-create-regexp-features-plugin": "^7.7.4", 790 | "@babel/helper-plugin-utils": "^7.0.0" 791 | } 792 | }, 793 | "@babel/preset-env": { 794 | "version": "7.7.4", 795 | "resolved": "http://npm.weimob.com/@babel%2fpreset-env/-/preset-env-7.7.4.tgz", 796 | "integrity": "sha1-zK8wmujR7iQJyFpOK14oDO7oMPg=", 797 | "dev": true, 798 | "requires": { 799 | "@babel/helper-module-imports": "^7.7.4", 800 | "@babel/helper-plugin-utils": "^7.0.0", 801 | "@babel/plugin-proposal-async-generator-functions": "^7.7.4", 802 | "@babel/plugin-proposal-dynamic-import": "^7.7.4", 803 | "@babel/plugin-proposal-json-strings": "^7.7.4", 804 | "@babel/plugin-proposal-object-rest-spread": "^7.7.4", 805 | "@babel/plugin-proposal-optional-catch-binding": "^7.7.4", 806 | "@babel/plugin-proposal-unicode-property-regex": "^7.7.4", 807 | "@babel/plugin-syntax-async-generators": "^7.7.4", 808 | "@babel/plugin-syntax-dynamic-import": "^7.7.4", 809 | "@babel/plugin-syntax-json-strings": "^7.7.4", 810 | "@babel/plugin-syntax-object-rest-spread": "^7.7.4", 811 | "@babel/plugin-syntax-optional-catch-binding": "^7.7.4", 812 | "@babel/plugin-syntax-top-level-await": "^7.7.4", 813 | "@babel/plugin-transform-arrow-functions": "^7.7.4", 814 | "@babel/plugin-transform-async-to-generator": "^7.7.4", 815 | "@babel/plugin-transform-block-scoped-functions": "^7.7.4", 816 | "@babel/plugin-transform-block-scoping": "^7.7.4", 817 | "@babel/plugin-transform-classes": "^7.7.4", 818 | "@babel/plugin-transform-computed-properties": "^7.7.4", 819 | "@babel/plugin-transform-destructuring": "^7.7.4", 820 | "@babel/plugin-transform-dotall-regex": "^7.7.4", 821 | "@babel/plugin-transform-duplicate-keys": "^7.7.4", 822 | "@babel/plugin-transform-exponentiation-operator": "^7.7.4", 823 | "@babel/plugin-transform-for-of": "^7.7.4", 824 | "@babel/plugin-transform-function-name": "^7.7.4", 825 | "@babel/plugin-transform-literals": "^7.7.4", 826 | "@babel/plugin-transform-member-expression-literals": "^7.7.4", 827 | "@babel/plugin-transform-modules-amd": "^7.7.4", 828 | "@babel/plugin-transform-modules-commonjs": "^7.7.4", 829 | "@babel/plugin-transform-modules-systemjs": "^7.7.4", 830 | "@babel/plugin-transform-modules-umd": "^7.7.4", 831 | "@babel/plugin-transform-named-capturing-groups-regex": "^7.7.4", 832 | "@babel/plugin-transform-new-target": "^7.7.4", 833 | "@babel/plugin-transform-object-super": "^7.7.4", 834 | "@babel/plugin-transform-parameters": "^7.7.4", 835 | "@babel/plugin-transform-property-literals": "^7.7.4", 836 | "@babel/plugin-transform-regenerator": "^7.7.4", 837 | "@babel/plugin-transform-reserved-words": "^7.7.4", 838 | "@babel/plugin-transform-shorthand-properties": "^7.7.4", 839 | "@babel/plugin-transform-spread": "^7.7.4", 840 | "@babel/plugin-transform-sticky-regex": "^7.7.4", 841 | "@babel/plugin-transform-template-literals": "^7.7.4", 842 | "@babel/plugin-transform-typeof-symbol": "^7.7.4", 843 | "@babel/plugin-transform-unicode-regex": "^7.7.4", 844 | "@babel/types": "^7.7.4", 845 | "browserslist": "^4.6.0", 846 | "core-js-compat": "^3.1.1", 847 | "invariant": "^2.2.2", 848 | "js-levenshtein": "^1.1.3", 849 | "semver": "^5.5.0" 850 | } 851 | }, 852 | "@babel/preset-react": { 853 | "version": "7.7.4", 854 | "resolved": "http://npm.weimob.com/@babel%2fpreset-react/-/preset-react-7.7.4.tgz", 855 | "integrity": "sha1-P+LqaY2PtTbY54gaWSw8Hui/Vwc=", 856 | "dev": true, 857 | "requires": { 858 | "@babel/helper-plugin-utils": "^7.0.0", 859 | "@babel/plugin-transform-react-display-name": "^7.7.4", 860 | "@babel/plugin-transform-react-jsx": "^7.7.4", 861 | "@babel/plugin-transform-react-jsx-self": "^7.7.4", 862 | "@babel/plugin-transform-react-jsx-source": "^7.7.4" 863 | } 864 | }, 865 | "@babel/template": { 866 | "version": "7.7.4", 867 | "resolved": "http://npm.weimob.com/@babel%2ftemplate/-/template-7.7.4.tgz", 868 | "integrity": "sha1-Qop9nuz/4n3qwKmOI7+ONnXSp3s=", 869 | "dev": true, 870 | "requires": { 871 | "@babel/code-frame": "^7.0.0", 872 | "@babel/parser": "^7.7.4", 873 | "@babel/types": "^7.7.4" 874 | } 875 | }, 876 | "@babel/traverse": { 877 | "version": "7.7.4", 878 | "resolved": "http://npm.weimob.com/@babel%2ftraverse/-/traverse-7.7.4.tgz", 879 | "integrity": "sha1-nB58YPtnn+T8+qQlAIMzM8IFhVg=", 880 | "dev": true, 881 | "requires": { 882 | "@babel/code-frame": "^7.5.5", 883 | "@babel/generator": "^7.7.4", 884 | "@babel/helper-function-name": "^7.7.4", 885 | "@babel/helper-split-export-declaration": "^7.7.4", 886 | "@babel/parser": "^7.7.4", 887 | "@babel/types": "^7.7.4", 888 | "debug": "^4.1.0", 889 | "globals": "^11.1.0", 890 | "lodash": "^4.17.13" 891 | } 892 | }, 893 | "@babel/types": { 894 | "version": "7.7.4", 895 | "resolved": "https://registry.npm.taobao.org/@babel/types/download/@babel/types-7.7.4.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Ftypes%2Fdownload%2F%40babel%2Ftypes-7.7.4.tgz", 896 | "integrity": "sha1-UWVw1TnkTd8wjAdWnCWP+U/ekZM=", 897 | "dev": true, 898 | "requires": { 899 | "esutils": "^2.0.2", 900 | "lodash": "^4.17.13", 901 | "to-fast-properties": "^2.0.0" 902 | } 903 | }, 904 | "@types/estree": { 905 | "version": "0.0.40", 906 | "resolved": "http://npm.weimob.com/@types%2festree/-/estree-0.0.40.tgz", 907 | "integrity": "sha1-Dmy5ubvQmAMfoZ5LToExvHDl3hM=", 908 | "dev": true 909 | }, 910 | "@types/node": { 911 | "version": "12.12.14", 912 | "resolved": "https://registry.npm.taobao.org/@types/node/download/@types/node-12.12.14.tgz", 913 | "integrity": "sha1-HB1uPHXbpGbgMmlI1W6L1yoZA9I=", 914 | "dev": true 915 | }, 916 | "@types/resolve": { 917 | "version": "0.0.8", 918 | "resolved": "https://registry.npm.taobao.org/@types/resolve/download/@types/resolve-0.0.8.tgz", 919 | "integrity": "sha1-8mB00jjgJlnjI84aE9BB7uKA4ZQ=", 920 | "dev": true, 921 | "requires": { 922 | "@types/node": "*" 923 | } 924 | }, 925 | "acorn": { 926 | "version": "7.2.0", 927 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.2.0.tgz", 928 | "integrity": "sha512-apwXVmYVpQ34m/i71vrApRrRKCWQnZZF1+npOD0WV5xZFfwWOmKGQ2RWlfdy9vWITsenisM8M0Qeq8agcFHNiQ==", 929 | "dev": true 930 | }, 931 | "ansi-regex": { 932 | "version": "2.1.1", 933 | "resolved": "http://npm.weimob.com/ansi-regex/-/ansi-regex-2.1.1.tgz", 934 | "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", 935 | "dev": true 936 | }, 937 | "ansi-styles": { 938 | "version": "3.2.1", 939 | "resolved": "http://npm.weimob.com/ansi-styles/-/ansi-styles-3.2.1.tgz", 940 | "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=", 941 | "dev": true, 942 | "requires": { 943 | "color-convert": "^1.9.0" 944 | } 945 | }, 946 | "babel-code-frame": { 947 | "version": "6.26.0", 948 | "resolved": "http://npm.weimob.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz", 949 | "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", 950 | "dev": true, 951 | "requires": { 952 | "chalk": "^1.1.3", 953 | "esutils": "^2.0.2", 954 | "js-tokens": "^3.0.2" 955 | }, 956 | "dependencies": { 957 | "ansi-styles": { 958 | "version": "2.2.1", 959 | "resolved": "http://npm.weimob.com/ansi-styles/-/ansi-styles-2.2.1.tgz", 960 | "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", 961 | "dev": true 962 | }, 963 | "chalk": { 964 | "version": "1.1.3", 965 | "resolved": "http://npm.weimob.com/chalk/-/chalk-1.1.3.tgz", 966 | "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", 967 | "dev": true, 968 | "requires": { 969 | "ansi-styles": "^2.2.1", 970 | "escape-string-regexp": "^1.0.2", 971 | "has-ansi": "^2.0.0", 972 | "strip-ansi": "^3.0.0", 973 | "supports-color": "^2.0.0" 974 | } 975 | }, 976 | "js-tokens": { 977 | "version": "3.0.2", 978 | "resolved": "http://npm.weimob.com/js-tokens/-/js-tokens-3.0.2.tgz", 979 | "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", 980 | "dev": true 981 | }, 982 | "supports-color": { 983 | "version": "2.0.0", 984 | "resolved": "http://npm.weimob.com/supports-color/-/supports-color-2.0.0.tgz", 985 | "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", 986 | "dev": true 987 | } 988 | } 989 | }, 990 | "babel-helper-builder-binary-assignment-operator-visitor": { 991 | "version": "6.24.1", 992 | "resolved": "http://npm.weimob.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", 993 | "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=", 994 | "dev": true, 995 | "requires": { 996 | "babel-helper-explode-assignable-expression": "^6.24.1", 997 | "babel-runtime": "^6.22.0", 998 | "babel-types": "^6.24.1" 999 | } 1000 | }, 1001 | "babel-helper-call-delegate": { 1002 | "version": "6.24.1", 1003 | "resolved": "http://npm.weimob.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", 1004 | "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", 1005 | "dev": true, 1006 | "requires": { 1007 | "babel-helper-hoist-variables": "^6.24.1", 1008 | "babel-runtime": "^6.22.0", 1009 | "babel-traverse": "^6.24.1", 1010 | "babel-types": "^6.24.1" 1011 | } 1012 | }, 1013 | "babel-helper-define-map": { 1014 | "version": "6.26.0", 1015 | "resolved": "http://npm.weimob.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz", 1016 | "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=", 1017 | "dev": true, 1018 | "requires": { 1019 | "babel-helper-function-name": "^6.24.1", 1020 | "babel-runtime": "^6.26.0", 1021 | "babel-types": "^6.26.0", 1022 | "lodash": "^4.17.4" 1023 | } 1024 | }, 1025 | "babel-helper-explode-assignable-expression": { 1026 | "version": "6.24.1", 1027 | "resolved": "http://npm.weimob.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", 1028 | "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=", 1029 | "dev": true, 1030 | "requires": { 1031 | "babel-runtime": "^6.22.0", 1032 | "babel-traverse": "^6.24.1", 1033 | "babel-types": "^6.24.1" 1034 | } 1035 | }, 1036 | "babel-helper-function-name": { 1037 | "version": "6.24.1", 1038 | "resolved": "http://npm.weimob.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", 1039 | "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", 1040 | "dev": true, 1041 | "requires": { 1042 | "babel-helper-get-function-arity": "^6.24.1", 1043 | "babel-runtime": "^6.22.0", 1044 | "babel-template": "^6.24.1", 1045 | "babel-traverse": "^6.24.1", 1046 | "babel-types": "^6.24.1" 1047 | } 1048 | }, 1049 | "babel-helper-get-function-arity": { 1050 | "version": "6.24.1", 1051 | "resolved": "http://npm.weimob.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", 1052 | "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", 1053 | "dev": true, 1054 | "requires": { 1055 | "babel-runtime": "^6.22.0", 1056 | "babel-types": "^6.24.1" 1057 | } 1058 | }, 1059 | "babel-helper-hoist-variables": { 1060 | "version": "6.24.1", 1061 | "resolved": "http://npm.weimob.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", 1062 | "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", 1063 | "dev": true, 1064 | "requires": { 1065 | "babel-runtime": "^6.22.0", 1066 | "babel-types": "^6.24.1" 1067 | } 1068 | }, 1069 | "babel-helper-optimise-call-expression": { 1070 | "version": "6.24.1", 1071 | "resolved": "http://npm.weimob.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", 1072 | "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", 1073 | "dev": true, 1074 | "requires": { 1075 | "babel-runtime": "^6.22.0", 1076 | "babel-types": "^6.24.1" 1077 | } 1078 | }, 1079 | "babel-helper-regex": { 1080 | "version": "6.26.0", 1081 | "resolved": "http://npm.weimob.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz", 1082 | "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=", 1083 | "dev": true, 1084 | "requires": { 1085 | "babel-runtime": "^6.26.0", 1086 | "babel-types": "^6.26.0", 1087 | "lodash": "^4.17.4" 1088 | } 1089 | }, 1090 | "babel-helper-remap-async-to-generator": { 1091 | "version": "6.24.1", 1092 | "resolved": "http://npm.weimob.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", 1093 | "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=", 1094 | "dev": true, 1095 | "requires": { 1096 | "babel-helper-function-name": "^6.24.1", 1097 | "babel-runtime": "^6.22.0", 1098 | "babel-template": "^6.24.1", 1099 | "babel-traverse": "^6.24.1", 1100 | "babel-types": "^6.24.1" 1101 | } 1102 | }, 1103 | "babel-helper-replace-supers": { 1104 | "version": "6.24.1", 1105 | "resolved": "http://npm.weimob.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", 1106 | "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", 1107 | "dev": true, 1108 | "requires": { 1109 | "babel-helper-optimise-call-expression": "^6.24.1", 1110 | "babel-messages": "^6.23.0", 1111 | "babel-runtime": "^6.22.0", 1112 | "babel-template": "^6.24.1", 1113 | "babel-traverse": "^6.24.1", 1114 | "babel-types": "^6.24.1" 1115 | } 1116 | }, 1117 | "babel-messages": { 1118 | "version": "6.23.0", 1119 | "resolved": "http://npm.weimob.com/babel-messages/-/babel-messages-6.23.0.tgz", 1120 | "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", 1121 | "dev": true, 1122 | "requires": { 1123 | "babel-runtime": "^6.22.0" 1124 | } 1125 | }, 1126 | "babel-plugin-check-es2015-constants": { 1127 | "version": "6.22.0", 1128 | "resolved": "http://npm.weimob.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", 1129 | "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", 1130 | "dev": true, 1131 | "requires": { 1132 | "babel-runtime": "^6.22.0" 1133 | } 1134 | }, 1135 | "babel-plugin-dynamic-import-node": { 1136 | "version": "2.3.0", 1137 | "resolved": "http://npm.weimob.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz", 1138 | "integrity": "sha1-8A9Qe9qjw+P/bn5emNkKesq5b38=", 1139 | "dev": true, 1140 | "requires": { 1141 | "object.assign": "^4.1.0" 1142 | } 1143 | }, 1144 | "babel-plugin-syntax-async-functions": { 1145 | "version": "6.13.0", 1146 | "resolved": "http://npm.weimob.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", 1147 | "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=", 1148 | "dev": true 1149 | }, 1150 | "babel-plugin-syntax-exponentiation-operator": { 1151 | "version": "6.13.0", 1152 | "resolved": "http://npm.weimob.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", 1153 | "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=", 1154 | "dev": true 1155 | }, 1156 | "babel-plugin-syntax-trailing-function-commas": { 1157 | "version": "6.22.0", 1158 | "resolved": "http://npm.weimob.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", 1159 | "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=", 1160 | "dev": true 1161 | }, 1162 | "babel-plugin-transform-async-to-generator": { 1163 | "version": "6.24.1", 1164 | "resolved": "http://npm.weimob.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", 1165 | "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=", 1166 | "dev": true, 1167 | "requires": { 1168 | "babel-helper-remap-async-to-generator": "^6.24.1", 1169 | "babel-plugin-syntax-async-functions": "^6.8.0", 1170 | "babel-runtime": "^6.22.0" 1171 | } 1172 | }, 1173 | "babel-plugin-transform-es2015-arrow-functions": { 1174 | "version": "6.22.0", 1175 | "resolved": "http://npm.weimob.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", 1176 | "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", 1177 | "dev": true, 1178 | "requires": { 1179 | "babel-runtime": "^6.22.0" 1180 | } 1181 | }, 1182 | "babel-plugin-transform-es2015-block-scoped-functions": { 1183 | "version": "6.22.0", 1184 | "resolved": "http://npm.weimob.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", 1185 | "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", 1186 | "dev": true, 1187 | "requires": { 1188 | "babel-runtime": "^6.22.0" 1189 | } 1190 | }, 1191 | "babel-plugin-transform-es2015-block-scoping": { 1192 | "version": "6.26.0", 1193 | "resolved": "http://npm.weimob.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", 1194 | "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=", 1195 | "dev": true, 1196 | "requires": { 1197 | "babel-runtime": "^6.26.0", 1198 | "babel-template": "^6.26.0", 1199 | "babel-traverse": "^6.26.0", 1200 | "babel-types": "^6.26.0", 1201 | "lodash": "^4.17.4" 1202 | } 1203 | }, 1204 | "babel-plugin-transform-es2015-classes": { 1205 | "version": "6.24.1", 1206 | "resolved": "http://npm.weimob.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", 1207 | "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", 1208 | "dev": true, 1209 | "requires": { 1210 | "babel-helper-define-map": "^6.24.1", 1211 | "babel-helper-function-name": "^6.24.1", 1212 | "babel-helper-optimise-call-expression": "^6.24.1", 1213 | "babel-helper-replace-supers": "^6.24.1", 1214 | "babel-messages": "^6.23.0", 1215 | "babel-runtime": "^6.22.0", 1216 | "babel-template": "^6.24.1", 1217 | "babel-traverse": "^6.24.1", 1218 | "babel-types": "^6.24.1" 1219 | } 1220 | }, 1221 | "babel-plugin-transform-es2015-computed-properties": { 1222 | "version": "6.24.1", 1223 | "resolved": "http://npm.weimob.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", 1224 | "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", 1225 | "dev": true, 1226 | "requires": { 1227 | "babel-runtime": "^6.22.0", 1228 | "babel-template": "^6.24.1" 1229 | } 1230 | }, 1231 | "babel-plugin-transform-es2015-destructuring": { 1232 | "version": "6.23.0", 1233 | "resolved": "http://npm.weimob.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", 1234 | "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", 1235 | "dev": true, 1236 | "requires": { 1237 | "babel-runtime": "^6.22.0" 1238 | } 1239 | }, 1240 | "babel-plugin-transform-es2015-duplicate-keys": { 1241 | "version": "6.24.1", 1242 | "resolved": "http://npm.weimob.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", 1243 | "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", 1244 | "dev": true, 1245 | "requires": { 1246 | "babel-runtime": "^6.22.0", 1247 | "babel-types": "^6.24.1" 1248 | } 1249 | }, 1250 | "babel-plugin-transform-es2015-for-of": { 1251 | "version": "6.23.0", 1252 | "resolved": "http://npm.weimob.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", 1253 | "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", 1254 | "dev": true, 1255 | "requires": { 1256 | "babel-runtime": "^6.22.0" 1257 | } 1258 | }, 1259 | "babel-plugin-transform-es2015-function-name": { 1260 | "version": "6.24.1", 1261 | "resolved": "http://npm.weimob.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", 1262 | "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", 1263 | "dev": true, 1264 | "requires": { 1265 | "babel-helper-function-name": "^6.24.1", 1266 | "babel-runtime": "^6.22.0", 1267 | "babel-types": "^6.24.1" 1268 | } 1269 | }, 1270 | "babel-plugin-transform-es2015-literals": { 1271 | "version": "6.22.0", 1272 | "resolved": "http://npm.weimob.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", 1273 | "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", 1274 | "dev": true, 1275 | "requires": { 1276 | "babel-runtime": "^6.22.0" 1277 | } 1278 | }, 1279 | "babel-plugin-transform-es2015-modules-amd": { 1280 | "version": "6.24.1", 1281 | "resolved": "http://npm.weimob.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", 1282 | "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", 1283 | "dev": true, 1284 | "requires": { 1285 | "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", 1286 | "babel-runtime": "^6.22.0", 1287 | "babel-template": "^6.24.1" 1288 | } 1289 | }, 1290 | "babel-plugin-transform-es2015-modules-commonjs": { 1291 | "version": "6.26.2", 1292 | "resolved": "http://npm.weimob.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz", 1293 | "integrity": "sha1-WKeThjqefKhwvcWogRF/+sJ9tvM=", 1294 | "dev": true, 1295 | "requires": { 1296 | "babel-plugin-transform-strict-mode": "^6.24.1", 1297 | "babel-runtime": "^6.26.0", 1298 | "babel-template": "^6.26.0", 1299 | "babel-types": "^6.26.0" 1300 | } 1301 | }, 1302 | "babel-plugin-transform-es2015-modules-systemjs": { 1303 | "version": "6.24.1", 1304 | "resolved": "http://npm.weimob.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", 1305 | "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", 1306 | "dev": true, 1307 | "requires": { 1308 | "babel-helper-hoist-variables": "^6.24.1", 1309 | "babel-runtime": "^6.22.0", 1310 | "babel-template": "^6.24.1" 1311 | } 1312 | }, 1313 | "babel-plugin-transform-es2015-modules-umd": { 1314 | "version": "6.24.1", 1315 | "resolved": "http://npm.weimob.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", 1316 | "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", 1317 | "dev": true, 1318 | "requires": { 1319 | "babel-plugin-transform-es2015-modules-amd": "^6.24.1", 1320 | "babel-runtime": "^6.22.0", 1321 | "babel-template": "^6.24.1" 1322 | } 1323 | }, 1324 | "babel-plugin-transform-es2015-object-super": { 1325 | "version": "6.24.1", 1326 | "resolved": "http://npm.weimob.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", 1327 | "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", 1328 | "dev": true, 1329 | "requires": { 1330 | "babel-helper-replace-supers": "^6.24.1", 1331 | "babel-runtime": "^6.22.0" 1332 | } 1333 | }, 1334 | "babel-plugin-transform-es2015-parameters": { 1335 | "version": "6.24.1", 1336 | "resolved": "http://npm.weimob.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", 1337 | "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", 1338 | "dev": true, 1339 | "requires": { 1340 | "babel-helper-call-delegate": "^6.24.1", 1341 | "babel-helper-get-function-arity": "^6.24.1", 1342 | "babel-runtime": "^6.22.0", 1343 | "babel-template": "^6.24.1", 1344 | "babel-traverse": "^6.24.1", 1345 | "babel-types": "^6.24.1" 1346 | } 1347 | }, 1348 | "babel-plugin-transform-es2015-shorthand-properties": { 1349 | "version": "6.24.1", 1350 | "resolved": "http://npm.weimob.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", 1351 | "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", 1352 | "dev": true, 1353 | "requires": { 1354 | "babel-runtime": "^6.22.0", 1355 | "babel-types": "^6.24.1" 1356 | } 1357 | }, 1358 | "babel-plugin-transform-es2015-spread": { 1359 | "version": "6.22.0", 1360 | "resolved": "http://npm.weimob.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", 1361 | "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", 1362 | "dev": true, 1363 | "requires": { 1364 | "babel-runtime": "^6.22.0" 1365 | } 1366 | }, 1367 | "babel-plugin-transform-es2015-sticky-regex": { 1368 | "version": "6.24.1", 1369 | "resolved": "http://npm.weimob.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", 1370 | "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", 1371 | "dev": true, 1372 | "requires": { 1373 | "babel-helper-regex": "^6.24.1", 1374 | "babel-runtime": "^6.22.0", 1375 | "babel-types": "^6.24.1" 1376 | } 1377 | }, 1378 | "babel-plugin-transform-es2015-template-literals": { 1379 | "version": "6.22.0", 1380 | "resolved": "http://npm.weimob.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", 1381 | "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", 1382 | "dev": true, 1383 | "requires": { 1384 | "babel-runtime": "^6.22.0" 1385 | } 1386 | }, 1387 | "babel-plugin-transform-es2015-typeof-symbol": { 1388 | "version": "6.23.0", 1389 | "resolved": "http://npm.weimob.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", 1390 | "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", 1391 | "dev": true, 1392 | "requires": { 1393 | "babel-runtime": "^6.22.0" 1394 | } 1395 | }, 1396 | "babel-plugin-transform-es2015-unicode-regex": { 1397 | "version": "6.24.1", 1398 | "resolved": "http://npm.weimob.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", 1399 | "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", 1400 | "dev": true, 1401 | "requires": { 1402 | "babel-helper-regex": "^6.24.1", 1403 | "babel-runtime": "^6.22.0", 1404 | "regexpu-core": "^2.0.0" 1405 | }, 1406 | "dependencies": { 1407 | "jsesc": { 1408 | "version": "0.5.0", 1409 | "resolved": "http://npm.weimob.com/jsesc/-/jsesc-0.5.0.tgz", 1410 | "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", 1411 | "dev": true 1412 | }, 1413 | "regexpu-core": { 1414 | "version": "2.0.0", 1415 | "resolved": "http://npm.weimob.com/regexpu-core/-/regexpu-core-2.0.0.tgz", 1416 | "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", 1417 | "dev": true, 1418 | "requires": { 1419 | "regenerate": "^1.2.1", 1420 | "regjsgen": "^0.2.0", 1421 | "regjsparser": "^0.1.4" 1422 | } 1423 | }, 1424 | "regjsgen": { 1425 | "version": "0.2.0", 1426 | "resolved": "http://npm.weimob.com/regjsgen/-/regjsgen-0.2.0.tgz", 1427 | "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=", 1428 | "dev": true 1429 | }, 1430 | "regjsparser": { 1431 | "version": "0.1.5", 1432 | "resolved": "http://npm.weimob.com/regjsparser/-/regjsparser-0.1.5.tgz", 1433 | "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", 1434 | "dev": true, 1435 | "requires": { 1436 | "jsesc": "~0.5.0" 1437 | } 1438 | } 1439 | } 1440 | }, 1441 | "babel-plugin-transform-exponentiation-operator": { 1442 | "version": "6.24.1", 1443 | "resolved": "http://npm.weimob.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", 1444 | "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=", 1445 | "dev": true, 1446 | "requires": { 1447 | "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", 1448 | "babel-plugin-syntax-exponentiation-operator": "^6.8.0", 1449 | "babel-runtime": "^6.22.0" 1450 | } 1451 | }, 1452 | "babel-plugin-transform-regenerator": { 1453 | "version": "6.26.0", 1454 | "resolved": "http://npm.weimob.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", 1455 | "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=", 1456 | "dev": true, 1457 | "requires": { 1458 | "regenerator-transform": "^0.10.0" 1459 | }, 1460 | "dependencies": { 1461 | "regenerator-transform": { 1462 | "version": "0.10.1", 1463 | "resolved": "http://npm.weimob.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz", 1464 | "integrity": "sha1-HkmWg3Ix2ot/PPQRTXG1aRoGgN0=", 1465 | "dev": true, 1466 | "requires": { 1467 | "babel-runtime": "^6.18.0", 1468 | "babel-types": "^6.19.0", 1469 | "private": "^0.1.6" 1470 | } 1471 | } 1472 | } 1473 | }, 1474 | "babel-plugin-transform-strict-mode": { 1475 | "version": "6.24.1", 1476 | "resolved": "http://npm.weimob.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", 1477 | "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", 1478 | "dev": true, 1479 | "requires": { 1480 | "babel-runtime": "^6.22.0", 1481 | "babel-types": "^6.24.1" 1482 | } 1483 | }, 1484 | "babel-preset-es2015": { 1485 | "version": "6.24.1", 1486 | "resolved": "http://npm.weimob.com/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz", 1487 | "integrity": "sha1-1EBQ1rwsn+6nAqrzjXJ6AhBTiTk=", 1488 | "dev": true, 1489 | "requires": { 1490 | "babel-plugin-check-es2015-constants": "^6.22.0", 1491 | "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", 1492 | "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", 1493 | "babel-plugin-transform-es2015-block-scoping": "^6.24.1", 1494 | "babel-plugin-transform-es2015-classes": "^6.24.1", 1495 | "babel-plugin-transform-es2015-computed-properties": "^6.24.1", 1496 | "babel-plugin-transform-es2015-destructuring": "^6.22.0", 1497 | "babel-plugin-transform-es2015-duplicate-keys": "^6.24.1", 1498 | "babel-plugin-transform-es2015-for-of": "^6.22.0", 1499 | "babel-plugin-transform-es2015-function-name": "^6.24.1", 1500 | "babel-plugin-transform-es2015-literals": "^6.22.0", 1501 | "babel-plugin-transform-es2015-modules-amd": "^6.24.1", 1502 | "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", 1503 | "babel-plugin-transform-es2015-modules-systemjs": "^6.24.1", 1504 | "babel-plugin-transform-es2015-modules-umd": "^6.24.1", 1505 | "babel-plugin-transform-es2015-object-super": "^6.24.1", 1506 | "babel-plugin-transform-es2015-parameters": "^6.24.1", 1507 | "babel-plugin-transform-es2015-shorthand-properties": "^6.24.1", 1508 | "babel-plugin-transform-es2015-spread": "^6.22.0", 1509 | "babel-plugin-transform-es2015-sticky-regex": "^6.24.1", 1510 | "babel-plugin-transform-es2015-template-literals": "^6.22.0", 1511 | "babel-plugin-transform-es2015-typeof-symbol": "^6.22.0", 1512 | "babel-plugin-transform-es2015-unicode-regex": "^6.24.1", 1513 | "babel-plugin-transform-regenerator": "^6.24.1" 1514 | } 1515 | }, 1516 | "babel-preset-es2016": { 1517 | "version": "6.24.1", 1518 | "resolved": "http://npm.weimob.com/babel-preset-es2016/-/babel-preset-es2016-6.24.1.tgz", 1519 | "integrity": "sha1-+QC/k+LrwNJ235uKtZck6/2Vn4s=", 1520 | "dev": true, 1521 | "requires": { 1522 | "babel-plugin-transform-exponentiation-operator": "^6.24.1" 1523 | } 1524 | }, 1525 | "babel-preset-es2017": { 1526 | "version": "6.24.1", 1527 | "resolved": "http://npm.weimob.com/babel-preset-es2017/-/babel-preset-es2017-6.24.1.tgz", 1528 | "integrity": "sha1-WXvq37n38gi8/YoS6bKym4svFNE=", 1529 | "dev": true, 1530 | "requires": { 1531 | "babel-plugin-syntax-trailing-function-commas": "^6.22.0", 1532 | "babel-plugin-transform-async-to-generator": "^6.24.1" 1533 | } 1534 | }, 1535 | "babel-preset-latest": { 1536 | "version": "6.24.1", 1537 | "resolved": "http://npm.weimob.com/babel-preset-latest/-/babel-preset-latest-6.24.1.tgz", 1538 | "integrity": "sha1-Z33gaRVKdIXC0lxXfAL2JLhbheg=", 1539 | "dev": true, 1540 | "requires": { 1541 | "babel-preset-es2015": "^6.24.1", 1542 | "babel-preset-es2016": "^6.24.1", 1543 | "babel-preset-es2017": "^6.24.1" 1544 | } 1545 | }, 1546 | "babel-runtime": { 1547 | "version": "6.26.0", 1548 | "resolved": "http://npm.weimob.com/babel-runtime/-/babel-runtime-6.26.0.tgz", 1549 | "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", 1550 | "dev": true, 1551 | "requires": { 1552 | "core-js": "^2.4.0", 1553 | "regenerator-runtime": "^0.11.0" 1554 | } 1555 | }, 1556 | "babel-template": { 1557 | "version": "6.26.0", 1558 | "resolved": "http://npm.weimob.com/babel-template/-/babel-template-6.26.0.tgz", 1559 | "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", 1560 | "dev": true, 1561 | "requires": { 1562 | "babel-runtime": "^6.26.0", 1563 | "babel-traverse": "^6.26.0", 1564 | "babel-types": "^6.26.0", 1565 | "babylon": "^6.18.0", 1566 | "lodash": "^4.17.4" 1567 | } 1568 | }, 1569 | "babel-traverse": { 1570 | "version": "6.26.0", 1571 | "resolved": "http://npm.weimob.com/babel-traverse/-/babel-traverse-6.26.0.tgz", 1572 | "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", 1573 | "dev": true, 1574 | "requires": { 1575 | "babel-code-frame": "^6.26.0", 1576 | "babel-messages": "^6.23.0", 1577 | "babel-runtime": "^6.26.0", 1578 | "babel-types": "^6.26.0", 1579 | "babylon": "^6.18.0", 1580 | "debug": "^2.6.8", 1581 | "globals": "^9.18.0", 1582 | "invariant": "^2.2.2", 1583 | "lodash": "^4.17.4" 1584 | }, 1585 | "dependencies": { 1586 | "debug": { 1587 | "version": "2.6.9", 1588 | "resolved": "http://npm.weimob.com/debug/-/debug-2.6.9.tgz", 1589 | "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", 1590 | "dev": true, 1591 | "requires": { 1592 | "ms": "2.0.0" 1593 | } 1594 | }, 1595 | "globals": { 1596 | "version": "9.18.0", 1597 | "resolved": "http://npm.weimob.com/globals/-/globals-9.18.0.tgz", 1598 | "integrity": "sha1-qjiWs+abSH8X4x7SFD1pqOMMLYo=", 1599 | "dev": true 1600 | }, 1601 | "ms": { 1602 | "version": "2.0.0", 1603 | "resolved": "http://npm.weimob.com/ms/-/ms-2.0.0.tgz", 1604 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", 1605 | "dev": true 1606 | } 1607 | } 1608 | }, 1609 | "babel-types": { 1610 | "version": "6.26.0", 1611 | "resolved": "http://npm.weimob.com/babel-types/-/babel-types-6.26.0.tgz", 1612 | "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", 1613 | "dev": true, 1614 | "requires": { 1615 | "babel-runtime": "^6.26.0", 1616 | "esutils": "^2.0.2", 1617 | "lodash": "^4.17.4", 1618 | "to-fast-properties": "^1.0.3" 1619 | }, 1620 | "dependencies": { 1621 | "to-fast-properties": { 1622 | "version": "1.0.3", 1623 | "resolved": "http://npm.weimob.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz", 1624 | "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", 1625 | "dev": true 1626 | } 1627 | } 1628 | }, 1629 | "babylon": { 1630 | "version": "6.18.0", 1631 | "resolved": "http://npm.weimob.com/babylon/-/babylon-6.18.0.tgz", 1632 | "integrity": "sha1-ry87iPpvXB5MY00aD46sT1WzleM=", 1633 | "dev": true 1634 | }, 1635 | "browserslist": { 1636 | "version": "4.16.6", 1637 | "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", 1638 | "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", 1639 | "dev": true, 1640 | "requires": { 1641 | "caniuse-lite": "^1.0.30001219", 1642 | "colorette": "^1.2.2", 1643 | "electron-to-chromium": "^1.3.723", 1644 | "escalade": "^3.1.1", 1645 | "node-releases": "^1.1.71" 1646 | }, 1647 | "dependencies": { 1648 | "caniuse-lite": { 1649 | "version": "1.0.30001230", 1650 | "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001230.tgz", 1651 | "integrity": "sha512-5yBd5nWCBS+jWKTcHOzXwo5xzcj4ePE/yjtkZyUV1BTUmrBaA9MRGC+e7mxnqXSA90CmCA8L3eKLaSUkt099IQ==", 1652 | "dev": true 1653 | }, 1654 | "electron-to-chromium": { 1655 | "version": "1.3.739", 1656 | "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.739.tgz", 1657 | "integrity": "sha512-+LPJVRsN7hGZ9EIUUiWCpO7l4E3qBYHNadazlucBfsXBbccDFNKUBAgzE68FnkWGJPwD/AfKhSzL+G+Iqb8A4A==", 1658 | "dev": true 1659 | }, 1660 | "node-releases": { 1661 | "version": "1.1.72", 1662 | "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz", 1663 | "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==", 1664 | "dev": true 1665 | } 1666 | } 1667 | }, 1668 | "builtin-modules": { 1669 | "version": "3.1.0", 1670 | "resolved": "https://registry.npm.taobao.org/builtin-modules/download/builtin-modules-3.1.0.tgz", 1671 | "integrity": "sha1-qtl8FRMet2tltQ7yCOdYTNdqdIQ=", 1672 | "dev": true 1673 | }, 1674 | "chalk": { 1675 | "version": "2.4.2", 1676 | "resolved": "http://npm.weimob.com/chalk/-/chalk-2.4.2.tgz", 1677 | "integrity": "sha1-zUJUFnelQzPPVBpJEIwUMrRMlCQ=", 1678 | "dev": true, 1679 | "requires": { 1680 | "ansi-styles": "^3.2.1", 1681 | "escape-string-regexp": "^1.0.5", 1682 | "supports-color": "^5.3.0" 1683 | } 1684 | }, 1685 | "color-convert": { 1686 | "version": "1.9.3", 1687 | "resolved": "http://npm.weimob.com/color-convert/-/color-convert-1.9.3.tgz", 1688 | "integrity": "sha1-u3GFBpDh8TZWfeYp0tVHHe2kweg=", 1689 | "dev": true, 1690 | "requires": { 1691 | "color-name": "1.1.3" 1692 | } 1693 | }, 1694 | "color-name": { 1695 | "version": "1.1.3", 1696 | "resolved": "http://npm.weimob.com/color-name/-/color-name-1.1.3.tgz", 1697 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", 1698 | "dev": true 1699 | }, 1700 | "colorette": { 1701 | "version": "1.2.2", 1702 | "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", 1703 | "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", 1704 | "dev": true 1705 | }, 1706 | "commander": { 1707 | "version": "2.20.3", 1708 | "resolved": "http://npm.weimob.com/commander/-/commander-2.20.3.tgz", 1709 | "integrity": "sha1-/UhehMA+tIgcIHIrpIA16FMa6zM=", 1710 | "dev": true 1711 | }, 1712 | "convert-source-map": { 1713 | "version": "1.7.0", 1714 | "resolved": "http://npm.weimob.com/convert-source-map/-/convert-source-map-1.7.0.tgz", 1715 | "integrity": "sha1-F6LLiC1/d9NJBYXizmxSRCSjpEI=", 1716 | "dev": true, 1717 | "requires": { 1718 | "safe-buffer": "~5.1.1" 1719 | } 1720 | }, 1721 | "core-js": { 1722 | "version": "2.6.10", 1723 | "resolved": "http://npm.weimob.com/core-js/-/core-js-2.6.10.tgz", 1724 | "integrity": "sha1-iluDkfjMcBPacDQRzltYVwYwDX8=", 1725 | "dev": true 1726 | }, 1727 | "core-js-compat": { 1728 | "version": "3.4.4", 1729 | "resolved": "http://npm.weimob.com/core-js-compat/-/core-js-compat-3.4.4.tgz", 1730 | "integrity": "sha1-0KoBsdYm4SlFXVGqlMJxJ8Vkuis=", 1731 | "dev": true, 1732 | "requires": { 1733 | "browserslist": "^4.7.3", 1734 | "semver": "^6.3.0" 1735 | }, 1736 | "dependencies": { 1737 | "semver": { 1738 | "version": "6.3.0", 1739 | "resolved": "http://npm.weimob.com/semver/-/semver-6.3.0.tgz", 1740 | "integrity": "sha1-7gpkyK9ejO6mdoexM3YeG+y9HT0=", 1741 | "dev": true 1742 | } 1743 | } 1744 | }, 1745 | "cross-env": { 1746 | "version": "6.0.3", 1747 | "resolved": "http://npm.weimob.com/cross-env/-/cross-env-6.0.3.tgz", 1748 | "integrity": "sha1-Qla3HkmzpAY3oM5wdopu9ccq6UE=", 1749 | "dev": true, 1750 | "requires": { 1751 | "cross-spawn": "^7.0.0" 1752 | } 1753 | }, 1754 | "cross-spawn": { 1755 | "version": "7.0.1", 1756 | "resolved": "http://npm.weimob.com/cross-spawn/-/cross-spawn-7.0.1.tgz", 1757 | "integrity": "sha1-CrVihuD3wk4VPQTMKqAn5DqaXRQ=", 1758 | "dev": true, 1759 | "requires": { 1760 | "path-key": "^3.1.0", 1761 | "shebang-command": "^2.0.0", 1762 | "which": "^2.0.1" 1763 | } 1764 | }, 1765 | "de-indent": { 1766 | "version": "1.0.2", 1767 | "resolved": "http://npm.weimob.com/de-indent/-/de-indent-1.0.2.tgz", 1768 | "integrity": "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=", 1769 | "dev": true 1770 | }, 1771 | "debug": { 1772 | "version": "4.1.1", 1773 | "resolved": "http://npm.weimob.com/debug/-/debug-4.1.1.tgz", 1774 | "integrity": "sha1-O3ImAlUQnGtYnO4FDx1RYTlmR5E=", 1775 | "dev": true, 1776 | "requires": { 1777 | "ms": "^2.1.1" 1778 | } 1779 | }, 1780 | "define-properties": { 1781 | "version": "1.1.3", 1782 | "resolved": "http://npm.weimob.com/define-properties/-/define-properties-1.1.3.tgz", 1783 | "integrity": "sha1-z4jabL7ib+bbcJT2HYcMvYTO6fE=", 1784 | "dev": true, 1785 | "requires": { 1786 | "object-keys": "^1.0.12" 1787 | } 1788 | }, 1789 | "escalade": { 1790 | "version": "3.1.1", 1791 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", 1792 | "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", 1793 | "dev": true 1794 | }, 1795 | "escape-string-regexp": { 1796 | "version": "1.0.5", 1797 | "resolved": "http://npm.weimob.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 1798 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", 1799 | "dev": true 1800 | }, 1801 | "estree-walker": { 1802 | "version": "0.6.1", 1803 | "resolved": "https://registry.npm.taobao.org/estree-walker/download/estree-walker-0.6.1.tgz", 1804 | "integrity": "sha1-UwSRQ/QMbrkYsjZx0f4yGfOhs2I=", 1805 | "dev": true 1806 | }, 1807 | "esutils": { 1808 | "version": "2.0.3", 1809 | "resolved": "https://registry.npm.taobao.org/esutils/download/esutils-2.0.3.tgz", 1810 | "integrity": "sha1-dNLrTeC42hKTcRkQ1Qd1ubcQ72Q=", 1811 | "dev": true 1812 | }, 1813 | "function-bind": { 1814 | "version": "1.1.1", 1815 | "resolved": "http://npm.weimob.com/function-bind/-/function-bind-1.1.1.tgz", 1816 | "integrity": "sha1-pWiZ0+o8m6uHS7l3O3xe3pL0iV0=", 1817 | "dev": true 1818 | }, 1819 | "globals": { 1820 | "version": "11.12.0", 1821 | "resolved": "http://npm.weimob.com/globals/-/globals-11.12.0.tgz", 1822 | "integrity": "sha1-q4eVM4hooLq9hSV1gBjCp+uVxC4=", 1823 | "dev": true 1824 | }, 1825 | "has-ansi": { 1826 | "version": "2.0.0", 1827 | "resolved": "http://npm.weimob.com/has-ansi/-/has-ansi-2.0.0.tgz", 1828 | "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", 1829 | "dev": true, 1830 | "requires": { 1831 | "ansi-regex": "^2.0.0" 1832 | } 1833 | }, 1834 | "has-flag": { 1835 | "version": "3.0.0", 1836 | "resolved": "http://npm.weimob.com/has-flag/-/has-flag-3.0.0.tgz", 1837 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 1838 | "dev": true 1839 | }, 1840 | "has-symbols": { 1841 | "version": "1.0.1", 1842 | "resolved": "http://npm.weimob.com/has-symbols/-/has-symbols-1.0.1.tgz", 1843 | "integrity": "sha1-n1IUdYpEGWxAbZvXbOv4HsLdMeg=", 1844 | "dev": true 1845 | }, 1846 | "he": { 1847 | "version": "1.2.0", 1848 | "resolved": "http://npm.weimob.com/he/-/he-1.2.0.tgz", 1849 | "integrity": "sha1-hK5l+n6vsWX922FWauFLrwVmTw8=", 1850 | "dev": true 1851 | }, 1852 | "invariant": { 1853 | "version": "2.2.4", 1854 | "resolved": "http://npm.weimob.com/invariant/-/invariant-2.2.4.tgz", 1855 | "integrity": "sha1-YQ88ksk1nOHbYW5TgAjSP/NRWOY=", 1856 | "dev": true, 1857 | "requires": { 1858 | "loose-envify": "^1.0.0" 1859 | } 1860 | }, 1861 | "is-module": { 1862 | "version": "1.0.0", 1863 | "resolved": "https://registry.npm.taobao.org/is-module/download/is-module-1.0.0.tgz", 1864 | "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", 1865 | "dev": true 1866 | }, 1867 | "is-reference": { 1868 | "version": "1.1.4", 1869 | "resolved": "http://npm.weimob.com/is-reference/-/is-reference-1.1.4.tgz", 1870 | "integrity": "sha1-P5WEmIbdtwJWo+bQYrGmjBPFFCc=", 1871 | "dev": true, 1872 | "requires": { 1873 | "@types/estree": "0.0.39" 1874 | }, 1875 | "dependencies": { 1876 | "@types/estree": { 1877 | "version": "0.0.39", 1878 | "resolved": "http://npm.weimob.com/@types%2festree/-/estree-0.0.39.tgz", 1879 | "integrity": "sha1-4Xfmme4bjCLSMXTKqnQiZEOJUJ8=", 1880 | "dev": true 1881 | } 1882 | } 1883 | }, 1884 | "isexe": { 1885 | "version": "2.0.0", 1886 | "resolved": "http://npm.weimob.com/isexe/-/isexe-2.0.0.tgz", 1887 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", 1888 | "dev": true 1889 | }, 1890 | "jest-worker": { 1891 | "version": "24.9.0", 1892 | "resolved": "http://npm.weimob.com/jest-worker/-/jest-worker-24.9.0.tgz", 1893 | "integrity": "sha1-Xb/bWy0yLphWeJgjipaXvM5ns+U=", 1894 | "dev": true, 1895 | "requires": { 1896 | "merge-stream": "^2.0.0", 1897 | "supports-color": "^6.1.0" 1898 | }, 1899 | "dependencies": { 1900 | "supports-color": { 1901 | "version": "6.1.0", 1902 | "resolved": "http://npm.weimob.com/supports-color/-/supports-color-6.1.0.tgz", 1903 | "integrity": "sha1-B2Srxpxj1ayELdSGfo0CXogN+PM=", 1904 | "dev": true, 1905 | "requires": { 1906 | "has-flag": "^3.0.0" 1907 | } 1908 | } 1909 | } 1910 | }, 1911 | "js-levenshtein": { 1912 | "version": "1.1.6", 1913 | "resolved": "http://npm.weimob.com/js-levenshtein/-/js-levenshtein-1.1.6.tgz", 1914 | "integrity": "sha1-xs7ljrNVA3LfjeuF+tXOZs4B1Z0=", 1915 | "dev": true 1916 | }, 1917 | "js-tokens": { 1918 | "version": "4.0.0", 1919 | "resolved": "http://npm.weimob.com/js-tokens/-/js-tokens-4.0.0.tgz", 1920 | "integrity": "sha1-GSA/tZmR35jjoocFDUZHzerzJJk=", 1921 | "dev": true 1922 | }, 1923 | "jsesc": { 1924 | "version": "2.5.2", 1925 | "resolved": "http://npm.weimob.com/jsesc/-/jsesc-2.5.2.tgz", 1926 | "integrity": "sha1-gFZNLkg9rPbo7yCWUKZ98/DCg6Q=", 1927 | "dev": true 1928 | }, 1929 | "json5": { 1930 | "version": "2.1.1", 1931 | "resolved": "http://npm.weimob.com/json5/-/json5-2.1.1.tgz", 1932 | "integrity": "sha1-gbbLBOm6SW8ccAXQe0NoomOPkLY=", 1933 | "dev": true, 1934 | "requires": { 1935 | "minimist": "^1.2.0" 1936 | } 1937 | }, 1938 | "lodash": { 1939 | "version": "4.17.21", 1940 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", 1941 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", 1942 | "dev": true 1943 | }, 1944 | "loose-envify": { 1945 | "version": "1.4.0", 1946 | "resolved": "http://npm.weimob.com/loose-envify/-/loose-envify-1.4.0.tgz", 1947 | "integrity": "sha1-ce5R+nvkyuwaY4OffmgtgTLTDK8=", 1948 | "dev": true, 1949 | "requires": { 1950 | "js-tokens": "^3.0.0 || ^4.0.0" 1951 | } 1952 | }, 1953 | "magic-string": { 1954 | "version": "0.25.4", 1955 | "resolved": "http://npm.weimob.com/magic-string/-/magic-string-0.25.4.tgz", 1956 | "integrity": "sha1-MluKCnn8Qj2xCbd/1aGRg7e6UUM=", 1957 | "dev": true, 1958 | "requires": { 1959 | "sourcemap-codec": "^1.4.4" 1960 | } 1961 | }, 1962 | "merge-stream": { 1963 | "version": "2.0.0", 1964 | "resolved": "http://npm.weimob.com/merge-stream/-/merge-stream-2.0.0.tgz", 1965 | "integrity": "sha1-UoI2KaFN0AyXcPtq1H3GMQ8sH2A=", 1966 | "dev": true 1967 | }, 1968 | "minimist": { 1969 | "version": "1.2.6", 1970 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", 1971 | "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", 1972 | "dev": true 1973 | }, 1974 | "ms": { 1975 | "version": "2.1.2", 1976 | "resolved": "http://npm.weimob.com/ms/-/ms-2.1.2.tgz", 1977 | "integrity": "sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk=", 1978 | "dev": true 1979 | }, 1980 | "object-assign": { 1981 | "version": "4.1.1", 1982 | "resolved": "http://npm.weimob.com/object-assign/-/object-assign-4.1.1.tgz", 1983 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", 1984 | "dev": true 1985 | }, 1986 | "object-keys": { 1987 | "version": "1.1.1", 1988 | "resolved": "http://npm.weimob.com/object-keys/-/object-keys-1.1.1.tgz", 1989 | "integrity": "sha1-HEfyct8nfzsdrwYWd9nILiMixg4=", 1990 | "dev": true 1991 | }, 1992 | "object.assign": { 1993 | "version": "4.1.0", 1994 | "resolved": "http://npm.weimob.com/object.assign/-/object.assign-4.1.0.tgz", 1995 | "integrity": "sha1-lovxEA15Vrs8oIbwBvhGs7xACNo=", 1996 | "dev": true, 1997 | "requires": { 1998 | "define-properties": "^1.1.2", 1999 | "function-bind": "^1.1.1", 2000 | "has-symbols": "^1.0.0", 2001 | "object-keys": "^1.0.11" 2002 | } 2003 | }, 2004 | "path-key": { 2005 | "version": "3.1.1", 2006 | "resolved": "http://npm.weimob.com/path-key/-/path-key-3.1.1.tgz", 2007 | "integrity": "sha1-WB9q3mWMu6ZaDTOA3ndTKVBU83U=", 2008 | "dev": true 2009 | }, 2010 | "path-parse": { 2011 | "version": "1.0.7", 2012 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", 2013 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", 2014 | "dev": true 2015 | }, 2016 | "portal-vue": { 2017 | "version": "2.1.7", 2018 | "resolved": "https://registry.npmjs.org/portal-vue/-/portal-vue-2.1.7.tgz", 2019 | "integrity": "sha512-+yCno2oB3xA7irTt0EU5Ezw22L2J51uKAacE/6hMPMoO/mx3h4rXFkkBkT4GFsMDv/vEe8TNKC3ujJJ0PTwb6g==" 2020 | }, 2021 | "private": { 2022 | "version": "0.1.8", 2023 | "resolved": "http://npm.weimob.com/private/-/private-0.1.8.tgz", 2024 | "integrity": "sha1-I4Hts2ifelPWUxkAYPz4ItLzaP8=", 2025 | "dev": true 2026 | }, 2027 | "prop-types": { 2028 | "version": "15.7.2", 2029 | "resolved": "http://npm.weimob.com/prop-types/-/prop-types-15.7.2.tgz", 2030 | "integrity": "sha1-UsQedbjIfnK52TYOAga5ncv/psU=", 2031 | "dev": true, 2032 | "requires": { 2033 | "loose-envify": "^1.4.0", 2034 | "object-assign": "^4.1.1", 2035 | "react-is": "^16.8.1" 2036 | } 2037 | }, 2038 | "react": { 2039 | "version": "16.12.0", 2040 | "resolved": "http://npm.weimob.com/react/-/react-16.12.0.tgz", 2041 | "integrity": "sha1-DAqcahQkKeNhSDTVp3jhiqeKC4M=", 2042 | "dev": true, 2043 | "requires": { 2044 | "loose-envify": "^1.1.0", 2045 | "object-assign": "^4.1.1", 2046 | "prop-types": "^15.6.2" 2047 | } 2048 | }, 2049 | "react-dom": { 2050 | "version": "16.12.0", 2051 | "resolved": "http://npm.weimob.com/react-dom/-/react-dom-16.12.0.tgz", 2052 | "integrity": "sha1-DaS3FLjRPCA4yTlrVKkrrqYz/hE=", 2053 | "dev": true, 2054 | "requires": { 2055 | "loose-envify": "^1.1.0", 2056 | "object-assign": "^4.1.1", 2057 | "prop-types": "^15.6.2", 2058 | "scheduler": "^0.18.0" 2059 | } 2060 | }, 2061 | "react-is": { 2062 | "version": "16.12.0", 2063 | "resolved": "http://npm.weimob.com/react-is/-/react-is-16.12.0.tgz", 2064 | "integrity": "sha1-LMD+D7p0LZf9UnxCoTvsTusGJBw=", 2065 | "dev": true 2066 | }, 2067 | "regenerate": { 2068 | "version": "1.4.0", 2069 | "resolved": "http://npm.weimob.com/regenerate/-/regenerate-1.4.0.tgz", 2070 | "integrity": "sha1-SoVuxLVuQHfFV1icroXnpMiGmhE=", 2071 | "dev": true 2072 | }, 2073 | "regenerate-unicode-properties": { 2074 | "version": "8.1.0", 2075 | "resolved": "http://npm.weimob.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz", 2076 | "integrity": "sha1-71Hg8OpK1CS3e/fLQfPgFccKPw4=", 2077 | "dev": true, 2078 | "requires": { 2079 | "regenerate": "^1.4.0" 2080 | } 2081 | }, 2082 | "regenerator-runtime": { 2083 | "version": "0.11.1", 2084 | "resolved": "http://npm.weimob.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", 2085 | "integrity": "sha1-vgWtf5v30i4Fb5cmzuUBf78Z4uk=", 2086 | "dev": true 2087 | }, 2088 | "regenerator-transform": { 2089 | "version": "0.14.1", 2090 | "resolved": "http://npm.weimob.com/regenerator-transform/-/regenerator-transform-0.14.1.tgz", 2091 | "integrity": "sha1-Oy/OThq3cywI9mXf2zFHScfd0vs=", 2092 | "dev": true, 2093 | "requires": { 2094 | "private": "^0.1.6" 2095 | } 2096 | }, 2097 | "regexpu-core": { 2098 | "version": "4.6.0", 2099 | "resolved": "http://npm.weimob.com/regexpu-core/-/regexpu-core-4.6.0.tgz", 2100 | "integrity": "sha1-IDfBizJ8/Oim/qKk7EQfJDKvuLY=", 2101 | "dev": true, 2102 | "requires": { 2103 | "regenerate": "^1.4.0", 2104 | "regenerate-unicode-properties": "^8.1.0", 2105 | "regjsgen": "^0.5.0", 2106 | "regjsparser": "^0.6.0", 2107 | "unicode-match-property-ecmascript": "^1.0.4", 2108 | "unicode-match-property-value-ecmascript": "^1.1.0" 2109 | } 2110 | }, 2111 | "regjsgen": { 2112 | "version": "0.5.1", 2113 | "resolved": "http://npm.weimob.com/regjsgen/-/regjsgen-0.5.1.tgz", 2114 | "integrity": "sha1-SPC/Gl6iBRlpKcDZeYtC0e2YRDw=", 2115 | "dev": true 2116 | }, 2117 | "regjsparser": { 2118 | "version": "0.6.0", 2119 | "resolved": "http://npm.weimob.com/regjsparser/-/regjsparser-0.6.0.tgz", 2120 | "integrity": "sha1-8eaui32iuulsmTmbhozWyTOiupw=", 2121 | "dev": true, 2122 | "requires": { 2123 | "jsesc": "~0.5.0" 2124 | }, 2125 | "dependencies": { 2126 | "jsesc": { 2127 | "version": "0.5.0", 2128 | "resolved": "http://npm.weimob.com/jsesc/-/jsesc-0.5.0.tgz", 2129 | "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", 2130 | "dev": true 2131 | } 2132 | } 2133 | }, 2134 | "resolve": { 2135 | "version": "1.13.1", 2136 | "resolved": "https://registry.npm.taobao.org/resolve/download/resolve-1.13.1.tgz", 2137 | "integrity": "sha1-vgqkwGrNUwg1BauzX01mkyqzXRY=", 2138 | "dev": true, 2139 | "requires": { 2140 | "path-parse": "^1.0.6" 2141 | } 2142 | }, 2143 | "rollup": { 2144 | "version": "1.27.5", 2145 | "resolved": "http://npm.weimob.com/rollup/-/rollup-1.27.5.tgz", 2146 | "integrity": "sha1-0QD7D/2DU1dcsgVxUlR7mr/d/lk=", 2147 | "dev": true, 2148 | "requires": { 2149 | "@types/estree": "*", 2150 | "@types/node": "*", 2151 | "acorn": "^7.1.0" 2152 | } 2153 | }, 2154 | "rollup-plugin-babel": { 2155 | "version": "4.3.3", 2156 | "resolved": "https://registry.npm.taobao.org/rollup-plugin-babel/download/rollup-plugin-babel-4.3.3.tgz", 2157 | "integrity": "sha1-frWsFtm1gxw/1dl+jfd7olxyoqo=", 2158 | "dev": true, 2159 | "requires": { 2160 | "@babel/helper-module-imports": "^7.0.0", 2161 | "rollup-pluginutils": "^2.8.1" 2162 | } 2163 | }, 2164 | "rollup-plugin-commonjs": { 2165 | "version": "10.1.0", 2166 | "resolved": "http://npm.weimob.com/rollup-plugin-commonjs/-/rollup-plugin-commonjs-10.1.0.tgz", 2167 | "integrity": "sha1-QXrztUUDh44ITRJ6300cr4vrhvs=", 2168 | "dev": true, 2169 | "requires": { 2170 | "estree-walker": "^0.6.1", 2171 | "is-reference": "^1.1.2", 2172 | "magic-string": "^0.25.2", 2173 | "resolve": "^1.11.0", 2174 | "rollup-pluginutils": "^2.8.1" 2175 | } 2176 | }, 2177 | "rollup-plugin-node-resolve": { 2178 | "version": "5.2.0", 2179 | "resolved": "https://registry.npm.taobao.org/rollup-plugin-node-resolve/download/rollup-plugin-node-resolve-5.2.0.tgz", 2180 | "integrity": "sha1-cw+T0Q7SAkc7H7VKWZen24xthSM=", 2181 | "dev": true, 2182 | "requires": { 2183 | "@types/resolve": "0.0.8", 2184 | "builtin-modules": "^3.1.0", 2185 | "is-module": "^1.0.0", 2186 | "resolve": "^1.11.1", 2187 | "rollup-pluginutils": "^2.8.1" 2188 | } 2189 | }, 2190 | "rollup-plugin-uglify": { 2191 | "version": "6.0.3", 2192 | "resolved": "http://npm.weimob.com/rollup-plugin-uglify/-/rollup-plugin-uglify-6.0.3.tgz", 2193 | "integrity": "sha1-4/d2FxNEtYC+xsariIhiK2cJlFc=", 2194 | "dev": true, 2195 | "requires": { 2196 | "@babel/code-frame": "^7.0.0", 2197 | "jest-worker": "^24.0.0", 2198 | "serialize-javascript": "^1.9.0", 2199 | "uglify-js": "^3.4.9" 2200 | } 2201 | }, 2202 | "rollup-pluginutils": { 2203 | "version": "2.8.2", 2204 | "resolved": "https://registry.npm.taobao.org/rollup-pluginutils/download/rollup-pluginutils-2.8.2.tgz?cache=0&sync_timestamp=1568405888956&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Frollup-pluginutils%2Fdownload%2Frollup-pluginutils-2.8.2.tgz", 2205 | "integrity": "sha1-cvKvB0i1kjZNvTOJ5gDlqURKNR4=", 2206 | "dev": true, 2207 | "requires": { 2208 | "estree-walker": "^0.6.1" 2209 | } 2210 | }, 2211 | "safe-buffer": { 2212 | "version": "5.1.2", 2213 | "resolved": "http://npm.weimob.com/safe-buffer/-/safe-buffer-5.1.2.tgz", 2214 | "integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0=", 2215 | "dev": true 2216 | }, 2217 | "scheduler": { 2218 | "version": "0.18.0", 2219 | "resolved": "http://npm.weimob.com/scheduler/-/scheduler-0.18.0.tgz", 2220 | "integrity": "sha1-WQGtZlm8HY8/2vNut6Z7DWdGscQ=", 2221 | "dev": true, 2222 | "requires": { 2223 | "loose-envify": "^1.1.0", 2224 | "object-assign": "^4.1.1" 2225 | } 2226 | }, 2227 | "semver": { 2228 | "version": "5.7.1", 2229 | "resolved": "http://npm.weimob.com/semver/-/semver-5.7.1.tgz", 2230 | "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=", 2231 | "dev": true 2232 | }, 2233 | "serialize-javascript": { 2234 | "version": "1.9.1", 2235 | "resolved": "http://npm.weimob.com/serialize-javascript/-/serialize-javascript-1.9.1.tgz", 2236 | "integrity": "sha1-z8IArvd7YAxH2pu4FJyUPnmML9s=", 2237 | "dev": true 2238 | }, 2239 | "shebang-command": { 2240 | "version": "2.0.0", 2241 | "resolved": "http://npm.weimob.com/shebang-command/-/shebang-command-2.0.0.tgz", 2242 | "integrity": "sha1-zNCvT4g1+9wmW4JGGq8MNmY/NOo=", 2243 | "dev": true, 2244 | "requires": { 2245 | "shebang-regex": "^3.0.0" 2246 | } 2247 | }, 2248 | "shebang-regex": { 2249 | "version": "3.0.0", 2250 | "resolved": "http://npm.weimob.com/shebang-regex/-/shebang-regex-3.0.0.tgz", 2251 | "integrity": "sha1-rhbxZE2HPsrYQ7AwexQzYtTEIXI=", 2252 | "dev": true 2253 | }, 2254 | "source-map": { 2255 | "version": "0.5.7", 2256 | "resolved": "http://npm.weimob.com/source-map/-/source-map-0.5.7.tgz", 2257 | "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", 2258 | "dev": true 2259 | }, 2260 | "sourcemap-codec": { 2261 | "version": "1.4.6", 2262 | "resolved": "http://npm.weimob.com/sourcemap-codec/-/sourcemap-codec-1.4.6.tgz", 2263 | "integrity": "sha1-4wp08EArrQmAdkDTnpcQkKCM4ek=", 2264 | "dev": true 2265 | }, 2266 | "strip-ansi": { 2267 | "version": "3.0.1", 2268 | "resolved": "http://npm.weimob.com/strip-ansi/-/strip-ansi-3.0.1.tgz", 2269 | "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", 2270 | "dev": true, 2271 | "requires": { 2272 | "ansi-regex": "^2.0.0" 2273 | } 2274 | }, 2275 | "supports-color": { 2276 | "version": "5.5.0", 2277 | "resolved": "http://npm.weimob.com/supports-color/-/supports-color-5.5.0.tgz", 2278 | "integrity": "sha1-4uaaRKyHcveKHsCzW2id9lMO/I8=", 2279 | "dev": true, 2280 | "requires": { 2281 | "has-flag": "^3.0.0" 2282 | } 2283 | }, 2284 | "to-fast-properties": { 2285 | "version": "2.0.0", 2286 | "resolved": "https://registry.npm.taobao.org/to-fast-properties/download/to-fast-properties-2.0.0.tgz", 2287 | "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", 2288 | "dev": true 2289 | }, 2290 | "uglify-js": { 2291 | "version": "3.7.0", 2292 | "resolved": "http://npm.weimob.com/uglify-js/-/uglify-js-3.7.0.tgz", 2293 | "integrity": "sha1-FLhUADOGt6fARZEPQ6+8ltKqUwc=", 2294 | "dev": true, 2295 | "requires": { 2296 | "commander": "~2.20.3", 2297 | "source-map": "~0.6.1" 2298 | }, 2299 | "dependencies": { 2300 | "source-map": { 2301 | "version": "0.6.1", 2302 | "resolved": "http://npm.weimob.com/source-map/-/source-map-0.6.1.tgz", 2303 | "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=", 2304 | "dev": true 2305 | } 2306 | } 2307 | }, 2308 | "unicode-canonical-property-names-ecmascript": { 2309 | "version": "1.0.4", 2310 | "resolved": "http://npm.weimob.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", 2311 | "integrity": "sha1-JhmADEyCWADv3YNDr33Zkzy+KBg=", 2312 | "dev": true 2313 | }, 2314 | "unicode-match-property-ecmascript": { 2315 | "version": "1.0.4", 2316 | "resolved": "http://npm.weimob.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", 2317 | "integrity": "sha1-jtKjJWmWG86SJ9Cc0/+7j+1fAgw=", 2318 | "dev": true, 2319 | "requires": { 2320 | "unicode-canonical-property-names-ecmascript": "^1.0.4", 2321 | "unicode-property-aliases-ecmascript": "^1.0.4" 2322 | } 2323 | }, 2324 | "unicode-match-property-value-ecmascript": { 2325 | "version": "1.1.0", 2326 | "resolved": "http://npm.weimob.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.1.0.tgz", 2327 | "integrity": "sha1-W0tCbgjROoA2Xg1lesemwexGonc=", 2328 | "dev": true 2329 | }, 2330 | "unicode-property-aliases-ecmascript": { 2331 | "version": "1.0.5", 2332 | "resolved": "http://npm.weimob.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz", 2333 | "integrity": "sha1-qcxsx85joKMCP8meNBuUQx1AWlc=", 2334 | "dev": true 2335 | }, 2336 | "vue": { 2337 | "version": "2.6.10", 2338 | "resolved": "http://npm.weimob.com/vue/-/vue-2.6.10.tgz", 2339 | "integrity": "sha1-pysaQqTYKnIepDjRtr9V5mGVxjc=", 2340 | "dev": true 2341 | }, 2342 | "vue-template-compiler": { 2343 | "version": "2.6.10", 2344 | "resolved": "http://npm.weimob.com/vue-template-compiler/-/vue-template-compiler-2.6.10.tgz", 2345 | "integrity": "sha1-MjtPNJXwT6o1AzN6gvXWUHeZycw=", 2346 | "dev": true, 2347 | "requires": { 2348 | "de-indent": "^1.0.2", 2349 | "he": "^1.1.0" 2350 | } 2351 | }, 2352 | "vue-template-es2015-compiler": { 2353 | "version": "1.9.1", 2354 | "resolved": "http://npm.weimob.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz", 2355 | "integrity": "sha1-HuO8mhbsv1EYvjNLsV+cRvgvWCU=", 2356 | "dev": true 2357 | }, 2358 | "which": { 2359 | "version": "2.0.2", 2360 | "resolved": "http://npm.weimob.com/which/-/which-2.0.2.tgz", 2361 | "integrity": "sha1-fGqN0KY2oDJ+ELWckobu6T8/UbE=", 2362 | "dev": true, 2363 | "requires": { 2364 | "isexe": "^2.0.0" 2365 | } 2366 | } 2367 | } 2368 | } 2369 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vuereact-combined", 3 | "private": false, 4 | "version": "1.2.11", 5 | "description": "Vue和React快捷集成的工具包,并且适合复杂的集成场景", 6 | "main": "dist/vuereact.umd.js", 7 | "module": "dist/vuereact.esm.js", 8 | "typings": "types/vuereact.d.ts", 9 | "scripts": { 10 | "build": "cross-env BABEL_ENV=rollup rollup -c" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/devilwjp/vuereact-combined.git" 15 | }, 16 | "author": "Devle Wu", 17 | "license": "ISC", 18 | "bugs": { 19 | "url": "https://github.com/devilwjp/vuereact-combined/issues" 20 | }, 21 | "files": [ 22 | "dist", 23 | "types" 24 | ], 25 | "homepage": "https://github.com/devilwjp/vuereact-combined#readme", 26 | "peerDependencies": { 27 | "react": ">= 16.3.0", 28 | "react-dom": ">= 16.3.0", 29 | "vue": "^2.6.0" 30 | }, 31 | "devDependencies": { 32 | "@babel/core": "^7.7.4", 33 | "@babel/plugin-external-helpers": "^7.7.4", 34 | "@babel/plugin-proposal-class-properties": "^7.7.4", 35 | "@babel/plugin-proposal-object-rest-spread": "^7.7.4", 36 | "@babel/preset-env": "^7.7.4", 37 | "@babel/preset-react": "^7.7.4", 38 | "babel-preset-latest": "^6.24.1", 39 | "cross-env": "^6.0.3", 40 | "react": "^16.12.0", 41 | "react-dom": "^16.12.0", 42 | "rollup": "^1.27.5", 43 | "rollup-plugin-babel": "^4.3.3", 44 | "rollup-plugin-commonjs": "^10.1.0", 45 | "rollup-plugin-node-resolve": "^5.2.0", 46 | "rollup-plugin-uglify": "^6.0.3", 47 | "vue": "^2.6.10", 48 | "vue-template-compiler": "^2.6.10", 49 | "vue-template-es2015-compiler": "^1.9.1" 50 | }, 51 | "keywords": [ 52 | "vue", 53 | "react", 54 | "vuereact", 55 | "reactvue", 56 | "vueinreact", 57 | "reactinvue", 58 | "redux", 59 | "vuex", 60 | "lazyvue", 61 | "lazyreact" 62 | ] 63 | } 64 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable prefer-object-spread/prefer-object-spread */ 2 | 3 | import resolve from 'rollup-plugin-node-resolve' 4 | import babel from 'rollup-plugin-babel' 5 | import {uglify} from 'rollup-plugin-uglify' 6 | import commonjs from 'rollup-plugin-commonjs' 7 | 8 | const shared = { 9 | input: 'src/index.js', 10 | plugins: [ 11 | resolve({ 12 | customResolveOptions: { 13 | moduleDirectory: 'node_modules', 14 | }, 15 | }), 16 | babel({ 17 | exclude: 'node-modules/**', 18 | }), 19 | commonjs(), 20 | uglify({ 21 | compress: { 22 | // 这个设置会导致压缩时一些不该被删的代码被误删 23 | // pure_getters: true, 24 | // unsafe: true, 25 | // unsafe_comps: true 26 | } 27 | }) 28 | ], 29 | external: ['react', 'react-dom', 'vue', 'portal-vue'], 30 | } 31 | 32 | export default [ 33 | Object.assign({}, shared, { 34 | output: { 35 | file: 'dist/vuereact.umd.js', 36 | format: 'umd', 37 | name: 'vuereact', 38 | globals: { 39 | react: 'React', 40 | 'react-dom': 'ReactDOM', 41 | vue: 'Vue' 42 | }, 43 | }, 44 | }), 45 | Object.assign({}, shared, { 46 | output: { 47 | file: 'dist/vuereact.esm.js', 48 | format: 'esm', 49 | name: 'vuereact', 50 | globals: { 51 | react: 'React', 52 | 'react-dom': 'ReactDOM', 53 | vue: 'Vue' 54 | }, 55 | }, 56 | }), 57 | ] 58 | -------------------------------------------------------------------------------- /src/applyReactInVue.js: -------------------------------------------------------------------------------- 1 | import React, { version } from "react" 2 | import applyVueInReact, { VueContainer } from "./applyVueInReact" 3 | import options, { setOptions } from "./options" 4 | import { createPortal } from "react-dom" 5 | import ReactDOM from 'react-dom' 6 | // vueRootInfo是为了保存vue的root节点options部分信息,现在保存router、store,在applyVueInReact方法中创建vue的中间件实例时会被设置 7 | // 为了使applyReactInVue -> applyVueInReact之后的vue组件依旧能引用vuex和vue router 8 | import vueRootInfo from "./vueRootInfo" 9 | 10 | const ReactMajorVersion = parseInt(version) 11 | const domMethods = ["getElementById", "getElementsByClassName", "getElementsByTagName", "getElementsByTagNameNS", "querySelector", "querySelectorAll"] 12 | const domTopObject = { Document: {}, Element: {} } 13 | // 覆盖原生的查找dom对象的方法,为了确保react在销毁前都可以获取dom,而vue的beforeDestroy阶段已经将dom卸载的问题 14 | function overwriteDomMethods(refDom) { 15 | Object.keys(domTopObject).forEach((key) => { 16 | domMethods.forEach((method) => { 17 | const old = window[key].prototype[method] 18 | domTopObject[key][method] = old 19 | window[key].prototype[method] = function (...args) { 20 | const oldResult = old.apply(this, args) 21 | if ((oldResult && oldResult.constructor !== NodeList) || (oldResult && oldResult.constructor === NodeList && oldResult.length > 0)) return oldResult 22 | return Element.prototype[method].apply(refDom, args) 23 | } 24 | }) 25 | }) 26 | } 27 | // 恢复原生方法 28 | function recoverDomMethods() { 29 | Object.keys(domTopObject).forEach((key) => { 30 | domMethods.forEach((method) => { 31 | window[key].prototype[method] = domTopObject[key][method] 32 | }) 33 | }) 34 | } 35 | 36 | class FunctionComponentWrap extends React.Component { 37 | constructor(props) { 38 | super(props) 39 | } 40 | 41 | render() { 42 | const Component = this.props.component 43 | const { ref, ...props } = this.props.passedProps 44 | return {this.props.children} 45 | } 46 | } 47 | const createReactContainer = (Component, options, wrapInstance) => class applyReact extends React.Component { 48 | // 用于reactDevTools调试用 49 | static displayName = `useReact_${Component.displayName || Component.name || "Component"}` 50 | 51 | // 使用静态方法申明是因为可以节省性能开销,因为内部没有调用到实例属性和方法 52 | setRef(ref) { 53 | if (!ref) return 54 | // 使用reactRef属性保存目标react组件的实例,可以被父组setRef件的实例获取到 55 | wrapInstance.reactRef = ref 56 | // 将react实例的可枚举属性挂到vue实例中 57 | Object.keys(ref).forEach((key) => { 58 | if (!wrapInstance[key]) { 59 | wrapInstance[key] = ref[key] 60 | } 61 | }) 62 | Promise.resolve().then(() => { 63 | Object.keys(ref).forEach((key) => { 64 | if (!wrapInstance[key]) { 65 | wrapInstance[key] = ref[key] 66 | } 67 | }) 68 | }) 69 | 70 | 71 | // 兼容接收useRef类型的参数 72 | this.setRef.current = ref 73 | 74 | // 并且将vue的中间件实例保存在react组件的实例中 75 | // react组件可以通过这个属性来判断是否被包囊使用 76 | ref.vueWrapperRef = wrapInstance 77 | } 78 | 79 | constructor(props) { 80 | super(props) 81 | // 将所有的属性全部寄存在中间件的状态中,原理是通过一个有状态的React组件作为中间件,触发目标组件的props 82 | this.state = { 83 | ...props, 84 | ...(options.isSlots ? { children: Component } : {}), 85 | } 86 | this.setRef = this.setRef.bind(this) 87 | this.vueInReactCall = this.vueInReactCall.bind(this) 88 | this.vueWrapperRef = wrapInstance 89 | } 90 | 91 | // 对于插槽的处理仍然需要将VNode转换成React组件 92 | createSlot(children) { 93 | const { style, ...attrs } = options.react.slotWrapAttrs 94 | return { 95 | inheritAttrs: false, 96 | __fromReactSlot: true, 97 | render(createElement) { 98 | if (children instanceof Function) { 99 | children = children(this) 100 | } 101 | // 有些react组件通过直接处理自身children的方式给children中的组件传递属性,会导致传递到包囊层中 102 | // 这里对包囊层属性进行透传,透传条件为children中只有一个vnode 103 | if (children?.length === 1 && children[0]?.data) { 104 | // 过滤掉内部属性 105 | const {key, ['data-passed-props']:dataPassedProps, ...otherAttrs} = this.$attrs 106 | children[0].data.attrs = {...otherAttrs, ...children[0].data.attrs} 107 | } 108 | return createElement(options.react.slotWrap, { attrs, style }, children) 109 | }, 110 | } 111 | } 112 | 113 | componentWillUnmount() { 114 | if (!wrapInstance.reactRef) return 115 | // 垃圾回收,但是保留属性名,借鉴vue的refs对于组件销毁保留属性名的模式 116 | wrapInstance.reactRef.vueWrapperRef = null 117 | wrapInstance.reactRef = null 118 | } 119 | 120 | static catchVueRefs() { 121 | if (!wrapInstance.$parent) return false 122 | for (const ref in wrapInstance.$parent.$refs) { 123 | if (wrapInstance.$parent.$refs[ref] === wrapInstance) { 124 | return true 125 | } 126 | } 127 | return false 128 | } 129 | 130 | vueInReactCall(children, customOptions = {}, division) { 131 | if (division) { 132 | if (children && children[0]) { 133 | return children.map((child, index) => applyVueInReact(this.createSlot(child instanceof Function ? child : [child]), { 134 | ...options, ...customOptions, isSlots: true, wrapInstance, 135 | }).render({ key: child?.data?.key || index })) 136 | } 137 | } 138 | return applyVueInReact(this.createSlot(children), { 139 | ...options, ...customOptions, isSlots: true, wrapInstance, 140 | }).render() 141 | } 142 | 143 | render() { 144 | let { 145 | "data-passed-props": __passedProps, 146 | hashList, 147 | ...props 148 | } = this.state 149 | let children 150 | // 保留一份作用域和具名插槽,用于之后再透传给vue组件 151 | const $slots = {} 152 | const $scopedSlots = {} 153 | // 插槽的解析 154 | for (const i in props) { 155 | if (!props.hasOwnProperty(i) || props[i] == null) continue 156 | if (props[i].__slot) { 157 | if (!props[i].reactSlot) { 158 | const vueSlot = props[i] 159 | // 执行applyVueInReact方法将直接获得react组件对象,无需使用jsx 160 | // props[i] = { ...applyVueInReact(this.createSlot(props[i]))() } 161 | // 自定义插槽处理 162 | if (options.defaultSlotsFormatter) { 163 | props[i].__top__ = this.vueWrapperRef 164 | props[i] = options.defaultSlotsFormatter(props[i], this.vueInReactCall, hashList) 165 | function cloneChildren() { 166 | if (props[i] instanceof Array) { 167 | props[i] = [...props[i]] 168 | return 169 | } 170 | if (["string", "number"].indexOf(typeof props[i]) > -1) { 171 | props[i] = [props[i]] 172 | return 173 | } 174 | if (typeof props[i] === "object") { 175 | props[i] = { ...props[i] } 176 | } 177 | } 178 | cloneChildren() 179 | } else { 180 | props[i] = { ...applyVueInReact(this.createSlot(props[i]), { ...options, isSlots: true, wrapInstance }).render() } 181 | } 182 | props[i].vueSlot = vueSlot 183 | } else { 184 | props[i] = props[i].reactSlot 185 | } 186 | $slots[i] = props[i] 187 | continue 188 | } 189 | if (props[i].__scopedSlot) { 190 | // 作用域插槽是个纯函数,在react组件中需要传入作用域调用,然后再创建vue的插槽组件 191 | props[i] = props[i](this.createSlot) 192 | $scopedSlots[i] = props[i] 193 | } 194 | } 195 | // 普通插槽 196 | if (!props.children?.vueFunction) { 197 | children = props.children 198 | } 199 | $slots.default = children 200 | // 封装透传属性 201 | __passedProps = { ...__passedProps, ...{ $slots, $scopedSlots }, children } 202 | const refInfo = {} 203 | refInfo.ref = this.setRef 204 | if (options.isSlots) { 205 | return this.state.children || this.props.children 206 | } 207 | let finalProps = props 208 | // 自定义处理参数 209 | if (options.defaultPropsFormatter) { 210 | finalProps = options.defaultPropsFormatter(props, this.vueInReactCall, hashList) 211 | } 212 | const newProps = { ...finalProps, ...{ "data-passed-props": __passedProps } } 213 | // 判断是否要通过一个class组件包装一下来获取ref 214 | // 通过判断Component的原型是否不是Function原型 215 | if ((Object.getPrototypeOf(Component) !== Function.prototype && !(typeof Component === "object" && !Component.render)) || applyReact.catchVueRefs()) { 216 | return ( 217 | 219 | {children || newProps.children} 220 | 221 | ) 222 | } 223 | return {children || newProps.children} 224 | } 225 | } 226 | export default function applyReactInVue(component, options = {}) { 227 | // 兼容esModule 228 | if (component.__esModule && component.default) { 229 | component = component.default 230 | } 231 | if (options.isSlots) { 232 | component = component() 233 | } 234 | // 处理附加参数 235 | options = setOptions(options, undefined, true) 236 | return { 237 | originReactComponent: component, 238 | data() { 239 | return { 240 | portals: [], 241 | portalKeyPool: [], 242 | maxPortalCount: 0, 243 | } 244 | }, 245 | created() { 246 | // this.vnodeData = this.$vnode.data 247 | this.cleanVnodeStyleClass() 248 | if (this.$root.$options.router) { 249 | vueRootInfo.router = this.$root.$options.router 250 | } 251 | if (this.$root.$options.router) { 252 | vueRootInfo.store = this.$root.$options.store 253 | } 254 | }, 255 | props: ["dataPassedProps"], 256 | render(createElement) { 257 | this.slotsInit() 258 | const { style, ...attrs } = options.react.componentWrapAttrs 259 | // return createElement(options.react.componentWrap, { ref: "react", attrs, style }, this.portals.map((Portal, index) => Portal(createElement, index))) 260 | return createElement(options.react.componentWrap, { ref: "react", attrs, style }, this.portals.map(({ Portal, key }) => Portal(createElement, key))) 261 | }, 262 | methods: { 263 | pushVuePortal(vuePortal) { 264 | const key = this.portalKeyPool.shift() || this.maxPortalCount++ 265 | this.portals.push({ 266 | Portal: vuePortal, 267 | key, 268 | }) 269 | }, 270 | removeVuePortal(vuePortal) { 271 | let index 272 | const portalData = this.portals.find((obj, i) => { 273 | if (obj.Portal === vuePortal) { 274 | index = i 275 | return true 276 | } 277 | }) 278 | this.portalKeyPool.push(portalData.key) 279 | this.portals.splice(index, 1) 280 | }, 281 | // hack!!!! 一定要在render函数李触发,才能激活具名插槽 282 | slotsInit(vnode) { 283 | // 针对pureTransformer类型的react组件进行兼容,解决具名插槽和作用域插槽不更新的问题 284 | if (vnode) { 285 | if (vnode.componentOptions?.Ctor?.options && !vnode.componentOptions?.Ctor?.options.originReactComponent) return 286 | if (vnode.data?.scopedSlots) { 287 | Object.keys(vnode.data?.scopedSlots).forEach((key) => { 288 | if (typeof vnode.data.scopedSlots[key] === "function") { 289 | try { 290 | vnode.data.scopedSlots[key]() 291 | } catch (e) {} 292 | } 293 | }) 294 | } 295 | const children = vnode.children || vnode.componentOptions?.children || [] 296 | children.forEach((subVnode) => { 297 | this.slotsInit(subVnode) 298 | }) 299 | return 300 | } 301 | Object.keys(this.$slots).forEach((key) => { 302 | (this.$slots[key] || []).forEach((subVnode) => { 303 | this.slotsInit(subVnode) 304 | }) 305 | }) 306 | Object.keys(this.$scopedSlots).forEach((key) => { 307 | try { 308 | this.$scopedSlots[key]() 309 | } catch (e) {} 310 | }) 311 | }, 312 | updateLastVnodeData(vnode) { 313 | this.lastVnodeData = { 314 | style: { ...this.formatStyle(vnode.data.style), ...this.formatStyle(vnode.data.staticStyle) }, 315 | class: Array.from(new Set([...this.formatClass(vnode.data.class), ...this.formatClass(vnode.data.staticClass)])).join(" "), 316 | } 317 | Object.assign(vnode.data, { 318 | staticStyle: null, 319 | style: null, 320 | staticClass: null, 321 | class: null, 322 | }) 323 | return vnode 324 | }, 325 | // 清除style和class,避免包囊层被污染 326 | cleanVnodeStyleClass() { 327 | let vnode = this.$vnode 328 | this.updateLastVnodeData(vnode) 329 | // 每次$vnode被修改,将vnode.data中的style、staticStyle、class、staticClass记下来并且清除 330 | Object.defineProperty(this, "$vnode", { 331 | get() { 332 | return vnode 333 | }, 334 | set: (val) => { 335 | if (val === vnode) return vnode 336 | vnode = this.updateLastVnodeData(val) 337 | return vnode 338 | }, 339 | }) 340 | }, 341 | toCamelCase(val) { 342 | const reg = /-(\w)/g 343 | return val.replace(reg, ($, $1) => $1.toUpperCase()) 344 | }, 345 | formatStyle(val) { 346 | if (!val) return {} 347 | if (typeof val === "string") { 348 | val = val.trim() 349 | return val.split(/\s*;\s*/).reduce((prev, cur) => { 350 | if (!cur) { 351 | return prev 352 | } 353 | cur = cur.split(/\s*:\s*/) 354 | if (cur.length !== 2) return prev 355 | Object.assign(prev, { 356 | [this.toCamelCase(cur[0])]: cur[1], 357 | }) 358 | return prev 359 | }, {}) 360 | } 361 | if (typeof val === "object") { 362 | const newVal = {} 363 | Object.keys(val).forEach((v) => { 364 | newVal[this.toCamelCase(v)] = val[v] 365 | }) 366 | return newVal 367 | } 368 | return {} 369 | }, 370 | formatClass(val) { 371 | if (!val) return [] 372 | if (val instanceof Array) return val 373 | if (typeof val === "string") { 374 | val = val.trim() 375 | return val.split(/\s+/) 376 | } 377 | if (typeof val === "object") { 378 | return Object.keys(val).map((v) => (val[v] ? val[v] : "")) 379 | } 380 | return [] 381 | }, 382 | // 用多阶函数解决作用域插槽的传递问题 383 | getScopeSlot(slotFunction, hashList, originSlotFunction) { 384 | const _this = this 385 | function scopedSlotFunction(createReactSlot) { 386 | function getSlot(...args) { 387 | if (slotFunction.reactFunction) { 388 | return slotFunction.reactFunction.apply(this, args) 389 | } 390 | if (options.defaultSlotsFormatter) { 391 | let scopeSlot = slotFunction.apply(this, args) 392 | scopeSlot.__top__ = _this 393 | scopeSlot = options.defaultSlotsFormatter(scopeSlot, _this.vueInReactCall, hashList) 394 | if (scopeSlot instanceof Array || (typeof scopeSlot).indexOf("string", "number") > -1) { 395 | scopeSlot = [...scopeSlot] 396 | } else if (typeof scopeSlot === "object") { 397 | scopeSlot = { ...scopeSlot } 398 | } 399 | return scopeSlot 400 | } 401 | return applyVueInReact(createReactSlot(slotFunction.apply(this, args)), { ...options, isSlots: true, wrapInstance: _this }).render() 402 | } 403 | if (options.pureTransformer && originSlotFunction) { 404 | getSlot.vueFunction = originSlotFunction 405 | } else { 406 | getSlot.vueFunction = slotFunction 407 | } 408 | return getSlot 409 | } 410 | scopedSlotFunction.__scopedSlot = true 411 | return scopedSlotFunction 412 | }, 413 | __syncUpdateProps(extraData) { 414 | // this.mountReactComponent(true, false, extraData) 415 | this.reactInstance && this.reactInstance.setState(extraData) 416 | }, 417 | mountReactComponent(update, updateType, extraData = {}) { 418 | // 先提取透传属性 419 | let { 420 | on: __passedPropsOn, 421 | $slots: __passedPropsSlots, 422 | $scopedSlots: __passedPropsScopedSlots, 423 | children, 424 | ...__passedPropsRest 425 | } = (this.$props.dataPassedProps != null ? this.$props.dataPassedProps : {}) 426 | 427 | // 获取style scoped生成的hash 428 | const hashMap = {} 429 | const hashList = [] 430 | const scopedId = this.$vnode.context?.$vnode?.componentOptions?.Ctor?.extendOptions?._scopeId 431 | if (scopedId) { 432 | hashMap[scopedId] = "" 433 | hashList.push(scopedId) 434 | } 435 | // for (let i in this.$el.dataset) { 436 | // if (this.$el.dataset.hasOwnProperty(i) && (i.match(/v-[\da-z]+/) || i.match(/v[A-Z][\da-zA-Z]+/))) { 437 | // // 尝试驼峰转中划线 438 | // i = i.replace(/([A-Z])/g, "-$1").toLowerCase() 439 | // hashMap[`data-${i}`] = "" 440 | // hashList.push(`data-${i}`) 441 | // } 442 | // } 443 | 444 | const normalSlots = {} 445 | const scopedSlots = {} 446 | if (!update || update && updateType?.slot) { 447 | // 处理具名插槽,将作为属性被传递 448 | 449 | const mergeSlots = { ...__passedPropsSlots, ...this.$slots } 450 | // 对插槽类型的属性做标记 451 | for (const i in mergeSlots) { 452 | normalSlots[i] = mergeSlots[i] 453 | normalSlots[i].__slot = true 454 | } 455 | // 对作用域插槽进行处理 456 | const mergeScopedSlots = { ...__passedPropsScopedSlots, ...this.$scopedSlots } 457 | for (const i in mergeScopedSlots) { 458 | // 过滤普通插槽 459 | if (normalSlots[i]) { 460 | // 并且做上标记,vue2.6之后,所有插槽都推荐用作用域,所以之后要转成普通插槽 461 | if (this.$scopedSlots[i]) { 462 | this.$scopedSlots[i].__slot = true 463 | } 464 | continue 465 | } 466 | // 如果发现作用域插槽中有普通插槽的标记,就转成成普通插槽 467 | if (mergeScopedSlots[i].__slot) { 468 | normalSlots[i] = mergeScopedSlots[i]() 469 | normalSlots[i].__slot = true 470 | continue 471 | } 472 | scopedSlots[i] = this.getScopeSlot(mergeScopedSlots[i], hashList, this.$vnode?.data?.scopedSlots?.[i]) 473 | } 474 | } 475 | 476 | 477 | // 预生成react组件的透传属性 478 | const __passedProps = { 479 | ...__passedPropsRest, 480 | ...{ ...this.$attrs }, 481 | ...(!update || update && updateType?.slot ? { 482 | $slots: normalSlots, 483 | $scopedSlots: scopedSlots, 484 | children, 485 | } : {}), 486 | on: { ...__passedPropsOn, ...this.$listeners }, 487 | } 488 | let lastNormalSlots 489 | if (!update || update && updateType?.slot) { 490 | lastNormalSlots = { ...normalSlots } 491 | children = lastNormalSlots.default 492 | delete lastNormalSlots.default 493 | } 494 | 495 | // 存上一次 496 | this.last = this.last || {} 497 | this.last.slot = this.last.slot || {} 498 | this.last.listeners = this.last.listeners || {} 499 | this.last.attrs = this.last.attrs || {} 500 | const compareLast = { 501 | slot: () => { 502 | this.last.slot = { 503 | ...(children ? { children } : {children: null}), 504 | ...lastNormalSlots, 505 | ...scopedSlots, 506 | } 507 | }, 508 | listeners: () => { 509 | this.last.listeners = __passedProps.on 510 | }, 511 | attrs: () => { 512 | this.last.attrs = this.$attrs 513 | } 514 | } 515 | if (updateType) { 516 | Object.keys(updateType).forEach((key) => compareLast[key]()) 517 | } 518 | // 如果不传入组件,就作为更新 519 | if (!update) { 520 | compareLast.slot() 521 | compareLast.listeners() 522 | compareLast.attrs() 523 | const Component = createReactContainer(component, options, this) 524 | const reactEvent = {} 525 | Object.keys(__passedProps.on).forEach((key) => { 526 | reactEvent[`on${key.replace(/^(\w)/, ($, $1) => $1.toUpperCase())}`] = __passedProps.on[key] 527 | }) 528 | let reactRootComponent = (this.reactInstance = ref)} 542 | /> 543 | // 必须通过ReactReduxContext连接context 544 | if (this.$redux && this.$redux.store && this.$redux.ReactReduxContext) { 545 | const ReduxContext = this.$redux.ReactReduxContext 546 | reactRootComponent = {reactRootComponent} 547 | } 548 | // 必须异步,等待包囊层的react实例完毕 549 | // this.$nextTick(() => { 550 | const container = this.$refs.react 551 | let reactWrapperRef = options.wrapInstance 552 | 553 | if (!reactWrapperRef) { 554 | let parentInstance = this.$parent 555 | // 向上查找react包囊层 556 | while (parentInstance) { 557 | if (parentInstance.parentReactWrapperRef) { 558 | reactWrapperRef = parentInstance.parentReactWrapperRef 559 | break 560 | } 561 | if (parentInstance.reactWrapperRef) { 562 | reactWrapperRef = parentInstance.reactWrapperRef 563 | break 564 | } 565 | parentInstance = parentInstance.$parent 566 | } 567 | } else { 568 | reactWrapperRef = options.wrapInstance 569 | reactWrapperRef.vueWrapperRef = this 570 | } 571 | 572 | // 如果存在包囊层,则激活portal 573 | if (reactWrapperRef) { 574 | // 存储包囊层引用 575 | this.parentReactWrapperRef = reactWrapperRef 576 | // 存储portal引用 577 | this.reactPortal = () => createPortal( 578 | reactRootComponent, 579 | container, 580 | ) 581 | reactWrapperRef.pushReactPortal(this.reactPortal) 582 | return 583 | } 584 | 585 | if (ReactMajorVersion > 17) { 586 | // I'm not afraid of being fired 587 | if (ReactDOM.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED !== undefined) { 588 | ReactDOM.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.usingClientEntryPoint = true 589 | } 590 | this.__veauryReactApp__ = ReactDOM.createRoot(container) 591 | this.__veauryReactApp__.render(reactRootComponent) 592 | return 593 | } 594 | const reactInstance = ReactDOM.render( 595 | reactRootComponent, 596 | container, 597 | ) 598 | // }) 599 | } else { 600 | 601 | const setReactState = () => { 602 | this.reactInstance && this.reactInstance.setState((prevState) => { 603 | // 清除之前的state,阻止合并 604 | Object.keys(prevState).forEach((key) => { 605 | if (options.isSlots && key === 'children') return 606 | delete prevState[key] 607 | }) 608 | return { 609 | ...this.cache, 610 | ...!options.isSlots && this.last.slot, 611 | ...this.last.attrs, 612 | ...reactEvent 613 | } 614 | }) 615 | this.cache = null 616 | } 617 | 618 | 619 | // 更新 620 | if (this.microTaskUpdate) { 621 | // Promise异步合并更新 622 | if (!this.cache) { 623 | this.$nextTick(() => { 624 | // this.reactInstance && this.reactInstance.setState(this.cache) 625 | setReactState() 626 | this.microTaskUpdate = false 627 | }) 628 | } 629 | } 630 | 631 | // 宏任务合并更新 632 | if (this.macroTaskUpdate) { 633 | clearTimeout(this.updateTimer) 634 | this.updateTimer = setTimeout(() => { 635 | clearTimeout(this.updateTimer) 636 | // this.reactInstance && this.reactInstance.setState(this.cache) 637 | // this.cache = null 638 | setReactState() 639 | this.macroTaskUpdate = false 640 | }) 641 | } 642 | 643 | const reactEvent = {} 644 | Object.keys(this.last.listeners).forEach((key) => { 645 | reactEvent[`on${key.replace(/^(\w)/, ($, $1) => $1.toUpperCase())}`] = this.$listeners[key] 646 | }) 647 | this.cache = { 648 | ...this.cache || {}, 649 | ...{ 650 | ...__passedPropsRest, 651 | // ...this.last.attrs, 652 | // ...reactEvent, 653 | // ...(update && updateType?.slot ? {...this.last.slot} : {}), 654 | ...extraData, 655 | ...{ "data-passed-props": __passedProps }, 656 | ...(this.lastVnodeData.class ? { className: this.lastVnodeData.class } : {}), 657 | ...{ ...hashMap }, 658 | hashList, 659 | style: this.lastVnodeData.style, 660 | }, 661 | } 662 | 663 | // 同步更新 664 | if (!this.macroTaskUpdate && !this.microTaskUpdate) { 665 | // ...this.last.attrs, 666 | // ...reactEvent, 667 | // ...(update && updateType?.slot ? {...this.last.slot} : {}), 668 | // this.reactInstance && this.reactInstance.setState(this.cache) 669 | setReactState() 670 | } 671 | } 672 | }, 673 | }, 674 | mounted() { 675 | clearTimeout(this.updateTimer) 676 | this.mountReactComponent() 677 | }, 678 | beforeDestroy() { 679 | clearTimeout(this.updateTimer) 680 | // 删除portal 681 | if (this.reactPortal) { 682 | // 骚操作,覆盖原生dom查找dom的一些方法,使react在vue组件销毁前仍然可以查到dom 683 | overwriteDomMethods(this.$refs.react) 684 | this.parentReactWrapperRef && this.parentReactWrapperRef.removeReactPortal(this.reactPortal) 685 | // 恢复原生方法 686 | recoverDomMethods() 687 | return 688 | } 689 | // 删除根节点 690 | // 骚操作,覆盖原生dom查找dom的一些方法,使react在vue组件销毁前仍然可以查到dom 691 | overwriteDomMethods(this.$refs.react) 692 | if (ReactMajorVersion > 17) { 693 | this.__veauryReactApp__.unmount() 694 | } else { 695 | ReactDOM.unmountComponentAtNode(this.$refs.react) 696 | } 697 | // 恢复原生方法 698 | recoverDomMethods() 699 | }, 700 | updated() { 701 | // if (this.attrsUpdated) return 702 | this.mountReactComponent(true, {slot: true}) 703 | }, 704 | inheritAttrs: false, 705 | watch: { 706 | $attrs: { 707 | handler() { 708 | this.mountReactComponent(true, {attrs: true}) 709 | // this.attrsUpdated = true 710 | // Promise.resolve().then(() => { 711 | // this.attrsUpdated = false 712 | // }) 713 | }, 714 | deep: true, 715 | }, 716 | $listeners: { 717 | handler() { 718 | this.mountReactComponent(true, {listeners: true}) 719 | }, 720 | deep: true, 721 | }, 722 | "$props.dataPassedProps": { 723 | handler() { 724 | this.mountReactComponent(true, {passedProps: true}) 725 | }, 726 | deep: true, 727 | }, 728 | }, 729 | } 730 | } 731 | -------------------------------------------------------------------------------- /src/applyReactRouterInVue.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | let reactRouterInfo = {} 3 | function applyReactRouterInVue (withRouter) { 4 | // 只允许调用一次 5 | if (reactRouterInfo.withRouter) return reactRouterInfo.withRouter 6 | reactRouterInfo.withRouter = withRouter 7 | return reactRouterInfo.withRouter 8 | } 9 | export { 10 | reactRouterInfo 11 | } 12 | export function setReactRouterInVue (reactRouter) { 13 | if (reactRouterInfo.vueInstance) { 14 | updateReactRouterInVue(reactRouter) 15 | return 16 | } 17 | reactRouterInfo.vueInstance = new Vue({ 18 | data: { 19 | ...reactRouter 20 | } 21 | }) 22 | Vue.prototype.$reactRouter = reactRouterInfo.vueInstance.$data 23 | } 24 | export function updateReactRouterInVue (reactRouter) { 25 | Object.assign(reactRouterInfo.vueInstance.$data, { ...reactRouter }) 26 | } 27 | export default applyReactRouterInVue 28 | -------------------------------------------------------------------------------- /src/applyRedux.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | class ReduxLinkVue { 3 | constructor (store) { 4 | if (!store || !store.subscribe || !store.getState) { 5 | throw Error('incorrect store passed in, please check the function applyRedux\'s parameter must contains redux store') 6 | return 7 | } 8 | this.store = store 9 | // 订阅 10 | // 由于vue组件的设计机制,store是中心化的存在,使得不用关心取消订阅 11 | store.subscribe(() => { 12 | this._vm.state = store.getState() 13 | }) 14 | // 利用一个vue实例做双向绑定 15 | this._vm = new Vue({ 16 | data () { 17 | return { 18 | state: store.getState() // 初始化的数据 19 | } 20 | } 21 | }) 22 | } 23 | // 访问state对象时候,就直接返回响应式的数据 24 | get state () { 25 | return this._vm.state 26 | } 27 | get dispatch () { 28 | return this.store.dispatch 29 | } 30 | } 31 | let reduxInstance 32 | function applyRedux ({ store, ReactReduxContext }) { 33 | // 只允许调用一次 34 | if (reduxInstance) return reduxInstance 35 | // 创建redux与vue组件的连接 36 | reduxInstance = new ReduxLinkVue(store) 37 | // 如果提供了ReactReduxContext,就注册到applyReactInVue中,允许在vue中使用的react组件可以使用redux 38 | if (ReactReduxContext) { 39 | reduxInstance.ReactReduxContext = ReactReduxContext 40 | } 41 | // 和react-redux的provider不同,这里直接设计所有vue组件都注入redux 42 | Vue.prototype.$redux = reduxInstance 43 | return reduxInstance 44 | } 45 | export default applyRedux 46 | -------------------------------------------------------------------------------- /src/applyVueInReact.js: -------------------------------------------------------------------------------- 1 | import React, {version} from 'react' 2 | import Vue from 'vue' 3 | 4 | import applyReactInVue from './applyReactInVue' 5 | import vueRootInfo from './vueRootInfo' 6 | import { reactRouterInfo, setReactRouterInVue, updateReactRouterInVue } from './applyReactRouterInVue' 7 | import globalOptions, {setOptions} from './options' 8 | import {MountingPortal} from './portal-vue.esm' 9 | import REACT_ALL_HANDLERS from './reactAllHandles' 10 | 11 | const unsafePrefix = parseFloat(version) >= 17 ? 'UNSAFE_' : '' 12 | const optionsName = 'vuereact-combined-options' 13 | 14 | // 根据传入的是否是字符串,判断是否需要获取Vue的全局组件 15 | function filterVueComponent (component) { 16 | if (typeof component === 'string') { 17 | return Vue.component(component) 18 | } 19 | return component 20 | } 21 | // 获取组件选项对象 22 | function getOptions (Component) { 23 | if (typeof Component === 'function') { 24 | // return new (Component)().$options 25 | return Component.options 26 | } 27 | return Component 28 | } 29 | // 利用多阶组件来获取reactRouter 30 | class GetReactRouterPropsCom extends React.Component { 31 | constructor (props) { 32 | super(props) 33 | let { history, match, location } = props 34 | // 设置react router属性绑定倒所有的vue的原型上 35 | setReactRouterInVue({ 36 | history, 37 | match, 38 | location 39 | }) 40 | } 41 | [`${unsafePrefix}componentWillReceiveProps`] (nextProps) { 42 | let { history, match, location } = nextProps 43 | updateReactRouterInVue({ 44 | history, 45 | match, 46 | location 47 | }) 48 | } 49 | render () { 50 | const { history, match, location, ...newProps } = this.props 51 | return 52 | } 53 | } 54 | const VueContainer = React.forwardRef((props, ref) => { 55 | const globalOptions = setOptions(props[optionsName] || {}, undefined, true) 56 | 57 | // 判断是否获取过reactRouter 58 | if (reactRouterInfo.withRouter) { 59 | if (!VueContainer.RouterTargetComponent) { 60 | VueContainer.RouterTargetComponent = reactRouterInfo.withRouter(GetReactRouterPropsCom) 61 | } 62 | // withRouter方法是通过wrappedComponentRef来传递ref的 63 | return ( 64 | 65 | ) 66 | } else { 67 | return 68 | } 69 | }) 70 | 71 | export { 72 | VueContainer 73 | } 74 | class VueComponentLoader extends React.Component { 75 | constructor (props) { 76 | super(props) 77 | this.state = { 78 | portals: [], 79 | } 80 | this.portalKeyPool = [] 81 | this.maxPortalCount = 0 82 | // 捕获vue组件 83 | this.currentVueComponent = filterVueComponent(props.component) 84 | this.createVueInstance = this.createVueInstance.bind(this) 85 | this.vueComponentContainer = this.createVueComponentContainer() 86 | } 87 | 88 | pushReactPortal (reactPortal) { 89 | let { portals } = this.state 90 | const key = this.portalKeyPool.shift() || this.maxPortalCount++ 91 | portals.push({ 92 | Portal: reactPortal, 93 | key 94 | }) 95 | this.setState({ portals }) 96 | } 97 | 98 | removeReactPortal (reactPortal) { 99 | const { portals } = this.state 100 | let index 101 | const portalData = portals.find((obj, i) => { 102 | if (obj.Portal === reactPortal) { 103 | index = i 104 | return true 105 | } 106 | }) 107 | this.portalKeyPool.push(portalData.key) 108 | portals.splice(index, 1) 109 | this.vueRef && this.setState({ portals }) 110 | } 111 | 112 | // 这一步变的复杂是要判断插槽和组件的区别,如果是插槽则对wrapper传入原生事件和插槽相关的属性,如果是组件对wrapper不传入原生事件 113 | createVueComponentContainer () { 114 | let nativeProps = {} 115 | const options = this.props[optionsName] 116 | if (options.isSlots) { 117 | Object.keys(this.props).forEach((keyName) => { 118 | if (REACT_ALL_HANDLERS.has(keyName) && typeof this.props[keyName] === 'function') { 119 | nativeProps[keyName] = this.props[keyName] 120 | } 121 | }) 122 | if (options.vue.slotWrapAttrs) { 123 | nativeProps = { 124 | ...nativeProps, 125 | ...options.vue.slotWrapAttrs 126 | } 127 | } 128 | } else { 129 | if (options.vue.componentWrapAttrs) { 130 | nativeProps = { 131 | ...nativeProps, 132 | ...options.vue.componentWrapAttrs 133 | } 134 | } 135 | } 136 | 137 | return options.vue.componentWrapHOC(
, nativeProps) 138 | } 139 | 140 | [`${unsafePrefix}componentWillReceiveProps`] (nextProps) { 141 | let { component, [optionsName]: options, children, $slots, ...props } = nextProps 142 | component = filterVueComponent(component) 143 | if (this.currentVueComponent !== component) { 144 | this.updateVueComponent(component) 145 | } 146 | 147 | if (!this.vueInstance) return 148 | children = this.transferChildren(children) 149 | $slots = this.transferSlots($slots) 150 | if (children) { 151 | props.children = children 152 | } 153 | if ($slots) { 154 | props.$slots = $slots 155 | } 156 | 157 | // 更改vue组件的data 158 | const newProps = this.doSync(this.doVModel(props)) 159 | Object.keys(this.vueInstance.$data.reactProps).forEach((key) => { 160 | if (!(key in newProps) && key !== 'data-passed-props') { 161 | this.vueInstance.$set(this.vueInstance.$data.reactProps, key, undefined) 162 | } 163 | }) 164 | Object.keys(newProps).forEach((key) => { 165 | this.vueInstance.$set(this.vueInstance.$data.reactProps, key, newProps[key]) 166 | }) 167 | } 168 | 169 | componentWillUnmount () { 170 | // 删除portal 171 | if (this.vuePortal) { 172 | this.parentVueWrapperRef.removeVuePortal(this.vuePortal) 173 | return 174 | } 175 | this.vueInstance && this.vueInstance.$destroy() 176 | } 177 | 178 | // 处理v-model 179 | doVModel (props) { 180 | let { $model, ...newProps } = props 181 | if ($model === undefined) return props 182 | // 考虑到了自定义v-model 183 | let vueInstanceModelOption = { ...{ prop: 'value', event: 'input' }, ...getOptions(this.currentVueComponent).model } 184 | let modelProp = { [vueInstanceModelOption.prop]: $model.value } 185 | // 如果有绑定的事件和v-model事件相同,需合并两个绑定函数 186 | if (!newProps.on) newProps.on = {} 187 | if (newProps.on[vueInstanceModelOption.event]) { 188 | let oldFun = newProps.on[vueInstanceModelOption.event] 189 | newProps.on[vueInstanceModelOption.event] = function (...args) { 190 | oldFun.apply(this, args) 191 | $model.setter && $model.setter.apply(this, args) 192 | } 193 | } else { 194 | newProps.on = { ...newProps.on, ...{ [vueInstanceModelOption.event]: $model.setter || (() => {}) } } 195 | } 196 | return { ...newProps, ...modelProp } 197 | } 198 | 199 | // 处理sync 200 | doSync (props) { 201 | let { $sync, ...newProps } = props 202 | if ($sync === undefined) return props 203 | const syncValues = {} 204 | for (let i in $sync) { 205 | if (!$sync.hasOwnProperty(i) || !$sync[i] || $sync[i].value == null || $sync[i].setter == null) continue 206 | syncValues[i] = $sync[i].value 207 | let syncEvent = 'update:' + i 208 | // 如果有绑定的事件和sync事件相同,需合并两个绑定函数 209 | if (!newProps.on) newProps.on = {} 210 | if (newProps.on[syncEvent]) { 211 | let oldFun = newProps.on[syncEvent] 212 | newProps.on[syncEvent] = function (...args) { 213 | oldFun.apply(this, args) 214 | $sync[i].setter && $sync[i].setter.apply(this, args) 215 | } 216 | } else { 217 | newProps.on = { ...newProps.on, ...{ [syncEvent]: $sync[i].setter || (() => {}) } } 218 | } 219 | } 220 | return { ...newProps, ...syncValues } 221 | } 222 | transferSlots ($slots) { 223 | // 将$slots中的内容处理成函数,防止被vue的data进行observer处理 224 | if ($slots) { 225 | Object.keys($slots).forEach((key) => { 226 | const originSlot = $slots[key] 227 | $slots[key] = () => originSlot 228 | }) 229 | return $slots 230 | } 231 | } 232 | transferChildren (children) { 233 | // 将children中的内容处理成函数,防止被vue的data进行observer处理 234 | if (children) { 235 | const originChildren = children 236 | children = () => originChildren 237 | return children 238 | } 239 | } 240 | // 将通过react组件的ref回调方式接收组件的dom对象,并且在class的constructor中已经绑定了上下文 241 | createVueInstance (targetElement) { 242 | const VueContainerInstance = this 243 | let { component, 'data-passed-props': __passedProps = {}, [optionsName]: options, children, $slots, ...props } = this.props 244 | children = this.transferChildren(children) 245 | $slots = this.transferSlots($slots) 246 | if (children) { 247 | props.children = children 248 | } 249 | if ($slots) { 250 | props.$slots = $slots 251 | } 252 | 253 | component = filterVueComponent(component) 254 | // 过滤vue组件实例化后的$attrs 255 | let filterAttrs = (props) => { 256 | // 对mixin进行合并 257 | let mixinsPropsArray = [] 258 | let mixinsPropsJson = {} 259 | // 这一步我暂时没有想到更好的方案 260 | let componentOptions = getOptions(this.currentVueComponent) 261 | if (componentOptions.mixins) { 262 | componentOptions.mixins.forEach((v) => { 263 | if (v.props) { 264 | if (v.props instanceof Array) { 265 | mixinsPropsArray = [...v.props] 266 | } else { 267 | mixinsPropsJson = { ...v.props } 268 | } 269 | } 270 | }) 271 | } 272 | 273 | let attrs = Object.assign({}, props) 274 | let optionProps = componentOptions.props 275 | if (optionProps) { 276 | if (optionProps instanceof Array) { 277 | let tempArr = [...optionProps, ...mixinsPropsArray] 278 | tempArr.forEach((v) => { 279 | delete attrs[v] 280 | }) 281 | } else { 282 | let tempJson = { ...optionProps, ...mixinsPropsJson } 283 | for (let i in tempJson) { 284 | if (!tempJson.hasOwnProperty(i)) continue 285 | delete attrs[i] 286 | } 287 | } 288 | } 289 | return attrs 290 | } 291 | 292 | // 从作用域插槽中过滤具名插槽 293 | let filterNamedSlots = (scopedSlots, slots) => { 294 | if (!scopedSlots) return {} 295 | if (!slots) return scopedSlots 296 | for (let i in scopedSlots) { 297 | if (!scopedSlots.hasOwnProperty(i)) continue 298 | if (slots[i]) delete scopedSlots[i] 299 | } 300 | return scopedSlots 301 | } 302 | 303 | function setVueInstance(instance) { 304 | if (!this.vueInstance) { 305 | this.vueInstance = instance 306 | } 307 | } 308 | setVueInstance = setVueInstance.bind(this) 309 | // 将vue组件的inheritAttrs设置为false,以便组件可以顺利拿到任何类型的attrs 310 | // 这一步不确定是否多余,但是vue默认是true,导致属性如果是函数,又不在props中,会出警告,正常都需要在组件内部自己去设置false 311 | // component.inheritAttrs = false 312 | const vueOptionsData = { ...this.doSync(this.doVModel(props)), 'data-passed-props': __passedProps } 313 | const vueOptions = { 314 | ...vueRootInfo, 315 | data() { 316 | return { 317 | reactProps: vueOptionsData 318 | } 319 | }, 320 | created() { 321 | this.reactWrapperRef = VueContainerInstance 322 | setVueInstance(this) 323 | }, 324 | methods: { 325 | // 获取具名插槽 326 | // 将react组件传入的$slots属性逐个转成vue组件,但是透传的插槽不做处理 327 | getNamespaceSlots (createElement, $slots) { 328 | if (!this.getNamespaceSlots.__namespaceSlots) { 329 | this.getNamespaceSlots.__namespaceSlots = {} 330 | } 331 | let tempSlots = Object.assign({}, $slots) 332 | for (let i in tempSlots) { 333 | if (!tempSlots.hasOwnProperty(i) || !tempSlots[i]) continue 334 | if (typeof tempSlots[i] === 'function') tempSlots[i] = tempSlots[i]() 335 | tempSlots[i] = ((slot, slotName) => { 336 | if (slot.vueSlot) { 337 | return slot.vueSlot 338 | } 339 | // 使用单例模式进行缓存,类似getChildren 340 | let newSlot 341 | if (!this.getNamespaceSlots.__namespaceSlots[i]?.[0]?.child?.reactInstance) { 342 | newSlot = [createElement(applyReactInVue(() => slot, { ...options, isSlots: true, wrapInstance: VueContainerInstance }), { slot: slotName })] 343 | this.getNamespaceSlots.__namespaceSlots[i] = newSlot 344 | } else { 345 | newSlot = this.getNamespaceSlots.__namespaceSlots[i] 346 | this.$nextTick(() => { 347 | newSlot[0].child.reactInstance.setState({ children: slot }) 348 | }) 349 | } 350 | newSlot.reactSlot = slot 351 | return newSlot 352 | })(tempSlots[i], i) 353 | } 354 | return tempSlots 355 | }, 356 | // 获取作用域插槽 357 | // 将react组件传入的$scopedSlots属性逐个转成vue组件 358 | getScopedSlots (createElement, $scopedSlots) { 359 | if (!this.getScopedSlots.__scopeSlots) { 360 | this.getScopedSlots.__scopeSlots = {} 361 | } 362 | const tempScopedSlots = { ...$scopedSlots } 363 | for (let i in tempScopedSlots) { 364 | if (!tempScopedSlots.hasOwnProperty(i)) continue 365 | let reactFunction = tempScopedSlots[i] 366 | tempScopedSlots[i] = ((scopedSlot) => { 367 | return (...args) => { 368 | if (scopedSlot.vueFunction) { 369 | return scopedSlot.vueFunction.apply(this, args) 370 | } 371 | // 使用单例模式进行缓存,类似getChildren 372 | let newSlot 373 | if (!this.getScopedSlots.__scopeSlots[i]?.child?.reactInstance) { 374 | newSlot = createElement(applyReactInVue(() => scopedSlot.apply(this, args), { ...options, isSlots: true, wrapInstance: VueContainerInstance })) 375 | this.getScopedSlots.__scopeSlots[i] = newSlot 376 | } else { 377 | newSlot = this.getScopedSlots.__scopeSlots[i] 378 | // 触发通信层更新fiberNode 379 | this.$nextTick(() => { 380 | newSlot.child.reactInstance.setState({ children: scopedSlot.apply(this, args) }) 381 | }) 382 | } 383 | return newSlot 384 | } 385 | })(reactFunction) 386 | tempScopedSlots[i].reactFunction = reactFunction 387 | } 388 | return tempScopedSlots 389 | }, 390 | // 获取插槽整体数据 391 | // children是react jsx的插槽,需要使用applyReactInVue转换成vue的组件选项对象 392 | // 转化规则是单例原则,转换的vnode是用于react插槽的,vnode只是作为容器存在,恒久不变,除非chidren为空就则不返回vnode,容器将销毁 393 | // vnode容器恒久保持只有一个子元素,children更新时,直接对子元素浅更新,(浅更新其实可以省略),因为真正操作react fiberNode更新是reactInstance.setState 394 | // 在applyReactInVue中的通信层react实力会保存react插槽的children到state,获取通信层更定为vnode.child.reactInstance 395 | getChildren (createElement, children) { 396 | // 这里要做判断,否则没有普通插槽传入,vue组件又设置了slot,会报错 397 | if (children != null) { 398 | if (typeof children === 'function') children = children() 399 | if (children.vueSlot) { 400 | return children.vueSlot 401 | } 402 | let newSlot 403 | if (!this.getChildren.__vnode?.[0]?.child?.reactInstance) { 404 | newSlot = [createElement(applyReactInVue(() => children, { ...options, isSlots: true, wrapInstance: VueContainerInstance }))] 405 | this.getChildren.__vnode = newSlot 406 | } else { 407 | // 此步vnode的浅更新可以省略 408 | // Object.assign(this.getChildren.__vnode[0], createElement(applyReactInVue(() => children, {...options, isSlots: true}))) 409 | newSlot = this.getChildren.__vnode 410 | // 直接修改react的fiberNode,此过程vnode无感知,此方案只是临时 411 | this.$nextTick(() => { 412 | newSlot[0].child.reactInstance.setState({ children }) 413 | }) 414 | } 415 | newSlot.reactSlot = children 416 | return newSlot 417 | } 418 | } 419 | }, 420 | mounted () { 421 | // 在react包囊实例中,使用vueRef保存vue的目标组件实例 422 | VueContainerInstance.vueRef = this.$children[0] 423 | // 在vue的目标组件实例中,使用reactWrapperRef保存react包囊实例,vue组件可以通过这个属性来判断是否被包囊使用 424 | this.$children[0].reactWrapperRef = VueContainerInstance 425 | }, 426 | beforeDestroy () { 427 | // 垃圾回收 428 | VueContainerInstance.vueRef = null 429 | this.$children[0].reactWrapperRef = null 430 | }, 431 | render (createElement) { 432 | // 这里很重要,将不是属性的内容过滤掉,并单独抽取 433 | let { component, 434 | on, 435 | $slots, 436 | $scopedSlots, 437 | children, 438 | 'class': className = '', 439 | style = '', 440 | 'data-passed-props': { 441 | $slots: __passedPropsSlots, 442 | $scopedSlots: __passedPropsScopedSlots, 443 | children: __passedPropsChildren, 444 | on: __passedPropsOn, 445 | ...__passedPropsRest 446 | }, ...props } = this.$data.reactProps 447 | filterNamedSlots(__passedPropsScopedSlots, __passedPropsSlots) 448 | // 作用域插槽的处理 449 | const scopedSlots = this.getScopedSlots(createElement, { ...__passedPropsScopedSlots, ...$scopedSlots }) 450 | const lastChildren = this.getChildren(createElement, this.reactProps.children || __passedPropsChildren) 451 | // 获取插槽数据(包含了具名插槽) 452 | const namedSlots = this.getNamespaceSlots(createElement, { ...__passedPropsSlots, ...$slots }) 453 | if (lastChildren) namedSlots.default = lastChildren 454 | const lastSlots = [ 455 | (lastChildren || []), 456 | ...Object.keys(namedSlots).map((key) => { 457 | if (key === 'default') { 458 | return 459 | } 460 | return namedSlots[key] 461 | }) 462 | ] 463 | const lastOn = { ...__passedPropsOn, ...on } 464 | const nativeOn = {} 465 | 466 | // 解决原生事件 467 | Object.keys(props).forEach((keyName) => { 468 | if (REACT_ALL_HANDLERS.has(keyName) && typeof props[keyName] === 'function') { 469 | nativeOn[keyName.replace(/^on/, '').toLowerCase()] = props[keyName] 470 | delete props[keyName] 471 | } 472 | }) 473 | 474 | let lastProps = { 475 | ...__passedPropsRest, 476 | ...props, 477 | // 封装透传属性 478 | 'data-passed-props': { 479 | ...__passedPropsRest, 480 | ...props, 481 | on: lastOn, 482 | children: lastChildren, 483 | $slots: namedSlots, 484 | $scopedSlots: scopedSlots 485 | } 486 | } 487 | 488 | // 手动把props丛attrs中去除, 489 | // 这一步有点繁琐,但是又必须得处理 490 | const attrs = filterAttrs({ ...lastProps }) 491 | const {className: newClassName, classname: newClassName1, ...lastAttrs} = attrs 492 | return createElement( 493 | 'use_vue_wrapper', 494 | { 495 | props: lastProps, 496 | on: lastOn, 497 | nativeOn, 498 | attrs: lastAttrs, 499 | 'class': className || newClassName || newClassName1 || '', 500 | style, 501 | scopedSlots: { ...scopedSlots } 502 | }, 503 | lastSlots 504 | ) 505 | }, 506 | components: { 507 | 'use_vue_wrapper': component 508 | } 509 | } 510 | 511 | if (!targetElement) return 512 | 513 | // Vue.nextTick(() => { 514 | const targetId = '__vue_wrapper_container_' + (Math.random() + '').substr(2) 515 | targetElement.id = targetId 516 | // 获取react的fiber实例 517 | let vueWrapperRef = options.wrapInstance 518 | if (!vueWrapperRef) { 519 | const fiberNode = this._reactInternals || this._reactInternalFiber 520 | let parentInstance = fiberNode.return 521 | // 向上查找react包囊层 522 | while (parentInstance) { 523 | if (parentInstance.stateNode?.parentVueWrapperRef) { 524 | vueWrapperRef = parentInstance.stateNode.parentVueWrapperRef 525 | break 526 | } 527 | if (parentInstance.stateNode?.vueWrapperRef) { 528 | vueWrapperRef = parentInstance.stateNode.vueWrapperRef 529 | break 530 | } 531 | parentInstance = parentInstance.return 532 | } 533 | } else { 534 | vueWrapperRef = options.wrapInstance 535 | vueWrapperRef.reactWrapperRef = VueContainerInstance 536 | } 537 | 538 | // 如果存在包囊层,则激活portal 539 | if (vueWrapperRef && document.getElementById(targetId)) { 540 | // 存储包囊层引用 541 | this.parentVueWrapperRef = vueWrapperRef 542 | 543 | // 存储portal引用 544 | this.vuePortal = (createElement, key) => createElement(MountingPortal, {props: {mountTo: '#' + targetId, slim:true, targetSlim: true}, key: targetId}, [createElement(Object.assign(vueOptions, {router: this._router}))]) 545 | vueWrapperRef.pushVuePortal(this.vuePortal) 546 | return 547 | } 548 | 549 | // 创建vue实例 550 | this.vueInstance = new Vue({...vueOptions, el: targetElement}) 551 | // }) 552 | 553 | } 554 | 555 | updateVueComponent (nextComponent) { 556 | this.currentVueComponent = nextComponent 557 | if (!this.vueInstance) return 558 | 559 | // 使用$forceUpdate强制重新渲染vue实例,因为此方法只会重新渲染当前实例和插槽,不会重新渲染子组件,所以不会造成性能问题 560 | // $options.components包含了vue实例中所对应的组件序列, $option是只读,但是确实可以修改components属性,依靠此实现了动态组件替换 561 | if (nextComponent.__fromReactSlot) { 562 | // 如果是来自react的slot,就强行通过修改vue组件构造器的use_vue_wrapper的缓存 563 | Object.assign(this.vueInstance.$options.components.use_vue_wrapper._Ctor[0].options, nextComponent) 564 | } else { 565 | // 如果是标准的vue组件,则整个替换use_vue_wrapper为新的组件 566 | this.vueInstance.$options.components.use_vue_wrapper = nextComponent 567 | } 568 | this.vueInstance.$forceUpdate() 569 | } 570 | 571 | render () { 572 | return 573 | } 574 | } 575 | 576 | export default function applyVueInReact (component, options = {}) { 577 | if (!component) { 578 | console.warn('Component must be passed in applyVueInReact!') 579 | } 580 | 581 | // 兼容esModule 582 | if (component.__esModule && component.default) { 583 | component = component.default 584 | } 585 | 586 | // // 使用React.forwardRef之后,组件不再是函数组件,如果使用applyVueInReact处理插槽vue的插槽,需要直接调用返回对象的render方法 587 | return React.forwardRef((props, ref) => { 588 | return 589 | }) 590 | } 591 | -------------------------------------------------------------------------------- /src/applyVuex.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import vueRootInfo from './vueRootInfo' 3 | let vuexStore 4 | export function connectVuex ({ mapStateToProps = (state) => {}, mapGettersToProps = (getters) => {}, mapCommitToProps = (commit) => {}, mapDispatchToProps = (dispatch) => {} }) { 5 | return function (Component) { 6 | class VuexCom extends React.Component { 7 | constructor (props) { 8 | super(props) 9 | if (vueRootInfo.store) { 10 | vuexStore = vueRootInfo.store 11 | } 12 | if (!vuexStore || !vuexStore.state || !vuexStore.subscribe || !vuexStore.dispatch || !vuexStore.commit) { 13 | throw Error('[vuereact-combined warn]Error: incorrect store passed in, please check the function applyVuex\'s parameter must be vuex store') 14 | } 15 | this.state = {...mapStateToProps(vuexStore.state), ...mapGettersToProps(vuexStore.getters)} 16 | } 17 | componentDidMount () { 18 | // 订阅 19 | this.watch = vuexStore.watch(function() { 20 | return {...mapStateToProps(vuexStore.state), ...mapGettersToProps(vuexStore.getters)} 21 | }, (newVal) => { 22 | this.setState(newVal) 23 | }, { 24 | deep: true 25 | }) 26 | } 27 | componentWillUnmount () { 28 | // 停止订阅 29 | this.watch() 30 | } 31 | render () { 32 | return ( 33 | 34 | ) 35 | } 36 | } 37 | // 转发ref 38 | return React.forwardRef((props, ref) => ( 39 | 40 | )) 41 | } 42 | } 43 | 44 | export default function applyVuex (store) { 45 | vuexStore = store 46 | } 47 | -------------------------------------------------------------------------------- /src/cleanStyle.js: -------------------------------------------------------------------------------- 1 | const style = document.createElement('style') 2 | const styleValue = { 3 | position: 'static', 4 | display: 'inline', 5 | margin: 0, 6 | padding: 0, 7 | float: 'none', 8 | border: 0, 9 | 'line-height': 'normal', 10 | background: 'none', 11 | width: 'auto', 12 | height: 'auto' 13 | } 14 | const cssText = '[__use_react_component_wrap],[data-use-vue-component-wrap],[__use_react_slot_wrap]' + '{' + Object.keys(styleValue).map(function(v){return v + ':' + styleValue[v] + ';'}).join('') + '}' 15 | const head = document.getElementsByTagName('head')[0] 16 | style.type = 'text/css' 17 | try { 18 | style.appendChild(document.createTextNode(cssText)) 19 | } catch (e) { 20 | style.styleSheet.cssText = 'cssText' // IE 21 | } 22 | head && head.appendChild(style) 23 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import lazyVueInReact from './lazyVueInReact' 2 | import lazyReactInVue from './lazyReactInVue' 3 | import applyReactInVue from './applyReactInVue' 4 | import applyVueInReact, { VueContainer } from './applyVueInReact' 5 | import applyRedux from './applyRedux' 6 | import applyVuex, { connectVuex } from './applyVuex' 7 | import withVueRouter from './withVueRouter' 8 | import vueRootInfo from './vueRootInfo' 9 | import applyReactRouterInVue from './applyReactRouterInVue' 10 | import REACT_ALL_HANDLERS from './reactAllHandles' 11 | // import './cleanStyle' 12 | // 兼容旧的方法名(因为旧的方法名中的use与react hook有冲突) 13 | const useReactInVue = applyReactInVue 14 | const useVueInReact = applyVueInReact 15 | const useRedux = applyRedux 16 | const useVuex = applyVuex 17 | export { 18 | lazyVueInReact, 19 | lazyReactInVue, 20 | applyReactInVue, 21 | applyVueInReact, 22 | VueContainer, 23 | applyRedux, 24 | applyVuex, 25 | connectVuex, 26 | useReactInVue, 27 | useVueInReact, 28 | useRedux, 29 | useVuex, 30 | withVueRouter, 31 | vueRootInfo, 32 | applyReactRouterInVue, 33 | REACT_ALL_HANDLERS 34 | } 35 | -------------------------------------------------------------------------------- /src/lazyReactInVue.js: -------------------------------------------------------------------------------- 1 | import applyReactInVue from './applyReactInVue' 2 | export default function lazyReactInVue (asyncImport, useReactOptions) { 3 | return () => asyncImport().then((mod) => { 4 | return applyReactInVue(mod.default, useReactOptions) 5 | }) 6 | } 7 | -------------------------------------------------------------------------------- /src/lazyVueInReact.js: -------------------------------------------------------------------------------- 1 | import { lazy } from 'react' 2 | import applyVueInReact from './applyVueInReact' 3 | export default function lazyVueInReact (asyncImport, useVueOptions) { 4 | return lazy(() => asyncImport().then((mod) => { 5 | return { default: applyVueInReact(mod.default, useVueOptions) } 6 | })) 7 | } 8 | -------------------------------------------------------------------------------- /src/options.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const originOptions = { 4 | react: { 5 | componentWrap: 'div', 6 | slotWrap: 'div', 7 | componentWrapAttrs: { 8 | __use_react_component_wrap: '', 9 | style: { 10 | all: 'unset' 11 | } 12 | }, 13 | slotWrapAttrs: { 14 | __use_react_slot_wrap: '', 15 | style: { 16 | all: 'unset' 17 | } 18 | } 19 | }, 20 | vue: { 21 | // 组件wrapper 22 | componentWrapHOC: (VueComponentMountAt, nativeProps = []) => { 23 | // 传入portals 24 | return function ({ portals = [] } = {}) { 25 | return (
{VueComponentMountAt}{portals.map(({ Portal, key }) => )}
) 26 | } 27 | }, 28 | componentWrapAttrs: { 29 | 'data-use-vue-component-wrap': '', 30 | style: { 31 | all: 'unset', 32 | } 33 | }, 34 | slotWrapAttrs: { 35 | 'data-use-vue-slot-wrap': '', 36 | style: { 37 | all: 'unset' 38 | } 39 | } 40 | } 41 | } 42 | 43 | export function setOptions (newOptions = { 44 | react: {}, 45 | vue: {} 46 | }, options = originOptions, clone) { 47 | if (!newOptions.vue) { 48 | newOptions.vue = {} 49 | } 50 | if (!newOptions.react) { 51 | newOptions.react = {} 52 | } 53 | const params = [options, { 54 | ...newOptions, 55 | react: { 56 | ...options.react, 57 | ...newOptions.react, 58 | componentWrapAttrs: { 59 | ...options.react.componentWrapAttrs, 60 | ...newOptions.react.componentWrapAttrs 61 | }, 62 | slotWrapAttrs: { 63 | ...options.react.slotWrapAttrs, 64 | ...newOptions.react.slotWrapAttrs 65 | } 66 | }, 67 | vue: { 68 | ...options.vue, 69 | ...newOptions.vue, 70 | componentWrapAttrs: { 71 | ...options.vue.componentWrapAttrs, 72 | ...newOptions.vue.componentWrapAttrs 73 | }, 74 | slotWrapAttrs: { 75 | ...options.vue.slotWrapAttrs, 76 | ...newOptions.vue.slotWrapAttrs 77 | } 78 | } 79 | }] 80 | if (clone) { 81 | params.unshift({}) 82 | } 83 | 84 | return Object.assign.apply(this, params) 85 | } 86 | 87 | export default originOptions 88 | -------------------------------------------------------------------------------- /src/portal-vue.esm.js: -------------------------------------------------------------------------------- 1 | 2 | /*! 3 | * portal-vue © Thorsten Lünborg, 2019 4 | * 5 | * Version: 2.1.7 6 | * 7 | * LICENCE: MIT 8 | * 9 | * https://github.com/linusborg/portal-vue 10 | * 11 | */ 12 | 13 | import Vue from 'vue'; 14 | 15 | function _typeof(obj) { 16 | if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { 17 | _typeof = function (obj) { 18 | return typeof obj; 19 | }; 20 | } else { 21 | _typeof = function (obj) { 22 | return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; 23 | }; 24 | } 25 | 26 | return _typeof(obj); 27 | } 28 | 29 | function _toConsumableArray(arr) { 30 | return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); 31 | } 32 | 33 | function _arrayWithoutHoles(arr) { 34 | if (Array.isArray(arr)) { 35 | for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; 36 | 37 | return arr2; 38 | } 39 | } 40 | 41 | function _iterableToArray(iter) { 42 | if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); 43 | } 44 | 45 | function _nonIterableSpread() { 46 | throw new TypeError("Invalid attempt to spread non-iterable instance"); 47 | } 48 | 49 | var inBrowser = typeof window !== 'undefined'; 50 | function freeze(item) { 51 | if (Array.isArray(item) || _typeof(item) === 'object') { 52 | return Object.freeze(item); 53 | } 54 | 55 | return item; 56 | } 57 | function combinePassengers(transports) { 58 | var slotProps = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 59 | return transports.reduce(function (passengers, transport) { 60 | var temp = transport.passengers[0]; 61 | var newPassengers = typeof temp === 'function' ? temp(slotProps) : transport.passengers; 62 | return passengers.concat(newPassengers); 63 | }, []); 64 | } 65 | function stableSort(array, compareFn) { 66 | return array.map(function (v, idx) { 67 | return [idx, v]; 68 | }).sort(function (a, b) { 69 | return compareFn(a[1], b[1]) || a[0] - b[0]; 70 | }).map(function (c) { 71 | return c[1]; 72 | }); 73 | } 74 | function pick(obj, keys) { 75 | return keys.reduce(function (acc, key) { 76 | if (obj.hasOwnProperty(key)) { 77 | acc[key] = obj[key]; 78 | } 79 | 80 | return acc; 81 | }, {}); 82 | } 83 | 84 | var transports = {}; 85 | var targets = {}; 86 | var sources = {}; 87 | var Wormhole = Vue.extend({ 88 | data: function data() { 89 | return { 90 | transports: transports, 91 | targets: targets, 92 | sources: sources, 93 | trackInstances: inBrowser 94 | }; 95 | }, 96 | methods: { 97 | open: function open(transport) { 98 | if (!inBrowser) return; 99 | var to = transport.to, 100 | from = transport.from, 101 | passengers = transport.passengers, 102 | _transport$order = transport.order, 103 | order = _transport$order === void 0 ? Infinity : _transport$order; 104 | if (!to || !from || !passengers) return; 105 | var newTransport = { 106 | to: to, 107 | from: from, 108 | passengers: freeze(passengers), 109 | order: order 110 | }; 111 | var keys = Object.keys(this.transports); 112 | 113 | if (keys.indexOf(to) === -1) { 114 | Vue.set(this.transports, to, []); 115 | } 116 | 117 | var currentIndex = this.$_getTransportIndex(newTransport); // Copying the array here so that the PortalTarget change event will actually contain two distinct arrays 118 | 119 | var newTransports = this.transports[to].slice(0); 120 | 121 | if (currentIndex === -1) { 122 | newTransports.push(newTransport); 123 | } else { 124 | newTransports[currentIndex] = newTransport; 125 | } 126 | 127 | this.transports[to] = stableSort(newTransports, function (a, b) { 128 | return a.order - b.order; 129 | }); 130 | }, 131 | close: function close(transport) { 132 | var force = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; 133 | var to = transport.to, 134 | from = transport.from; 135 | if (!to || !from && force === false) return; 136 | 137 | if (!this.transports[to]) { 138 | return; 139 | } 140 | 141 | if (force) { 142 | this.transports[to] = []; 143 | } else { 144 | var index = this.$_getTransportIndex(transport); 145 | 146 | if (index >= 0) { 147 | // Copying the array here so that the PortalTarget change event will actually contain two distinct arrays 148 | var newTransports = this.transports[to].slice(0); 149 | newTransports.splice(index, 1); 150 | this.transports[to] = newTransports; 151 | } 152 | } 153 | }, 154 | registerTarget: function registerTarget(target, vm, force) { 155 | if (!inBrowser) return; 156 | 157 | if (this.trackInstances && !force && this.targets[target]) { 158 | console.warn("[portal-vue]: Target ".concat(target, " already exists")); 159 | } 160 | 161 | this.$set(this.targets, target, Object.freeze([vm])); 162 | }, 163 | unregisterTarget: function unregisterTarget(target) { 164 | this.$delete(this.targets, target); 165 | }, 166 | registerSource: function registerSource(source, vm, force) { 167 | if (!inBrowser) return; 168 | 169 | if (this.trackInstances && !force && this.sources[source]) { 170 | console.warn("[portal-vue]: source ".concat(source, " already exists")); 171 | } 172 | 173 | this.$set(this.sources, source, Object.freeze([vm])); 174 | }, 175 | unregisterSource: function unregisterSource(source) { 176 | this.$delete(this.sources, source); 177 | }, 178 | hasTarget: function hasTarget(to) { 179 | return !!(this.targets[to] && this.targets[to][0]); 180 | }, 181 | hasSource: function hasSource(to) { 182 | return !!(this.sources[to] && this.sources[to][0]); 183 | }, 184 | hasContentFor: function hasContentFor(to) { 185 | return !!this.transports[to] && !!this.transports[to].length; 186 | }, 187 | // Internal 188 | $_getTransportIndex: function $_getTransportIndex(_ref) { 189 | var to = _ref.to, 190 | from = _ref.from; 191 | 192 | for (var i in this.transports[to]) { 193 | if (this.transports[to][i].from === from) { 194 | return +i; 195 | } 196 | } 197 | 198 | return -1; 199 | } 200 | } 201 | }); 202 | var wormhole = new Wormhole(transports); 203 | 204 | var _id = 1; 205 | var Portal = Vue.extend({ 206 | name: 'portal', 207 | props: { 208 | disabled: { 209 | type: Boolean 210 | }, 211 | name: { 212 | type: String, 213 | default: function _default() { 214 | return String(_id++); 215 | } 216 | }, 217 | order: { 218 | type: Number, 219 | default: 0 220 | }, 221 | slim: { 222 | type: Boolean 223 | }, 224 | slotProps: { 225 | type: Object, 226 | default: function _default() { 227 | return {}; 228 | } 229 | }, 230 | tag: { 231 | type: String, 232 | default: 'DIV' 233 | }, 234 | to: { 235 | type: String, 236 | default: function _default() { 237 | return String(Math.round(Math.random() * 10000000)); 238 | } 239 | } 240 | }, 241 | created: function created() { 242 | var _this = this; 243 | 244 | this.$nextTick(function () { 245 | wormhole.registerSource(_this.name, _this); 246 | }); 247 | }, 248 | mounted: function mounted() { 249 | if (!this.disabled) { 250 | this.sendUpdate(); 251 | } 252 | }, 253 | updated: function updated() { 254 | if (this.disabled) { 255 | this.clear(); 256 | } else { 257 | this.sendUpdate(); 258 | } 259 | }, 260 | beforeDestroy: function beforeDestroy() { 261 | wormhole.unregisterSource(this.name); 262 | this.clear(); 263 | }, 264 | watch: { 265 | to: function to(newValue, oldValue) { 266 | oldValue && oldValue !== newValue && this.clear(oldValue); 267 | this.sendUpdate(); 268 | } 269 | }, 270 | methods: { 271 | clear: function clear(target) { 272 | var closer = { 273 | from: this.name, 274 | to: target || this.to 275 | }; 276 | wormhole.close(closer); 277 | }, 278 | normalizeSlots: function normalizeSlots() { 279 | return this.$scopedSlots.default ? [this.$scopedSlots.default] : this.$slots.default; 280 | }, 281 | normalizeOwnChildren: function normalizeOwnChildren(children) { 282 | return typeof children === 'function' ? children(this.slotProps) : children; 283 | }, 284 | sendUpdate: function sendUpdate() { 285 | var slotContent = this.normalizeSlots(); 286 | 287 | if (slotContent) { 288 | var transport = { 289 | from: this.name, 290 | to: this.to, 291 | passengers: _toConsumableArray(slotContent), 292 | order: this.order 293 | }; 294 | wormhole.open(transport); 295 | } else { 296 | this.clear(); 297 | } 298 | } 299 | }, 300 | render: function render(h) { 301 | var children = this.$slots.default || this.$scopedSlots.default || []; 302 | var Tag = this.tag; 303 | 304 | if (children && this.disabled) { 305 | return children.length <= 1 && this.slim ? this.normalizeOwnChildren(children)[0] : h(Tag, [this.normalizeOwnChildren(children)]); 306 | } else { 307 | return this.slim ? h() : h(Tag, { 308 | class: { 309 | 'v-portal': true 310 | }, 311 | style: { 312 | display: 'none' 313 | }, 314 | key: 'v-portal-placeholder' 315 | }); 316 | } 317 | } 318 | }); 319 | 320 | var PortalTarget = Vue.extend({ 321 | name: 'portalTarget', 322 | props: { 323 | multiple: { 324 | type: Boolean, 325 | default: false 326 | }, 327 | name: { 328 | type: String, 329 | required: true 330 | }, 331 | slim: { 332 | type: Boolean, 333 | default: false 334 | }, 335 | slotProps: { 336 | type: Object, 337 | default: function _default() { 338 | return {}; 339 | } 340 | }, 341 | tag: { 342 | type: String, 343 | default: 'div' 344 | }, 345 | transition: { 346 | type: [String, Object, Function] 347 | } 348 | }, 349 | data: function data() { 350 | return { 351 | transports: wormhole.transports, 352 | firstRender: true 353 | }; 354 | }, 355 | created: function created() { 356 | var _this = this; 357 | 358 | this.$nextTick(function () { 359 | wormhole.registerTarget(_this.name, _this); 360 | }); 361 | }, 362 | watch: { 363 | ownTransports: function ownTransports() { 364 | this.$emit('change', this.children().length > 0); 365 | }, 366 | name: function name(newVal, oldVal) { 367 | /** 368 | * TODO 369 | * This should warn as well ... 370 | */ 371 | wormhole.unregisterTarget(oldVal); 372 | wormhole.registerTarget(newVal, this); 373 | } 374 | }, 375 | mounted: function mounted() { 376 | var _this2 = this; 377 | 378 | if (this.transition) { 379 | this.$nextTick(function () { 380 | // only when we have a transition, because it causes a re-render 381 | _this2.firstRender = false; 382 | }); 383 | } 384 | }, 385 | beforeDestroy: function beforeDestroy() { 386 | wormhole.unregisterTarget(this.name); 387 | }, 388 | computed: { 389 | ownTransports: function ownTransports() { 390 | var transports = this.transports[this.name] || []; 391 | 392 | if (this.multiple) { 393 | return transports; 394 | } 395 | 396 | return transports.length === 0 ? [] : [transports[transports.length - 1]]; 397 | }, 398 | passengers: function passengers() { 399 | return combinePassengers(this.ownTransports, this.slotProps); 400 | } 401 | }, 402 | methods: { 403 | // can't be a computed prop because it has to "react" to $slot changes. 404 | children: function children() { 405 | return this.passengers.length !== 0 ? this.passengers : this.$scopedSlots.default ? this.$scopedSlots.default(this.slotProps) : this.$slots.default || []; 406 | }, 407 | // can't be a computed prop because it has to "react" to this.children(). 408 | noWrapper: function noWrapper() { 409 | var noWrapper = this.slim && !this.transition; 410 | 411 | if (noWrapper && this.children().length > 1) { 412 | console.warn('[portal-vue]: PortalTarget with `slim` option received more than one child element.'); 413 | } 414 | 415 | return noWrapper; 416 | } 417 | }, 418 | render: function render(h) { 419 | var noWrapper = this.noWrapper(); 420 | var children = this.children(); 421 | var Tag = this.transition || this.tag; 422 | return noWrapper ? children[0] : this.slim && !Tag ? h() : h(Tag, { 423 | props: { 424 | // if we have a transition component, pass the tag if it exists 425 | tag: this.transition && this.tag ? this.tag : undefined 426 | }, 427 | class: { 428 | 'vue-portal-target': true 429 | } 430 | }, children); 431 | } 432 | }); 433 | 434 | var _id$1 = 0; 435 | var portalProps = ['disabled', 'name', 'order', 'slim', 'slotProps', 'tag', 'to']; 436 | var targetProps = ['multiple', 'transition']; 437 | var MountingPortal = Vue.extend({ 438 | name: 'MountingPortal', 439 | inheritAttrs: false, 440 | props: { 441 | append: { 442 | type: [Boolean, String] 443 | }, 444 | bail: { 445 | type: Boolean 446 | }, 447 | mountTo: { 448 | type: String, 449 | required: true 450 | }, 451 | // Portal 452 | disabled: { 453 | type: Boolean 454 | }, 455 | // name for the portal 456 | name: { 457 | type: String, 458 | default: function _default() { 459 | return 'mounted_' + String(_id$1++); 460 | } 461 | }, 462 | order: { 463 | type: Number, 464 | default: 0 465 | }, 466 | slim: { 467 | type: Boolean 468 | }, 469 | slotProps: { 470 | type: Object, 471 | default: function _default() { 472 | return {}; 473 | } 474 | }, 475 | tag: { 476 | type: String, 477 | default: 'DIV' 478 | }, 479 | // name for the target 480 | to: { 481 | type: String, 482 | default: function _default() { 483 | return String(Math.round(Math.random() * 10000000)); 484 | } 485 | }, 486 | // Target 487 | multiple: { 488 | type: Boolean, 489 | default: false 490 | }, 491 | targetSlim: { 492 | type: Boolean 493 | }, 494 | targetSlotProps: { 495 | type: Object, 496 | default: function _default() { 497 | return {}; 498 | } 499 | }, 500 | targetTag: { 501 | type: String, 502 | default: 'div' 503 | }, 504 | transition: { 505 | type: [String, Object, Function] 506 | } 507 | }, 508 | created: function created() { 509 | if (typeof document === 'undefined') return; 510 | var el = document.querySelector(this.mountTo); 511 | 512 | if (!el) { 513 | console.error("[portal-vue]: Mount Point '".concat(this.mountTo, "' not found in document")); 514 | return; 515 | } 516 | 517 | var props = this.$props; // Target already exists 518 | 519 | if (wormhole.targets[props.name]) { 520 | if (props.bail) { 521 | console.warn("[portal-vue]: Target ".concat(props.name, " is already mounted.\n Aborting because 'bail: true' is set")); 522 | } else { 523 | this.portalTarget = wormhole.targets[props.name]; 524 | } 525 | 526 | return; 527 | } 528 | 529 | var append = props.append; 530 | 531 | if (append) { 532 | var type = typeof append === 'string' ? append : 'DIV'; 533 | var mountEl = document.createElement(type); 534 | el.appendChild(mountEl); 535 | el = mountEl; 536 | } // get props for target from $props 537 | // we have to rename a few of them 538 | 539 | 540 | var _props = pick(this.$props, targetProps); 541 | 542 | _props.slim = this.targetSlim; 543 | _props.tag = this.targetTag; 544 | _props.slotProps = this.targetSlotProps; 545 | _props.name = this.to; 546 | this.portalTarget = new PortalTarget({ 547 | el: el, 548 | parent: this.$parent || this, 549 | propsData: _props 550 | }); 551 | }, 552 | beforeDestroy: function beforeDestroy() { 553 | var target = this.portalTarget; 554 | 555 | if (this.append) { 556 | var el = target.$el; 557 | el.parentNode.removeChild(el); 558 | } 559 | 560 | target.$destroy(); 561 | }, 562 | render: function render(h) { 563 | if (!this.portalTarget) { 564 | console.warn("[portal-vue] Target wasn't mounted"); 565 | return h(); 566 | } // if there's no "manual" scoped slot, so we create a ourselves 567 | 568 | 569 | if (!this.$scopedSlots.manual) { 570 | var props = pick(this.$props, portalProps); 571 | return h(Portal, { 572 | props: props, 573 | attrs: this.$attrs, 574 | on: this.$listeners, 575 | scopedSlots: this.$scopedSlots 576 | }, this.$slots.default); 577 | } // else, we render the scoped slot 578 | 579 | 580 | var content = this.$scopedSlots.manual({ 581 | to: this.to 582 | }); // if user used