diff --git a/package.json b/package.json index 54d62a01d1..5a4c34f628 100644 --- a/package.json +++ b/package.json @@ -66,10 +66,6 @@ "webpack": "^1.9.6", "webpack-dev-server": "^1.8.2" }, - "dependencies": { - "invariant": "^2.0.0", - "warning": "^2.0.0" - }, "npmName": "redux", "npmFileMap": [ { diff --git a/src/createStore.js b/src/createStore.js index 43b76ae5d1..085af13c12 100644 --- a/src/createStore.js +++ b/src/createStore.js @@ -1,4 +1,3 @@ -import invariant from 'invariant'; import isPlainObject from './utils/isPlainObject'; /** @@ -32,10 +31,9 @@ export var ActionTypes = { * and subscribe to changes. */ export default function createStore(reducer, initialState) { - invariant( - typeof reducer === 'function', - 'Expected the reducer to be a function.' - ); + if (typeof reducer !== 'function') { + throw new Error('Expected the reducer to be a function.'); + } var currentReducer = reducer; var currentState = initialState; @@ -92,15 +90,13 @@ export default function createStore(reducer, initialState) { * return something else (for example, a Promise you can await). */ function dispatch(action) { - invariant( - isPlainObject(action), - 'Actions must be plain objects. Use custom middleware for async actions.' - ); + if (!isPlainObject(action)) { + throw new Error('Actions must be plain objects. Use custom middleware for async actions.'); + } - invariant( - isDispatching === false, - 'Reducers may not dispatch actions.' - ); + if (isDispatching) { + throw new Error('Reducers may not dispatch actions.'); + } try { isDispatching = true; diff --git a/src/utils/bindActionCreators.js b/src/utils/bindActionCreators.js index 977ab90dc6..6134f445a6 100644 --- a/src/utils/bindActionCreators.js +++ b/src/utils/bindActionCreators.js @@ -1,4 +1,3 @@ -import invariant from 'invariant'; import mapValues from '../utils/mapValues'; function bindActionCreator(actionCreator, dispatch) { @@ -31,12 +30,12 @@ export default function bindActionCreators(actionCreators, dispatch) { return bindActionCreator(actionCreators, dispatch); } - invariant( - typeof actionCreators === 'object' && actionCreators != null, - 'bindActionCreators expected an object or a function, instead received %s. ' + - 'Did you write "import ActionCreators from" instead of "import * as ActionCreators from"?', - typeof actionCreators - ); + if (typeof actionCreators !== 'object' || actionCreators == null) { + throw new Error( + `bindActionCreators expected an object or a function, instead received ${typeof actionCreators}. ` + + `Did you write "import ActionCreators from" instead of "import * as ActionCreators from"?` + ); + } return mapValues(actionCreators, actionCreator => bindActionCreator(actionCreator, dispatch) diff --git a/src/utils/combineReducers.js b/src/utils/combineReducers.js index 1a9fca8973..aebe5b66b5 100644 --- a/src/utils/combineReducers.js +++ b/src/utils/combineReducers.js @@ -2,8 +2,6 @@ import { ActionTypes } from '../createStore'; import isPlainObject from '../utils/isPlainObject'; import mapValues from '../utils/mapValues'; import pick from '../utils/pick'; -import invariant from 'invariant'; -import warning from 'warning'; function getErrorMessage(key, action) { var actionType = action && action.type; @@ -19,8 +17,7 @@ function verifyStateShape(initialState, currentState) { var reducerKeys = Object.keys(currentState); if (reducerKeys.length === 0) { - warning( - false, + console.error( 'Store does not have a valid reducer. Make sure the argument passed ' + 'to combineReducers is an object whose values are reducers.' ); @@ -28,8 +25,7 @@ function verifyStateShape(initialState, currentState) { } if (!isPlainObject(initialState)) { - warning( - false, + console.error( 'initialState has unexpected type of "' + ({}).toString.call(initialState).match(/\s([a-z|A-Z]+)/)[1] + '". Expected initialState to be an object with the following ' + @@ -42,12 +38,13 @@ function verifyStateShape(initialState, currentState) { key => reducerKeys.indexOf(key) < 0 ); - warning( - unexpectedKeys.length === 0, - `Unexpected ${unexpectedKeys.length > 1 ? 'keys' : 'key'} ` + - `"${unexpectedKeys.join('", "')}" in initialState will be ignored. ` + - `Expected to find one of the known reducer keys instead: "${reducerKeys.join('", "')}"` - ); + if (unexpectedKeys.length > 0) { + console.error( + `Unexpected ${unexpectedKeys.length > 1 ? 'keys' : 'key'} ` + + `"${unexpectedKeys.join('", "')}" in initialState will be ignored. ` + + `Expected to find one of the known reducer keys instead: "${reducerKeys.join('", "')}"` + ); + } } /** @@ -72,24 +69,26 @@ export default function combineReducers(reducers) { Object.keys(finalReducers).forEach(key => { var reducer = finalReducers[key]; - invariant( - typeof reducer(undefined, { type: ActionTypes.INIT }) !== 'undefined', - `Reducer "${key}" returned undefined during initialization. ` + - `If the state passed to the reducer is undefined, you must ` + - `explicitly return the initial state. The initial state may ` + - `not be undefined.` - ); + if (typeof reducer(undefined, { type: ActionTypes.INIT }) === 'undefined') { + throw new Error( + `Reducer "${key}" returned undefined during initialization. ` + + `If the state passed to the reducer is undefined, you must ` + + `explicitly return the initial state. The initial state may ` + + `not be undefined.` + ); + } var type = Math.random().toString(36).substring(7).split('').join('.'); - invariant( - typeof reducer(undefined, { type }) !== 'undefined', - `Reducer "${key}" returned undefined when probed with a random type. ` + - `Don't try to handle ${ActionTypes.INIT} or other actions in "redux/*" ` + - `namespace. They are considered private. Instead, you must return the ` + - `current state for any unknown actions, unless it is undefined, ` + - `in which case you must return the initial state, regardless of the ` + - `action type. The initial state may not be undefined.` - ); + if (typeof reducer(undefined, { type }) === 'undefined') { + throw new Error( + `Reducer "${key}" returned undefined when probed with a random type. ` + + `Don't try to handle ${ActionTypes.INIT} or other actions in "redux/*" ` + + `namespace. They are considered private. Instead, you must return the ` + + `current state for any unknown actions, unless it is undefined, ` + + `in which case you must return the initial state, regardless of the ` + + `action type. The initial state may not be undefined.` + ); + } }); var defaultState = mapValues(finalReducers, () => undefined); @@ -98,10 +97,9 @@ export default function combineReducers(reducers) { return function combination(state = defaultState, action) { var finalState = mapValues(finalReducers, (reducer, key) => { var newState = reducer(state[key], action); - invariant( - typeof newState !== 'undefined', - getErrorMessage(key, action) - ); + if (typeof newState === 'undefined') { + throw new Error(getErrorMessage(key, action)); + } return newState; }); diff --git a/test/utils/bindActionCreators.spec.js b/test/utils/bindActionCreators.spec.js index 2c55e4ad82..affbd64965 100644 --- a/test/utils/bindActionCreators.spec.js +++ b/test/utils/bindActionCreators.spec.js @@ -38,7 +38,7 @@ describe('bindActionCreators', () => { ]); }); - it('should throw an invariant violation for an undefined actionCreator', () => { + it('should throw for an undefined actionCreator', () => { expect(() => { bindActionCreators(undefined, store.dispatch); }).toThrow( @@ -47,7 +47,7 @@ describe('bindActionCreators', () => { ); }); - it('should throw an invariant violation for a null actionCreator', () => { + it('should throw for a null actionCreator', () => { expect(() => { bindActionCreators(null, store.dispatch); }).toThrow( @@ -56,7 +56,7 @@ describe('bindActionCreators', () => { ); }); - it('should throw an invariant violation for a primitive actionCreator', () => { + it('should throw for a primitive actionCreator', () => { expect(() => { bindActionCreators('string', store.dispatch); }).toThrow(