提交 6d6bdf84 编写于 作者: fxy060608's avatar fxy060608

feat(h5): createSelectorQuery支持 in方法

上级 f7344c53
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
"scripts": { "scripts": {
"lint": "eslint --fix --config package.json --ext .js --ext .vue --ignore-path .eslintignore build src", "lint": "eslint --fix --config package.json --ext .js --ext .vue --ignore-path .eslintignore build src",
"dev:h5": "npm run lint && cross-env NODE_ENV=production UNI_WATCH=true UNI_PLATFORM=h5 node build/build.js", "dev:h5": "npm run lint && cross-env NODE_ENV=production UNI_WATCH=true UNI_PLATFORM=h5 node build/build.js",
"build:h5": "npm run lint && cross-env NODE_ENV=production UNI_WATCH=false UNI_PLATFORM=h5 node build/build.js", "build:h5": "npm run lint && cross-env NODE_ENV=production UNI_WATCH=false UNI_PLATFORM=h5 node build/build.js",
"build:app-plus": "npm run lint && cross-env UNI_PLATFORM=app-plus rollup -c build/rollup.config.js", "build:app-plus": "npm run lint && cross-env UNI_PLATFORM=app-plus rollup -c build/rollup.config.js",
"build:mp-weixin": "npm run lint && cross-env UNI_PLATFORM=mp-weixin rollup -c build/rollup.config.js", "build:mp-weixin": "npm run lint && cross-env UNI_PLATFORM=mp-weixin rollup -c build/rollup.config.js",
"build:mp-baidu": "npm run lint && cross-env UNI_PLATFORM=mp-baidu rollup -c build/rollup.config.js", "build:mp-baidu": "npm run lint && cross-env UNI_PLATFORM=mp-baidu rollup -c build/rollup.config.js",
......
...@@ -277,33 +277,53 @@ function initMocks (vm) { ...@@ -277,33 +277,53 @@ function initMocks (vm) {
}); });
} }
function initHooks (mpOptions, hooks) { function initHooks (mpOptions, hooks, delay = false) {
hooks.forEach(hook => { hooks.forEach(hook => {
mpOptions[hook] = function (args) { mpOptions[hook] = function (args) {
this.$vm.__call_hook(hook, args); if (delay) {
setTimeout(() => this.$vm.__call_hook(hook, args));
} else {
this.$vm.__call_hook(hook, args);
}
}; };
}); });
} }
function getData (data) { function getData (vueOptions) {
let data = vueOptions.data || {};
const methods = vueOptions.methods || {};
if (typeof data === 'function') { if (typeof data === 'function') {
try { try {
return data() data = data();
} catch (e) { } catch (e) {
console.warn('根据 Vue 的 data 函数初始化小程序 data 失败,请尽量确保 data 函数中不访问 vm 对象,否则可能影响首次数据渲染速度。'); if (process.env.VUE_APP_DEBUG) {
console.warn('根据 Vue 的 data 函数初始化小程序 data 失败,请尽量确保 data 函数中不访问 vm 对象,否则可能影响首次数据渲染速度。', data);
}
} }
return {}
} }
return data || {}
return Object.assign(data, methods)
} }
const PROP_TYPES = [String, Number, Boolean, Object, Array, null]; const PROP_TYPES = [String, Number, Boolean, Object, Array, null];
function createObserver (name) {
return function observer (newVal, oldVal) {
if (this.$vm) {
this.$vm[name] = newVal; // 为了触发其他非 render watcher
}
}
}
function getProperties (props) { function getProperties (props) {
const properties = {}; const properties = {};
if (Array.isArray(props)) { // ['title'] if (Array.isArray(props)) { // ['title']
props.forEach(key => { props.forEach(key => {
properties[key] = null; properties[key] = {
type: null,
observer: createObserver(key)
};
}); });
} else if (isPlainObject(props)) { // {title:{type:String,default:''},content:String} } else if (isPlainObject(props)) { // {title:{type:String,default:''},content:String}
Object.keys(props).forEach(key => { Object.keys(props).forEach(key => {
...@@ -315,10 +335,14 @@ function getProperties (props) { ...@@ -315,10 +335,14 @@ function getProperties (props) {
} }
properties[key] = { properties[key] = {
type: PROP_TYPES.includes(opts.type) ? opts.type : null, type: PROP_TYPES.includes(opts.type) ? opts.type : null,
value value,
observer: createObserver(key)
}; };
} else { // content:String } else { // content:String
properties[key] = PROP_TYPES.includes(opts) ? opts : null; properties[key] = {
type: PROP_TYPES.includes(opts) ? opts : null,
observer: createObserver(key)
};
} }
}); });
} }
...@@ -331,6 +355,7 @@ function wrapper$1 (event) { ...@@ -331,6 +355,7 @@ function wrapper$1 (event) {
event.target = event.target || {}; event.target = event.target || {};
event.detail = event.detail || {}; event.detail = event.detail || {};
// TODO 又得兼容 mpvue 的 mp 对象 // TODO 又得兼容 mpvue 的 mp 对象
event.mp = event; event.mp = event;
event.target = Object.assign({}, event.target, event.detail); event.target = Object.assign({}, event.target, event.detail);
...@@ -379,6 +404,9 @@ function handleEvent (event) { ...@@ -379,6 +404,9 @@ function handleEvent (event) {
if (eventsArray && eventType === type) { if (eventsArray && eventType === type) {
eventsArray.forEach(eventArray => { eventsArray.forEach(eventArray => {
const handler = this.$vm[eventArray[0]]; const handler = this.$vm[eventArray[0]];
if (!isFn(handler)) {
throw new Error(` _vm.${eventArray[0]} is not a function`)
}
if (isOnce) { if (isOnce) {
if (handler.once) { if (handler.once) {
return return
...@@ -400,12 +428,12 @@ function initRefs (vm) { ...@@ -400,12 +428,12 @@ function initRefs (vm) {
Object.defineProperty(vm, '$refs', { Object.defineProperty(vm, '$refs', {
get () { get () {
const $refs = Object.create(null); const $refs = Object.create(null);
const components = mpInstance.selectAllComponents('.__ref__'); const components = mpInstance.selectAllComponents('.vue-ref');
components.forEach(component => { components.forEach(component => {
const ref = component.dataset.ref; const ref = component.dataset.ref;
$refs[ref] = component.$vm; $refs[ref] = component.$vm;
}); });
const forComponents = mpInstance.selectAllComponents('.__ref-in-for__'); const forComponents = mpInstance.selectAllComponents('.vue-ref-in-for');
forComponents.forEach(component => { forComponents.forEach(component => {
const ref = component.dataset.ref; const ref = component.dataset.ref;
if (!$refs[ref]) { if (!$refs[ref]) {
...@@ -416,6 +444,20 @@ function initRefs (vm) { ...@@ -416,6 +444,20 @@ function initRefs (vm) {
return $refs return $refs
} }
}); });
}
function initChildren (vm) {
const mpInstance = vm.$mp[vm.mpType];
Object.defineProperty(vm, '$children', {
get () {
const $children = [];
const components = mpInstance.selectAllComponents('.vue-com');
components.forEach(component => {
$children.push(component.$vm);
});
return $children
}
});
} }
const hooks = [ const hooks = [
...@@ -427,20 +469,41 @@ const hooks = [ ...@@ -427,20 +469,41 @@ const hooks = [
function createApp (vueOptions) { function createApp (vueOptions) {
vueOptions = vueOptions.default || vueOptions; vueOptions = vueOptions.default || vueOptions;
// 外部初始化时 Vue 还未初始化,放到 createApp 内部初始化 mixin
Vue.mixin({
beforeCreate () {
if (!this.$options.mpType) {
return
}
this.mpType = this.$options.mpType;
this.$mp = {
data: {},
[this.mpType]: this.$options.mpInstance
};
delete this.$options.mpType;
delete this.$options.mpInstance;
if (this.mpType !== 'app') {
initRefs(this);
initMocks(this);
initChildren(this);
}
}
});
const appOptions = { const appOptions = {
onLaunch (args) { onLaunch (args) {
this.$vm = new Vue(vueOptions); this.$vm = new Vue(Object.assign(vueOptions, {
this.$vm.mpType = 'app'; mpType: 'app',
this.$vm.$mp = { mpInstance: this
app: this }));
};
this.$vm.$mount(); this.$vm.$mount();
this.$vm.__call_hook('onLaunch', args); setTimeout(() => this.$vm.__call_hook('onLaunch', args));
} }
}; };
initHooks(appOptions, hooks); initHooks(appOptions, hooks, true); // 延迟执行,因为 App 的注册在 main.js 之前,可能导致生命周期内 Vue 原型上开发者注册的属性无法访问
App(appOptions); App(appOptions);
...@@ -466,28 +529,27 @@ const hooks$1 = [ ...@@ -466,28 +529,27 @@ const hooks$1 = [
function createPage (vueOptions) { function createPage (vueOptions) {
vueOptions = vueOptions.default || vueOptions; vueOptions = vueOptions.default || vueOptions;
const pageOptions = { const pageOptions = {
data: getData(vueOptions.data), data: getData(vueOptions),
onLoad (args) { onLoad (args) {
this.$vm = new Vue(vueOptions);
this.$vm.mpType = 'page';
this.$vm.$mp = {
data: {},
page: this
};
initRefs(this.$vm); this.$vm = new Vue(Object.assign(vueOptions, {
initMocks(this.$vm); mpType: 'page',
mpInstance: this
}));
this.$vm.$mount(); this.$vm.$mount();
this.$vm.__call_hook('onLoad', args); this.$vm.__call_hook('onLoad', args);
}, },
onReady () { onReady () {
this.$vm._isMounted = true; this.$vm._isMounted = true;
this.$vm.__call_hook('mounted');
this.$vm.__call_hook('onReady'); this.$vm.__call_hook('onReady');
}, },
onUnload () { onUnload () {
this.$vm.__call_hook('onUnload'); this.$vm.__call_hook('onUnload');
this.$vm.$destroy(); {
this.$vm.$destroy();
}
}, },
__e: handleEvent, __e: handleEvent,
__l: handleLink __l: handleLink
...@@ -498,6 +560,23 @@ function createPage (vueOptions) { ...@@ -498,6 +560,23 @@ function createPage (vueOptions) {
return Page(pageOptions) return Page(pageOptions)
} }
function initVueComponent (mpInstace, VueComponent) {
if (mpInstace.$vm) {
return
}
const options = {
mpType: 'component',
mpInstance: mpInstace,
propsData: mpInstace.properties
};
// 初始化 vue 实例
mpInstace.$vm = new VueComponent(options);
// 初始化渲染数据
mpInstace.$vm.$mount();
}
function createComponent (vueOptions) { function createComponent (vueOptions) {
vueOptions = vueOptions.default || vueOptions; vueOptions = vueOptions.default || vueOptions;
...@@ -510,50 +589,39 @@ function createComponent (vueOptions) { ...@@ -510,50 +589,39 @@ function createComponent (vueOptions) {
multipleSlots: true, multipleSlots: true,
addGlobalClass: true addGlobalClass: true
}, },
data: getData(vueOptions.data), data: getData(vueOptions),
properties, properties,
attached () { lifetimes: {
// props的处理,一个是直接 与 mp 的 properties 对接,另一个是要做成 reactive,且排除掉 render watch attached () {
const options = { initVueComponent(this, VueComponent);
propsData: this.properties, },
$component: this ready () {
}; initVueComponent(this, VueComponent); // 目前发现部分情况小程序 attached 不触发
// 初始化 vue 实例
this.$vm = new VueComponent(options);
this.$vm.mpType = 'component';
this.$vm.$mp = {
data: {},
component: this
};
initRefs(this.$vm); {
initMocks(this.$vm); this.triggerEvent('__l', this.$vm); // TODO 百度仅能传递 json 对象
}
// 初始化渲染数据 const eventId = this.dataset.eventId;
this.$vm.$mount(); if (eventId) {
}, const listeners = this.$vm.$parent.$mp.listeners;
ready () { if (listeners) {
this.triggerEvent('__l', this.$vm); const listenerOpts = listeners[eventId];
Object.keys(listenerOpts).forEach(eventType => {
const eventId = this.dataset.eventId; listenerOpts[eventType].forEach(handler => {
if (eventId) { this.$vm[handler.once ? '$once' : '$on'](eventType, handler);
const listeners = this.$vm.$parent.$mp.listeners; });
if (listeners) {
const listenerOpts = listeners[eventId];
Object.keys(listenerOpts).forEach(eventType => {
listenerOpts[eventType].forEach(handler => {
this.$vm[handler.once ? '$once' : '$on'](eventType, handler);
}); });
}); }
} }
}
this.$vm._isMounted = true; this.$vm._isMounted = true;
this.$vm.__call_hook('mounted'); this.$vm.__call_hook('mounted');
this.$vm.__call_hook('onReady'); this.$vm.__call_hook('onReady');
}, },
detached () { detached () {
this.$vm.$destroy(); this.$vm.$destroy();
}
}, },
pageLifetimes: { pageLifetimes: {
show (args) { show (args) {
......
{ {
"name": "@dcloudio/uni-app-plus", "name": "@dcloudio/uni-app-plus",
"version": "0.0.2", "version": "0.0.201",
"description": "uni-app app-plus", "description": "uni-app app-plus",
"main": "dist/index.js", "main": "dist/index.js",
"scripts": { "scripts": {
......
...@@ -404,7 +404,7 @@ function initHooks (mpOptions, hooks, delay = false) { ...@@ -404,7 +404,7 @@ function initHooks (mpOptions, hooks, delay = false) {
}); });
} }
function getData (vueOptions) { function getData (vueOptions) {
let data = vueOptions.data || {}; let data = vueOptions.data || {};
const methods = vueOptions.methods || {}; const methods = vueOptions.methods || {};
...@@ -412,7 +412,9 @@ function getData (vueOptions) { ...@@ -412,7 +412,9 @@ function getData (vueOptions) {
try { try {
data = data(); data = data();
} catch (e) { } catch (e) {
console.warn('根据 Vue 的 data 函数初始化小程序 data 失败,请尽量确保 data 函数中不访问 vm 对象,否则可能影响首次数据渲染速度。', data); if (process.env.VUE_APP_DEBUG) {
console.warn('根据 Vue 的 data 函数初始化小程序 data 失败,请尽量确保 data 函数中不访问 vm 对象,否则可能影响首次数据渲染速度。', data);
}
} }
} }
...@@ -677,7 +679,8 @@ function createPage (vueOptions) { ...@@ -677,7 +679,8 @@ function createPage (vueOptions) {
this.$vm.__call_hook('onLoad', args); this.$vm.__call_hook('onLoad', args);
}, },
onReady () { onReady () {
this.$vm._isMounted = true; this.$vm._isMounted = true;
this.$vm.__call_hook('mounted');
this.$vm.__call_hook('onReady'); this.$vm.__call_hook('onReady');
}, },
onUnload () { onUnload () {
......
{ {
"name": "@dcloudio/uni-mp-baidu", "name": "@dcloudio/uni-mp-baidu",
"version": "0.0.804", "version": "0.0.806",
"description": "uni-app mp-baidu", "description": "uni-app mp-baidu",
"main": "dist/index.js", "main": "dist/index.js",
"scripts": { "scripts": {
......
...@@ -449,7 +449,7 @@ function initHooks (mpOptions, hooks, delay = false) { ...@@ -449,7 +449,7 @@ function initHooks (mpOptions, hooks, delay = false) {
}); });
} }
function getData (vueOptions) { function getData (vueOptions) {
let data = vueOptions.data || {}; let data = vueOptions.data || {};
const methods = vueOptions.methods || {}; const methods = vueOptions.methods || {};
...@@ -457,7 +457,9 @@ function getData (vueOptions) { ...@@ -457,7 +457,9 @@ function getData (vueOptions) {
try { try {
data = data(); data = data();
} catch (e) { } catch (e) {
console.warn('根据 Vue 的 data 函数初始化小程序 data 失败,请尽量确保 data 函数中不访问 vm 对象,否则可能影响首次数据渲染速度。', data); if (process.env.VUE_APP_DEBUG) {
console.warn('根据 Vue 的 data 函数初始化小程序 data 失败,请尽量确保 data 函数中不访问 vm 对象,否则可能影响首次数据渲染速度。', data);
}
} }
} }
...@@ -699,7 +701,8 @@ function createPage (vueOptions) { ...@@ -699,7 +701,8 @@ function createPage (vueOptions) {
this.$vm.__call_hook('onLoad', args); this.$vm.__call_hook('onLoad', args);
}, },
onReady () { onReady () {
this.$vm._isMounted = true; this.$vm._isMounted = true;
this.$vm.__call_hook('mounted');
this.$vm.__call_hook('onReady'); this.$vm.__call_hook('onReady');
}, },
onUnload () { onUnload () {
......
{ {
"name": "@dcloudio/uni-mp-toutiao", "name": "@dcloudio/uni-mp-toutiao",
"version": "0.0.301", "version": "0.0.303",
"description": "uni-app mp-toutiao", "description": "uni-app mp-toutiao",
"main": "dist/index.js", "main": "dist/index.js",
"scripts": { "scripts": {
......
...@@ -291,7 +291,7 @@ function initHooks (mpOptions, hooks, delay = false) { ...@@ -291,7 +291,7 @@ function initHooks (mpOptions, hooks, delay = false) {
}); });
} }
function getData (vueOptions) { function getData (vueOptions) {
let data = vueOptions.data || {}; let data = vueOptions.data || {};
const methods = vueOptions.methods || {}; const methods = vueOptions.methods || {};
...@@ -299,7 +299,9 @@ function getData (vueOptions) { ...@@ -299,7 +299,9 @@ function getData (vueOptions) {
try { try {
data = data(); data = data();
} catch (e) { } catch (e) {
console.warn('根据 Vue 的 data 函数初始化小程序 data 失败,请尽量确保 data 函数中不访问 vm 对象,否则可能影响首次数据渲染速度。', data); if (process.env.VUE_APP_DEBUG) {
console.warn('根据 Vue 的 data 函数初始化小程序 data 失败,请尽量确保 data 函数中不访问 vm 对象,否则可能影响首次数据渲染速度。', data);
}
} }
} }
...@@ -541,7 +543,8 @@ function createPage (vueOptions) { ...@@ -541,7 +543,8 @@ function createPage (vueOptions) {
this.$vm.__call_hook('onLoad', args); this.$vm.__call_hook('onLoad', args);
}, },
onReady () { onReady () {
this.$vm._isMounted = true; this.$vm._isMounted = true;
this.$vm.__call_hook('mounted');
this.$vm.__call_hook('onReady'); this.$vm.__call_hook('onReady');
}, },
onUnload () { onUnload () {
......
{ {
"name": "@dcloudio/uni-mp-weixin", "name": "@dcloudio/uni-mp-weixin",
"version": "0.0.905", "version": "0.0.907",
"description": "uni-app mp-weixin", "description": "uni-app mp-weixin",
"main": "dist/index.js", "main": "dist/index.js",
"scripts": { "scripts": {
......
...@@ -42,7 +42,8 @@ export function createPage (vueOptions) { ...@@ -42,7 +42,8 @@ export function createPage (vueOptions) {
this.$vm.__call_hook('onLoad', args) this.$vm.__call_hook('onLoad', args)
}, },
onReady () { onReady () {
this.$vm._isMounted = true this.$vm._isMounted = true
this.$vm.__call_hook('mounted')
this.$vm.__call_hook('onReady') this.$vm.__call_hook('onReady')
}, },
onUnload () { onUnload () {
......
...@@ -28,7 +28,7 @@ export function initHooks (mpOptions, hooks, delay = false) { ...@@ -28,7 +28,7 @@ export function initHooks (mpOptions, hooks, delay = false) {
}) })
} }
export function getData (vueOptions) { export function getData (vueOptions) {
let data = vueOptions.data || {} let data = vueOptions.data || {}
const methods = vueOptions.methods || {} const methods = vueOptions.methods || {}
...@@ -36,7 +36,9 @@ export function getData (vueOptions) { ...@@ -36,7 +36,9 @@ export function getData (vueOptions) {
try { try {
data = data() data = data()
} catch (e) { } catch (e) {
console.warn('根据 Vue 的 data 函数初始化小程序 data 失败,请尽量确保 data 函数中不访问 vm 对象,否则可能影响首次数据渲染速度。', data) if (process.env.VUE_APP_DEBUG) {
console.warn('根据 Vue 的 data 函数初始化小程序 data 失败,请尽量确保 data 函数中不访问 vm 对象,否则可能影响首次数据渲染速度。', data)
}
} }
} }
......
...@@ -84,7 +84,7 @@ class SelectorQuery { ...@@ -84,7 +84,7 @@ class SelectorQuery {
} }
['in'] (component) { ['in'] (component) {
console.error('Unsupported method:SelectorQuery.in') this._component = component
return this return this
} }
......
...@@ -74,7 +74,8 @@ function getNodeInfo (el, fields) { ...@@ -74,7 +74,8 @@ function getNodeInfo (el, fields) {
} }
function getNodesInfo (pageVm, component, selector, single, fields) { function getNodesInfo (pageVm, component, selector, single, fields) {
const $el = pageVm.$el /* eslint-disable no-mixed-operators */
const $el = component && component.$el || pageVm.$el
if (single) { if (single) {
const node = $el && ($el.matches(selector) ? $el : $el.querySelector(selector)) const node = $el && ($el.matches(selector) ? $el : $el.querySelector(selector))
if (node) { if (node) {
...@@ -129,4 +130,4 @@ export default function requestComponentInfo ({ ...@@ -129,4 +130,4 @@ export default function requestComponentInfo ({
reqId, reqId,
res: result res: result
}, pageVm.$page.id) }, pageVm.$page.id)
} }
...@@ -1784,10 +1784,14 @@ caniuse-api@^3.0.0: ...@@ -1784,10 +1784,14 @@ caniuse-api@^3.0.0:
lodash.memoize "^4.1.2" lodash.memoize "^4.1.2"
lodash.uniq "^4.5.0" lodash.uniq "^4.5.0"
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000939, caniuse-lite@^1.0.30000940: caniuse-lite@^1.0.0:
version "1.0.30000940" version "1.0.30000940"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000940.tgz#19f2b1497fbfa5b96b615963097c3757f27989ce" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000940.tgz#19f2b1497fbfa5b96b615963097c3757f27989ce"
caniuse-lite@^1.0.30000939, caniuse-lite@^1.0.30000940:
version "1.0.30000948"
resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000948.tgz#793ed7c28fe664856beb92b43fc013fc22b81633"
case-sensitive-paths-webpack-plugin@^2.2.0: case-sensitive-paths-webpack-plugin@^2.2.0:
version "2.2.0" version "2.2.0"
resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.2.0.tgz#3371ef6365ef9c25fa4b81c16ace0e9c7dc58c3e" resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.2.0.tgz#3371ef6365ef9c25fa4b81c16ace0e9c7dc58c3e"
...@@ -2698,8 +2702,8 @@ ejs@^2.6.1: ...@@ -2698,8 +2702,8 @@ ejs@^2.6.1:
resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.6.1.tgz#498ec0d495655abc6f23cd61868d926464071aa0" resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.6.1.tgz#498ec0d495655abc6f23cd61868d926464071aa0"
electron-to-chromium@^1.3.113: electron-to-chromium@^1.3.113:
version "1.3.113" version "1.3.116"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.113.tgz#b1ccf619df7295aea17bc6951dc689632629e4a9" resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.116.tgz#1dbfee6a592a0c14ade77dbdfe54fef86387d702"
elliptic@^6.0.0: elliptic@^6.0.0:
version "6.4.1" version "6.4.1"
...@@ -4953,8 +4957,8 @@ node-pre-gyp@^0.10.0: ...@@ -4953,8 +4957,8 @@ node-pre-gyp@^0.10.0:
tar "^4" tar "^4"
node-releases@^1.1.8: node-releases@^1.1.8:
version "1.1.9" version "1.1.10"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.9.tgz#70d0985ec4bf7de9f08fc481f5dae111889ca482" resolved "https://registry.npmjs.org/node-releases/-/node-releases-1.1.10.tgz#5dbeb6bc7f4e9c85b899e2e7adcc0635c9b2adf7"
dependencies: dependencies:
semver "^5.3.0" semver "^5.3.0"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册