├── .eslintrc ├── .gitignore ├── LICENSE ├── README.md ├── demo ├── App.js └── index.js ├── lerna.json ├── package.json ├── packages ├── rax-polyfill-all │ ├── .babelrc │ ├── README.md │ ├── package.json │ └── src │ │ └── index.js ├── rax-polyfill-context │ ├── .babelrc │ ├── README.md │ ├── package.json │ └── src │ │ └── index.js ├── rax-polyfill-hooks │ ├── .babelrc │ ├── README.md │ ├── package.json │ └── src │ │ └── index.js ├── rax-polyfill-memo │ ├── .babelrc │ ├── README.md │ ├── package.json │ └── src │ │ └── index.js ├── rax-polyfill-ref │ ├── .babelrc │ ├── README.md │ ├── package.json │ └── src │ │ └── index.js ├── react-polyfill-all │ ├── .babelrc │ ├── README.md │ ├── package.json │ └── src │ │ ├── index.d.ts │ │ └── index.js ├── react-polyfill-context │ ├── .babelrc │ ├── README.md │ ├── package.json │ └── src │ │ └── index.js ├── react-polyfill-fragment │ ├── .babelrc │ ├── README.md │ ├── package.json │ └── src │ │ └── index.js ├── react-polyfill-hooks │ ├── .babelrc │ ├── README.md │ ├── package.json │ └── src │ │ └── index.js ├── react-polyfill-memo │ ├── .babelrc │ ├── README.md │ ├── package.json │ └── src │ │ └── index.js ├── react-polyfill-patch │ ├── .babelrc │ ├── README.md │ ├── package.json │ └── src │ │ └── index.js ├── react-polyfill-portal │ ├── .babelrc │ ├── README.md │ ├── package.json │ └── src │ │ └── index.js ├── react-polyfill-pure-component │ ├── .babelrc │ ├── README.md │ ├── package.json │ └── src │ │ └── index.js ├── react-polyfill-ref │ ├── .babelrc │ ├── README.md │ ├── package.json │ └── src │ │ └── index.js ├── universal-polyfill-context │ ├── .babelrc │ ├── README.md │ ├── package.json │ └── src │ │ └── index.js ├── universal-polyfill-engine │ ├── .babelrc │ ├── README.md │ ├── package.json │ └── src │ │ └── index.js ├── universal-polyfill-hooks │ ├── .babelrc │ ├── README.md │ ├── package.json │ └── src │ │ ├── dispatcher.js │ │ ├── index.js │ │ ├── types.js │ │ └── utils.js ├── universal-polyfill-memo │ ├── .babelrc │ ├── README.md │ ├── package.json │ └── src │ │ └── index.js └── universal-polyfill-ref │ ├── .babelrc │ ├── README.md │ ├── package.json │ └── src │ └── index.js └── webpack.config.js /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | "env": { 4 | "browser": true, 5 | "es6": true 6 | }, 7 | "plugins": ["react", "import"], 8 | "extends": "eslint-config-ali/react", 9 | "parserOptions": { 10 | "ecmaVersion": 9, 11 | "sourceType": "module", 12 | "ecmaFeatures": { 13 | "jsx": true 14 | } 15 | }, 16 | "rules": { 17 | /**------CORE RULES START------**/ 18 | // errors 19 | "no-undef": [2, "always"], 20 | // disallow assignment in conditional expressions 21 | "no-cond-assign": [2, "always"], 22 | // disallow use of console 23 | "no-console": 1, 24 | // disallow use of constant expressions in conditions 25 | "no-constant-condition": 1, 26 | // disallow control characters in regular expressions 27 | "no-control-regex": 2, 28 | // disallow use of debugger 29 | "no-debugger": 1, 30 | // disallow duplicate arguments in functions 31 | "no-dupe-args": 2, 32 | // disallow duplicate keys when creating object literals 33 | "no-dupe-keys": 2, 34 | // disallow a duplicate case label. 35 | "no-duplicate-case": 2, 36 | // disallow the use of empty character classes in regular expressions 37 | "no-empty-character-class": 2, 38 | // disallow empty statements 39 | "no-empty": 2, 40 | // disallow assigning to the exception in a catch block 41 | "no-ex-assign": 2, 42 | // disallow double-negation boolean casts in a boolean context 43 | "no-extra-boolean-cast": 0, 44 | // disallow unnecessary parentheses 45 | // http://eslint.org/docs/rules/no-extra-parens 46 | "no-extra-parens": [0, "all", { 47 | "conditionalAssign": true, 48 | "nestedBinaryExpressions": false, 49 | }], 50 | // disallow unnecessary semicolons 51 | "no-extra-semi": 2, 52 | // disallow overwriting functions written as function declarations 53 | "no-func-assign": 2, 54 | // disallow function or variable declarations in nested blocks 55 | "no-inner-declarations": 2, 56 | // disallow invalid regular expression strings in the RegExp constructor 57 | "no-invalid-regexp": 2, 58 | // disallow irregular whitespace outside of strings and comments 59 | "no-irregular-whitespace": 2, 60 | // disallow negation of the left operand of an in expression 61 | "no-negated-in-lhs": 2, 62 | // disallow the use of object properties of the global object (Math and JSON) as functions 63 | "no-obj-calls": 2, 64 | // disallow multiple spaces in a regular expression literal 65 | "no-regex-spaces": 2, 66 | // disallow sparse arrays 67 | "no-sparse-arrays": 2, 68 | // disallow trailing whitespace at the end of lines 69 | "no-trailing-spaces": [2, { "skipBlankLines": true }], 70 | // disallow unreachable statements after a return, throw, continue, or break statement 71 | "no-unreachable": 2, 72 | // disallow comparisons with the value NaN 73 | "use-isnan": 2, 74 | // ensure JSDoc comments are valid 75 | // http://eslint.org/docs/rules/valid-jsdoc 76 | "valid-jsdoc": 0, 77 | // ensure that the results of typeof are compared against a valid string 78 | "valid-typeof": 2, 79 | // Avoid code that looks like two expressions but is actually one 80 | "no-unexpected-multiline": 0, 81 | 82 | // es6 83 | // disallow invalid exports, e.g. multiple defaults 84 | // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/export.md 85 | "import/export": 2, 86 | // ensure default import coupled with default export 87 | // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/default.md#when-not-to-use-it 88 | "import/default": 0, 89 | // Ensure consistent use of file extension within the import path 90 | // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/extensions.md 91 | "import/extensions": [0, "never"], 92 | // ensure named imports coupled with named exports 93 | // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/named.md#when-not-to-use-it 94 | "import/named": 2, 95 | // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/namespace.md 96 | "import/namespace": 0, 97 | // Forbid the use of extraneous packages 98 | // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-extraneous-dependencies.md 99 | "import/no-extraneous-dependencies": [0, { 100 | "devDependencies": false, 101 | "optionalDependencies": false, 102 | }], 103 | // ensure imports point to files/modules that can be resolved 104 | // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-unresolved.md 105 | "import/no-unresolved": 2, 106 | // do not allow a default import name to match a named export 107 | // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-named-as-default.md 108 | "import/no-named-as-default": 0, 109 | // disallow require() 110 | // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-commonjs.md 111 | "import/no-commonjs": 0, 112 | // disallow AMD require/define 113 | // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-amd.md 114 | "import/no-amd": 2, 115 | // disallow non-import statements appearing before import statements 116 | // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/imports-first.md 117 | "import/imports-first": [0, "absolute-first"], 118 | // disallow duplicate imports 119 | // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-duplicates.md 120 | "import/no-duplicates": 2, 121 | // disallow use of jsdoc-marked-deprecated imports 122 | // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-deprecated.md 123 | "import/no-deprecated": 0, 124 | // disallow namespace imports 125 | // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-namespace.md 126 | "import/no-namespace": 0, 127 | // warn on accessing default export property names that are also named exports 128 | // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-named-as-default-member.md 129 | "import/no-named-as-default-member": 0, 130 | // No Node.js builtin modules 131 | // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-nodejs-modules.md 132 | "import/no-nodejs-modules": 0, 133 | // Enforce a convention in module import order 134 | // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/order.md 135 | "import/order": [0, { 136 | "groups": ["builtin", "external", "internal", "parent", "sibling", "index"], 137 | "newlines-between": "never", 138 | }], 139 | // Require a newline after the last import/require in a group 140 | // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/newline-after-import.md 141 | "import/newline-after-import": 0, 142 | // Forbid mutable exports 143 | // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-mutable-exports.md 144 | "import/no-mutable-exports": 2, 145 | /**------CORE RULES END------**/ 146 | 147 | /*------ code styles------**/ 148 | "comma-dangle": [2, "only-multiline"], 149 | "react/jsx-closing-bracket-location": [1, "after-props"], 150 | "no-new": 1, 151 | "new-cap": ["warn", {"capIsNewExceptions": ["CSSModules"]}] 152 | } 153 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # TypeScript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # next.js build output 61 | .next 62 | 63 | lib 64 | 65 | package-lock.json 66 | yarn.lock 67 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 ningzbruc 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 all 13 | 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 THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-polyfills 2 | 3 | > React/Rax polyfills for ref, context and hooks 4 | 5 | ## usage 6 | 7 | ### React 8 | 9 | > version < v16.3 10 | 11 | ```js 12 | import { 13 | // memo 14 | memo, 15 | // ref 16 | createRef, 17 | forwardRef, 18 | // Fragment 19 | Fragment, 20 | // PureComponent 21 | PureComponent, 22 | // portal 23 | createPortal, 24 | // context 25 | createContext, 26 | // hooks 27 | withHooks, 28 | useRef, 29 | useState, 30 | useContext, 31 | useReducer, 32 | useEffect, 33 | useLayoutEffect, 34 | useMemo, 35 | useCallback, 36 | useImperativeHandle 37 | } from 'react-polyfill-all'; 38 | ``` 39 | 40 | #### use react patch 41 | 42 | ```js 43 | import 'react-polyfill-patch'; 44 | import { 45 | // memo 46 | memo, 47 | // ref 48 | createRef, 49 | forwardRef, 50 | // Fragment 51 | Fragment, 52 | // PureComponent 53 | PureComponent, 54 | // context 55 | createContext, 56 | // hooks 57 | useRef, 58 | useState, 59 | useContext, 60 | useReducer, 61 | useEffect, 62 | useLayoutEffect, 63 | useMemo, 64 | useCallback, 65 | useImperativeHandle 66 | } from 'react'; 67 | import { createPortal } from 'react-dom'; 68 | ``` 69 | 70 | ### Rax 71 | 72 | > version <= 0.6.7 73 | 74 | ```js 75 | import { 76 | // memo 77 | memo, 78 | // ref 79 | createRef, 80 | forwardRef, 81 | // context 82 | createContext, 83 | // hooks 84 | withHooks, 85 | useRef, 86 | useState, 87 | useContext, 88 | useReducer, 89 | useEffect, 90 | useLayoutEffect, 91 | useMemo, 92 | useCallback, 93 | useImperativeHandle 94 | } from 'rax-polyfill-all'; 95 | ``` 96 | 97 | ### More information 98 | 99 | * [react-polyfill-all](https://www.npmjs.com/package/react-polyfill-all) 100 | * [react-polyfill-patch](https://www.npmjs.com/package/react-polyfill-patch) 101 | * [rax-polyfill-all](https://www.npmjs.com/package/rax-polyfill-all) -------------------------------------------------------------------------------- /demo/App.js: -------------------------------------------------------------------------------- 1 | import 'react-polyfill-patch'; 2 | import React, { 3 | memo, 4 | Fragment, 5 | PureComponent, 6 | createRef, 7 | forwardRef, 8 | createContext, 9 | useState, 10 | useContext, 11 | useEffect, 12 | useLayoutEffect, 13 | useReducer, 14 | useCallback, 15 | useImperativeHandle, 16 | useRef 17 | } from 'react'; 18 | import { createPortal } from 'react-dom'; 19 | 20 | console.log([createRef()]); 21 | 22 | const Context = createContext(0); 23 | const Forward = forwardRef((props, ref) =>
Forward: {props.text}
); 24 | 25 | const Child = forwardRef(({ onAdd, onMinus }, ref) => { 26 | const inputRef = useRef(); 27 | const value = useContext(Context); 28 | const [state] = useState(0); 29 | 30 | useImperativeHandle(ref, () => ({ 31 | focus() { 32 | inputRef.current.focus(); 33 | } 34 | })); 35 | 36 | useLayoutEffect(() => { 37 | console.log('child layout'); 38 | return () => { 39 | console.log('child layout unmount'); 40 | }; 41 | }, [value <= 5]); 42 | 43 | useEffect(() => { 44 | console.log(state); 45 | console.log('child effect'); 46 | return () => { 47 | console.log('child unmount'); 48 | }; 49 | }, []); 50 | 51 | return ( 52 |
53 |

Child: {value}

54 |

+

55 |

-

56 | 57 |
58 | ); 59 | }); 60 | 61 | const Memo = memo(({ text }) => { 62 | return
memo: {text}
63 | }); 64 | 65 | const Pure = class extends PureComponent { 66 | render() { 67 | return
pure: {this.props.text}
68 | } 69 | }; 70 | 71 | const Portal = ({ children }) => { 72 | return createPortal(children, document.body); 73 | } 74 | 75 | const List = ({ items }) => { 76 | return ( 77 | 78 | {items.map((item, i) =>
  • {item}
  • )} 79 |
    80 | ); 81 | }; 82 | 83 | function reducer(state, action) { 84 | switch (action.type) { 85 | case 'add': 86 | return { count: state.count + 1 }; 87 | case 'minus': 88 | return { count: state.count - 1 }; 89 | default: 90 | return state; 91 | } 92 | } 93 | 94 | function getItems(length) { 95 | const items = []; 96 | for (let i = 0; i < length; i++) { 97 | items.push(length); 98 | } 99 | return items; 100 | } 101 | 102 | function App() { 103 | const ref = useRef(); 104 | const fRef = useRef(); 105 | const [state, dispatch] = useReducer(reducer, { count: 0 }); 106 | const add = useCallback(() => dispatch({ type: 'add' }), []); 107 | const minus = useCallback(() => dispatch({ type: 'minus' }), []); 108 | const focus = useCallback(() => ref.current.focus(), [ref.current]); 109 | const items = getItems(state.count); 110 | 111 | useLayoutEffect(() => { 112 | console.log('app layout'); 113 | }); 114 | 115 | useEffect(() => { 116 | console.log('app effect'); 117 | console.log(ref.current); 118 | console.log(fRef.current); 119 | }); 120 | 121 | return ( 122 |
    123 | {state.count >= 0 ? : null} 124 |

    App: {state.count}

    125 | 126 | {state.count >= -5 ? : null} 127 | 128 |

    focus

    129 | 132 | 133 | 134 | 135 |

    portal

    136 |
    137 |
    138 | ); 139 | }; 140 | 141 | export default App; -------------------------------------------------------------------------------- /demo/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | 5 | const container = document.createElement('div'); 6 | document.body.appendChild(container); 7 | ReactDOM.render(, container); -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": [ 3 | "packages/*" 4 | ], 5 | "command": { 6 | "publish": { 7 | "allowBranch": "master", 8 | "verifyAccess": false 9 | }, 10 | "bootstrap": { 11 | "npmClientArgs": [ 12 | "--no-package-lock" 13 | ] 14 | } 15 | }, 16 | "ignoreChanges": [ 17 | "**/*.md" 18 | ], 19 | "version": "1.1.9" 20 | } 21 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "root", 3 | "private": true, 4 | "scripts": { 5 | "link": "lerna link", 6 | "bootstrap": "lerna bootstrap", 7 | "start": "NODE_ENV=deveploment webpack-dev-server", 8 | "build": "lerna run build", 9 | "release": "npm run build && lerna publish" 10 | }, 11 | "devDependencies": { 12 | "@babel/core": "^7.5.5", 13 | "@babel/plugin-proposal-class-properties": "^7.5.5", 14 | "@babel/preset-env": "^7.5.5", 15 | "@babel/preset-react": "^7.0.0", 16 | "babel-eslint": "^8.2.6", 17 | "babel-loader": "^8.0.6", 18 | "eslint": "^5.16.0", 19 | "eslint-config-airbnb": "^17.1.0", 20 | "eslint-config-ali": "^3.0.0", 21 | "eslint-plugin-import": "^2.17.2", 22 | "eslint-plugin-jsx-a11y": "^6.2.1", 23 | "eslint-plugin-react": "^7.12.4", 24 | "glob": "^7.1.4", 25 | "html-webpack-plugin": "^3.2.0", 26 | "lerna": "^3.15.0", 27 | "react": "^15.7.0", 28 | "react-dom": "^15.7.0", 29 | "webpack": "^4.39.3", 30 | "webpack-cli": "^3.3.7", 31 | "webpack-dev-server": "^3.8.0" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /packages/rax-polyfill-all/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["@babel/preset-env"], 4 | "@babel/preset-react" 5 | ], 6 | "plugins": ["@babel/plugin-proposal-class-properties"] 7 | } -------------------------------------------------------------------------------- /packages/rax-polyfill-all/README.md: -------------------------------------------------------------------------------- 1 | # `rax-polyfill-all` 2 | 3 | > Polyfills for Rax new api 4 | 5 | ## Support 6 | 7 | `>= Rax@0.6.5` 8 | 9 | ## Usage 10 | 11 | ```js 12 | import { 13 | // memo 14 | memo, 15 | // ref 16 | createRef, 17 | forwardRef, 18 | // context 19 | createContext, 20 | // hooks 21 | withHooks, 22 | useRef, 23 | useState, 24 | useContext, 25 | useReducer, 26 | useEffect, 27 | useLayoutEffect, 28 | useMemo, 29 | useCallback, 30 | useImperativeHandle 31 | } from 'rax-polyfill-all'; 32 | ``` 33 | 34 | Checkout usages below 35 | 36 | * [rax-polyfill-ref](https://www.npmjs.com/package/rax-polyfill-ref) 37 | * [rax-polyfill-memo](https://www.npmjs.com/package/rax-polyfill-memo) 38 | * [rax-polyfill-context](https://www.npmjs.com/package/rax-polyfill-context) 39 | * [rax-polyfill-hooks](https://www.npmjs.com/package/rax-polyfill-hooks) 40 | 41 | -------------------------------------------------------------------------------- /packages/rax-polyfill-all/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rax-polyfill-all", 3 | "version": "1.1.9", 4 | "description": "Rax all polyfills", 5 | "keywords": [ 6 | "Rax", 7 | "ref", 8 | "memo", 9 | "context", 10 | "hooks", 11 | "polyfill" 12 | ], 13 | "author": "huya.nzb ", 14 | "homepage": "https://github.com/kingback/react-polyfills", 15 | "license": "MIT", 16 | "main": "lib/index.js", 17 | "directories": { 18 | "lib": "lib" 19 | }, 20 | "files": [ 21 | "lib" 22 | ], 23 | "repository": { 24 | "type": "git", 25 | "url": "git+https://github.com/kingback/react-polyfills.git" 26 | }, 27 | "scripts": { 28 | "test": "echo \"Error: run tests from root\" && exit 1", 29 | "build": "babel src --out-dir lib" 30 | }, 31 | "bugs": { 32 | "url": "https://github.com/kingback/react-polyfills/issues" 33 | }, 34 | "dependencies": { 35 | "rax-polyfill-context": "^1.0.12", 36 | "rax-polyfill-hooks": "^1.1.9", 37 | "rax-polyfill-memo": "^1.1.0", 38 | "rax-polyfill-ref": "^1.0.13" 39 | }, 40 | "devDependencies": { 41 | "@babel/cli": "^7.5.5", 42 | "@babel/core": "^7.5.5", 43 | "@babel/plugin-proposal-class-properties": "^7.5.5", 44 | "@babel/preset-env": "^7.5.5", 45 | "@babel/preset-react": "^7.0.0", 46 | "babel-loader": "^8.0.6", 47 | "rax": "^0.6.5" 48 | }, 49 | "gitHead": "bbd582fd27ee0fc1397e1d290d791c0c1af38386" 50 | } 51 | -------------------------------------------------------------------------------- /packages/rax-polyfill-all/src/index.js: -------------------------------------------------------------------------------- 1 | import memo from 'rax-polyfill-memo'; 2 | import { createContext } from 'rax-polyfill-context'; 3 | import { createRef, forwardRef } from 'rax-polyfill-ref'; 4 | import { 5 | withHooks, 6 | useRef, 7 | useState, 8 | useContext, 9 | useReducer, 10 | useEffect, 11 | useLayoutEffect, 12 | useMemo, 13 | useCallback, 14 | useImperativeHandle, 15 | useDebugValue 16 | } from 'rax-polyfill-hooks'; 17 | 18 | export { 19 | memo, 20 | createRef, 21 | forwardRef, 22 | createContext, 23 | withHooks, 24 | useRef, 25 | useState, 26 | useContext, 27 | useReducer, 28 | useEffect, 29 | useLayoutEffect, 30 | useMemo, 31 | useCallback, 32 | useImperativeHandle, 33 | useDebugValue 34 | }; -------------------------------------------------------------------------------- /packages/rax-polyfill-context/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["@babel/preset-env"], 4 | "@babel/preset-react" 5 | ], 6 | "plugins": ["@babel/plugin-proposal-class-properties"] 7 | } -------------------------------------------------------------------------------- /packages/rax-polyfill-context/README.md: -------------------------------------------------------------------------------- 1 | # `rax-polyfill-context` 2 | 3 | > Polyfill for Rax new context api 4 | 5 | ## Support 6 | 7 | `>= rax@0.6.5` 8 | 9 | ## Usage 10 | 11 | ```jsx 12 | import { render } from 'rax'; 13 | import { createContext } from 'rax-polyfill-context'; 14 | const Context = createContext(); 15 | 16 | function App() { 17 | return ( 18 |
    19 | {(value) => ( 20 |

    {value}

    21 | )}
    22 |
    23 | ); 24 | } 25 | 26 | render(( 27 | 28 | 29 | 30 | ), document) 31 | ``` 32 | 33 | For more usage, see 34 | 35 | ## Others 36 | 37 | You can use it with [rax-polyfill-ref](https://www.npmjs.com/package/rax-polyfill-ref) and [rax-polyfill-hooks](https://www.npmjs.com/package/rax-polyfill-hooks) 38 | 39 | -------------------------------------------------------------------------------- /packages/rax-polyfill-context/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rax-polyfill-context", 3 | "version": "1.0.12", 4 | "description": "Rax createContext polyfill", 5 | "keywords": [ 6 | "Rax", 7 | "createContext", 8 | "polyfill" 9 | ], 10 | "author": "huya.nzb ", 11 | "homepage": "https://github.com/kingback/react-polyfills", 12 | "license": "MIT", 13 | "main": "lib/index.js", 14 | "directories": { 15 | "lib": "lib" 16 | }, 17 | "files": [ 18 | "lib" 19 | ], 20 | "repository": { 21 | "type": "git", 22 | "url": "git+https://github.com/kingback/react-polyfills.git" 23 | }, 24 | "scripts": { 25 | "test": "echo \"Error: run tests from root\" && exit 1", 26 | "build": "babel src --out-dir lib" 27 | }, 28 | "bugs": { 29 | "url": "https://github.com/kingback/react-polyfills/issues" 30 | }, 31 | "dependencies": { 32 | "universal-polyfill-context": "^1.0.12", 33 | "universal-polyfill-engine": "^1.0.9" 34 | }, 35 | "devDependencies": { 36 | "@babel/cli": "^7.5.5", 37 | "@babel/core": "^7.5.5", 38 | "@babel/plugin-proposal-class-properties": "^7.5.5", 39 | "@babel/preset-env": "^7.5.5", 40 | "@babel/preset-react": "^7.0.0", 41 | "rax": "^0.6.5" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /packages/rax-polyfill-context/src/index.js: -------------------------------------------------------------------------------- 1 | import * as Rax from 'rax'; 2 | import Engine from 'universal-polyfill-engine'; 3 | import { createContext, useFallbackContext } from 'universal-polyfill-context'; 4 | 5 | !Rax.useState && useFallbackContext(); 6 | Engine.set(Rax); 7 | 8 | export { createContext }; -------------------------------------------------------------------------------- /packages/rax-polyfill-hooks/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["@babel/preset-env"], 4 | "@babel/preset-react" 5 | ], 6 | "plugins": ["@babel/plugin-proposal-class-properties"] 7 | } -------------------------------------------------------------------------------- /packages/rax-polyfill-hooks/README.md: -------------------------------------------------------------------------------- 1 | # `rax-polyfill-hooks` 2 | 3 | > Polyfill for Rax new hooks api 4 | 5 | ## Support 6 | 7 | `>= rax@0.6.5` 8 | 9 | ## Usage 10 | 11 | Just use `withHooks` to wrap your component, everything is just like the new Rax. 12 | 13 | ```jsx 14 | import { 15 | withHooks, 16 | useState, 17 | useEffect, 18 | useReducer, 19 | useCallback, 20 | useRef 21 | } from 'rax-polyfill-hooks'; 22 | 23 | const App = withHooks((props) => { 24 | const [count, setCount] = useState(props.count || 0); 25 | const inputRef = useRef(); 26 | 27 | useEffect(() => { 28 | console.log(count); 29 | }); 30 | 31 | useEffect(() => { 32 | inputRef.current.focus(); 33 | return () => { 34 | inputRef.current.blur(); 35 | }; 36 | }, []); 37 | 38 | return ( 39 |
    40 |

    {count}

    41 | 42 | 43 | 44 |
    45 | ); 46 | }); 47 | 48 | function reducer(state, action) { 49 | switch (action.type) { 50 | case 'add': 51 | return { count: state.count + 1 }; 52 | case 'minus': 53 | return { count: state.count - 1 }; 54 | default: 55 | return state; 56 | } 57 | } 58 | 59 | const ReduxApp = withHooks((props) => { 60 | const [state, dispatch] = useReducer(reducer, { count: 0 }); 61 | const add = useCallback(() => dispatch({ type: 'add' }), []); 62 | const minus = useCallback(() => dispatch({ type: 'minus' }), []); 63 | 64 | return ( 65 |
    66 |

    {state.count}

    67 | 68 | 69 |
    70 | ); 71 | }); 72 | ``` 73 | 74 | For more usage, see 75 | 76 | * [useState](https://reactjs.org/docs/hooks-reference.html#usestate) 77 | * [useEffect](https://reactjs.org/docs/hooks-reference.html#useeffect) 78 | * [useContext](https://reactjs.org/docs/hooks-reference.html#usecontext) 79 | * [useReducer](https://reactjs.org/docs/hooks-reference.html#usereducer) 80 | * [useCallback](https://reactjs.org/docs/hooks-reference.html#usecallback) 81 | * [useMemo](https://reactjs.org/docs/hooks-reference.html#usememo) 82 | * [useRef](https://reactjs.org/docs/hooks-reference.html#useref) 83 | * [useImperativeHandle](https://reactjs.org/docs/hooks-reference.html#useimperativehandle) 84 | * [useLayoutEffect](https://reactjs.org/docs/hooks-reference.html#uselayouteffect) 85 | * [useDebugValue](https://reactjs.org/docs/hooks-reference.html#usedebugvalue)(Just an empty function) 86 | 87 | ## Others 88 | 89 | You can use it with [rax-polyfill-ref](https://www.npmjs.com/package/rax-polyfill-ref) and [rax-polyfill-context](https://www.npmjs.com/package/rax-polyfill-context) 90 | 91 | -------------------------------------------------------------------------------- /packages/rax-polyfill-hooks/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rax-polyfill-hooks", 3 | "version": "1.1.9", 4 | "description": "Rax hooks polyfill", 5 | "keywords": [ 6 | "Rax", 7 | "hooks", 8 | "polyfill" 9 | ], 10 | "author": "huya.nzb ", 11 | "homepage": "https://github.com/kingback/react-polyfills", 12 | "license": "MIT", 13 | "main": "lib/index.js", 14 | "directories": { 15 | "lib": "lib" 16 | }, 17 | "files": [ 18 | "lib" 19 | ], 20 | "repository": { 21 | "type": "git", 22 | "url": "git+https://github.com/kingback/react-polyfills.git" 23 | }, 24 | "scripts": { 25 | "test": "echo \"Error: run tests from root\" && exit 1", 26 | "build": "babel src --out-dir lib" 27 | }, 28 | "bugs": { 29 | "url": "https://github.com/kingback/react-polyfills/issues" 30 | }, 31 | "dependencies": { 32 | "universal-polyfill-engine": "^1.0.9", 33 | "universal-polyfill-hooks": "^1.1.9" 34 | }, 35 | "devDependencies": { 36 | "@babel/cli": "^7.5.5", 37 | "@babel/core": "^7.5.5", 38 | "@babel/plugin-proposal-class-properties": "^7.5.5", 39 | "@babel/preset-env": "^7.5.5", 40 | "@babel/preset-react": "^7.0.0", 41 | "babel-loader": "^8.0.6", 42 | "rax": "^0.6.5" 43 | }, 44 | "gitHead": "bbd582fd27ee0fc1397e1d290d791c0c1af38386" 45 | } 46 | -------------------------------------------------------------------------------- /packages/rax-polyfill-hooks/src/index.js: -------------------------------------------------------------------------------- 1 | import * as Rax from 'rax'; 2 | import Engine from 'universal-polyfill-engine'; 3 | import { 4 | withHooks, 5 | useRef, 6 | useState, 7 | useContext, 8 | useReducer, 9 | useEffect, 10 | useLayoutEffect, 11 | useMemo, 12 | useCallback, 13 | useImperativeHandle, 14 | useDebugValue 15 | } from 'universal-polyfill-hooks'; 16 | 17 | Engine.set(Rax); 18 | 19 | export { 20 | withHooks, 21 | useRef, 22 | useState, 23 | useContext, 24 | useReducer, 25 | useEffect, 26 | useLayoutEffect, 27 | useMemo, 28 | useCallback, 29 | useImperativeHandle, 30 | useDebugValue 31 | }; -------------------------------------------------------------------------------- /packages/rax-polyfill-memo/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["@babel/preset-env"], 4 | "@babel/preset-react" 5 | ], 6 | "plugins": ["@babel/plugin-proposal-class-properties"] 7 | } -------------------------------------------------------------------------------- /packages/rax-polyfill-memo/README.md: -------------------------------------------------------------------------------- 1 | # `rax-polyfill-memo` 2 | 3 | > Polyfill for Rax new memo api 4 | 5 | ## Support 6 | 7 | `>= rax@0.6.5` 8 | 9 | ## Usage 10 | 11 | ```jsx 12 | import memo from 'rax-polyfill-memo'; 13 | import Text from 'rax-text'; 14 | 15 | const MyComponent = memo((props) => { 16 | return {props.text} 17 | }); 18 | ``` 19 | 20 | For more usage, see 21 | -------------------------------------------------------------------------------- /packages/rax-polyfill-memo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rax-polyfill-memo", 3 | "version": "1.1.0", 4 | "description": "Rax memo polyfill", 5 | "keywords": [ 6 | "Rax", 7 | "memo", 8 | "polyfill" 9 | ], 10 | "author": "huya.nzb ", 11 | "homepage": "https://github.com/kingback/react-polyfills", 12 | "license": "MIT", 13 | "main": "lib/index.js", 14 | "directories": { 15 | "lib": "lib" 16 | }, 17 | "files": [ 18 | "lib" 19 | ], 20 | "repository": { 21 | "type": "git", 22 | "url": "git+https://github.com/kingback/react-polyfills.git" 23 | }, 24 | "scripts": { 25 | "test": "echo \"Error: run tests from root\" && exit 1", 26 | "build": "babel src --out-dir lib" 27 | }, 28 | "bugs": { 29 | "url": "https://github.com/kingback/react-polyfills/issues" 30 | }, 31 | "dependencies": { 32 | "universal-polyfill-engine": "^1.0.9", 33 | "universal-polyfill-memo": "^1.1.0" 34 | }, 35 | "devDependencies": { 36 | "@babel/cli": "^7.5.5", 37 | "@babel/core": "^7.5.5", 38 | "@babel/plugin-proposal-class-properties": "^7.5.5", 39 | "@babel/preset-env": "^7.5.5", 40 | "@babel/preset-react": "^7.0.0", 41 | "rax": "^0.6.5" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /packages/rax-polyfill-memo/src/index.js: -------------------------------------------------------------------------------- 1 | import * as Rax from 'rax'; 2 | import Engine from 'universal-polyfill-engine'; 3 | import memo from 'universal-polyfill-memo'; 4 | 5 | Engine.set(Rax); 6 | 7 | export default memo; -------------------------------------------------------------------------------- /packages/rax-polyfill-ref/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["@babel/preset-env"], 4 | "@babel/preset-react" 5 | ], 6 | "plugins": ["@babel/plugin-proposal-class-properties"] 7 | } -------------------------------------------------------------------------------- /packages/rax-polyfill-ref/README.md: -------------------------------------------------------------------------------- 1 | # `rax-polyfill-ref` 2 | 3 | > Polyfill for Rax new ref api 4 | 5 | ## Support 6 | 7 | `>= rax@0.6.5` 8 | 9 | ## Usage 10 | 11 | ```jsx 12 | import { createRef, forwardRef } from 'rax-polyfill-ref'; 13 | const ref = createRef(); 14 | 15 | function App() { 16 | return ( 17 |
    18 | 19 | 20 |
    21 | ); 22 | } 23 | 24 | // forwardRef 25 | 26 | const ref = createRef(); 27 | 28 | const Input = forwardRef((props, ref) => { 29 | return 30 | }); 31 | 32 | const App = () => { 33 | return ( 34 |
    35 | 36 | 37 |
    38 | ); 39 | }; 40 | ``` 41 | 42 | For more usage, see 43 | 44 | ## Others 45 | 46 | You can use it with [rax-polyfill-context](https://www.npmjs.com/package/rax-polyfill-context) and [rax-polyfill-hooks](https://www.npmjs.com/package/rax-polyfill-hooks) 47 | 48 | -------------------------------------------------------------------------------- /packages/rax-polyfill-ref/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rax-polyfill-ref", 3 | "version": "1.0.13", 4 | "description": "Rax createRef forwardRef polyfill", 5 | "keywords": [ 6 | "Rax", 7 | "createRef", 8 | "forwardRef", 9 | "polyfill" 10 | ], 11 | "author": "huya.nzb ", 12 | "homepage": "https://github.com/kingback/react-polyfills", 13 | "license": "MIT", 14 | "main": "lib/index.js", 15 | "directories": { 16 | "lib": "lib" 17 | }, 18 | "files": [ 19 | "lib" 20 | ], 21 | "repository": { 22 | "type": "git", 23 | "url": "git+https://github.com/kingback/react-polyfills.git" 24 | }, 25 | "scripts": { 26 | "test": "echo \"Error: run tests from root\" && exit 1", 27 | "build": "babel src --out-dir lib" 28 | }, 29 | "bugs": { 30 | "url": "https://github.com/kingback/react-polyfills/issues" 31 | }, 32 | "dependencies": { 33 | "universal-polyfill-engine": "^1.0.9", 34 | "universal-polyfill-ref": "^1.0.13" 35 | }, 36 | "devDependencies": { 37 | "@babel/cli": "^7.5.5", 38 | "@babel/core": "^7.5.5", 39 | "@babel/plugin-proposal-class-properties": "^7.5.5", 40 | "@babel/preset-env": "^7.5.5", 41 | "@babel/preset-react": "^7.0.0", 42 | "rax": "^0.6.5" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /packages/rax-polyfill-ref/src/index.js: -------------------------------------------------------------------------------- 1 | import * as Rax from 'rax'; 2 | import Engine from 'universal-polyfill-engine'; 3 | import { createRef, forwardRef } from 'universal-polyfill-ref'; 4 | 5 | Engine.set(Rax); 6 | 7 | export { createRef, forwardRef }; -------------------------------------------------------------------------------- /packages/react-polyfill-all/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["@babel/preset-env"], 4 | "@babel/preset-react" 5 | ], 6 | "plugins": ["@babel/plugin-proposal-class-properties"] 7 | } -------------------------------------------------------------------------------- /packages/react-polyfill-all/README.md: -------------------------------------------------------------------------------- 1 | # `react-polyfill-all` 2 | 3 | > Polyfills for React new api 4 | 5 | ## Support 6 | 7 | `>= react@0.14.9` 8 | 9 | ## Usage 10 | 11 | ```js 12 | import { 13 | // memo 14 | memo, 15 | // ref 16 | createRef, 17 | forwardRef, 18 | // Fragment 19 | Fragment, 20 | // PureComponent 21 | PureComponent, 22 | // portal 23 | createPortal, 24 | // context 25 | createContext, 26 | // hooks 27 | withHooks, 28 | useRef, 29 | useState, 30 | useContext, 31 | useReducer, 32 | useEffect, 33 | useLayoutEffect, 34 | useMemo, 35 | useCallback, 36 | useImperativeHandle 37 | } from 'react-polyfill-all'; 38 | ``` 39 | 40 | Checkout usages below 41 | 42 | * [react-polyfill-ref](https://www.npmjs.com/package/react-polyfill-ref) 43 | * [react-polyfill-memo](https://www.npmjs.com/package/react-polyfill-memo) 44 | * [react-polyfill-portal](https://www.npmjs.com/package/react-polyfill-portal) 45 | * [react-polyfill-fragment](https://www.npmjs.com/package/react-polyfill-fragment) 46 | * [react-polyfill-context](https://www.npmjs.com/package/react-polyfill-context) 47 | * [react-polyfill-hooks](https://www.npmjs.com/package/react-polyfill-hooks) 48 | * [react-polyfill-pure-component](https://www.npmjs.com/package/react-polyfill-pure-component) 49 | 50 | -------------------------------------------------------------------------------- /packages/react-polyfill-all/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-polyfill-all", 3 | "version": "1.1.9", 4 | "description": "React all polyfills", 5 | "keywords": [ 6 | "React", 7 | "ref", 8 | "memo", 9 | "context", 10 | "hooks", 11 | "PureComponent", 12 | "polyfill" 13 | ], 14 | "author": "huya.nzb ", 15 | "homepage": "https://github.com/kingback/react-polyfills", 16 | "license": "MIT", 17 | "main": "lib/index.js", 18 | "directories": { 19 | "lib": "lib" 20 | }, 21 | "files": [ 22 | "lib" 23 | ], 24 | "repository": { 25 | "type": "git", 26 | "url": "git+https://github.com/kingback/react-polyfills.git" 27 | }, 28 | "scripts": { 29 | "test": "echo \"Error: run tests from root\" && exit 1", 30 | "build": "babel src --out-dir lib && cp src/index.d.ts lib/index.d.ts" 31 | }, 32 | "bugs": { 33 | "url": "https://github.com/kingback/react-polyfills/issues" 34 | }, 35 | "dependencies": { 36 | "react-polyfill-context": "^1.0.12", 37 | "react-polyfill-fragment": "^1.1.0", 38 | "react-polyfill-hooks": "^1.1.9", 39 | "react-polyfill-memo": "^1.1.0", 40 | "react-polyfill-portal": "^1.1.0", 41 | "react-polyfill-pure-component": "^1.1.0", 42 | "react-polyfill-ref": "^1.0.13" 43 | }, 44 | "devDependencies": { 45 | "@babel/cli": "^7.5.5", 46 | "@babel/core": "^7.5.5", 47 | "@babel/plugin-proposal-class-properties": "^7.5.5", 48 | "@babel/preset-env": "^7.5.5", 49 | "@babel/preset-react": "^7.0.0", 50 | "babel-loader": "^8.0.6", 51 | "react": "^0.14.9", 52 | "react-dom": "^0.14.9" 53 | }, 54 | "gitHead": "bbd582fd27ee0fc1397e1d290d791c0c1af38386" 55 | } 56 | -------------------------------------------------------------------------------- /packages/react-polyfill-all/src/index.d.ts: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import * as ReactDOM from 'react-dom'; 3 | 4 | export const memo: typeof React.memo; 5 | export const createRef: typeof React.createRef; 6 | export const forwardRef: typeof React.forwardRef; 7 | export const createContext: typeof React.createContext; 8 | export const Fragment: typeof React.Fragment; 9 | export const PureComponent: typeof React.PureComponent; 10 | 11 | export const createPortal: typeof ReactDOM.createPortal; 12 | 13 | export const withHooks: (render: React.FC) => React.Component; 14 | export const useRef: typeof React.useRef; 15 | export const useState: typeof React.useState; 16 | export const useContext: typeof React.useContext; 17 | export const useReducer: typeof React.useReducer; 18 | export const useEffect: typeof React.useEffect; 19 | export const useLayoutEffect: typeof React.useLayoutEffect; 20 | export const useMemo: typeof React.useMemo; 21 | export const useCallback: typeof React.useCallback; 22 | export const useImperativeHandle: typeof React.useImperativeHandle; 23 | export const useDebugValue: typeof React.useDebugValue; -------------------------------------------------------------------------------- /packages/react-polyfill-all/src/index.js: -------------------------------------------------------------------------------- 1 | import memo from 'react-polyfill-memo'; 2 | import Fragment from 'react-polyfill-fragment'; 3 | import PureComponent from 'react-polyfill-pure-component'; 4 | import { createPortal } from 'react-polyfill-portal'; 5 | import { createContext } from 'react-polyfill-context'; 6 | import { createRef, forwardRef } from 'react-polyfill-ref'; 7 | import { 8 | withHooks, 9 | useRef, 10 | useState, 11 | useContext, 12 | useReducer, 13 | useEffect, 14 | useLayoutEffect, 15 | useMemo, 16 | useCallback, 17 | useImperativeHandle, 18 | useDebugValue 19 | } from 'react-polyfill-hooks'; 20 | 21 | export { 22 | memo, 23 | createRef, 24 | forwardRef, 25 | createPortal, 26 | createContext, 27 | PureComponent, 28 | Fragment, 29 | withHooks, 30 | useRef, 31 | useState, 32 | useContext, 33 | useReducer, 34 | useEffect, 35 | useLayoutEffect, 36 | useMemo, 37 | useCallback, 38 | useImperativeHandle, 39 | useDebugValue 40 | }; -------------------------------------------------------------------------------- /packages/react-polyfill-context/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["@babel/preset-env"], 4 | "@babel/preset-react" 5 | ], 6 | "plugins": ["@babel/plugin-proposal-class-properties"] 7 | } -------------------------------------------------------------------------------- /packages/react-polyfill-context/README.md: -------------------------------------------------------------------------------- 1 | # `react-polyfill-context` 2 | 3 | > Polyfill for React new context api 4 | 5 | ## Support 6 | 7 | `>= react@0.14.9` 8 | 9 | ## Usage 10 | 11 | ```jsx 12 | import React from 'react'; 13 | import { render } from 'react-dom'; 14 | import { createContext } from 'react-polyfill-context'; 15 | const Context = createContext(); 16 | 17 | function App() { 18 | return ( 19 |
    20 | {(value) => ( 21 |

    {value}

    22 | )}
    23 |
    24 | ); 25 | } 26 | 27 | render(( 28 | 29 | 30 | 31 | ), document) 32 | ``` 33 | 34 | For more usage, see 35 | 36 | ## Others 37 | 38 | You can use it with [react-polyfill-ref](https://www.npmjs.com/package/react-polyfill-ref) and [react-polyfill-hooks](https://www.npmjs.com/package/react-polyfill-hooks) 39 | 40 | -------------------------------------------------------------------------------- /packages/react-polyfill-context/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-polyfill-context", 3 | "version": "1.0.12", 4 | "description": "React createContext polyfill", 5 | "keywords": [ 6 | "React", 7 | "createContext", 8 | "polyfill" 9 | ], 10 | "author": "huya.nzb ", 11 | "homepage": "https://github.com/kingback/react-polyfills", 12 | "license": "MIT", 13 | "main": "lib/index.js", 14 | "directories": { 15 | "lib": "lib" 16 | }, 17 | "files": [ 18 | "lib" 19 | ], 20 | "repository": { 21 | "type": "git", 22 | "url": "git+https://github.com/kingback/react-polyfills.git" 23 | }, 24 | "scripts": { 25 | "test": "echo \"Error: run tests from root\" && exit 1", 26 | "build": "babel src --out-dir lib" 27 | }, 28 | "bugs": { 29 | "url": "https://github.com/kingback/react-polyfills/issues" 30 | }, 31 | "dependencies": { 32 | "universal-polyfill-context": "^1.0.12", 33 | "universal-polyfill-engine": "^1.0.9" 34 | }, 35 | "devDependencies": { 36 | "@babel/cli": "^7.5.5", 37 | "@babel/core": "^7.5.5", 38 | "@babel/plugin-proposal-class-properties": "^7.5.5", 39 | "@babel/preset-env": "^7.5.5", 40 | "@babel/preset-react": "^7.0.0", 41 | "react": "^0.14.9", 42 | "react-dom": "^0.14.9" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /packages/react-polyfill-context/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Engine from 'universal-polyfill-engine'; 3 | import { createContext } from 'universal-polyfill-context'; 4 | 5 | Engine.set(React); 6 | 7 | export { createContext }; -------------------------------------------------------------------------------- /packages/react-polyfill-fragment/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["@babel/preset-env"], 4 | "@babel/preset-react" 5 | ], 6 | "plugins": ["@babel/plugin-proposal-class-properties"] 7 | } -------------------------------------------------------------------------------- /packages/react-polyfill-fragment/README.md: -------------------------------------------------------------------------------- 1 | # `react-polyfill-fragment` 2 | 3 | > Polyfill for React new Fragment api 4 | 5 | ## Support 6 | 7 | `>= react@0.14.9` 8 | 9 | ## Usage 10 | 11 | ```jsx 12 | import Fragment from 'react-polyfill-fragment'; 13 | 14 | function List({ items }) { 15 | return ( 16 | 17 | {items.map(item =>
  • {item}
  • )} 18 |
    19 | ); 20 | } 21 | 22 | function App() { 23 | const items = [1, 2]; 24 | return ( 25 |
      26 | 27 |
    28 | ); 29 | } 30 | ``` 31 | 32 | For more usage, see 33 | 34 | -------------------------------------------------------------------------------- /packages/react-polyfill-fragment/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-polyfill-fragment", 3 | "version": "1.1.0", 4 | "description": "React Fragment polyfill", 5 | "keywords": [ 6 | "React", 7 | "Fragment", 8 | "fragment", 9 | "polyfill" 10 | ], 11 | "author": "huya.nzb ", 12 | "homepage": "https://github.com/kingback/react-polyfills", 13 | "license": "MIT", 14 | "main": "lib/index.js", 15 | "directories": { 16 | "lib": "lib" 17 | }, 18 | "files": [ 19 | "lib" 20 | ], 21 | "repository": { 22 | "type": "git", 23 | "url": "git+https://github.com/kingback/react-polyfills.git" 24 | }, 25 | "scripts": { 26 | "test": "echo \"Error: run tests from root\" && exit 1", 27 | "build": "babel src --out-dir lib" 28 | }, 29 | "bugs": { 30 | "url": "https://github.com/kingback/react-polyfills/issues" 31 | }, 32 | "dependencies": { 33 | "react-dot-fragment": "^0.2.10" 34 | }, 35 | "devDependencies": { 36 | "@babel/cli": "^7.5.5", 37 | "@babel/core": "^7.5.5", 38 | "@babel/plugin-proposal-class-properties": "^7.5.5", 39 | "@babel/preset-env": "^7.5.5", 40 | "@babel/preset-react": "^7.0.0", 41 | "react": "^0.14.9", 42 | "react-dom": "^0.14.9" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /packages/react-polyfill-fragment/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Fragment from 'react-dot-fragment'; 3 | export default React.Fragment || Fragment; 4 | -------------------------------------------------------------------------------- /packages/react-polyfill-hooks/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["@babel/preset-env"], 4 | "@babel/preset-react" 5 | ], 6 | "plugins": ["@babel/plugin-proposal-class-properties"] 7 | } -------------------------------------------------------------------------------- /packages/react-polyfill-hooks/README.md: -------------------------------------------------------------------------------- 1 | # `react-polyfill-hooks` 2 | 3 | > Polyfill for React new hooks api 4 | 5 | ## Support 6 | 7 | `>= react@0.14.9` 8 | 9 | ## Usage 10 | 11 | Just use `withHooks` to wrap your component, everything is just like the new React. 12 | 13 | ```jsx 14 | import { 15 | withHooks, 16 | useState, 17 | useEffect, 18 | useReducer, 19 | useCallback, 20 | useRef 21 | } from 'react-polyfill-hooks'; 22 | 23 | const App = withHooks((props) => { 24 | const [count, setCount] = useState(props.count || 0); 25 | const inputRef = useRef(); 26 | 27 | useEffect(() => { 28 | console.log(count); 29 | }); 30 | 31 | useEffect(() => { 32 | inputRef.current.focus(); 33 | return () => { 34 | inputRef.current.blur(); 35 | }; 36 | }, []); 37 | 38 | return ( 39 |
    40 |

    {count}

    41 | 42 | 43 | 44 |
    45 | ); 46 | }); 47 | 48 | function reducer(state, action) { 49 | switch (action.type) { 50 | case 'add': 51 | return { count: state.count + 1 }; 52 | case 'minus': 53 | return { count: state.count - 1 }; 54 | default: 55 | return state; 56 | } 57 | } 58 | 59 | const ReduxApp = withHooks((props) => { 60 | const [state, dispatch] = useReducer(reducer, { count: 0 }); 61 | const add = useCallback(() => dispatch({ type: 'add' }), []); 62 | const minus = useCallback(() => dispatch({ type: 'minus' }), []); 63 | 64 | return ( 65 |
    66 |

    {state.count}

    67 | 68 | 69 |
    70 | ); 71 | }); 72 | ``` 73 | 74 | For more usage, see 75 | 76 | * [useState](https://reactjs.org/docs/hooks-reference.html#usestate) 77 | * [useEffect](https://reactjs.org/docs/hooks-reference.html#useeffect) 78 | * [useContext](https://reactjs.org/docs/hooks-reference.html#usecontext) 79 | * [useReducer](https://reactjs.org/docs/hooks-reference.html#usereducer) 80 | * [useCallback](https://reactjs.org/docs/hooks-reference.html#usecallback) 81 | * [useMemo](https://reactjs.org/docs/hooks-reference.html#usememo) 82 | * [useRef](https://reactjs.org/docs/hooks-reference.html#useref) 83 | * [useImperativeHandle](https://reactjs.org/docs/hooks-reference.html#useimperativehandle) 84 | * [useLayoutEffect](https://reactjs.org/docs/hooks-reference.html#uselayouteffect) 85 | * [useDebugValue](https://reactjs.org/docs/hooks-reference.html#usedebugvalue)(Just an empty function) 86 | 87 | ## Others 88 | 89 | You can use it with [react-polyfill-ref](https://www.npmjs.com/package/react-polyfill-ref) and [react-polyfill-context](https://www.npmjs.com/package/react-polyfill-context) 90 | 91 | -------------------------------------------------------------------------------- /packages/react-polyfill-hooks/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-polyfill-hooks", 3 | "version": "1.1.9", 4 | "description": "React hooks polyfill", 5 | "keywords": [ 6 | "React", 7 | "hooks", 8 | "polyfill" 9 | ], 10 | "author": "huya.nzb ", 11 | "homepage": "https://github.com/kingback/react-polyfills", 12 | "license": "MIT", 13 | "main": "lib/index.js", 14 | "directories": { 15 | "lib": "lib" 16 | }, 17 | "files": [ 18 | "lib" 19 | ], 20 | "repository": { 21 | "type": "git", 22 | "url": "git+https://github.com/kingback/react-polyfills.git" 23 | }, 24 | "scripts": { 25 | "test": "echo \"Error: run tests from root\" && exit 1", 26 | "build": "babel src --out-dir lib" 27 | }, 28 | "bugs": { 29 | "url": "https://github.com/kingback/react-polyfills/issues" 30 | }, 31 | "dependencies": { 32 | "universal-polyfill-engine": "^1.0.9", 33 | "universal-polyfill-hooks": "^1.1.9" 34 | }, 35 | "devDependencies": { 36 | "@babel/cli": "^7.5.5", 37 | "@babel/core": "^7.5.5", 38 | "@babel/plugin-proposal-class-properties": "^7.5.5", 39 | "@babel/preset-env": "^7.5.5", 40 | "@babel/preset-react": "^7.0.0", 41 | "babel-loader": "^8.0.6", 42 | "react": "^0.14.9", 43 | "react-dom": "^0.14.9" 44 | }, 45 | "gitHead": "bbd582fd27ee0fc1397e1d290d791c0c1af38386" 46 | } 47 | -------------------------------------------------------------------------------- /packages/react-polyfill-hooks/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Engine from 'universal-polyfill-engine'; 3 | import { 4 | withHooks, 5 | useRef, 6 | useState, 7 | useContext, 8 | useReducer, 9 | useEffect, 10 | useLayoutEffect, 11 | useMemo, 12 | useCallback, 13 | useImperativeHandle, 14 | useDebugValue 15 | } from 'universal-polyfill-hooks'; 16 | 17 | Engine.set(React); 18 | 19 | export { 20 | withHooks, 21 | useRef, 22 | useState, 23 | useContext, 24 | useReducer, 25 | useEffect, 26 | useLayoutEffect, 27 | useMemo, 28 | useCallback, 29 | useImperativeHandle, 30 | useDebugValue 31 | }; -------------------------------------------------------------------------------- /packages/react-polyfill-memo/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["@babel/preset-env"], 4 | "@babel/preset-react" 5 | ], 6 | "plugins": ["@babel/plugin-proposal-class-properties"] 7 | } -------------------------------------------------------------------------------- /packages/react-polyfill-memo/README.md: -------------------------------------------------------------------------------- 1 | # `react-polyfill-memo` 2 | 3 | > Polyfill for React new memo api 4 | 5 | ## Support 6 | 7 | `>= react@0.14.9` 8 | 9 | ## Usage 10 | 11 | ```jsx 12 | import memo from 'react-polyfill-memo'; 13 | 14 | const MyComponent = memo((props) => { 15 | return
    {props.text}
    16 | }); 17 | ``` 18 | 19 | For more usage, see 20 | 21 | -------------------------------------------------------------------------------- /packages/react-polyfill-memo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-polyfill-memo", 3 | "version": "1.1.0", 4 | "description": "React memo polyfill", 5 | "keywords": [ 6 | "React", 7 | "memo", 8 | "polyfill" 9 | ], 10 | "author": "huya.nzb ", 11 | "homepage": "https://github.com/kingback/react-polyfills", 12 | "license": "MIT", 13 | "main": "lib/index.js", 14 | "directories": { 15 | "lib": "lib" 16 | }, 17 | "files": [ 18 | "lib" 19 | ], 20 | "repository": { 21 | "type": "git", 22 | "url": "git+https://github.com/kingback/react-polyfills.git" 23 | }, 24 | "scripts": { 25 | "test": "echo \"Error: run tests from root\" && exit 1", 26 | "build": "babel src --out-dir lib" 27 | }, 28 | "bugs": { 29 | "url": "https://github.com/kingback/react-polyfills/issues" 30 | }, 31 | "dependencies": { 32 | "universal-polyfill-engine": "^1.0.9", 33 | "universal-polyfill-memo": "^1.1.0" 34 | }, 35 | "devDependencies": { 36 | "@babel/cli": "^7.5.5", 37 | "@babel/core": "^7.5.5", 38 | "@babel/plugin-proposal-class-properties": "^7.5.5", 39 | "@babel/preset-env": "^7.5.5", 40 | "@babel/preset-react": "^7.0.0", 41 | "react": "^0.14.9", 42 | "react-dom": "^0.14.9" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /packages/react-polyfill-memo/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Engine from 'universal-polyfill-engine'; 3 | import memo from 'universal-polyfill-memo'; 4 | 5 | Engine.set(React); 6 | 7 | export default memo; -------------------------------------------------------------------------------- /packages/react-polyfill-patch/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["@babel/preset-env"], 4 | "@babel/preset-react" 5 | ], 6 | "plugins": ["@babel/plugin-proposal-class-properties"] 7 | } -------------------------------------------------------------------------------- /packages/react-polyfill-patch/README.md: -------------------------------------------------------------------------------- 1 | # `react-polyfill-patch` 2 | 3 | > Polyfills patch for React new api 4 | 5 | ## Support 6 | 7 | `>= react@0.14.9` 8 | 9 | ## Usage 10 | 11 | ```js 12 | import 'react-polyfill-patch'; 13 | import { 14 | // memo 15 | memo, 16 | // ref 17 | createRef, 18 | forwardRef, 19 | // Fragment 20 | Fragment, 21 | // PureComponent 22 | PureComponent, 23 | // context 24 | createContext, 25 | // hooks 26 | useRef, 27 | useState, 28 | useContext, 29 | useReducer, 30 | useEffect, 31 | useLayoutEffect, 32 | useMemo, 33 | useCallback, 34 | useImperativeHandle 35 | } from 'react'; 36 | import { createPortal } from 'react-dom'; 37 | ``` 38 | 39 | Checkout usages below 40 | 41 | * [react-polyfill-ref](https://www.npmjs.com/package/react-polyfill-ref) 42 | * [react-polyfill-memo](https://www.npmjs.com/package/react-polyfill-memo) 43 | * [react-polyfill-portal](https://www.npmjs.com/package/react-polyfill-portal) 44 | * [react-polyfill-fragment](https://www.npmjs.com/package/react-polyfill-fragment) 45 | * [react-polyfill-context](https://www.npmjs.com/package/react-polyfill-context) 46 | * [react-polyfill-hooks](https://www.npmjs.com/package/react-polyfill-hooks) 47 | * [react-polyfill-pure-component](https://www.npmjs.com/package/react-polyfill-pure-component) 48 | 49 | -------------------------------------------------------------------------------- /packages/react-polyfill-patch/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-polyfill-patch", 3 | "version": "1.1.9", 4 | "description": "React polyfills patch", 5 | "keywords": [ 6 | "React", 7 | "ref", 8 | "context", 9 | "hooks", 10 | "polyfill", 11 | "patch" 12 | ], 13 | "author": "huya.nzb ", 14 | "homepage": "https://github.com/kingback/react-polyfills", 15 | "license": "MIT", 16 | "main": "lib/index.js", 17 | "directories": { 18 | "lib": "lib" 19 | }, 20 | "files": [ 21 | "lib" 22 | ], 23 | "repository": { 24 | "type": "git", 25 | "url": "git+https://github.com/kingback/react-polyfills.git" 26 | }, 27 | "scripts": { 28 | "test": "echo \"Error: run tests from root\" && exit 1", 29 | "build": "babel src --out-dir lib" 30 | }, 31 | "bugs": { 32 | "url": "https://github.com/kingback/react-polyfills/issues" 33 | }, 34 | "dependencies": { 35 | "react-polyfill-all": "^1.1.9" 36 | }, 37 | "devDependencies": { 38 | "@babel/cli": "^7.5.5", 39 | "@babel/core": "^7.5.5", 40 | "@babel/plugin-proposal-class-properties": "^7.5.5", 41 | "@babel/preset-env": "^7.5.5", 42 | "@babel/preset-react": "^7.0.0", 43 | "babel-loader": "^8.0.6", 44 | "react": "^0.14.9", 45 | "react-dom": "^0.14.9" 46 | }, 47 | "gitHead": "bbd582fd27ee0fc1397e1d290d791c0c1af38386" 48 | } 49 | -------------------------------------------------------------------------------- /packages/react-polyfill-patch/src/index.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import * as polyfills from 'react-polyfill-all'; 4 | 5 | const { withHooks, createPortal } = polyfills; 6 | const createElement = React.createElement; 7 | 8 | function isFunctionComponent(component) { 9 | return typeof component === 'function' && ( 10 | !component.prototype || ( 11 | typeof component.prototype.render !== 'function' && 12 | !component.prototype.isReactComponent 13 | ) 14 | ); 15 | } 16 | 17 | function cloneFunctionComponent(component) { 18 | function CloneFunctionComponent() { 19 | if (!component.__with_hooks_component__) { 20 | try { 21 | const ret = component.apply(this, arguments); 22 | // v0.14 don't support return null/undefined 23 | // @see https://github.com/facebook/react/issues/5355 24 | return ret == null && /^0\.14\./.test(React.version || '') ? React.createElement('noscript', {}) : ret; 25 | } catch (e) { 26 | if (/^\[HOOKS_POLYFILL_ERROR\]/.test(e.message)) { 27 | component.__with_hooks_component__ = withHooks(component); 28 | } else { 29 | throw e; 30 | } 31 | } 32 | } 33 | const WithHooksComponent = component.__with_hooks_component__; 34 | return WithHooksComponent ? new WithHooksComponent(...arguments) : null; 35 | }; 36 | CloneFunctionComponent.displayName = component.displayName || component.name || 'CloneFunctionComponent'; 37 | return CloneFunctionComponent; 38 | } 39 | 40 | if (!useState) { 41 | React.createElement = function(type, ...args) { 42 | if (isFunctionComponent(type)) { 43 | type = type.__renderFunction__ || (type.__renderFunction__ = cloneFunctionComponent(type)); 44 | } 45 | return createElement.call(this, type, ...args); 46 | }; 47 | } 48 | 49 | Object.keys(polyfills).forEach(p => { 50 | if (!React[p] && (p !== 'createPortal')) React[p] = polyfills[p]; 51 | }); 52 | 53 | if (!ReactDOM.createPortal) { 54 | ReactDOM.createPortal = createPortal; 55 | } -------------------------------------------------------------------------------- /packages/react-polyfill-portal/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["@babel/preset-env"], 4 | "@babel/preset-react" 5 | ], 6 | "plugins": ["@babel/plugin-proposal-class-properties"] 7 | } -------------------------------------------------------------------------------- /packages/react-polyfill-portal/README.md: -------------------------------------------------------------------------------- 1 | # `react-polyfill-portal` 2 | 3 | > Polyfill for React new portal api 4 | 5 | ## Support 6 | 7 | `>= react@0.14.9` 8 | 9 | ## Usage 10 | 11 | ```jsx 12 | import { createPortal } from 'react-polyfill-portal'; 13 | 14 | function Portal() { 15 | return createPortal(props.children, document.body); 16 | } 17 | 18 | function App() { 19 | return ( 20 |
    21 | 22 |

    text

    23 |
    24 |
    25 | ); 26 | } 27 | ``` 28 | 29 | For more usage, see 30 | 31 | -------------------------------------------------------------------------------- /packages/react-polyfill-portal/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-polyfill-portal", 3 | "version": "1.1.0", 4 | "description": "React createPortal polyfill", 5 | "keywords": [ 6 | "React", 7 | "portal", 8 | "createPortal", 9 | "polyfill" 10 | ], 11 | "author": "huya.nzb ", 12 | "homepage": "https://github.com/kingback/react-polyfills", 13 | "license": "MIT", 14 | "main": "lib/index.js", 15 | "directories": { 16 | "lib": "lib" 17 | }, 18 | "files": [ 19 | "lib" 20 | ], 21 | "repository": { 22 | "type": "git", 23 | "url": "git+https://github.com/kingback/react-polyfills.git" 24 | }, 25 | "scripts": { 26 | "test": "echo \"Error: run tests from root\" && exit 1", 27 | "build": "babel src --out-dir lib" 28 | }, 29 | "bugs": { 30 | "url": "https://github.com/kingback/react-polyfills/issues" 31 | }, 32 | "devDependencies": { 33 | "@babel/cli": "^7.5.5", 34 | "@babel/core": "^7.5.5", 35 | "@babel/plugin-proposal-class-properties": "^7.5.5", 36 | "@babel/preset-env": "^7.5.5", 37 | "@babel/preset-react": "^7.0.0", 38 | "react": "^0.14.9", 39 | "react-dom": "^0.14.9" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /packages/react-polyfill-portal/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | 4 | class Portal extends React.Component { 5 | 6 | static defaultProps = { 7 | target: document.body, 8 | alwaysAppend: false 9 | }; 10 | 11 | constructor(props) { 12 | super(props); 13 | const { 14 | className 15 | } = this.props; 16 | 17 | this.wrapper = document.createElement('div'); 18 | if (className) { 19 | this.wrapper.className = className; 20 | } 21 | } 22 | 23 | componentDidMount() { 24 | this.mountChild(this.props.target); 25 | this.updateChild(); 26 | } 27 | 28 | componentWillReceiveProps(nextProps) { 29 | const { 30 | alwaysAppend 31 | } = nextProps; 32 | 33 | if (alwaysAppend || (this.targetNode && nextProps.target !== this.props.target)) { 34 | this.unmountChild(); 35 | this.mountChild(nextProps.target); 36 | } 37 | } 38 | 39 | componentDidUpdate() { 40 | this.updateChild(); 41 | } 42 | 43 | componentWillUnmount() { 44 | this.unmountChild(); 45 | } 46 | 47 | mountChild(target) { 48 | this.targetNode = ReactDOM.findDOMNode(target); 49 | this.wrapperNode = this.targetNode.appendChild(this.wrapper); 50 | } 51 | 52 | updateChild() { 53 | let { children } = this.props; 54 | const childrenCount = React.Children.count(children); 55 | if (childrenCount < 1) { 56 | return; 57 | } 58 | if (childrenCount > 1) { 59 | children =
    {children}
    ; 60 | } 61 | ReactDOM.unstable_renderSubtreeIntoContainer(this, children, this.wrapperNode); 62 | } 63 | 64 | unmountChild() { 65 | if (this.targetNode) { 66 | ReactDOM.unmountComponentAtNode(this.wrapper); 67 | this.targetNode.removeChild(this.wrapper); 68 | this.targetNode = null; 69 | } 70 | } 71 | 72 | render() { 73 | return null; 74 | } 75 | } 76 | 77 | export const createPortal = ReactDOM.createPortal || function createPortal(children, container) { 78 | return {children}; 79 | } -------------------------------------------------------------------------------- /packages/react-polyfill-pure-component/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["@babel/preset-env"], 4 | "@babel/preset-react" 5 | ], 6 | "plugins": ["@babel/plugin-proposal-class-properties"] 7 | } -------------------------------------------------------------------------------- /packages/react-polyfill-pure-component/README.md: -------------------------------------------------------------------------------- 1 | # `react-polyfill-pure-component` 2 | 3 | > Polyfill for React new PureComponent api 4 | 5 | ## Support 6 | 7 | `>= react@0.14.9` 8 | 9 | ## Usage 10 | 11 | ```jsx 12 | import PureComponent from 'react-polyfill-pure-component'; 13 | 14 | class MyComponent extends PureComponent { 15 | render() {} 16 | } 17 | ``` 18 | 19 | For more usage, see 20 | 21 | -------------------------------------------------------------------------------- /packages/react-polyfill-pure-component/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-polyfill-pure-component", 3 | "version": "1.1.0", 4 | "description": "React PureComponent polyfill", 5 | "keywords": [ 6 | "React", 7 | "PureComponent", 8 | "pure", 9 | "component", 10 | "polyfill" 11 | ], 12 | "author": "huya.nzb ", 13 | "homepage": "https://github.com/kingback/react-polyfills", 14 | "license": "MIT", 15 | "main": "lib/index.js", 16 | "directories": { 17 | "lib": "lib" 18 | }, 19 | "files": [ 20 | "lib" 21 | ], 22 | "repository": { 23 | "type": "git", 24 | "url": "git+https://github.com/kingback/react-polyfills.git" 25 | }, 26 | "scripts": { 27 | "test": "echo \"Error: run tests from root\" && exit 1", 28 | "build": "babel src --out-dir lib" 29 | }, 30 | "bugs": { 31 | "url": "https://github.com/kingback/react-polyfills/issues" 32 | }, 33 | "dependencies": { 34 | "react-addons-shallow-compare": "^15.6.3" 35 | }, 36 | "devDependencies": { 37 | "@babel/cli": "^7.5.5", 38 | "@babel/core": "^7.5.5", 39 | "@babel/plugin-proposal-class-properties": "^7.5.5", 40 | "@babel/preset-env": "^7.5.5", 41 | "@babel/preset-react": "^7.0.0", 42 | "react": "^0.14.9", 43 | "react-dom": "^0.14.9" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /packages/react-polyfill-pure-component/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import shallowCompare from 'react-addons-shallow-compare'; 3 | 4 | const PureComponent = React.PureComponent || class extends React.Component { 5 | shouldComponentUpdate(nextProps, nextState) { 6 | return shallowCompare(this, nextProps, nextState); 7 | } 8 | }; 9 | 10 | export default PureComponent; 11 | -------------------------------------------------------------------------------- /packages/react-polyfill-ref/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["@babel/preset-env"], 4 | "@babel/preset-react" 5 | ], 6 | "plugins": ["@babel/plugin-proposal-class-properties"] 7 | } -------------------------------------------------------------------------------- /packages/react-polyfill-ref/README.md: -------------------------------------------------------------------------------- 1 | # `react-polyfill-ref` 2 | 3 | > Polyfill for React new ref api 4 | 5 | ## Support 6 | 7 | `>= react@0.14.9` 8 | 9 | ## Usage 10 | 11 | ```jsx 12 | import { createRef, forwardRef } from 'react-polyfill-ref'; 13 | const ref = createRef(); 14 | 15 | function App() { 16 | return ( 17 |
    18 | 19 | 20 |
    21 | ); 22 | } 23 | 24 | // forwardRef 25 | 26 | const ref = createRef(); 27 | 28 | const Input = forwardRef((props, ref) => { 29 | return 30 | }); 31 | 32 | const App = () => { 33 | return ( 34 |
    35 | 36 | 37 |
    38 | ); 39 | }; 40 | ``` 41 | 42 | For more usage, see 43 | 44 | ## Others 45 | 46 | You can use it with [react-polyfill-context](https://www.npmjs.com/package/react-polyfill-context) and [react-polyfill-hooks](https://www.npmjs.com/package/react-polyfill-hooks) 47 | 48 | -------------------------------------------------------------------------------- /packages/react-polyfill-ref/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-polyfill-ref", 3 | "version": "1.0.13", 4 | "description": "React createRef forwardRef polyfill", 5 | "keywords": [ 6 | "React", 7 | "createRef", 8 | "forwardRef", 9 | "polyfill" 10 | ], 11 | "author": "huya.nzb ", 12 | "homepage": "https://github.com/kingback/react-polyfills", 13 | "license": "MIT", 14 | "main": "lib/index.js", 15 | "directories": { 16 | "lib": "lib" 17 | }, 18 | "files": [ 19 | "lib" 20 | ], 21 | "repository": { 22 | "type": "git", 23 | "url": "git+https://github.com/kingback/react-polyfills.git" 24 | }, 25 | "scripts": { 26 | "test": "echo \"Error: run tests from root\" && exit 1", 27 | "build": "babel src --out-dir lib" 28 | }, 29 | "bugs": { 30 | "url": "https://github.com/kingback/react-polyfills/issues" 31 | }, 32 | "dependencies": { 33 | "universal-polyfill-engine": "^1.0.9", 34 | "universal-polyfill-ref": "^1.0.13" 35 | }, 36 | "devDependencies": { 37 | "@babel/cli": "^7.5.5", 38 | "@babel/core": "^7.5.5", 39 | "@babel/plugin-proposal-class-properties": "^7.5.5", 40 | "@babel/preset-env": "^7.5.5", 41 | "@babel/preset-react": "^7.0.0", 42 | "react": "^0.14.9", 43 | "react-dom": "^0.14.9" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /packages/react-polyfill-ref/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Engine from 'universal-polyfill-engine'; 3 | import { createRef, forwardRef } from 'universal-polyfill-ref'; 4 | 5 | Engine.set(React); 6 | 7 | export { createRef, forwardRef }; -------------------------------------------------------------------------------- /packages/universal-polyfill-context/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["@babel/preset-env"], 4 | "@babel/preset-react" 5 | ], 6 | "plugins": ["@babel/plugin-proposal-class-properties"] 7 | } -------------------------------------------------------------------------------- /packages/universal-polyfill-context/README.md: -------------------------------------------------------------------------------- 1 | # `universal-polyfill-context` 2 | 3 | > Context polyfill for React/Rax 4 | 5 | ## Usage 6 | 7 | ```js 8 | import Engine from 'universal-polyfill-engine'; 9 | import { createContext } from 'universal-polyfill-context'; 10 | 11 | import React from 'react'; 12 | Engine.set(React); 13 | 14 | import * as Rax from 'rax'; 15 | Engine.set(Rax); 16 | ``` 17 | 18 | ## Others 19 | 20 | See: 21 | 22 | * [react-polyfill-context](https://www.npmjs.com/package/react-polyfill-context) 23 | * [rax-polyfill-context](https://www.npmjs.com/package/rax-polyfill-context) 24 | -------------------------------------------------------------------------------- /packages/universal-polyfill-context/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "universal-polyfill-context", 3 | "version": "1.0.12", 4 | "description": "Universal polyfill context", 5 | "keywords": [ 6 | "Universal", 7 | "Polyfill", 8 | "Context", 9 | "Rax", 10 | "React" 11 | ], 12 | "author": "huya.nzb ", 13 | "homepage": "https://github.com/kingback/react-polyfills", 14 | "license": "MIT", 15 | "main": "lib/index", 16 | "directories": { 17 | "lib": "lib" 18 | }, 19 | "files": [ 20 | "lib" 21 | ], 22 | "repository": { 23 | "type": "git", 24 | "url": "git+https://github.com/kingback/react-polyfills.git" 25 | }, 26 | "scripts": { 27 | "test": "echo \"Error: run tests from root\" && exit 1", 28 | "build": "babel src --out-dir lib" 29 | }, 30 | "bugs": { 31 | "url": "https://github.com/kingback/react-polyfills/issues" 32 | }, 33 | "dependencies": { 34 | "universal-polyfill-engine": "^1.0.9" 35 | }, 36 | "devDependencies": { 37 | "@babel/cli": "^7.5.5", 38 | "@babel/core": "^7.5.5", 39 | "@babel/plugin-proposal-class-properties": "^7.5.5", 40 | "@babel/preset-env": "^7.5.5", 41 | "@babel/preset-react": "^7.0.0" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /packages/universal-polyfill-context/src/index.js: -------------------------------------------------------------------------------- 1 | import Engine from 'universal-polyfill-engine'; 2 | const PropTypes = { any: () => {} }; 3 | let supportNewContext = true; 4 | 5 | export function useFallbackContext() { 6 | supportNewContext = false; 7 | } 8 | 9 | function createContextProvider(Context) { 10 | return class ContextProvider extends Engine.get().Component { 11 | static childContextTypes = { 12 | value: PropTypes.any, 13 | provider: PropTypes.any 14 | }; 15 | 16 | static propTypes = { 17 | value: PropTypes.any 18 | }; 19 | 20 | getChildContext() { 21 | const { value } = this.props; 22 | Context._currentValue = value; // for useContext 23 | return { 24 | value, 25 | provider: this.constructor 26 | }; 27 | } 28 | 29 | render() { 30 | return Engine.get().Children.only(this.props.children); 31 | } 32 | }; 33 | } 34 | 35 | function createContextConsumer(defaultValue, Context) { 36 | return class ContextConsumer extends Engine.get().Component { 37 | static contextTypes = { 38 | value: PropTypes.any, 39 | provider: PropTypes.any 40 | }; 41 | 42 | render() { 43 | const { children } = this.props; 44 | return typeof children === 'function' ? children(this.context && (this.context.provider === Context.Provider) ? this.context.value : defaultValue) : null; 45 | } 46 | }; 47 | } 48 | 49 | // TODO 50 | // contextType 51 | export function createContext(defaultValue) { 52 | if (Engine.get().createContext && Engine.get().createContext !== createContext && supportNewContext) return Engine.get().createContext(defaultValue); 53 | const Context = { _currentValue: defaultValue }; // for useContext 54 | Context.Provider = createContextProvider(Context); 55 | Context.Consumer = createContextConsumer(defaultValue, Context); 56 | return Context; 57 | } -------------------------------------------------------------------------------- /packages/universal-polyfill-engine/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["@babel/preset-env"], 4 | "@babel/preset-react" 5 | ], 6 | "plugins": ["@babel/plugin-proposal-class-properties"] 7 | } -------------------------------------------------------------------------------- /packages/universal-polyfill-engine/README.md: -------------------------------------------------------------------------------- 1 | # `universal-polyfill-engine` 2 | 3 | > Set polyfill engine 4 | 5 | ## Usage 6 | 7 | ```js 8 | import Engine from 'universal-polyfill-engine'; 9 | 10 | import React from 'react'; 11 | Engine.set(React); 12 | 13 | import * as Rax from 'rax'; 14 | Engine.set(Rax); 15 | ``` 16 | -------------------------------------------------------------------------------- /packages/universal-polyfill-engine/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "universal-polyfill-engine", 3 | "version": "1.0.9", 4 | "description": "Universal polyfill engine", 5 | "keywords": [ 6 | "Universal", 7 | "Polyfill", 8 | "Engine", 9 | "React", 10 | "Rax" 11 | ], 12 | "author": "huya.nzb ", 13 | "homepage": "https://github.com/kingback/react-polyfills", 14 | "license": "MIT", 15 | "main": "lib/index.js", 16 | "directories": { 17 | "lib": "lib" 18 | }, 19 | "files": [ 20 | "lib" 21 | ], 22 | "repository": { 23 | "type": "git", 24 | "url": "git+https://github.com/kingback/react-polyfills.git" 25 | }, 26 | "scripts": { 27 | "test": "echo \"Error: run tests from root\" && exit 1", 28 | "build": "babel src --out-dir lib" 29 | }, 30 | "bugs": { 31 | "url": "https://github.com/kingback/react-polyfills/issues" 32 | }, 33 | "devDependencies": { 34 | "@babel/cli": "^7.5.5", 35 | "@babel/core": "^7.5.5", 36 | "@babel/plugin-proposal-class-properties": "^7.5.5", 37 | "@babel/preset-env": "^7.5.5", 38 | "@babel/preset-react": "^7.0.0" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /packages/universal-polyfill-engine/src/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | engine: null, 3 | 4 | get() { 5 | return this.engine; 6 | }, 7 | 8 | set(engine) { 9 | return (this.engine = engine); 10 | } 11 | } -------------------------------------------------------------------------------- /packages/universal-polyfill-hooks/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["@babel/preset-env"], 4 | "@babel/preset-react" 5 | ], 6 | "plugins": ["@babel/plugin-proposal-class-properties"] 7 | } -------------------------------------------------------------------------------- /packages/universal-polyfill-hooks/README.md: -------------------------------------------------------------------------------- 1 | # `universal-polyfill-hooks` 2 | 3 | > Hooks polyfill for React/Rax 4 | 5 | ## Usage 6 | 7 | ```js 8 | import Engine from 'universal-polyfill-engine'; 9 | import { useState, useEffect } from 'universal-polyfill-hooks'; 10 | 11 | import React from 'react'; 12 | Engine.set(React); 13 | 14 | import * as Rax from 'rax'; 15 | Engine.set(Rax); 16 | ``` 17 | 18 | ## Others 19 | 20 | See: 21 | 22 | * [react-polyfill-hooks](https://www.npmjs.com/package/react-polyfill-hooks) 23 | * [rax-polyfill-hooks](https://www.npmjs.com/package/rax-polyfill-hooks) 24 | -------------------------------------------------------------------------------- /packages/universal-polyfill-hooks/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "universal-polyfill-hooks", 3 | "version": "1.1.9", 4 | "description": "Universal polyfill hooks", 5 | "keywords": [ 6 | "Universal", 7 | "Polyfill", 8 | "Hooks", 9 | "Rax", 10 | "React" 11 | ], 12 | "author": "huya.nzb ", 13 | "homepage": "https://github.com/kingback/react-polyfills", 14 | "license": "MIT", 15 | "main": "lib/index.js", 16 | "directories": { 17 | "lib": "lib" 18 | }, 19 | "files": [ 20 | "lib" 21 | ], 22 | "repository": { 23 | "type": "git", 24 | "url": "git+https://github.com/kingback/react-polyfills.git" 25 | }, 26 | "scripts": { 27 | "test": "echo \"Error: run tests from root\" && exit 1", 28 | "build": "babel src --out-dir lib" 29 | }, 30 | "bugs": { 31 | "url": "https://github.com/kingback/react-polyfills/issues" 32 | }, 33 | "dependencies": { 34 | "universal-polyfill-engine": "^1.0.9", 35 | "universal-polyfill-ref": "^1.0.13" 36 | }, 37 | "devDependencies": { 38 | "@babel/cli": "^7.5.5", 39 | "@babel/core": "^7.5.5", 40 | "@babel/plugin-proposal-class-properties": "^7.5.5", 41 | "@babel/preset-env": "^7.5.5", 42 | "@babel/preset-react": "^7.0.0" 43 | }, 44 | "gitHead": "bbd582fd27ee0fc1397e1d290d791c0c1af38386" 45 | } 46 | -------------------------------------------------------------------------------- /packages/universal-polyfill-hooks/src/dispatcher.js: -------------------------------------------------------------------------------- 1 | import { rAF, isFunction, isDepsChanged, objectIs } from './utils'; 2 | import { MEMO, EFFECT, LAYOUT_EFFECT } from './types'; 3 | import { createRef } from 'universal-polyfill-ref'; 4 | 5 | /* eslint-disable no-plusplus, no-param-reassign */ 6 | 7 | export default class Dispatcher { 8 | static previous = null; 9 | 10 | static current = null; 11 | 12 | constructor(onUpdate) { 13 | this.index = 0; 14 | this.state = []; 15 | this.onUpdate = onUpdate; 16 | } 17 | 18 | reset() { 19 | this.index = 0; 20 | } 21 | 22 | update(unmount) { 23 | this.runEffects(LAYOUT_EFFECT, unmount); 24 | unmount ? 25 | this.runEffects(EFFECT, unmount) : 26 | rAF(() => this.runEffects(EFFECT)); 27 | } 28 | 29 | unmount() { 30 | this.update(true); 31 | this.state = []; 32 | this.index = 0; 33 | this.onUpdate = null; 34 | } 35 | 36 | initState(initial, useFunc = false) { 37 | const { state, index, onUpdate } = this; 38 | return (state[index] = { 39 | value: isFunction(initial) ? initial() : initial, // lazy init 40 | setter: useFunc ? null : (value) => { 41 | const prevValue = state[index].value; 42 | // get prevValue 43 | if (isFunction(value)) value = value(prevValue); 44 | if (!objectIs(value, prevValue)) { 45 | state[index].value = value; 46 | onUpdate && onUpdate(index, value); 47 | } 48 | } 49 | }); 50 | } 51 | 52 | useState(initial, useFunc) { 53 | const state = this.state[this.index] || this.initState(initial, useFunc); 54 | this.index++; 55 | return [state.value, state.setter]; 56 | } 57 | 58 | useReducer(reducer, initState, init) { 59 | const [redux] = this.useState(() => { 60 | const { state, index } = this; // cache index 61 | return { 62 | reducer, 63 | state: isFunction(init) ? init(initState) : initState, // modify initial state 64 | dispatch: (action) => { // never update 65 | const { value, setter } = state[index]; 66 | const newState = reducer(value.state, action); 67 | !objectIs(value.state, newState) && setter({ ...value, state: newState }); 68 | } 69 | }; 70 | }); 71 | return [redux.state, redux.dispatch]; 72 | } 73 | 74 | useFunc(callback, deps, type) { 75 | const [func] = this.useState({ callback, deps, type, run: true }, true); 76 | const isMemo = func.type === MEMO; 77 | if (func.run || isDepsChanged(func.deps, deps)) { 78 | func.run = !isMemo; 79 | func.deps = deps; 80 | func.callback = callback; 81 | isMemo && (func.value = func.callback()); 82 | } 83 | return func.value; 84 | } 85 | 86 | useEffect(callback, deps) { 87 | this.useFunc(callback, deps, EFFECT); 88 | } 89 | 90 | useLayoutEffect(callback, deps) { 91 | this.useFunc(callback, deps, LAYOUT_EFFECT); 92 | } 93 | 94 | useMemo(callback, deps) { 95 | return this.useFunc(callback, deps, MEMO); 96 | } 97 | 98 | useCallback(callback, deps) { 99 | return this.useMemo(() => callback, deps); 100 | } 101 | 102 | useRef(current) { 103 | return this.useState(() => { 104 | const ref = createRef(); 105 | ref.current = current; 106 | return ref; 107 | })[0]; 108 | } 109 | 110 | useImperativeHandle(ref, createHandle, deps) { 111 | return this.useMemo(() => { 112 | if (isFunction(ref)) { 113 | ref(createHandle()); 114 | } else if (ref) { 115 | ref.current = createHandle(); 116 | } 117 | }, deps); 118 | } 119 | 120 | useContext(context) { 121 | return this.useState(context)[0]._currentValue; 122 | } 123 | 124 | runEffects(type, unmount) { 125 | const effects = this.state.filter(state => ( 126 | state && 127 | state.value && 128 | (unmount || state.value.run) && 129 | state.value.callback && 130 | state.value.type === type 131 | )); 132 | 133 | // unmount 134 | effects.forEach((effect) => { 135 | (unmount || effect.value.run) && 136 | effect.value.unmount && effect.value.unmount(); 137 | }); 138 | 139 | // mount || update 140 | !unmount && effects.forEach((effect) => { 141 | if (effect.value.run) { 142 | effect.value.run = false; 143 | effect.value.unmount = effect.value.callback(); 144 | } 145 | }); 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /packages/universal-polyfill-hooks/src/index.js: -------------------------------------------------------------------------------- 1 | import Engine from 'universal-polyfill-engine'; 2 | import Dispatcher from './dispatcher'; 3 | import { useFallbackRef, createForwardRef } from 'universal-polyfill-ref'; 4 | const hooks = {}; 5 | 6 | /* eslint-disable max-len, prefer-spread */ 7 | 8 | function useHook(hook) { 9 | // lazy initial 10 | const hookFunc = function(...oArgs) { 11 | if (!hooks[hook]) { 12 | hooks[hook] = Engine.get()[hook] && Engine.get()[hook] !== hookFunc ? Engine.get()[hook] : (...args) => { 13 | if (Dispatcher.current) { 14 | return Dispatcher.current[hook].apply(Dispatcher.current, args); 15 | } else { 16 | throw new Error(`[HOOKS_POLYFILL_ERROR]: You can not use "${hook}" outside of the function.`); 17 | } 18 | }; 19 | } 20 | return hooks[hook](...oArgs); 21 | }; 22 | hookFunc.displayName = hook; 23 | return hookFunc; 24 | } 25 | 26 | export const useState = useHook('useState'); 27 | export const useReducer = useHook('useReducer'); 28 | export const useContext = useHook('useContext'); 29 | export const useMemo = useHook('useMemo'); 30 | export const useCallback = useHook('useCallback'); 31 | export const useEffect = useHook('useEffect'); 32 | export const useLayoutEffect = useHook('useLayoutEffect'); 33 | export const useRef = useHook('useRef'); 34 | export const useImperativeHandle = useHook('useImperativeHandle'); 35 | export function useDebugValue() {}; // empty function 36 | 37 | function createWithHooksComponent(render) { 38 | const isRax = !!Engine.get().render; 39 | return class WithHooksComponent extends Engine.get().Component { 40 | static __with_hooks__ = true; 41 | static displayName = render.displayName || render.name || 'WithHooksComponent'; 42 | 43 | constructor(props) { 44 | super(props); 45 | this.pendingTimer = null; 46 | this.state = { update: 0 }; 47 | this.dispatcher = new Dispatcher(() => { 48 | if (isRax) { 49 | if (!this.pendingTimer) { 50 | this.pendingTimer = Promise.resolve(0).then(() => { 51 | this.pendingTimer = null; 52 | this.update(); 53 | }); 54 | } 55 | } else { 56 | this.update(); 57 | } 58 | }); 59 | } 60 | 61 | componentDidMount() { 62 | this.dispatcher.update(); 63 | } 64 | 65 | componentDidUpdate() { 66 | this.dispatcher.update(); 67 | } 68 | 69 | componentWillUnmount() { 70 | this.dispatcher.unmount(); 71 | } 72 | 73 | update() { 74 | this.setState({ update: this.state.update + 1 }); // force update 75 | } 76 | 77 | render() { 78 | let view = null; 79 | Dispatcher.previous = Dispatcher.current; 80 | Dispatcher.current = this.dispatcher; 81 | Dispatcher.current.reset(); 82 | const needForwardRef = this.constructor.__need_forward_ref__; 83 | view = render(this.props, needForwardRef && createForwardRef(this)); 84 | Dispatcher.current.reset(); 85 | Dispatcher.current = Dispatcher.previous; 86 | return view; 87 | } 88 | }; 89 | } 90 | 91 | export function withHooks(render) { 92 | // >= 16.3 && <= 16.8 93 | // has createRef/forwardRef but do not support hooks 94 | const _useState = Engine.get().useState && Engine.get().useState !== useState; 95 | !_useState && useFallbackRef(); 96 | return _useState ? render : createWithHooksComponent(render); 97 | } 98 | -------------------------------------------------------------------------------- /packages/universal-polyfill-hooks/src/types.js: -------------------------------------------------------------------------------- 1 | export const MEMO = { memo: true }; 2 | export const EFFECT = { effect: true }; 3 | export const LAYOUT_EFFECT = { layoutEffect: true }; 4 | -------------------------------------------------------------------------------- /packages/universal-polyfill-hooks/src/utils.js: -------------------------------------------------------------------------------- 1 | export const rAF = (window.requestAnimationFrame || 2 | window.webkitRequestAnimationFrame || 3 | window.mozRequestAnimationFrame || 4 | window.oRequestAnimationFrame || 5 | window.msRequestAnimationFrame || 6 | function (callback) { 7 | return window.setTimeout(callback, 1000 / 60); 8 | }).bind(window); 9 | 10 | export function isString(str) { 11 | return typeof str === 'string'; 12 | } 13 | 14 | export function isFunction(func) { 15 | return typeof func === 'function'; 16 | } 17 | 18 | export function isDepsChanged(x, y) { 19 | if (x === undefined && y === undefined) { 20 | // undefined undefined 21 | return true; 22 | } else if (objectIs(x, y)) { 23 | // deps, deps 24 | return false; 25 | } else if (!x || !y || x.length !== y.length) { 26 | // undefined, [1] 27 | // [], [1] 28 | return true; 29 | } else { 30 | // [1, 2], [1, 3] 31 | let changed = false; 32 | x.some((dep, i) => (changed = !objectIs(dep, y[i]))); 33 | return changed; 34 | } 35 | } 36 | 37 | export function objectIs(x, y) { 38 | return Object.is ? Object.is(x, y) : ( 39 | (x === y && (x !== 0 || 1 / x === 1 / y)) || 40 | (x !== x && y !== y) 41 | ); 42 | } 43 | -------------------------------------------------------------------------------- /packages/universal-polyfill-memo/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["@babel/preset-env"], 4 | "@babel/preset-react" 5 | ], 6 | "plugins": ["@babel/plugin-proposal-class-properties"] 7 | } -------------------------------------------------------------------------------- /packages/universal-polyfill-memo/README.md: -------------------------------------------------------------------------------- 1 | # `universal-polyfill-memo` 2 | 3 | > Memo polyfill for React/Rax 4 | 5 | ## Usage 6 | 7 | ```js 8 | import Engine from 'universal-polyfill-engine'; 9 | import memo from 'universal-polyfill-memo'; 10 | 11 | import React from 'react'; 12 | Engine.set(React); 13 | 14 | import * as Rax from 'rax'; 15 | Engine.set(Rax); 16 | ``` 17 | 18 | ## Others 19 | 20 | See: 21 | 22 | * [react-polyfill-memo](https://www.npmjs.com/package/react-polyfill-memo) 23 | * [rax-polyfill-memo](https://www.npmjs.com/package/rax-polyfill-memo) 24 | -------------------------------------------------------------------------------- /packages/universal-polyfill-memo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "universal-polyfill-memo", 3 | "version": "1.1.0", 4 | "description": "Universal polyfill memo", 5 | "keywords": [ 6 | "Universal", 7 | "Polyfill", 8 | "Memo", 9 | "Rax", 10 | "React" 11 | ], 12 | "author": "huya.nzb ", 13 | "homepage": "https://github.com/kingback/react-polyfills", 14 | "license": "MIT", 15 | "main": "lib/index.js", 16 | "directories": { 17 | "lib": "lib" 18 | }, 19 | "files": [ 20 | "lib" 21 | ], 22 | "repository": { 23 | "type": "git", 24 | "url": "git+https://github.com/kingback/react-polyfills.git" 25 | }, 26 | "scripts": { 27 | "test": "echo \"Error: run tests from root\" && exit 1", 28 | "build": "babel src --out-dir lib" 29 | }, 30 | "bugs": { 31 | "url": "https://github.com/kingback/react-polyfills/issues" 32 | }, 33 | "dependencies": { 34 | "react-addons-shallow-compare": "^15.6.3", 35 | "universal-polyfill-engine": "^1.0.9" 36 | }, 37 | "devDependencies": { 38 | "@babel/cli": "^7.5.5", 39 | "@babel/core": "^7.5.5", 40 | "@babel/plugin-proposal-class-properties": "^7.5.5", 41 | "@babel/preset-env": "^7.5.5", 42 | "@babel/preset-react": "^7.0.0" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /packages/universal-polyfill-memo/src/index.js: -------------------------------------------------------------------------------- 1 | import Engine from 'universal-polyfill-engine'; 2 | import shallowCompare from 'react-addons-shallow-compare'; 3 | 4 | function shallowEqual(props, nextProps) { 5 | return !shallowCompare({ props }, nextProps); 6 | } 7 | 8 | export default function memo(Component, compare) { 9 | const engine = Engine.get(); 10 | if (engine.memo && engine.memo !== memo) return engine.memo(Component, compare); 11 | class MemoComponent extends engine.Component { 12 | shouldComponentUpdate(nextProps) { 13 | const isEqual = typeof compare === 'function' ? compare : shallowEqual; 14 | return !isEqual(this.props, nextProps); 15 | } 16 | 17 | render() { 18 | return engine.createElement(Component, this.props, this.props.children); 19 | } 20 | }; 21 | MemoComponent.displayName = Component.displayName || Component.name || 'MemoComponent'; 22 | return MemoComponent; 23 | } -------------------------------------------------------------------------------- /packages/universal-polyfill-ref/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["@babel/preset-env"], 4 | "@babel/preset-react" 5 | ], 6 | "plugins": ["@babel/plugin-proposal-class-properties"] 7 | } -------------------------------------------------------------------------------- /packages/universal-polyfill-ref/README.md: -------------------------------------------------------------------------------- 1 | # `universal-polyfill-ref` 2 | 3 | > Ref polyfill for React/Rax 4 | 5 | ## Usage 6 | 7 | ```js 8 | import Engine from 'universal-polyfill-engine'; 9 | import { createRef, forwardRef } from 'universal-polyfill-ref'; 10 | 11 | import React from 'react'; 12 | Engine.set(React); 13 | 14 | import * as Rax from 'rax'; 15 | Engine.set(Rax); 16 | ``` 17 | 18 | ## Others 19 | 20 | See: 21 | 22 | * [react-polyfill-ref](https://www.npmjs.com/package/react-polyfill-ref) 23 | * [rax-polyfill-ref](https://www.npmjs.com/package/rax-polyfill-ref) 24 | -------------------------------------------------------------------------------- /packages/universal-polyfill-ref/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "universal-polyfill-ref", 3 | "version": "1.0.13", 4 | "description": "Universal polyfill ref", 5 | "keywords": [ 6 | "Universal", 7 | "Polyfill", 8 | "Ref", 9 | "Rax", 10 | "React" 11 | ], 12 | "author": "huya.nzb ", 13 | "homepage": "https://github.com/kingback/react-polyfills", 14 | "license": "MIT", 15 | "main": "lib/index.js", 16 | "directories": { 17 | "lib": "lib" 18 | }, 19 | "files": [ 20 | "lib" 21 | ], 22 | "repository": { 23 | "type": "git", 24 | "url": "git+https://github.com/kingback/react-polyfills.git" 25 | }, 26 | "scripts": { 27 | "test": "echo \"Error: run tests from root\" && exit 1", 28 | "build": "babel src --out-dir lib" 29 | }, 30 | "bugs": { 31 | "url": "https://github.com/kingback/react-polyfills/issues" 32 | }, 33 | "dependencies": { 34 | "universal-polyfill-engine": "^1.0.9" 35 | }, 36 | "devDependencies": { 37 | "@babel/cli": "^7.5.5", 38 | "@babel/core": "^7.5.5", 39 | "@babel/plugin-proposal-class-properties": "^7.5.5", 40 | "@babel/preset-env": "^7.5.5", 41 | "@babel/preset-react": "^7.0.0" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /packages/universal-polyfill-ref/src/index.js: -------------------------------------------------------------------------------- 1 | import Engine from 'universal-polyfill-engine'; 2 | let supportNewRef = true; 3 | 4 | export function useFallbackRef() { 5 | supportNewRef = false; 6 | } 7 | 8 | export function getRef(component) { 9 | return ( // > 16.x 10 | component._reactInternalFiber && 11 | component._reactInternalFiber.ref 12 | ) || ( // < 16.x 13 | component._reactInternalInstance && 14 | component._reactInternalInstance._currentElement && 15 | component._reactInternalInstance._currentElement.ref 16 | ) || ( // < Rax 17 | component._internal && 18 | component._internal._currentElement && 19 | component._internal._currentElement.ref 20 | ); 21 | } 22 | 23 | export function createForwardRef(component) { 24 | const ref = getRef(component); 25 | if (ref && !component.forwardRef) { // for useRef 26 | ref.forward = component.forwardRef = inst => (ref.forward.current = (ref.current = inst)); 27 | ref.forward.current = null; 28 | } 29 | return component.forwardRef || null; 30 | } 31 | 32 | export function createRef() { 33 | if (supportNewRef && Engine.get().createRef && Engine.get().createRef !== createRef) { 34 | return Engine.get().createRef(); 35 | } else { 36 | const ref = inst => (!ref.forward && (ref.current = inst)); // for useRef 37 | ref.current = null; 38 | return ref; 39 | } 40 | } 41 | 42 | function createForwardRefComponent(render) { 43 | return class ForwardRefComponent extends Engine.get().Component { 44 | render() { 45 | return render(this.props, createForwardRef(this)); 46 | } 47 | }; 48 | } 49 | 50 | function addForwardRefTag(render) { 51 | render.__need_forward_ref__ = true; // for useRef 52 | return render; 53 | } 54 | 55 | export function forwardRef(render) { 56 | if (render.__with_hooks__) { 57 | return addForwardRefTag(render); 58 | } else if (supportNewRef && Engine.get().forwardRef && Engine.get().forwardRef !== forwardRef) { 59 | return Engine.get().forwardRef(render); 60 | } else if (Engine.get().withHooks) { 61 | return addForwardRefTag(Engine.get().withHooks(render)); 62 | } else { 63 | return createForwardRefComponent(render); 64 | } 65 | } -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const glob = require('glob'); 3 | const webpack = require('webpack'); 4 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 5 | 6 | const alias = { 7 | 'react$': require.resolve('react'), 8 | 'react-dom': require.resolve('react-dom'), 9 | }; 10 | 11 | glob.sync('./packages/*/src/index.js').forEach(file => { 12 | const pkg = file.match(/\.\/packages\/([^\/]+)\/src/)[1]; 13 | alias[pkg] = path.resolve(__dirname, file); 14 | }); 15 | 16 | module.exports = { 17 | mode: 'development', 18 | entry: './demo/index.js', 19 | devtool: 'source-map', 20 | output: { 21 | path: path.join(__dirname, 'dist'), 22 | filename: 'index.js' 23 | }, 24 | watch: true, 25 | devServer: { 26 | contentBase: path.join(__dirname, 'dist'), 27 | inline: true, 28 | hot: true, 29 | open: true, 30 | headers: { 31 | "Cache-Control": "no-cache" 32 | } 33 | }, 34 | plugins: [ 35 | new webpack.HotModuleReplacementPlugin() 36 | ], 37 | module: { 38 | rules: [ 39 | { 40 | test: /.js$/, 41 | exclude: /node_modules/, 42 | loader: 'babel-loader', 43 | options: { 44 | "presets": [ 45 | ["@babel/preset-env"], 46 | "@babel/preset-react" 47 | ], 48 | "plugins": ["@babel/plugin-proposal-class-properties"] 49 | } 50 | } 51 | ] 52 | }, 53 | plugins: [ 54 | new HtmlWebpackPlugin({}) 55 | ], 56 | resolve: { 57 | alias 58 | } 59 | } --------------------------------------------------------------------------------