diff --git a/.babelrc b/.babelrc index 05581748b..01d096c1f 100644 --- a/.babelrc +++ b/.babelrc @@ -1,3 +1,10 @@ { - "presets": ["es2015", "stage-2"] + "env": { + "development": { + "presets": ["es2015", "stage-2"] + }, + "production": { + "presets": ["es2015-rollup"] + } + } } diff --git a/README.md b/README.md index 5c79e60b8..d1f1b84c8 100644 --- a/README.md +++ b/README.md @@ -6,10 +6,8 @@

-## NOTE: Vuex is still in development - API may change anytime. - - [Documentation](http://vuex.vuejs.org/) -- [Great introduction and explanation by @skyronic](http://skyronic.com/2016/01/03/vuex-basics-tutorial/) +- [Great introduction and explanation by @skyronic](http://skyronic.com/2016/01/03/vuex-basics-tutorial/) (using outdated 0.3.0 API, but still worth a read!) ## Examples diff --git a/bower.json b/bower.json index 991d45a14..cc13a359c 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "vuex", - "main": "lib/index.js", + "main": "dist/vuex.js", "description": "state management for Vue.js", "authors": "Evan You", "license": "MIT", diff --git a/build/build.js b/build/build.js new file mode 100644 index 000000000..861395b37 --- /dev/null +++ b/build/build.js @@ -0,0 +1,70 @@ +process.env.BABEL_ENV = 'production' + +var fs = require('fs') +var zlib = require('zlib') +var rollup = require('rollup') +var uglify = require('uglify-js') +var babel = require('rollup-plugin-babel') +var version = process.env.VERSION || require('../package.json').version + +var banner = + '/*!\n' + + ' * Vuex v' + version + '\n' + + ' * (c) ' + new Date().getFullYear() + ' Evan You\n' + + ' * Released under the MIT License.\n' + + ' */' + +rollup.rollup({ + entry: 'src/index.js', + plugins: [babel()] +}) +.then(function (bundle) { + return write('dist/vuex.js', bundle.generate({ + format: 'umd', + banner: banner, + moduleName: 'Vuex' + }).code) +}) +.then(function () { + // Standalone Production Build + return rollup.rollup({ + entry: 'src/index.js', + plugins: [babel()] + }) +}) +.then(function (bundle) { + var code = bundle.generate({ + format: 'umd', + moduleName: 'Vuex' + }).code + var minified = banner + '\n' + uglify.minify(code, { + fromString: true, + output: { + ascii_only: true + } + }).code + return write('dist/vuex.min.js', minified) +}) +.catch(logError) + +function write (dest, code) { + return new Promise(function (resolve, reject) { + fs.writeFile(dest, code, function (err) { + if (err) return reject(err) + console.log(blue(dest) + ' ' + getSize(code)) + resolve() + }) + }) +} + +function getSize (code) { + return (code.length / 1024).toFixed(2) + 'kb' +} + +function logError (e) { + console.log(e) +} + +function blue (str) { + return '\x1b[1m\x1b[34m' + str + '\x1b[39m\x1b[22m' +} diff --git a/dist/vuex.js b/dist/vuex.js new file mode 100644 index 000000000..41a2e8904 --- /dev/null +++ b/dist/vuex.js @@ -0,0 +1,506 @@ +/*! + * Vuex v0.4.1 + * (c) 2016 Evan You + * Released under the MIT License. + */ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (factory((global.Vuex = global.Vuex || {}))); +}(this, function (exports) { 'use strict'; + + var babelHelpers = {}; + babelHelpers.typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { + return typeof obj; + } : function (obj) { + return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; + }; + + babelHelpers.classCallCheck = function (instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } + }; + + babelHelpers.createClass = function () { + function defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + return function (Constructor, protoProps, staticProps) { + if (protoProps) defineProperties(Constructor.prototype, protoProps); + if (staticProps) defineProperties(Constructor, staticProps); + return Constructor; + }; + }(); + + babelHelpers; + + /** + * Merge an array of objects into one. + * + * @param {Array} arr + * @return {Object} + */ + + function mergeObjects(arr) { + return arr.reduce(function (prev, obj) { + Object.keys(obj).forEach(function (key) { + var existing = prev[key]; + if (existing) { + // allow multiple mutation objects to contain duplicate + // handlers for the same mutation type + if (Array.isArray(existing)) { + existing.push(obj[key]); + } else { + prev[key] = [prev[key], obj[key]]; + } + } else { + prev[key] = obj[key]; + } + }); + return prev; + }, {}); + } + + /** + * Deep clone an object. Faster than JSON.parse(JSON.stringify()). + * + * @param {*} obj + * @return {*} + */ + + function deepClone(obj) { + if (Array.isArray(obj)) { + return obj.map(deepClone); + } else if (obj && (typeof obj === 'undefined' ? 'undefined' : babelHelpers.typeof(obj)) === 'object') { + var cloned = {}; + var keys = Object.keys(obj); + for (var i = 0, l = keys.length; i < l; i++) { + var key = keys[i]; + cloned[key] = deepClone(obj[key]); + } + return cloned; + } else { + return obj; + } + } + + var devtoolMiddleware = { + onInit: function onInit(state) { + // TODO + }, + onMutation: function onMutation(mutation, state) { + // TODO + } + }; + + // Credits: borrowed code from fcomb/redux-logger + + function createLogger() { + var _ref = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; + + var _ref$collapsed = _ref.collapsed; + var collapsed = _ref$collapsed === undefined ? true : _ref$collapsed; + var _ref$transformer = _ref.transformer; + var transformer = _ref$transformer === undefined ? function (state) { + return state; + } : _ref$transformer; + var _ref$mutationTransfor = _ref.mutationTransformer; + var mutationTransformer = _ref$mutationTransfor === undefined ? function (mut) { + return mut; + } : _ref$mutationTransfor; + + return { + snapshot: true, + onMutation: function onMutation(mutation, nextState, prevState) { + if (typeof console === 'undefined') { + return; + } + var time = new Date(); + var formattedTime = ' @ ' + pad(time.getHours(), 2) + ':' + pad(time.getMinutes(), 2) + ':' + pad(time.getSeconds(), 2) + '.' + pad(time.getMilliseconds(), 3); + var formattedMutation = mutationTransformer(mutation); + var message = 'mutation ' + mutation.type + formattedTime; + var startMessage = collapsed ? console.groupCollapsed : console.group; + + // render + try { + startMessage.call(console, message); + } catch (e) { + console.log(message); + } + + console.log('%c prev state', 'color: #9E9E9E; font-weight: bold', prevState); + console.log('%c mutation', 'color: #03A9F4; font-weight: bold', formattedMutation); + console.log('%c next state', 'color: #4CAF50; font-weight: bold', nextState); + + try { + console.groupEnd(); + } catch (e) { + console.log('—— log end ——'); + } + } + }; + } + + function repeat(str, times) { + return new Array(times + 1).join(str); + } + + function pad(num, maxLength) { + return repeat('0', maxLength - num.toString().length) + num; + } + + // export install function + function override (Vue) { + var _init = Vue.prototype._init; + Vue.prototype._init = function (options) { + var _this = this; + + options = options || {}; + var componentOptions = this.constructor.options; + // store injection + var store = options.store || componentOptions.store; + if (store) { + this.$store = store; + } else if (options.parent && options.parent.$store) { + this.$store = options.parent.$store; + } + // vuex option handling + var vuex = options.vuex || componentOptions.vuex; + if (vuex) { + (function () { + if (!_this.$store) { + console.warn('[vuex] store not injected. make sure to ' + 'provide the store option in your root component.'); + } + var state = vuex.state; + var actions = vuex.actions; + // state + + if (state) { + options.computed = options.computed || {}; + Object.keys(state).forEach(function (key) { + options.computed[key] = function vuexBoundGetter() { + return state[key].call(this, this.$store.state); + }; + }); + } + // actions + if (actions) { + options.methods = options.methods || {}; + Object.keys(actions).forEach(function (key) { + options.methods[key] = function vuexBoundAction() { + var _actions$key; + + for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + return (_actions$key = actions[key]).call.apply(_actions$key, [this, this.$store].concat(args)); + }; + }); + } + })(); + } + _init.call(this, options); + }; + } + + var Vue = undefined; + + var Store = function () { + + /** + * @param {Object} options + * - {Object} state + * - {Object} actions + * - {Object} mutations + * - {Array} middlewares + * - {Boolean} strict + */ + + function Store() { + var _this = this; + + var _ref = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; + + var _ref$state = _ref.state; + var state = _ref$state === undefined ? {} : _ref$state; + var _ref$mutations = _ref.mutations; + var mutations = _ref$mutations === undefined ? {} : _ref$mutations; + var _ref$modules = _ref.modules; + var modules = _ref$modules === undefined ? {} : _ref$modules; + var _ref$middlewares = _ref.middlewares; + var middlewares = _ref$middlewares === undefined ? [] : _ref$middlewares; + var _ref$strict = _ref.strict; + var strict = _ref$strict === undefined ? false : _ref$strict; + babelHelpers.classCallCheck(this, Store); + + this._dispatching = false; + this._rootMutations = this._mutations = mutations; + this._modules = modules; + // bind dispatch to self + var dispatch = this.dispatch; + this.dispatch = function () { + for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + dispatch.apply(_this, args); + }; + // use a Vue instance to store the state tree + this._vm = new Vue({ + data: state + }); + this._setupModuleState(state, modules); + this._setupModuleMutations(modules); + this._setupMiddlewares(middlewares, state); + // add extra warnings in strict mode + if (strict) { + this._setupMutationCheck(); + } + } + + /** + * Getter for the entire state tree. + * Read only. + * + * @return {Object} + */ + + babelHelpers.createClass(Store, [{ + key: 'dispatch', + + + /** + * Dispatch an action. + * + * @param {String} type + */ + + value: function dispatch(type) { + for (var _len2 = arguments.length, payload = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { + payload[_key2 - 1] = arguments[_key2]; + } + + var mutation = this._mutations[type]; + var prevSnapshot = this._prevSnapshot; + var state = this.state; + var snapshot = undefined, + clonedPayload = undefined; + if (mutation) { + this._dispatching = true; + // apply the mutation + if (Array.isArray(mutation)) { + mutation.forEach(function (m) { + return m.apply(undefined, [state].concat(payload)); + }); + } else { + mutation.apply(undefined, [state].concat(payload)); + } + this._dispatching = false; + // invoke middlewares + if (this._needSnapshots) { + snapshot = this._prevSnapshot = deepClone(state); + clonedPayload = deepClone(payload); + } + this._middlewares.forEach(function (m) { + if (m.onMutation) { + if (m.snapshot) { + m.onMutation({ type: type, payload: clonedPayload }, snapshot, prevSnapshot); + } else { + m.onMutation({ type: type, payload: payload }, state); + } + } + }); + } else { + console.warn('[vuex] Unknown mutation: ' + type); + } + } + + /** + * Watch state changes on the store. + * Same API as Vue's $watch, except when watching a function, + * the function gets the state as the first argument. + * + * @param {String|Function} expOrFn + * @param {Function} cb + * @param {Object} [options] + */ + + }, { + key: 'watch', + value: function watch(expOrFn, cb, options) { + var _this2 = this; + + return this._vm.$watch(function () { + return typeof expOrFn === 'function' ? expOrFn(_this2.state) : _this2._vm.$get(expOrFn); + }, cb, options); + } + + /** + * Hot update actions and mutations. + * + * @param {Object} options + * - {Object} [mutations] + * - {Object} [modules] + */ + + }, { + key: 'hotUpdate', + value: function hotUpdate() { + var _ref2 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; + + var mutations = _ref2.mutations; + var modules = _ref2.modules; + + this._rootMutations = this._mutations = mutations || this._rootMutations; + this._setupModuleMutations(modules || this._modules); + } + + /** + * Attach sub state tree of each module to the root tree. + * + * @param {Object} state + * @param {Object} modules + */ + + }, { + key: '_setupModuleState', + value: function _setupModuleState(state, modules) { + var setPath = Vue.parsers.path.setPath; + + Object.keys(modules).forEach(function (key) { + setPath(state, key, modules[key].state); + }); + } + + /** + * Bind mutations for each module to its sub tree and + * merge them all into one final mutations map. + * + * @param {Object} modules + */ + + }, { + key: '_setupModuleMutations', + value: function _setupModuleMutations(modules) { + this._modules = modules; + var getPath = Vue.parsers.path.getPath; + + var allMutations = [this._rootMutations]; + Object.keys(modules).forEach(function (key) { + var module = modules[key]; + // bind mutations to sub state tree + var mutations = {}; + Object.keys(module.mutations).forEach(function (name) { + var original = module.mutations[name]; + mutations[name] = function (state) { + for (var _len3 = arguments.length, args = Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) { + args[_key3 - 1] = arguments[_key3]; + } + + original.apply(undefined, [getPath(state, key)].concat(args)); + }; + }); + allMutations.push(mutations); + }); + this._mutations = mergeObjects(allMutations); + } + + /** + * Setup mutation check: if the vuex instance's state is mutated + * outside of a mutation handler, we throw en error. This effectively + * enforces all mutations to the state to be trackable and hot-reloadble. + * However, this comes at a run time cost since we are doing a deep + * watch on the entire state tree, so it is only enalbed with the + * strict option is set to true. + */ + + }, { + key: '_setupMutationCheck', + value: function _setupMutationCheck() { + var _this3 = this; + + // a hack to get the watcher constructor from older versions of Vue + // mainly because the public $watch method does not allow sync + // watchers. + var unwatch = this._vm.$watch('__vuex__', function (a) { + return a; + }); + var Watcher = this._vm._watchers[0].constructor; + unwatch(); + /* eslint-disable no-new */ + new Watcher(this._vm, '$data', function () { + if (!_this3._dispatching) { + throw new Error('[vuex] Do not mutate vuex store state outside mutation handlers.'); + } + }, { deep: true, sync: true }); + /* eslint-enable no-new */ + } + + /** + * Setup the middlewares. The devtools middleware is always + * included, since it does nothing if no devtool is detected. + * + * A middleware can demand the state it receives to be + * "snapshots", i.e. deep clones of the actual state tree. + * + * @param {Array} middlewares + * @param {Object} state + */ + + }, { + key: '_setupMiddlewares', + value: function _setupMiddlewares(middlewares, state) { + this._middlewares = [devtoolMiddleware].concat(middlewares); + this._needSnapshots = middlewares.some(function (m) { + return m.snapshot; + }); + if (this._needSnapshots) { + console.log('[vuex] One or more of your middlewares are taking state snapshots ' + 'for each mutation. Make sure to use them only during development.'); + } + var initialSnapshot = this._prevSnapshot = this._needSnapshots ? deepClone(state) : null; + // call init hooks + this._middlewares.forEach(function (m) { + if (m.onInit) { + m.onInit(m.snapshot ? initialSnapshot : state); + } + }); + } + }, { + key: 'state', + get: function get() { + return this._vm._data; + }, + set: function set(v) { + throw new Error('[vuex] Vuex root state is read only.'); + } + }]); + return Store; + }(); + + function install(_Vue) { + Vue = _Vue; + override(Vue); + } + + // also export the default + var index = { + Store: Store, + install: install, + createLogger: createLogger + }; + + exports.Store = Store; + exports.install = install; + exports.createLogger = createLogger; + exports['default'] = index; + +})); \ No newline at end of file diff --git a/dist/vuex.min.js b/dist/vuex.min.js new file mode 100644 index 000000000..6fa534d93 --- /dev/null +++ b/dist/vuex.min.js @@ -0,0 +1,6 @@ +/*! + * Vuex v0.4.1 + * (c) 2016 Evan You + * Released under the MIT License. + */ +!function(t,o){"object"==typeof exports&&"undefined"!=typeof module?o(exports):"function"==typeof define&&define.amd?define(["exports"],o):o(t.Vuex=t.Vuex||{})}(this,function(t){"use strict";function o(t){return t.reduce(function(t,o){return Object.keys(o).forEach(function(e){var n=t[e];n?Array.isArray(n)?n.push(o[e]):t[e]=[t[e],o[e]]:t[e]=o[e]}),t},{})}function e(t){if(Array.isArray(t))return t.map(e);if(t&&"object"===("undefined"==typeof t?"undefined":u["typeof"](t))){for(var o={},n=Object.keys(t),r=0,s=n.length;s>r;r++){var i=n[r];o[i]=e(t[i])}return o}return t}function n(){var t=arguments.length<=0||void 0===arguments[0]?{}:arguments[0],o=t.collapsed,e=void 0===o?!0:o,n=(t.transformer,t.mutationTransformer),r=void 0===n?function(t){return t}:n;return{snapshot:!0,onMutation:function(t,o,n){if("undefined"!=typeof console){var i=new Date,a=" @ "+s(i.getHours(),2)+":"+s(i.getMinutes(),2)+":"+s(i.getSeconds(),2)+"."+s(i.getMilliseconds(),3),u=r(t),c="mutation "+t.type+a,h=e?console.groupCollapsed:console.group;try{h.call(console,c)}catch(l){console.log(c)}console.log("%c prev state","color: #9E9E9E; font-weight: bold",n),console.log("%c mutation","color: #03A9F4; font-weight: bold",u),console.log("%c next state","color: #4CAF50; font-weight: bold",o);try{console.groupEnd()}catch(l){console.log("\u2014\u2014 log end \u2014\u2014")}}}}}function r(t,o){return new Array(o+1).join(t)}function s(t,o){return r("0",o-t.toString().length)+t}function i(t){var o=t.prototype._init;t.prototype._init=function(t){var e=this;t=t||{};var n=this.constructor.options,r=t.store||n.store;r?this.$store=r:t.parent&&t.parent.$store&&(this.$store=t.parent.$store);var s=t.vuex||n.vuex;s&&!function(){e.$store||console.warn("[vuex] store not injected. make sure to provide the store option in your root component.");var o=s.state,n=s.actions;o&&(t.computed=t.computed||{},Object.keys(o).forEach(function(e){t.computed[e]=function(){return o[e].call(this,this.$store.state)}})),n&&(t.methods=t.methods||{},Object.keys(n).forEach(function(o){t.methods[o]=function(){for(var t,e=arguments.length,r=Array(e),s=0;e>s;s++)r[s]=arguments[s];return(t=n[o]).call.apply(t,[this,this.$store].concat(r))}}))}(),o.call(this,t)}}function a(t){h=t,i(h)}var u={};u["typeof"]="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol?"symbol":typeof t},u.classCallCheck=function(t,o){if(!(t instanceof o))throw new TypeError("Cannot call a class as a function")},u.createClass=function(){function t(t,o){for(var e=0;en;n++)e[n]=arguments[n];v.apply(o,e)},this._vm=new h({data:r}),this._setupModuleState(r,c),this._setupModuleMutations(c),this._setupMiddlewares(f,r),p&&this._setupMutationCheck()}return u.createClass(t,[{key:"dispatch",value:function(t){for(var o=arguments.length,n=Array(o>1?o-1:0),r=1;o>r;r++)n[r-1]=arguments[r];var s=this._mutations[t],i=this._prevSnapshot,a=this.state,u=void 0,c=void 0;s?(this._dispatching=!0,Array.isArray(s)?s.forEach(function(t){return t.apply(void 0,[a].concat(n))}):s.apply(void 0,[a].concat(n)),this._dispatching=!1,this._needSnapshots&&(u=this._prevSnapshot=e(a),c=e(n)),this._middlewares.forEach(function(o){o.onMutation&&(o.snapshot?o.onMutation({type:t,payload:c},u,i):o.onMutation({type:t,payload:n},a))})):console.warn("[vuex] Unknown mutation: "+t)}},{key:"watch",value:function(t,o,e){var n=this;return this._vm.$watch(function(){return"function"==typeof t?t(n.state):n._vm.$get(t)},o,e)}},{key:"hotUpdate",value:function(){var t=arguments.length<=0||void 0===arguments[0]?{}:arguments[0],o=t.mutations,e=t.modules;this._rootMutations=this._mutations=o||this._rootMutations,this._setupModuleMutations(e||this._modules)}},{key:"_setupModuleState",value:function(t,o){var e=h.parsers.path.setPath;Object.keys(o).forEach(function(n){e(t,n,o[n].state)})}},{key:"_setupModuleMutations",value:function(t){this._modules=t;var e=h.parsers.path.getPath,n=[this._rootMutations];Object.keys(t).forEach(function(o){var r=t[o],s={};Object.keys(r.mutations).forEach(function(t){var n=r.mutations[t];s[t]=function(t){for(var r=arguments.length,s=Array(r>1?r-1:0),i=1;r>i;i++)s[i-1]=arguments[i];n.apply(void 0,[e(t,o)].concat(s))}}),n.push(s)}),this._mutations=o(n)}},{key:"_setupMutationCheck",value:function(){var t=this,o=this._vm.$watch("__vuex__",function(t){return t}),e=this._vm._watchers[0].constructor;o(),new e(this._vm,"$data",function(){if(!t._dispatching)throw new Error("[vuex] Do not mutate vuex store state outside mutation handlers.")},{deep:!0,sync:!0})}},{key:"_setupMiddlewares",value:function(t,o){this._middlewares=[c].concat(t),this._needSnapshots=t.some(function(t){return t.snapshot}),this._needSnapshots&&console.log("[vuex] One or more of your middlewares are taking state snapshots for each mutation. Make sure to use them only during development.");var n=this._prevSnapshot=this._needSnapshots?e(o):null;this._middlewares.forEach(function(t){t.onInit&&t.onInit(t.snapshot?n:o)})}},{key:"state",get:function(){return this._vm._data},set:function(t){throw new Error("[vuex] Vuex root state is read only.")}}]),t}(),f={Store:l,install:a,createLogger:n};t.Store=l,t.install=a,t.createLogger=n,t["default"]=f}); \ No newline at end of file diff --git a/package.json b/package.json index cd25dbda5..255e88c83 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,10 @@ { "name": "vuex", - "version": "0.4.0", + "version": "0.4.1", "description": "state management for Vue.js", - "main": "lib/index.js", + "main": "dist/vuex.js", "files": [ - "lib", + "dist", "src" ], "scripts": { @@ -13,7 +13,7 @@ "todomvc": "cd examples/todomvc && webpack-dev-server --inline --hot --config ../webpack.shared.config.js", "cart": "cd examples/shopping-cart && webpack-dev-server --inline --hot --config ../webpack.shared.config.js", "chat": "cd examples/chat && webpack-dev-server --inline --hot --config ../webpack.shared.config.js", - "prepublish": "babel src --out-dir lib --presets es2015 --plugins add-module-exports", + "build": "node build/build.js", "test": "eslint src && mocha --compilers js:babel-core/register", "docs": "cd docs && gitbook serve", "deploy-docs": "cd docs && ./deploy.sh" @@ -29,13 +29,13 @@ }, "homepage": "https://github.com/vuejs/vuex#readme", "devDependencies": { - "babel-cli": "^6.6.0", "babel-core": "^6.2.1", "babel-loader": "^6.2.0", "babel-plugin-add-module-exports": "^0.1.1", "babel-plugin-transform-runtime": "^6.1.18", "babel-polyfill": "^6.2.0", "babel-preset-es2015": "^6.1.18", + "babel-preset-es2015-rollup": "^1.1.1", "babel-preset-stage-2": "^6.1.18", "babel-runtime": "^5.8.0", "chai": "^3.4.1", @@ -45,12 +45,15 @@ "eslint-plugin-promise": "^1.0.8", "eslint-plugin-standard": "^1.3.2", "mocha": "^2.3.4", - "style-loader": "^0.13.0", + "rollup": "^0.25.4", + "rollup-plugin-babel": "^2.4.0", "todomvc-app-css": "^2.0.3", + "uglify-js": "^2.6.2", "vue": "^1.0.8", "vue-hot-reload-api": "^1.2.1", "vue-html-loader": "^1.0.0", "vue-loader": "^8.2.0", + "vue-style-loader": "^1.0.0", "webpack": "^1.12.8", "webpack-dev-server": "^1.12.1" }