├── .babelrc ├── .eslintrc ├── .gitignore ├── .npmignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── index.js ├── lib ├── __tests__ │ └── index.js └── index.js ├── package.json └── scripts ├── mocha_runner.js └── prepublish.sh /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015", "stage-2", "react"] 3 | } -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | 4 | "plugins": [ 5 | "babel", "react" 6 | ], 7 | 8 | "env": { 9 | "es6": true, 10 | "node": true 11 | }, 12 | 13 | "ecmaFeatures": { 14 | "arrowFunctions": true, 15 | "binaryLiterals": true, 16 | "blockBindings": true, 17 | "classes": true, 18 | "defaultParams": true, 19 | "destructuring": true, 20 | "experimentalObjectRestSpread": true, 21 | "forOf": true, 22 | "generators": true, 23 | "globalReturn": true, 24 | "jsx": true, 25 | "modules": true, 26 | "objectLiteralComputedProperties": true, 27 | "objectLiteralDuplicateProperties": true, 28 | "objectLiteralShorthandMethods": true, 29 | "objectLiteralShorthandProperties": true, 30 | "octalLiterals": true, 31 | "regexUFlag": true, 32 | "regexYFlag": true, 33 | "restParams": true, 34 | "spread": true, 35 | "superInFunctions": true, 36 | "templateStrings": true, 37 | "unicodeCodePointEscapes": true 38 | }, 39 | 40 | "rules": { 41 | "babel/arrow-parens": [2, "as-needed"], 42 | 43 | "array-bracket-spacing": [2, "always"], 44 | "arrow-spacing": 2, 45 | "block-scoped-var": 0, 46 | "brace-style": [2, "1tbs", {"allowSingleLine": true}], 47 | "callback-return": 2, 48 | "camelcase": [2, {"properties": "always"}], 49 | "comma-dangle": 0, 50 | "comma-spacing": 0, 51 | "comma-style": [2, "last"], 52 | "complexity": 0, 53 | "computed-property-spacing": [2, "never"], 54 | "consistent-return": 0, 55 | "consistent-this": 0, 56 | "curly": [2, "all"], 57 | "default-case": 0, 58 | "dot-location": [2, "property"], 59 | "dot-notation": 0, 60 | "eol-last": 2, 61 | "eqeqeq": 2, 62 | "func-names": 0, 63 | "func-style": 0, 64 | "generator-star-spacing": [0, {"before": true, "after": false}], 65 | "guard-for-in": 2, 66 | "handle-callback-err": [2, "error"], 67 | "id-length": 0, 68 | "id-match": [2, "^(?:_?[a-zA-Z0-9]*)|[_A-Z0-9]+$"], 69 | "indent": [2, 2, {"SwitchCase": 1}], 70 | "init-declarations": 0, 71 | "key-spacing": [2, {"beforeColon": false, "afterColon": true}], 72 | "linebreak-style": 2, 73 | "lines-around-comment": 0, 74 | "max-depth": 0, 75 | "max-len": [2, 80, 4], 76 | "max-nested-callbacks": 0, 77 | "max-params": 0, 78 | "max-statements": 0, 79 | "new-cap": 0, 80 | "new-parens": 2, 81 | "newline-after-var": 0, 82 | "no-alert": 2, 83 | "no-array-constructor": 2, 84 | "no-bitwise": 0, 85 | "no-caller": 2, 86 | "no-catch-shadow": 0, 87 | "no-class-assign": 2, 88 | "no-cond-assign": 2, 89 | "no-console": 1, 90 | "no-const-assign": 2, 91 | "no-constant-condition": 2, 92 | "no-continue": 0, 93 | "no-control-regex": 0, 94 | "no-debugger": 1, 95 | "no-delete-var": 2, 96 | "no-div-regex": 2, 97 | "no-dupe-args": 2, 98 | "no-dupe-keys": 2, 99 | "no-duplicate-case": 2, 100 | "no-else-return": 2, 101 | "no-empty": 2, 102 | "no-empty-character-class": 2, 103 | "no-empty-label": 2, 104 | "no-eq-null": 0, 105 | "no-eval": 2, 106 | "no-ex-assign": 2, 107 | "no-extend-native": 2, 108 | "no-extra-bind": 2, 109 | "no-extra-boolean-cast": 2, 110 | "no-extra-parens": 0, 111 | "no-extra-semi": 2, 112 | "no-fallthrough": 2, 113 | "no-floating-decimal": 2, 114 | "no-func-assign": 2, 115 | "no-implicit-coercion": 2, 116 | "no-implied-eval": 2, 117 | "no-inline-comments": 0, 118 | "no-inner-declarations": [2, "functions"], 119 | "no-invalid-regexp": 2, 120 | "no-invalid-this": 0, 121 | "no-irregular-whitespace": 2, 122 | "no-iterator": 2, 123 | "no-label-var": 2, 124 | "no-labels": 0, 125 | "no-lone-blocks": 2, 126 | "no-lonely-if": 2, 127 | "no-loop-func": 0, 128 | "no-mixed-requires": [2, true], 129 | "no-mixed-spaces-and-tabs": 2, 130 | "no-multi-spaces": 2, 131 | "no-multi-str": 2, 132 | "no-multiple-empty-lines": 0, 133 | "no-native-reassign": 0, 134 | "no-negated-in-lhs": 2, 135 | "no-nested-ternary": 0, 136 | "no-new": 2, 137 | "no-new-func": 0, 138 | "no-new-object": 2, 139 | "no-new-require": 2, 140 | "no-new-wrappers": 2, 141 | "no-obj-calls": 2, 142 | "no-octal": 2, 143 | "no-octal-escape": 2, 144 | "no-param-reassign": 2, 145 | "no-path-concat": 2, 146 | "no-plusplus": 0, 147 | "no-process-env": 0, 148 | "no-process-exit": 0, 149 | "no-proto": 2, 150 | "no-redeclare": 2, 151 | "no-regex-spaces": 2, 152 | "no-restricted-modules": 0, 153 | "no-return-assign": 2, 154 | "no-script-url": 2, 155 | "no-self-compare": 0, 156 | "no-sequences": 2, 157 | "no-shadow": 2, 158 | "no-shadow-restricted-names": 2, 159 | "no-spaced-func": 2, 160 | "no-sparse-arrays": 2, 161 | "no-sync": 2, 162 | "no-ternary": 0, 163 | "no-this-before-super": 2, 164 | "no-throw-literal": 2, 165 | "no-trailing-spaces": 2, 166 | "no-undef": 2, 167 | "no-undef-init": 2, 168 | "no-undefined": 0, 169 | "no-underscore-dangle": 0, 170 | "no-unexpected-multiline": 2, 171 | "no-unneeded-ternary": 2, 172 | "no-unreachable": 2, 173 | "no-unused-expressions": 2, 174 | "no-unused-vars": [2, {"vars": "all", "args": "after-used"}], 175 | "no-use-before-define": 0, 176 | "no-useless-call": 2, 177 | "no-var": 0, 178 | "no-void": 2, 179 | "no-warning-comments": 0, 180 | "no-with": 2, 181 | "object-curly-spacing": [0, "always"], 182 | "object-shorthand": [2, "always"], 183 | "one-var": [2, "never"], 184 | "operator-assignment": [2, "always"], 185 | "operator-linebreak": [2, "after"], 186 | "padded-blocks": 0, 187 | "prefer-const": 0, 188 | "prefer-reflect": 0, 189 | "prefer-spread": 0, 190 | "quote-props": [2, "as-needed"], 191 | "quotes": [2, "single"], 192 | "radix": 2, 193 | "require-yield": 2, 194 | "semi": [2, "always"], 195 | "semi-spacing": [2, {"before": false, "after": true}], 196 | "sort-vars": 0, 197 | "space-after-keywords": [2, "always"], 198 | "space-before-blocks": [2, "always"], 199 | "space-before-function-paren": [2, {"anonymous": "always", "named": "never"}], 200 | "space-in-parens": 0, 201 | "space-infix-ops": [2, {"int32Hint": false}], 202 | "space-return-throw-case": 2, 203 | "space-unary-ops": [2, {"words": true, "nonwords": false}], 204 | "spaced-comment": [2, "always"], 205 | "strict": 0, 206 | "use-isnan": 2, 207 | "valid-jsdoc": 0, 208 | "valid-typeof": 2, 209 | "vars-on-top": 0, 210 | "wrap-iife": 2, 211 | "wrap-regex": 0, 212 | "yoda": [2, "never", {"exceptRange": true}] 213 | } 214 | } 215 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | *~ 3 | *.iml 4 | .*.haste_cache.* 5 | .DS_Store 6 | .idea 7 | npm-debug.log 8 | node_modules 9 | dist -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | *~ 3 | *.iml 4 | .*.haste_cache.* 5 | .DS_Store 6 | .idea 7 | .babelrc 8 | .eslintrc 9 | npm-debug.log 10 | lib 11 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # ChangeLog 2 | 3 | ### v1.2.0 4 | 5 | * Update React to v15.0.0 6 | 7 | ### v1.1.0 8 | 9 | * Add support for React Native. See [PR4](https://github.com/kadirahq/react-simple-di/pull/4) 10 | 11 | ### v1.0.1 12 | * Fix issue of re-binding context to action multiple times as we apply context multiple time. 13 | See: [#2](https://github.com/kadirahq/react-simple-di/issues/2) 14 | 15 | ### v1.0.0 16 | 17 | Initial Version. 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Kadira Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-simple-di 2 | 3 | Simple dependancy injection solution for React. 4 | 5 | ### Installation 6 | 7 | ``` 8 | npm i react-simple-di 9 | ``` 10 | 11 | ### Intro 12 | 13 | In `react-simple-di`, we've two types of dependencies, they are: 14 | 15 | 1. context - These are usually, configurations, models and client for different remote data solutions. 16 | 2. actions - Actions are simple functions which used to perform business logic with the help of the above context. 17 | 18 | > Every action will receive the `context` as it's first argument. 19 | 20 | ### Injecting Dependancies 21 | 22 | First, we need to inject dependencies to a root level React component. Mostly, this will be the main layout component of our app. 23 | 24 | Here are our dependencies: 25 | ```js 26 | const context = { 27 | DB, 28 | Router, 29 | appName: 'My Blog' 30 | }; 31 | 32 | const actions = { 33 | posts: { 34 | create({DB, Router}, title, content) { 35 | const id = String(Math.random()); 36 | DB.createPost(id, title, content); 37 | Router.go(`/post/${id}`); 38 | } 39 | } 40 | }; 41 | ``` 42 | 43 | First we've defined our context. Then, we have our actions. Here actions must follow a structure like mentioned above. 44 | 45 | Let's inject our dependencies: 46 | 47 | ```js 48 | import {injectDeps} from 'react-simple-di'; 49 | import Layout from './layout.jsx'; 50 | 51 | // Above mentioned actions and context are defined here. 52 | 53 | const LayoutWithDeps = injectDeps(context, actions)(Layout); 54 | ``` 55 | 56 | Now you can use `LayoutWithDeps` anywhere in your app. 57 | 58 | ## Using Depedencies 59 | 60 | Any component rendered inside `LayoutWithDeps` can access both context and actions. 61 | 62 | When using dependecies it will compose a new React component and pass dependencies via props to the original component. 63 | 64 | First let's create our UI component. Here it will expect dependecies to come via props `appName` and `createPost`. 65 | 66 | ```js 67 | class CreatePost extends React.Component { 68 | render() { 69 | const {appName} = this.props; 70 | return ( 71 |
72 | Create a blog post on app: ${appName}.
73 | 74 |
75 | ); 76 | } 77 | 78 | create() { 79 | const {createPost} = this.props; 80 | createPost('My Blog Title', 'Some Content'); 81 | } 82 | } 83 | ``` 84 | 85 | So, let's use dependencies: 86 | 87 | ```js 88 | import {useDeps} from 'react-simple-di'; 89 | 90 | // Assume above mentioned CreatePost react component is 91 | // defined here. 92 | 93 | const depsToPropsMapper = (context, actions) => ({ 94 | appName: context.appName, 95 | createPost: actions.posts.create 96 | }); 97 | 98 | const CreatePostWithDeps = useDeps(depsToPropsMapper)(CreatePost); 99 | ``` 100 | 101 | That's it. 102 | 103 | > Note: Here when calling the `actions.posts.create` action, you don't need to provide the context as the first argument. It'll handle by `react-simple-di`. 104 | 105 | **Default Mapper** 106 | 107 | If you didn't provide a mapper function, useDeps will use a default mapper function will allows you to get context and props directy. Here's that default mapper: 108 | 109 | ```js 110 | const mapper = (context, actions) => ({ 111 | context: () => context, 112 | actions: () => actions 113 | }); 114 | ``` 115 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./dist/index'); -------------------------------------------------------------------------------- /lib/__tests__/index.js: -------------------------------------------------------------------------------- 1 | /* */ 2 | 3 | import {describe, it} from 'mocha'; 4 | import {expect} from 'chai'; 5 | import {injectDeps, useDeps} from '../'; 6 | import {shallow} from 'enzyme'; 7 | import React from 'react'; 8 | 9 | describe('Depedancy Injection', () => { 10 | it('should inject context and allow to use them', () => { 11 | const context = {name: 'arunoda'}; 12 | const Layout = class extends React.Component { 13 | render() { 14 | return this.props.children; 15 | } 16 | }; 17 | const LayoutWithDeps = injectDeps(context)(Layout); 18 | 19 | const Comp = ({name}) => (

{name}

); 20 | const mapper = c => ({ 21 | name: c.name 22 | }); 23 | const CompWithDeps = useDeps(mapper)(Comp); 24 | 25 | const el = shallow(( 26 |
27 | 28 | 29 | 30 |
31 | )); 32 | 33 | expect(el.html()).to.match(/arunoda/); 34 | }); 35 | 36 | it('should inject actions and allow to use them', () => { 37 | const context = {name: 'arunoda'}; 38 | const actions = { 39 | default: { 40 | getFullName({name}, surname) { 41 | return `${name}-${surname}`; 42 | } 43 | } 44 | }; 45 | const Layout = ({children}) => children; 46 | const LayoutWithDeps = injectDeps(context, actions)(Layout); 47 | 48 | const Comp = ({getName}) => (

{getName('susiripala')}

); 49 | const mapper = (c, a) => ({ 50 | getName: a.default.getFullName 51 | }); 52 | const CompWithDeps = useDeps(mapper)(Comp); 53 | 54 | const el = shallow(( 55 |
56 | 57 | 58 | 59 |
60 | )); 61 | 62 | expect(el.html()).to.match(/arunoda-susiripala/); 63 | }); 64 | 65 | it('should let use inject actions multiple times', () => { 66 | const context = {name: 'arunoda'}; 67 | const actions = { 68 | default: { 69 | getFullName({name}, surname) { 70 | return `${name}-${surname}`; 71 | } 72 | } 73 | }; 74 | const Layout = ({children}) => children; 75 | 76 | // Injecting again to make sure action binding works fine. 77 | injectDeps(context, actions)(Layout); 78 | 79 | const LayoutWithDeps = injectDeps(context, actions)(Layout); 80 | 81 | const Comp = ({getName}) => (

{getName('susiripala')}

); 82 | const mapper = (c, a) => ({ 83 | getName: a.default.getFullName 84 | }); 85 | const CompWithDeps = useDeps(mapper)(Comp); 86 | 87 | const el = shallow(( 88 |
89 | 90 | 91 | 92 |
93 | )); 94 | 95 | expect(el.html()).to.match(/arunoda-susiripala/); 96 | }); 97 | 98 | it('should use a default mapper if no mapper is provided', () => { 99 | const context = {name: 'arunoda'}; 100 | const actions = { 101 | default: { 102 | getFullName({name}, surname) { 103 | return `${name}-${surname}`; 104 | } 105 | } 106 | }; 107 | const Layout = ({children}) => children; 108 | const LayoutWithDeps = injectDeps(context, actions)(Layout); 109 | 110 | const Comp = props => (

{ 111 | props.actions().default.getFullName(props.context().name) 112 | }

); 113 | const CompWithDeps = useDeps()(Comp); 114 | 115 | const el = shallow(( 116 |
117 | 118 | 119 | 120 |
121 | )); 122 | 123 | expect(el.html()).to.match(/arunoda-arunoda/); 124 | }); 125 | 126 | it('should preseve original props', () => { 127 | const context = {}; 128 | const Layout = ({children}) => children; 129 | const LayoutWithDeps = injectDeps(context)(Layout); 130 | 131 | const Comp = ({name}) => (

{name}

); 132 | const CompWithDeps = useDeps()(Comp); 133 | 134 | const el = shallow(( 135 |
136 | 137 | 138 | 139 |
140 | )); 141 | 142 | expect(el.html()).to.match(/arunoda/); 143 | }); 144 | }); 145 | 146 | describe('Misc', () => { 147 | describe('static fields', () => { 148 | it('should preseve when injecting deps', () => { 149 | const Layout = () => (

); 150 | Layout.theme = 'light'; 151 | 152 | const LayoutWithDeps = injectDeps({})(Layout); 153 | expect(LayoutWithDeps.theme).to.be.equal('light'); 154 | }); 155 | 156 | it('should preseve when using deps', () => { 157 | const Comp = () => (

); 158 | Comp.theme = 'light'; 159 | 160 | const CompWithDeps = useDeps()(Comp); 161 | expect(CompWithDeps.theme).to.be.equal('light'); 162 | }); 163 | }); 164 | 165 | describe('displayName', () => { 166 | it('should extend when injecting deps', () => { 167 | const Layout = () => (

); 168 | Layout.displayName = 'TheLayout'; 169 | 170 | const LayoutWithDeps = injectDeps({})(Layout); 171 | expect(LayoutWithDeps.displayName).to.be.equal('WithDeps(TheLayout)'); 172 | }); 173 | 174 | it('should extend when using deps', () => { 175 | const Comp = () => (

); 176 | Comp.displayName = 'TheComp'; 177 | 178 | const CompWithDeps = useDeps()(Comp); 179 | expect(CompWithDeps.displayName).to.be.equal('UseDeps(TheComp)'); 180 | }); 181 | }); 182 | }); 183 | -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import hoistStatics from 'hoist-non-react-statics'; 3 | 4 | const getDisplayName = Component => ( 5 | Component.displayName || Component.name || 'Component' 6 | ); 7 | 8 | export function injectDeps(context, _actions) { 9 | const actions = {}; 10 | for (let key in _actions) { 11 | if (_actions.hasOwnProperty(key)) { 12 | const actionMap = _actions[key]; 13 | const newActionMap = {}; 14 | for (let actionName in actionMap) { 15 | if (actionMap.hasOwnProperty(actionName)) { 16 | newActionMap[actionName] = actionMap[actionName].bind(null, context); 17 | } 18 | } 19 | actions[key] = newActionMap; 20 | } 21 | } 22 | 23 | return function (Component) { 24 | const ComponentWithDeps = React.createClass({ 25 | childContextTypes: { 26 | context: React.PropTypes.object, 27 | actions: React.PropTypes.object 28 | }, 29 | 30 | getChildContext() { 31 | return { 32 | context, 33 | actions 34 | }; 35 | }, 36 | 37 | render() { 38 | return (); 39 | } 40 | }); 41 | 42 | ComponentWithDeps.displayName = `WithDeps(${getDisplayName(Component)})`; 43 | return hoistStatics(ComponentWithDeps, Component); 44 | }; 45 | } 46 | 47 | const defaultMapper = (context, actions) => ({ 48 | context: () => context, 49 | actions: () => actions 50 | }); 51 | 52 | export function useDeps(mapper = defaultMapper) { 53 | return function (Component) { 54 | const ComponentUseDeps = React.createClass({ 55 | render() { 56 | const {context, actions} = this.context; 57 | const mappedProps = mapper(context, actions); 58 | 59 | const newProps = { 60 | ...this.props, 61 | ...mappedProps 62 | }; 63 | 64 | return (); 65 | }, 66 | 67 | contextTypes: { 68 | context: React.PropTypes.object, 69 | actions: React.PropTypes.object 70 | } 71 | }); 72 | 73 | ComponentUseDeps.displayName = `UseDeps(${getDisplayName(Component)})`; 74 | return hoistStatics(ComponentUseDeps, Component); 75 | }; 76 | } 77 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-simple-di", 3 | "version": "1.2.0", 4 | "description": "Simple Dependancy Injection Solution for React", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/kadirahq/react-simple-di" 8 | }, 9 | "license": "MIT", 10 | "options": { 11 | "mocha": "--require scripts/mocha_runner lib/**/__tests__/**/*.js" 12 | }, 13 | "scripts": { 14 | "prepublish": ". ./scripts/prepublish.sh", 15 | "lint": "eslint ./lib", 16 | "lintfix": "eslint ./lib --fix", 17 | "testonly": "mocha $npm_package_options_mocha", 18 | "test": "npm run lint && npm run testonly" 19 | }, 20 | "devDependencies": { 21 | "nodemon": "1.7.x", 22 | "mocha": "2.x.x", 23 | "chai": "3.x.x", 24 | "eslint": "1.7.x", 25 | "eslint-plugin-react": "3.x.x", 26 | "babel-eslint": "4.x.x", 27 | "eslint-plugin-babel": "2.x.x", 28 | "babel-cli": "6.x.x", 29 | "babel-core": "6.x.x", 30 | "babel-polyfill": "6.x.x", 31 | "babel-preset-es2015": "6.x.x", 32 | "babel-preset-stage-2": "6.x.x", 33 | "babel-preset-react": "6.x.x", 34 | "babel-plugin-transform-runtime": "6.x.x", 35 | "react": "^15.0.0", 36 | "react-dom": "^15.0.0", 37 | "react-addons-test-utils": "^15.0.0", 38 | "enzyme": "^2.2.0" 39 | }, 40 | "peerDependencies": { 41 | "react": "^0.14.0 || ^15.0.0" 42 | }, 43 | "dependencies": { 44 | "babel-runtime": "6.x.x", 45 | "hoist-non-react-statics": "1.x.x" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /scripts/mocha_runner.js: -------------------------------------------------------------------------------- 1 | require('babel-core/register'); 2 | require('babel-polyfill'); 3 | 4 | process.on('unhandledRejection', function (error) { 5 | console.error('Unhandled Promise Rejection:'); 6 | console.error(error && error.stack || error); 7 | }); 8 | -------------------------------------------------------------------------------- /scripts/prepublish.sh: -------------------------------------------------------------------------------- 1 | echo "> Start transpiling ES2015" 2 | echo "" 3 | ./node_modules/.bin/babel --plugins "transform-runtime" lib --ignore __tests__ --out-dir ./dist 4 | echo "" 5 | echo "> Complete transpiling ES2015" --------------------------------------------------------------------------------