Sfoglia il codice sorgente

fix esm build exports

Evan You 8 anni fa
parent
commit
b821681863
6 ha cambiato i file con 452 aggiunte e 432 eliminazioni
  1. 0 1
      build/dev-entry.js
  2. 1 1
      build/rollup.config.js
  3. 1 1
      examples/webpack.config.js
  4. 20 0
      src/index.esm.js
  5. 1 429
      src/index.js
  6. 429 0
      src/store.js

+ 0 - 1
build/dev-entry.js

@@ -1 +0,0 @@
-module.exports = require('../src').default

+ 1 - 1
build/rollup.config.js

@@ -3,7 +3,7 @@ const replace = require('rollup-plugin-replace')
 const version = process.env.VERSION || require('../package.json').version
 
 module.exports = {
-  entry: 'src/index.js',
+  entry: process.env.ESM ? 'src/index.esm.js' : 'src/index.js',
   dest: process.env.ESM ? 'dist/vuex.esm.js' : 'dist/vuex.js',
   format: process.env.ESM ? 'es' : 'umd',
   moduleName: 'Vuex',

+ 1 - 1
examples/webpack.config.js

@@ -32,7 +32,7 @@ module.exports = {
 
   resolve: {
     alias: {
-      vuex: path.resolve(__dirname, '../build/dev-entry')
+      vuex: path.resolve(__dirname, '../src/index.esm.js')
     }
   },
 

+ 20 - 0
src/index.esm.js

@@ -0,0 +1,20 @@
+import { Store, install } from './store'
+import { mapState, mapMutations, mapGetters, mapActions } from './helpers'
+
+export default {
+  Store,
+  install,
+  version: '__VERSION__',
+  mapState,
+  mapMutations,
+  mapGetters,
+  mapActions
+}
+
+export {
+  Store,
+  mapState,
+  mapMutations,
+  mapGetters,
+  mapActions
+}

+ 1 - 429
src/index.js

@@ -1,434 +1,6 @@
-import applyMixin from './mixin'
-import devtoolPlugin from './plugins/devtool'
-import ModuleCollection from './module/module-collection'
-import { forEachValue, isObject, isPromise, assert } from './util'
+import { Store, install } from './store'
 import { mapState, mapMutations, mapGetters, mapActions } from './helpers'
 
-let Vue // bind on install
-
-class Store {
-  constructor (options = {}) {
-    assert(Vue, `must call Vue.use(Vuex) before creating a store instance.`)
-    assert(typeof Promise !== 'undefined', `vuex requires a Promise polyfill in this browser.`)
-
-    const {
-      state = {},
-      plugins = [],
-      strict = false
-    } = options
-
-    // store internal state
-    this._committing = false
-    this._actions = Object.create(null)
-    this._mutations = Object.create(null)
-    this._wrappedGetters = Object.create(null)
-    this._modules = new ModuleCollection(options)
-    this._modulesNamespaceMap = Object.create(null)
-    this._subscribers = []
-    this._watcherVM = new Vue()
-
-    // bind commit and dispatch to self
-    const store = this
-    const { dispatch, commit } = this
-    this.dispatch = function boundDispatch (type, payload) {
-      return dispatch.call(store, type, payload)
-    }
-    this.commit = function boundCommit (type, payload, options) {
-      return commit.call(store, type, payload, options)
-    }
-
-    // strict mode
-    this.strict = strict
-
-    // init root module.
-    // this also recursively registers all sub-modules
-    // and collects all module getters inside this._wrappedGetters
-    installModule(this, state, [], this._modules.root)
-
-    // initialize the store vm, which is responsible for the reactivity
-    // (also registers _wrappedGetters as computed properties)
-    resetStoreVM(this, state)
-
-    // apply plugins
-    plugins.concat(devtoolPlugin).forEach(plugin => plugin(this))
-  }
-
-  get state () {
-    return this._vm._data.$$state
-  }
-
-  set state (v) {
-    assert(false, `Use store.replaceState() to explicit replace store state.`)
-  }
-
-  commit (_type, _payload, _options) {
-    // check object-style commit
-    const {
-      type,
-      payload,
-      options
-    } = unifyObjectStyle(_type, _payload, _options)
-
-    const mutation = { type, payload }
-    const entry = this._mutations[type]
-    if (!entry) {
-      console.error(`[vuex] unknown mutation type: ${type}`)
-      return
-    }
-    this._withCommit(() => {
-      entry.forEach(function commitIterator (handler) {
-        handler(payload)
-      })
-    })
-    this._subscribers.forEach(sub => sub(mutation, this.state))
-
-    if (options && options.silent) {
-      console.warn(
-        `[vuex] mutation type: ${type}. Silent option has been removed. ` +
-        'Use the filter functionality in the vue-devtools'
-      )
-    }
-  }
-
-  dispatch (_type, _payload) {
-    // check object-style dispatch
-    const {
-      type,
-      payload
-    } = unifyObjectStyle(_type, _payload)
-
-    const entry = this._actions[type]
-    if (!entry) {
-      console.error(`[vuex] unknown action type: ${type}`)
-      return
-    }
-    return entry.length > 1
-      ? Promise.all(entry.map(handler => handler(payload)))
-      : entry[0](payload)
-  }
-
-  subscribe (fn) {
-    const subs = this._subscribers
-    if (subs.indexOf(fn) < 0) {
-      subs.push(fn)
-    }
-    return () => {
-      const i = subs.indexOf(fn)
-      if (i > -1) {
-        subs.splice(i, 1)
-      }
-    }
-  }
-
-  watch (getter, cb, options) {
-    assert(typeof getter === 'function', `store.watch only accepts a function.`)
-    return this._watcherVM.$watch(() => getter(this.state, this.getters), cb, options)
-  }
-
-  replaceState (state) {
-    this._withCommit(() => {
-      this._vm._data.$$state = state
-    })
-  }
-
-  registerModule (path, rawModule) {
-    if (typeof path === 'string') path = [path]
-    assert(Array.isArray(path), `module path must be a string or an Array.`)
-    this._modules.register(path, rawModule)
-    installModule(this, this.state, path, this._modules.get(path))
-    // reset store to update getters...
-    resetStoreVM(this, this.state)
-  }
-
-  unregisterModule (path) {
-    if (typeof path === 'string') path = [path]
-    assert(Array.isArray(path), `module path must be a string or an Array.`)
-    this._modules.unregister(path)
-    this._withCommit(() => {
-      const parentState = getNestedState(this.state, path.slice(0, -1))
-      Vue.delete(parentState, path[path.length - 1])
-    })
-    resetStore(this)
-  }
-
-  hotUpdate (newOptions) {
-    this._modules.update(newOptions)
-    resetStore(this, true)
-  }
-
-  _withCommit (fn) {
-    const committing = this._committing
-    this._committing = true
-    fn()
-    this._committing = committing
-  }
-}
-
-function resetStore (store, hot) {
-  store._actions = Object.create(null)
-  store._mutations = Object.create(null)
-  store._wrappedGetters = Object.create(null)
-  store._modulesNamespaceMap = Object.create(null)
-  const state = store.state
-  // init all modules
-  installModule(store, state, [], store._modules.root, true)
-  // reset vm
-  resetStoreVM(store, state, hot)
-}
-
-function resetStoreVM (store, state, hot) {
-  const oldVm = store._vm
-
-  // bind store public getters
-  store.getters = {}
-  const wrappedGetters = store._wrappedGetters
-  const computed = {}
-  forEachValue(wrappedGetters, (fn, key) => {
-    // use computed to leverage its lazy-caching mechanism
-    computed[key] = () => fn(store)
-    Object.defineProperty(store.getters, key, {
-      get: () => store._vm[key],
-      enumerable: true // for local getters
-    })
-  })
-
-  // use a Vue instance to store the state tree
-  // suppress warnings just in case the user has added
-  // some funky global mixins
-  const silent = Vue.config.silent
-  Vue.config.silent = true
-  store._vm = new Vue({
-    data: {
-      $$state: state
-    },
-    computed
-  })
-  Vue.config.silent = silent
-
-  // enable strict mode for new vm
-  if (store.strict) {
-    enableStrictMode(store)
-  }
-
-  if (oldVm) {
-    if (hot) {
-      // dispatch changes in all subscribed watchers
-      // to force getter re-evaluation for hot reloading.
-      store._withCommit(() => {
-        oldVm._data.$$state = null
-      })
-    }
-    Vue.nextTick(() => oldVm.$destroy())
-  }
-}
-
-function installModule (store, rootState, path, module, hot) {
-  const isRoot = !path.length
-  const namespace = store._modules.getNamespace(path)
-
-  // register in namespace map
-  if (namespace) {
-    store._modulesNamespaceMap[namespace] = module
-  }
-
-  // set state
-  if (!isRoot && !hot) {
-    const parentState = getNestedState(rootState, path.slice(0, -1))
-    const moduleName = path[path.length - 1]
-    store._withCommit(() => {
-      Vue.set(parentState, moduleName, module.state)
-    })
-  }
-
-  const local = module.context = makeLocalContext(store, namespace, path)
-
-  module.forEachMutation((mutation, key) => {
-    const namespacedType = namespace + key
-    registerMutation(store, namespacedType, mutation, local)
-  })
-
-  module.forEachAction((action, key) => {
-    const namespacedType = namespace + key
-    registerAction(store, namespacedType, action, local)
-  })
-
-  module.forEachGetter((getter, key) => {
-    const namespacedType = namespace + key
-    registerGetter(store, namespacedType, getter, local)
-  })
-
-  module.forEachChild((child, key) => {
-    installModule(store, rootState, path.concat(key), child, hot)
-  })
-}
-
-/**
- * make localized dispatch, commit, getters and state
- * if there is no namespace, just use root ones
- */
-function makeLocalContext (store, namespace, path) {
-  const noNamespace = namespace === ''
-
-  const local = {
-    dispatch: noNamespace ? store.dispatch : (_type, _payload, _options) => {
-      const args = unifyObjectStyle(_type, _payload, _options)
-      const { payload, options } = args
-      let { type } = args
-
-      if (!options || !options.root) {
-        type = namespace + type
-        if (!store._actions[type]) {
-          console.error(`[vuex] unknown local action type: ${args.type}, global type: ${type}`)
-          return
-        }
-      }
-
-      return store.dispatch(type, payload)
-    },
-
-    commit: noNamespace ? store.commit : (_type, _payload, _options) => {
-      const args = unifyObjectStyle(_type, _payload, _options)
-      const { payload, options } = args
-      let { type } = args
-
-      if (!options || !options.root) {
-        type = namespace + type
-        if (!store._mutations[type]) {
-          console.error(`[vuex] unknown local mutation type: ${args.type}, global type: ${type}`)
-          return
-        }
-      }
-
-      store.commit(type, payload, options)
-    }
-  }
-
-  // getters and state object must be gotten lazily
-  // because they will be changed by vm update
-  Object.defineProperties(local, {
-    getters: {
-      get: noNamespace
-        ? () => store.getters
-        : () => makeLocalGetters(store, namespace)
-    },
-    state: {
-      get: () => getNestedState(store.state, path)
-    }
-  })
-
-  return local
-}
-
-function makeLocalGetters (store, namespace) {
-  const gettersProxy = {}
-
-  const splitPos = namespace.length
-  Object.keys(store.getters).forEach(type => {
-    // skip if the target getter is not match this namespace
-    if (type.slice(0, splitPos) !== namespace) return
-
-    // extract local getter type
-    const localType = type.slice(splitPos)
-
-    // Add a port to the getters proxy.
-    // Define as getter property because
-    // we do not want to evaluate the getters in this time.
-    Object.defineProperty(gettersProxy, localType, {
-      get: () => store.getters[type],
-      enumerable: true
-    })
-  })
-
-  return gettersProxy
-}
-
-function registerMutation (store, type, handler, local) {
-  const entry = store._mutations[type] || (store._mutations[type] = [])
-  entry.push(function wrappedMutationHandler (payload) {
-    handler(local.state, payload)
-  })
-}
-
-function registerAction (store, type, handler, local) {
-  const entry = store._actions[type] || (store._actions[type] = [])
-  entry.push(function wrappedActionHandler (payload, cb) {
-    let res = handler({
-      dispatch: local.dispatch,
-      commit: local.commit,
-      getters: local.getters,
-      state: local.state,
-      rootGetters: store.getters,
-      rootState: store.state
-    }, payload, cb)
-    if (!isPromise(res)) {
-      res = Promise.resolve(res)
-    }
-    if (store._devtoolHook) {
-      return res.catch(err => {
-        store._devtoolHook.emit('vuex:error', err)
-        throw err
-      })
-    } else {
-      return res
-    }
-  })
-}
-
-function registerGetter (store, type, rawGetter, local) {
-  if (store._wrappedGetters[type]) {
-    console.error(`[vuex] duplicate getter key: ${type}`)
-    return
-  }
-  store._wrappedGetters[type] = function wrappedGetter (store) {
-    return rawGetter(
-      local.state, // local state
-      local.getters, // local getters
-      store.state, // root state
-      store.getters // root getters
-    )
-  }
-}
-
-function enableStrictMode (store) {
-  store._vm.$watch(function () { return this._data.$$state }, () => {
-    assert(store._committing, `Do not mutate vuex store state outside mutation handlers.`)
-  }, { deep: true, sync: true })
-}
-
-function getNestedState (state, path) {
-  return path.length
-    ? path.reduce((state, key) => state[key], state)
-    : state
-}
-
-function unifyObjectStyle (type, payload, options) {
-  if (isObject(type) && type.type) {
-    options = payload
-    payload = type
-    type = type.type
-  }
-
-  assert(typeof type === 'string', `Expects string as the type, but found ${typeof type}.`)
-
-  return { type, payload, options }
-}
-
-function install (_Vue) {
-  if (Vue) {
-    console.error(
-      '[vuex] already installed. Vue.use(Vuex) should be called only once.'
-    )
-    return
-  }
-  Vue = _Vue
-  applyMixin(Vue)
-}
-
-// auto install in dist mode
-if (typeof window !== 'undefined' && window.Vue) {
-  install(window.Vue)
-}
-
 export default {
   Store,
   install,

+ 429 - 0
src/store.js

@@ -0,0 +1,429 @@
+import applyMixin from './mixin'
+import devtoolPlugin from './plugins/devtool'
+import ModuleCollection from './module/module-collection'
+import { forEachValue, isObject, isPromise, assert } from './util'
+
+let Vue // bind on install
+
+export class Store {
+  constructor (options = {}) {
+    assert(Vue, `must call Vue.use(Vuex) before creating a store instance.`)
+    assert(typeof Promise !== 'undefined', `vuex requires a Promise polyfill in this browser.`)
+
+    const {
+      state = {},
+      plugins = [],
+      strict = false
+    } = options
+
+    // store internal state
+    this._committing = false
+    this._actions = Object.create(null)
+    this._mutations = Object.create(null)
+    this._wrappedGetters = Object.create(null)
+    this._modules = new ModuleCollection(options)
+    this._modulesNamespaceMap = Object.create(null)
+    this._subscribers = []
+    this._watcherVM = new Vue()
+
+    // bind commit and dispatch to self
+    const store = this
+    const { dispatch, commit } = this
+    this.dispatch = function boundDispatch (type, payload) {
+      return dispatch.call(store, type, payload)
+    }
+    this.commit = function boundCommit (type, payload, options) {
+      return commit.call(store, type, payload, options)
+    }
+
+    // strict mode
+    this.strict = strict
+
+    // init root module.
+    // this also recursively registers all sub-modules
+    // and collects all module getters inside this._wrappedGetters
+    installModule(this, state, [], this._modules.root)
+
+    // initialize the store vm, which is responsible for the reactivity
+    // (also registers _wrappedGetters as computed properties)
+    resetStoreVM(this, state)
+
+    // apply plugins
+    plugins.concat(devtoolPlugin).forEach(plugin => plugin(this))
+  }
+
+  get state () {
+    return this._vm._data.$$state
+  }
+
+  set state (v) {
+    assert(false, `Use store.replaceState() to explicit replace store state.`)
+  }
+
+  commit (_type, _payload, _options) {
+    // check object-style commit
+    const {
+      type,
+      payload,
+      options
+    } = unifyObjectStyle(_type, _payload, _options)
+
+    const mutation = { type, payload }
+    const entry = this._mutations[type]
+    if (!entry) {
+      console.error(`[vuex] unknown mutation type: ${type}`)
+      return
+    }
+    this._withCommit(() => {
+      entry.forEach(function commitIterator (handler) {
+        handler(payload)
+      })
+    })
+    this._subscribers.forEach(sub => sub(mutation, this.state))
+
+    if (options && options.silent) {
+      console.warn(
+        `[vuex] mutation type: ${type}. Silent option has been removed. ` +
+        'Use the filter functionality in the vue-devtools'
+      )
+    }
+  }
+
+  dispatch (_type, _payload) {
+    // check object-style dispatch
+    const {
+      type,
+      payload
+    } = unifyObjectStyle(_type, _payload)
+
+    const entry = this._actions[type]
+    if (!entry) {
+      console.error(`[vuex] unknown action type: ${type}`)
+      return
+    }
+    return entry.length > 1
+      ? Promise.all(entry.map(handler => handler(payload)))
+      : entry[0](payload)
+  }
+
+  subscribe (fn) {
+    const subs = this._subscribers
+    if (subs.indexOf(fn) < 0) {
+      subs.push(fn)
+    }
+    return () => {
+      const i = subs.indexOf(fn)
+      if (i > -1) {
+        subs.splice(i, 1)
+      }
+    }
+  }
+
+  watch (getter, cb, options) {
+    assert(typeof getter === 'function', `store.watch only accepts a function.`)
+    return this._watcherVM.$watch(() => getter(this.state, this.getters), cb, options)
+  }
+
+  replaceState (state) {
+    this._withCommit(() => {
+      this._vm._data.$$state = state
+    })
+  }
+
+  registerModule (path, rawModule) {
+    if (typeof path === 'string') path = [path]
+    assert(Array.isArray(path), `module path must be a string or an Array.`)
+    this._modules.register(path, rawModule)
+    installModule(this, this.state, path, this._modules.get(path))
+    // reset store to update getters...
+    resetStoreVM(this, this.state)
+  }
+
+  unregisterModule (path) {
+    if (typeof path === 'string') path = [path]
+    assert(Array.isArray(path), `module path must be a string or an Array.`)
+    this._modules.unregister(path)
+    this._withCommit(() => {
+      const parentState = getNestedState(this.state, path.slice(0, -1))
+      Vue.delete(parentState, path[path.length - 1])
+    })
+    resetStore(this)
+  }
+
+  hotUpdate (newOptions) {
+    this._modules.update(newOptions)
+    resetStore(this, true)
+  }
+
+  _withCommit (fn) {
+    const committing = this._committing
+    this._committing = true
+    fn()
+    this._committing = committing
+  }
+}
+
+function resetStore (store, hot) {
+  store._actions = Object.create(null)
+  store._mutations = Object.create(null)
+  store._wrappedGetters = Object.create(null)
+  store._modulesNamespaceMap = Object.create(null)
+  const state = store.state
+  // init all modules
+  installModule(store, state, [], store._modules.root, true)
+  // reset vm
+  resetStoreVM(store, state, hot)
+}
+
+function resetStoreVM (store, state, hot) {
+  const oldVm = store._vm
+
+  // bind store public getters
+  store.getters = {}
+  const wrappedGetters = store._wrappedGetters
+  const computed = {}
+  forEachValue(wrappedGetters, (fn, key) => {
+    // use computed to leverage its lazy-caching mechanism
+    computed[key] = () => fn(store)
+    Object.defineProperty(store.getters, key, {
+      get: () => store._vm[key],
+      enumerable: true // for local getters
+    })
+  })
+
+  // use a Vue instance to store the state tree
+  // suppress warnings just in case the user has added
+  // some funky global mixins
+  const silent = Vue.config.silent
+  Vue.config.silent = true
+  store._vm = new Vue({
+    data: {
+      $$state: state
+    },
+    computed
+  })
+  Vue.config.silent = silent
+
+  // enable strict mode for new vm
+  if (store.strict) {
+    enableStrictMode(store)
+  }
+
+  if (oldVm) {
+    if (hot) {
+      // dispatch changes in all subscribed watchers
+      // to force getter re-evaluation for hot reloading.
+      store._withCommit(() => {
+        oldVm._data.$$state = null
+      })
+    }
+    Vue.nextTick(() => oldVm.$destroy())
+  }
+}
+
+function installModule (store, rootState, path, module, hot) {
+  const isRoot = !path.length
+  const namespace = store._modules.getNamespace(path)
+
+  // register in namespace map
+  if (namespace) {
+    store._modulesNamespaceMap[namespace] = module
+  }
+
+  // set state
+  if (!isRoot && !hot) {
+    const parentState = getNestedState(rootState, path.slice(0, -1))
+    const moduleName = path[path.length - 1]
+    store._withCommit(() => {
+      Vue.set(parentState, moduleName, module.state)
+    })
+  }
+
+  const local = module.context = makeLocalContext(store, namespace, path)
+
+  module.forEachMutation((mutation, key) => {
+    const namespacedType = namespace + key
+    registerMutation(store, namespacedType, mutation, local)
+  })
+
+  module.forEachAction((action, key) => {
+    const namespacedType = namespace + key
+    registerAction(store, namespacedType, action, local)
+  })
+
+  module.forEachGetter((getter, key) => {
+    const namespacedType = namespace + key
+    registerGetter(store, namespacedType, getter, local)
+  })
+
+  module.forEachChild((child, key) => {
+    installModule(store, rootState, path.concat(key), child, hot)
+  })
+}
+
+/**
+ * make localized dispatch, commit, getters and state
+ * if there is no namespace, just use root ones
+ */
+function makeLocalContext (store, namespace, path) {
+  const noNamespace = namespace === ''
+
+  const local = {
+    dispatch: noNamespace ? store.dispatch : (_type, _payload, _options) => {
+      const args = unifyObjectStyle(_type, _payload, _options)
+      const { payload, options } = args
+      let { type } = args
+
+      if (!options || !options.root) {
+        type = namespace + type
+        if (!store._actions[type]) {
+          console.error(`[vuex] unknown local action type: ${args.type}, global type: ${type}`)
+          return
+        }
+      }
+
+      return store.dispatch(type, payload)
+    },
+
+    commit: noNamespace ? store.commit : (_type, _payload, _options) => {
+      const args = unifyObjectStyle(_type, _payload, _options)
+      const { payload, options } = args
+      let { type } = args
+
+      if (!options || !options.root) {
+        type = namespace + type
+        if (!store._mutations[type]) {
+          console.error(`[vuex] unknown local mutation type: ${args.type}, global type: ${type}`)
+          return
+        }
+      }
+
+      store.commit(type, payload, options)
+    }
+  }
+
+  // getters and state object must be gotten lazily
+  // because they will be changed by vm update
+  Object.defineProperties(local, {
+    getters: {
+      get: noNamespace
+        ? () => store.getters
+        : () => makeLocalGetters(store, namespace)
+    },
+    state: {
+      get: () => getNestedState(store.state, path)
+    }
+  })
+
+  return local
+}
+
+function makeLocalGetters (store, namespace) {
+  const gettersProxy = {}
+
+  const splitPos = namespace.length
+  Object.keys(store.getters).forEach(type => {
+    // skip if the target getter is not match this namespace
+    if (type.slice(0, splitPos) !== namespace) return
+
+    // extract local getter type
+    const localType = type.slice(splitPos)
+
+    // Add a port to the getters proxy.
+    // Define as getter property because
+    // we do not want to evaluate the getters in this time.
+    Object.defineProperty(gettersProxy, localType, {
+      get: () => store.getters[type],
+      enumerable: true
+    })
+  })
+
+  return gettersProxy
+}
+
+function registerMutation (store, type, handler, local) {
+  const entry = store._mutations[type] || (store._mutations[type] = [])
+  entry.push(function wrappedMutationHandler (payload) {
+    handler(local.state, payload)
+  })
+}
+
+function registerAction (store, type, handler, local) {
+  const entry = store._actions[type] || (store._actions[type] = [])
+  entry.push(function wrappedActionHandler (payload, cb) {
+    let res = handler({
+      dispatch: local.dispatch,
+      commit: local.commit,
+      getters: local.getters,
+      state: local.state,
+      rootGetters: store.getters,
+      rootState: store.state
+    }, payload, cb)
+    if (!isPromise(res)) {
+      res = Promise.resolve(res)
+    }
+    if (store._devtoolHook) {
+      return res.catch(err => {
+        store._devtoolHook.emit('vuex:error', err)
+        throw err
+      })
+    } else {
+      return res
+    }
+  })
+}
+
+function registerGetter (store, type, rawGetter, local) {
+  if (store._wrappedGetters[type]) {
+    console.error(`[vuex] duplicate getter key: ${type}`)
+    return
+  }
+  store._wrappedGetters[type] = function wrappedGetter (store) {
+    return rawGetter(
+      local.state, // local state
+      local.getters, // local getters
+      store.state, // root state
+      store.getters // root getters
+    )
+  }
+}
+
+function enableStrictMode (store) {
+  store._vm.$watch(function () { return this._data.$$state }, () => {
+    assert(store._committing, `Do not mutate vuex store state outside mutation handlers.`)
+  }, { deep: true, sync: true })
+}
+
+function getNestedState (state, path) {
+  return path.length
+    ? path.reduce((state, key) => state[key], state)
+    : state
+}
+
+function unifyObjectStyle (type, payload, options) {
+  if (isObject(type) && type.type) {
+    options = payload
+    payload = type
+    type = type.type
+  }
+
+  assert(typeof type === 'string', `Expects string as the type, but found ${typeof type}.`)
+
+  return { type, payload, options }
+}
+
+export function install (_Vue) {
+  if (Vue) {
+    console.error(
+      '[vuex] already installed. Vue.use(Vuex) should be called only once.'
+    )
+    return
+  }
+  Vue = _Vue
+  applyMixin(Vue)
+}
+
+// auto install in dist mode
+if (typeof window !== 'undefined' && window.Vue) {
+  install(window.Vue)
+}