You're Invited:Meet the Socket Team at BlackHat and DEF CON in Las Vegas, Aug 4-6.RSVP
Socket
Book a DemoInstallSign in
Socket

vue-hot-reload-api

Package Overview
Dependencies
Maintainers
1
Versions
33
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

vue-hot-reload-api - npm Package Compare versions

Comparing version

to
2.0.0

LICENSE

266

index.js
var Vue // late bind
var map = Object.create(null)
var shimmed = false
var map = window.__VUE_HOT_MAP__ = Object.create(null)
var installed = false
var isBrowserify = false
/**
* Determine compatibility and apply patch.
*
* @param {Function} vue
* @param {Boolean} browserify
*/
exports.install = function (vue, browserify) {
if (shimmed) return
shimmed = true
if (installed) return
installed = true

@@ -20,81 +13,13 @@ Vue = vue

exports.compatible = !!Vue.internalDirectives
exports.compatible = Number(Vue.version.split('.')[0]) >= 2
if (!exports.compatible) {
console.warn(
'[HMR] vue-loader hot reload is only compatible with ' +
'Vue.js 1.0.0+.'
'[HMR] You are using a version of vue-hot-reload-api that is ' +
'only compatible with Vue.js core ^2.0.0.'
)
return
}
// patch view directive
patchView(Vue.internalDirectives.component)
console.log('[HMR] Vue component hot reload shim applied.')
// shim router-view if present
var routerView = Vue.elementDirective('router-view')
if (routerView) {
patchView(routerView)
console.log('[HMR] vue-router <router-view> hot reload shim applied.')
}
}
/**
* Shim the view directive (component or router-view).
*
* @param {Object} View
*/
function patchView (View) {
var unbuild = View.unbuild
View.unbuild = function (defer) {
if (!this.hotUpdating) {
var prevComponent = this.childVM && this.childVM.constructor
removeView(prevComponent, this)
// defer = true means we are transitioning to a new
// Component. Register this new component to the list.
if (defer) {
addView(this.Component, this)
}
}
// call original
return unbuild.call(this, defer)
}
}
/**
* Add a component view to a Component's hot list
*
* @param {Function} Component
* @param {Directive} view - view directive instance
*/
function addView (Component, view) {
var id = Component && Component.options.hotID
if (id) {
if (!map[id]) {
map[id] = {
Component: Component,
views: [],
instances: []
}
}
map[id].views.push(view)
}
}
/**
* Remove a component view from a Component's hot list
*
* @param {Function} Component
* @param {Directive} view - view directive instance
*/
function removeView (Component, view) {
var id = Component && Component.options.hotID
if (id) {
map[id].views.$remove(view)
}
}
/**
* Create a record for a hot module, which keeps track of its construcotr,

@@ -114,4 +39,3 @@ * instnaces and views (component directives or router-views).

map[id] = {
Component: null,
views: [],
Ctor: null,
instances: []

@@ -130,7 +54,6 @@ }

function makeOptionsHot (id, options) {
options.hotID = id
injectHook(options, 'created', function () {
injectHook(options, 'init', function () {
var record = map[id]
if (!record.Component) {
record.Component = this.constructor
if (!record.Ctor) {
record.Ctor = this.constructor
}

@@ -140,3 +63,4 @@ record.instances.push(this)

injectHook(options, 'beforeDestroy', function () {
map[id].instances.$remove(this)
var instances = map[id].instances
instances.splice(instances.indexOf(this), 1)
})

@@ -163,141 +87,37 @@ }

/**
* Update a hot component.
*
* @param {String} id
* @param {Object|null} newOptions
* @param {String|null} newTemplate
*/
exports.update = function (id, newOptions, newTemplate) {
var record = map[id]
// force full-reload if an instance of the component is active but is not
// managed by a view
if (!record || (record.instances.length && !record.views.length)) {
console.log('[HMR] Root or manually-mounted instance modified. Full reload may be required.')
if (!isBrowserify) {
window.location.reload()
} else {
// browserify-hmr somehow sends incomplete bundle if we reload here
return
function tryWrap (fn) {
return function (id, arg) {
try { fn(id, arg) } catch (e) {
console.error(e)
console.warn('Something went wrong during Vue component hot-reload. Full reload required.')
}
}
if (!isBrowserify) {
// browserify-hmr already logs this
console.log('[HMR] Updating component: ' + format(id))
}
var Component = record.Component
// update constructor
if (newOptions) {
// in case the user exports a constructor
Component = record.Component = typeof newOptions === 'function'
? newOptions
: Vue.extend(newOptions)
makeOptionsHot(id, Component.options)
}
if (newTemplate) {
Component.options.template = newTemplate
}
// handle recursive lookup
if (Component.options.name) {
Component.options.components[Component.options.name] = Component
}
// reset constructor cached linker
Component.linker = null
// reload all views
record.views.forEach(function (view) {
updateView(view, Component)
})
// flush devtools
if (window.__VUE_DEVTOOLS_GLOBAL_HOOK__) {
window.__VUE_DEVTOOLS_GLOBAL_HOOK__.emit('flush')
}
}
/**
* Update a component view instance
*
* @param {Directive} view
* @param {Function} Component
*/
exports.rerender = tryWrap(function (id, fns) {
var record = map[id]
record.Ctor.options.render = fns.render
record.Ctor.options.staticRenderFns = fns.staticRenderFns
record.instances.slice().forEach(function (instance) {
instance.$options.render = fns.render
instance.$options.staticRenderFns = fns.staticRenderFns
instance._staticTrees = null // reset static trees
instance.$forceUpdate()
})
})
function updateView (view, Component) {
if (!view._bound) {
return
}
view.Component = Component
view.hotUpdating = true
// disable transitions
view.vm._isCompiled = false
// save state
var state = extractState(view.childVM)
// remount, make sure to disable keep-alive
var keepAlive = view.keepAlive
view.keepAlive = false
view.mountComponent()
view.keepAlive = keepAlive
// restore state
restoreState(view.childVM, state, true)
// re-eanble transitions
view.vm._isCompiled = true
view.hotUpdating = false
}
/**
* Extract state from a Vue instance.
*
* @param {Vue} vm
* @return {Object}
*/
function extractState (vm) {
return {
cid: vm.constructor.cid,
data: vm.$data,
children: vm.$children.map(extractState)
}
}
/**
* Restore state to a reloaded Vue instance.
*
* @param {Vue} vm
* @param {Object} state
*/
function restoreState (vm, state, isRoot) {
var oldAsyncConfig
if (isRoot) {
// set Vue into sync mode during state rehydration
oldAsyncConfig = Vue.config.async
Vue.config.async = false
}
// actual restore
if (isRoot || !vm._props) {
vm.$data = state.data
} else {
Object.keys(state.data).forEach(function (key) {
if (!vm._props[key]) {
// for non-root, only restore non-props fields
vm.$data[key] = state.data[key]
}
})
}
// verify child consistency
var hasSameChildren = vm.$children.every(function (c, i) {
return state.children[i] && state.children[i].cid === c.constructor.cid
exports.reload = tryWrap(function (id, options) {
makeOptionsHot(id, options)
var record = map[id]
var newCtor = Vue.extend(options)
record.Ctor.options = newCtor.options
record.Ctor.cid = newCtor.cid
newCtor.release()
record.instances.slice().forEach(function (instance) {
if (instance.$parent) {
instance.$parent.$forceUpdate()
} else {
console.warn('Root or manually mounted instance modified. Full reload required.')
}
})
if (hasSameChildren) {
// rehydrate children
vm.$children.forEach(function (c, i) {
restoreState(c, state.children[i])
})
}
if (isRoot) {
Vue.config.async = oldAsyncConfig
}
}
function format (id) {
return id.match(/[^\/]+\.vue$/)[0]
}
})
{
"name": "vue-hot-reload-api",
"version": "1.3.2",
"version": "2.0.0",
"description": "hot reload api for *.vue components",

@@ -5,0 +5,0 @@ "main": "index.js",