From b09bac3cbb8aad81a1af8bf8aa50781ab4ed1fd4 Mon Sep 17 00:00:00 2001 From: songzheng Date: Wed, 10 Mar 2021 12:32:30 +0800 Subject: [PATCH 01/13] feat: jsx-runtime --- packages/rax-jsx-runtime/README.md | 23 +++++ packages/rax-jsx-runtime/package.json | 18 ++++ .../src/__test__/jsx-runtime.test.js | 94 +++++++++++++++++++ packages/rax-jsx-runtime/src/index.js | 49 ++++++++++ 4 files changed, 184 insertions(+) create mode 100644 packages/rax-jsx-runtime/README.md create mode 100644 packages/rax-jsx-runtime/package.json create mode 100644 packages/rax-jsx-runtime/src/__test__/jsx-runtime.test.js create mode 100644 packages/rax-jsx-runtime/src/index.js diff --git a/packages/rax-jsx-runtime/README.md b/packages/rax-jsx-runtime/README.md new file mode 100644 index 000000000..27d61da4c --- /dev/null +++ b/packages/rax-jsx-runtime/README.md @@ -0,0 +1,23 @@ +# rax-jsx-runtime + +This module is adapted to react's jsx-runtime module. For more information, please see:[introducing-the-new-jsx-transform](https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.htm) + +## Installation +npm install rax-jsx-runtime + +## Usage +An example Babel configuration look like: + +```json +{ + "presets": [ + [ + "@babel/preset-react", + { + "runtime": "automatic", + "importSource": "rax-jsx-runtime" + } + ] + ] +} +``` diff --git a/packages/rax-jsx-runtime/package.json b/packages/rax-jsx-runtime/package.json new file mode 100644 index 000000000..586f2a15a --- /dev/null +++ b/packages/rax-jsx-runtime/package.json @@ -0,0 +1,18 @@ +{ + "name": "rax-jsx-runtime", + "version": "1.0.0", + "description": "Rax JSX Runtime", + "license": "BSD-3-Clause", + "main": "lib/index.js", + "repository": { + "type": "git", + "url": "git+https://github.com/alibaba/rax.git" + }, + "bugs": { + "url": "https://github.com/alibaba/rax/issues" + }, + "homepage": "https://github.com/alibaba/rax#readme", + "engines": { + "npm": ">=3.0.0" + } +} diff --git a/packages/rax-jsx-runtime/src/__test__/jsx-runtime.test.js b/packages/rax-jsx-runtime/src/__test__/jsx-runtime.test.js new file mode 100644 index 000000000..886b37238 --- /dev/null +++ b/packages/rax-jsx-runtime/src/__test__/jsx-runtime.test.js @@ -0,0 +1,94 @@ +import { Component, createElement, createRef } from 'rax'; +import { jsx, jsxs, jsxDEV, Fragment } from '../' + +describe('Support JSX-Runtime', () => { + + it('should export all modules needed by importSource', () => { + expect(typeof jsx).toBe('function'); + expect(typeof jsxs).toBe('function'); + expect(typeof jsxDEV).toBe('function'); + expect(typeof Fragment).toBe('function'); + }); + + it('should add key', () => { + const vnode = jsx('div', null, 'foo'); + expect(vnode.key).toBe('foo'); + }); + + it('should keep ref in props', () => { + let ref = () => null; + let vnode = jsx('div', { ref }); + expect(vnode.ref).toBe(ref); + + ref = 'fooRef'; + vnode = jsx('div', { ref }); + expect(vnode.ref).toBe('fooRef'); + + }); + + it('should apply defaultProps', () => { + class Foo extends Component { + render() { + return
; + } + } + + Foo.defaultProps = { + foo: 'bar', + fake: 'bar1', + }; + + let vnode = jsx(Foo, {}, null); + expect(vnode.props.foo).toBe('bar'); + + vnode = jsx(Foo, {fake: 'bar2'}, null); + expect(vnode.props.foo1).toBe('bar2'); + }); + + it('should keep props over defaultProps', () => { + class Foo extends Component { + render() { + return
; + } + } + + Foo.defaultProps = { + foo: 'bar' + }; + + const vnode = jsx(Foo, { foo: 'baz' }, null); + expect(vnode.props).toEqual({ + foo: 'baz' + }); + }); + + it('should set __source and __self', () => { + const vnode = jsx('div', { class: 'foo' }, 'key', 'source', 'self'); + expect(vnode.__source).toBe('source'); + expect(vnode.__self).toBe('self'); + }); + + it('should return a vnode like createElement', () => { + const elementVNode = createElement('div', { + class: 'foo', + key: 'key' + }); + const jsxVNode = jsx('div', { class: 'foo' }, 'key'); + delete jsxVNode.__self; + delete jsxVNode.__source; + expect(jsxVNode).toEqual(elementVNode); + }); + + it('should remove ref from props', () => { + const ref = createRef(); + const vnode = jsx('div', { ref }, null); + expect(vnode.props).toEqual({}); + expect(vnode.ref).toBe(ref); + }); + + it('should receive children props', () => { + const fooProps = {children: []}; + expect(Fragment(fooProps)).toEqual([]); + }); + +}); diff --git a/packages/rax-jsx-runtime/src/index.js b/packages/rax-jsx-runtime/src/index.js new file mode 100644 index 000000000..9c118f527 --- /dev/null +++ b/packages/rax-jsx-runtime/src/index.js @@ -0,0 +1,49 @@ +import { shared } from 'rax'; + +const { Host } = shared; + +function Fragment(props) { + return props.children; +} + +function generateVNode(type, props, key, __source, __self) { + let normalizedProps = {}; + let propName; + + // The default value of key and ref of rax element is null + let ref = props && props.ref || null; + key = key ? key : null; + + for (propName in props) { + if (propName !== 'ref') { + normalizedProps[propName] = props[propName]; + } + } + + let defaults; + if (typeof type === 'function' && (defaults = type.defaultProps)) { + for (propName in defaults) + if (normalizedProps[propName] === undefined) { + normalizedProps[propName] = defaults[propName]; + } + } + + return { + type, + props: normalizedProps, + key, + ref, + _owner: Host.owner, + __source, + __self, + }; + +} + +export { + generateVNode as jsx, + generateVNode as jsxs, + generateVNode as jsxDEV, + Fragment +}; + From 52c32684e274b5b58774f134773a11c55bcc7f6e Mon Sep 17 00:00:00 2001 From: songzheng Date: Wed, 10 Mar 2021 12:34:29 +0800 Subject: [PATCH 02/13] feat: jsx-runtime --- packages/rax-jsx-runtime/src/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/rax-jsx-runtime/src/index.js b/packages/rax-jsx-runtime/src/index.js index 9c118f527..e504be142 100644 --- a/packages/rax-jsx-runtime/src/index.js +++ b/packages/rax-jsx-runtime/src/index.js @@ -12,7 +12,7 @@ function generateVNode(type, props, key, __source, __self) { // The default value of key and ref of rax element is null let ref = props && props.ref || null; - key = key ? key : null; + key = key || null; for (propName in props) { if (propName !== 'ref') { From eaf2e272d75c1455503ec055849d48ef3a4f6a5b Mon Sep 17 00:00:00 2001 From: songzheng Date: Wed, 10 Mar 2021 12:43:39 +0800 Subject: [PATCH 03/13] feat: jsx-runtime --- packages/rax-jsx-runtime/package.json | 6 + .../src/__test__/jsx-runtime.test.js | 123 +++++++++--------- packages/rax-jsx-runtime/src/index.js | 1 - 3 files changed, 66 insertions(+), 64 deletions(-) diff --git a/packages/rax-jsx-runtime/package.json b/packages/rax-jsx-runtime/package.json index 586f2a15a..eeaa29caf 100644 --- a/packages/rax-jsx-runtime/package.json +++ b/packages/rax-jsx-runtime/package.json @@ -8,6 +8,12 @@ "type": "git", "url": "git+https://github.com/alibaba/rax.git" }, + "peerDependencies": { + "rax": "^1.0.0" + }, + "devDependencies": { + "rax": "^1.0.0" + }, "bugs": { "url": "https://github.com/alibaba/rax/issues" }, diff --git a/packages/rax-jsx-runtime/src/__test__/jsx-runtime.test.js b/packages/rax-jsx-runtime/src/__test__/jsx-runtime.test.js index 886b37238..7b44ac82d 100644 --- a/packages/rax-jsx-runtime/src/__test__/jsx-runtime.test.js +++ b/packages/rax-jsx-runtime/src/__test__/jsx-runtime.test.js @@ -1,19 +1,18 @@ import { Component, createElement, createRef } from 'rax'; -import { jsx, jsxs, jsxDEV, Fragment } from '../' +import { jsx, jsxs, jsxDEV, Fragment } from '../'; describe('Support JSX-Runtime', () => { + it('should export all modules needed by importSource', () => { + expect(typeof jsx).toBe('function'); + expect(typeof jsxs).toBe('function'); + expect(typeof jsxDEV).toBe('function'); + expect(typeof Fragment).toBe('function'); + }); - it('should export all modules needed by importSource', () => { - expect(typeof jsx).toBe('function'); - expect(typeof jsxs).toBe('function'); - expect(typeof jsxDEV).toBe('function'); - expect(typeof Fragment).toBe('function'); - }); - - it('should add key', () => { - const vnode = jsx('div', null, 'foo'); - expect(vnode.key).toBe('foo'); - }); + it('should add key', () => { + const vnode = jsx('div', null, 'foo'); + expect(vnode.key).toBe('foo'); + }); it('should keep ref in props', () => { let ref = () => null; @@ -23,72 +22,70 @@ describe('Support JSX-Runtime', () => { ref = 'fooRef'; vnode = jsx('div', { ref }); expect(vnode.ref).toBe('fooRef'); - }); - it('should apply defaultProps', () => { - class Foo extends Component { - render() { - return
; - } - } + it('should apply defaultProps', () => { + class Foo extends Component { + render() { + return
; + } + } - Foo.defaultProps = { - foo: 'bar', + Foo.defaultProps = { + foo: 'bar', fake: 'bar1', - }; + }; - let vnode = jsx(Foo, {}, null); - expect(vnode.props.foo).toBe('bar'); + let vnode = jsx(Foo, {}, null); + expect(vnode.props.foo).toBe('bar'); vnode = jsx(Foo, {fake: 'bar2'}, null); expect(vnode.props.foo1).toBe('bar2'); - }); - - it('should keep props over defaultProps', () => { - class Foo extends Component { - render() { - return
; - } - } - - Foo.defaultProps = { - foo: 'bar' - }; + }); - const vnode = jsx(Foo, { foo: 'baz' }, null); - expect(vnode.props).toEqual({ - foo: 'baz' - }); - }); + it('should keep props over defaultProps', () => { + class Foo extends Component { + render() { + return
; + } + } + + Foo.defaultProps = { + foo: 'bar' + }; + + const vnode = jsx(Foo, { foo: 'baz' }, null); + expect(vnode.props).toEqual({ + foo: 'baz' + }); + }); - it('should set __source and __self', () => { - const vnode = jsx('div', { class: 'foo' }, 'key', 'source', 'self'); - expect(vnode.__source).toBe('source'); - expect(vnode.__self).toBe('self'); - }); + it('should set __source and __self', () => { + const vnode = jsx('div', { class: 'foo' }, 'key', 'source', 'self'); + expect(vnode.__source).toBe('source'); + expect(vnode.__self).toBe('self'); + }); - it('should return a vnode like createElement', () => { - const elementVNode = createElement('div', { - class: 'foo', - key: 'key' - }); - const jsxVNode = jsx('div', { class: 'foo' }, 'key'); - delete jsxVNode.__self; - delete jsxVNode.__source; - expect(jsxVNode).toEqual(elementVNode); - }); + it('should return a vnode like createElement', () => { + const elementVNode = createElement('div', { + class: 'foo', + key: 'key' + }); + const jsxVNode = jsx('div', { class: 'foo' }, 'key'); + delete jsxVNode.__self; + delete jsxVNode.__source; + expect(jsxVNode).toEqual(elementVNode); + }); - it('should remove ref from props', () => { - const ref = createRef(); - const vnode = jsx('div', { ref }, null); - expect(vnode.props).toEqual({}); - expect(vnode.ref).toBe(ref); - }); + it('should remove ref from props', () => { + const ref = createRef(); + const vnode = jsx('div', { ref }, null); + expect(vnode.props).toEqual({}); + expect(vnode.ref).toBe(ref); + }); it('should receive children props', () => { const fooProps = {children: []}; expect(Fragment(fooProps)).toEqual([]); }); - }); diff --git a/packages/rax-jsx-runtime/src/index.js b/packages/rax-jsx-runtime/src/index.js index e504be142..ee0f22138 100644 --- a/packages/rax-jsx-runtime/src/index.js +++ b/packages/rax-jsx-runtime/src/index.js @@ -37,7 +37,6 @@ function generateVNode(type, props, key, __source, __self) { __source, __self, }; - } export { From 78cc660645801ade241b7d344236e1f96dfca08d Mon Sep 17 00:00:00 2001 From: songzheng Date: Mon, 12 Apr 2021 18:40:33 +0800 Subject: [PATCH 04/13] feat: jsx-runtime --- packages/rax-jsx-runtime/README.md | 23 ------------------ packages/rax-jsx-runtime/package.json | 24 ------------------- packages/rax/jsx-dev-runtime.js | 1 + packages/rax/jsx-runtime.js | 1 + packages/rax/package.json | 5 ++++ .../jsx-runtime}/__test__/jsx-runtime.test.js | 4 +++- .../src => rax/src/jsx-runtime}/index.js | 10 ++------ 7 files changed, 12 insertions(+), 56 deletions(-) delete mode 100644 packages/rax-jsx-runtime/README.md delete mode 100644 packages/rax-jsx-runtime/package.json create mode 100644 packages/rax/jsx-dev-runtime.js create mode 100644 packages/rax/jsx-runtime.js rename packages/{rax-jsx-runtime/src => rax/src/jsx-runtime}/__test__/jsx-runtime.test.js (94%) rename packages/{rax-jsx-runtime/src => rax/src/jsx-runtime}/index.js (86%) diff --git a/packages/rax-jsx-runtime/README.md b/packages/rax-jsx-runtime/README.md deleted file mode 100644 index 27d61da4c..000000000 --- a/packages/rax-jsx-runtime/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# rax-jsx-runtime - -This module is adapted to react's jsx-runtime module. For more information, please see:[introducing-the-new-jsx-transform](https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.htm) - -## Installation -npm install rax-jsx-runtime - -## Usage -An example Babel configuration look like: - -```json -{ - "presets": [ - [ - "@babel/preset-react", - { - "runtime": "automatic", - "importSource": "rax-jsx-runtime" - } - ] - ] -} -``` diff --git a/packages/rax-jsx-runtime/package.json b/packages/rax-jsx-runtime/package.json deleted file mode 100644 index eeaa29caf..000000000 --- a/packages/rax-jsx-runtime/package.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "name": "rax-jsx-runtime", - "version": "1.0.0", - "description": "Rax JSX Runtime", - "license": "BSD-3-Clause", - "main": "lib/index.js", - "repository": { - "type": "git", - "url": "git+https://github.com/alibaba/rax.git" - }, - "peerDependencies": { - "rax": "^1.0.0" - }, - "devDependencies": { - "rax": "^1.0.0" - }, - "bugs": { - "url": "https://github.com/alibaba/rax/issues" - }, - "homepage": "https://github.com/alibaba/rax#readme", - "engines": { - "npm": ">=3.0.0" - } -} diff --git a/packages/rax/jsx-dev-runtime.js b/packages/rax/jsx-dev-runtime.js new file mode 100644 index 000000000..cc089a669 --- /dev/null +++ b/packages/rax/jsx-dev-runtime.js @@ -0,0 +1 @@ +export {Fragment, jsxDEV} from './src/jsx-runtime'; diff --git a/packages/rax/jsx-runtime.js b/packages/rax/jsx-runtime.js new file mode 100644 index 000000000..21d9d072f --- /dev/null +++ b/packages/rax/jsx-runtime.js @@ -0,0 +1 @@ +export {Fragment, jsx, jsxs} from './src/jsx-runtime'; diff --git a/packages/rax/package.json b/packages/rax/package.json index 7d41a505c..a872d536d 100644 --- a/packages/rax/package.json +++ b/packages/rax/package.json @@ -4,6 +4,11 @@ "description": "A universal React-compatible render engine.", "license": "BSD-3-Clause", "main": "index.js", + "exports": { + ".": "./index.js", + "./jsx-runtime": "./jsx-runtime.js", + "./jsx-dev-runtime": "./jsx-dev-runtime.js" + }, "repository": { "type": "git", "url": "git+https://github.com/alibaba/rax.git" diff --git a/packages/rax-jsx-runtime/src/__test__/jsx-runtime.test.js b/packages/rax/src/jsx-runtime/__test__/jsx-runtime.test.js similarity index 94% rename from packages/rax-jsx-runtime/src/__test__/jsx-runtime.test.js rename to packages/rax/src/jsx-runtime/__test__/jsx-runtime.test.js index 7b44ac82d..36030b36d 100644 --- a/packages/rax-jsx-runtime/src/__test__/jsx-runtime.test.js +++ b/packages/rax/src/jsx-runtime/__test__/jsx-runtime.test.js @@ -1,4 +1,6 @@ -import { Component, createElement, createRef } from 'rax'; +import Component from '../../vdom/component'; +import createElement from '../../createElement'; +import createRef from '../../createRef'; import { jsx, jsxs, jsxDEV, Fragment } from '../'; describe('Support JSX-Runtime', () => { diff --git a/packages/rax-jsx-runtime/src/index.js b/packages/rax/src/jsx-runtime/index.js similarity index 86% rename from packages/rax-jsx-runtime/src/index.js rename to packages/rax/src/jsx-runtime/index.js index ee0f22138..beb66d31e 100644 --- a/packages/rax-jsx-runtime/src/index.js +++ b/packages/rax/src/jsx-runtime/index.js @@ -1,10 +1,4 @@ -import { shared } from 'rax'; - -const { Host } = shared; - -function Fragment(props) { - return props.children; -} +import Host from '../vdom/host'; function generateVNode(type, props, key, __source, __self) { let normalizedProps = {}; @@ -39,10 +33,10 @@ function generateVNode(type, props, key, __source, __self) { }; } +export Fragment from '../vdom/fragment'; export { generateVNode as jsx, generateVNode as jsxs, generateVNode as jsxDEV, - Fragment }; From be9d1e4236b16a7effbf7d26b678e11f551da297 Mon Sep 17 00:00:00 2001 From: songzheng Date: Wed, 14 Apr 2021 16:44:57 +0800 Subject: [PATCH 05/13] feat: jsx-runtime --- packages/rax/src/jsx-runtime/__test__/jsx-runtime.test.js | 6 ++---- packages/rax/src/jsx-runtime/index.js | 7 +++++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/packages/rax/src/jsx-runtime/__test__/jsx-runtime.test.js b/packages/rax/src/jsx-runtime/__test__/jsx-runtime.test.js index 36030b36d..813438a0b 100644 --- a/packages/rax/src/jsx-runtime/__test__/jsx-runtime.test.js +++ b/packages/rax/src/jsx-runtime/__test__/jsx-runtime.test.js @@ -1,6 +1,4 @@ -import Component from '../../vdom/component'; -import createElement from '../../createElement'; -import createRef from '../../createRef'; +import { Component, createElement, createRef } from "../../../index" import { jsx, jsxs, jsxDEV, Fragment } from '../'; describe('Support JSX-Runtime', () => { @@ -42,7 +40,7 @@ describe('Support JSX-Runtime', () => { expect(vnode.props.foo).toBe('bar'); vnode = jsx(Foo, {fake: 'bar2'}, null); - expect(vnode.props.foo1).toBe('bar2'); + expect(vnode.props.fake).toBe('bar2'); }); it('should keep props over defaultProps', () => { diff --git a/packages/rax/src/jsx-runtime/index.js b/packages/rax/src/jsx-runtime/index.js index beb66d31e..e851caf7f 100644 --- a/packages/rax/src/jsx-runtime/index.js +++ b/packages/rax/src/jsx-runtime/index.js @@ -1,4 +1,6 @@ -import Host from '../vdom/host'; +import { shared, Fragment } from "../../index" + +const Host = shared.Host; function generateVNode(type, props, key, __source, __self) { let normalizedProps = {}; @@ -33,10 +35,11 @@ function generateVNode(type, props, key, __source, __self) { }; } -export Fragment from '../vdom/fragment'; + export { generateVNode as jsx, generateVNode as jsxs, generateVNode as jsxDEV, + Fragment, }; From f895d08226241bdab33507b05eb759e4cc6630ed Mon Sep 17 00:00:00 2001 From: songzheng Date: Wed, 14 Apr 2021 16:57:11 +0800 Subject: [PATCH 06/13] feat: jsx-runtime --- packages/rax/src/jsx-runtime/__test__/jsx-runtime.test.js | 2 +- packages/rax/src/jsx-runtime/index.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/rax/src/jsx-runtime/__test__/jsx-runtime.test.js b/packages/rax/src/jsx-runtime/__test__/jsx-runtime.test.js index 813438a0b..503fb868b 100644 --- a/packages/rax/src/jsx-runtime/__test__/jsx-runtime.test.js +++ b/packages/rax/src/jsx-runtime/__test__/jsx-runtime.test.js @@ -1,4 +1,4 @@ -import { Component, createElement, createRef } from "../../../index" +import { Component, createElement, createRef } from '../../../index'; import { jsx, jsxs, jsxDEV, Fragment } from '../'; describe('Support JSX-Runtime', () => { diff --git a/packages/rax/src/jsx-runtime/index.js b/packages/rax/src/jsx-runtime/index.js index e851caf7f..72cff3964 100644 --- a/packages/rax/src/jsx-runtime/index.js +++ b/packages/rax/src/jsx-runtime/index.js @@ -1,4 +1,4 @@ -import { shared, Fragment } from "../../index" +import { shared, Fragment } from '../../index'; const Host = shared.Host; From ef8bb58b79e77150375490c0384ffafee262a8af Mon Sep 17 00:00:00 2001 From: songzheng Date: Sat, 17 Apr 2021 20:48:41 +0800 Subject: [PATCH 07/13] feat: jsx-runtime This module is adapted to react's jsx-runtime module. Implement Babel's "automatic" JSX runtime API: * 1.jsx(type, props, key) * 2.jsxs(type, props, key) * 3.jsxDEV(type, props, key, __source, __self) --- packages/rax/src/jsx-runtime/index.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/rax/src/jsx-runtime/index.js b/packages/rax/src/jsx-runtime/index.js index 72cff3964..2e275632d 100644 --- a/packages/rax/src/jsx-runtime/index.js +++ b/packages/rax/src/jsx-runtime/index.js @@ -1,6 +1,11 @@ import { shared, Fragment } from '../../index'; const Host = shared.Host; +/** + * This module is adapted to react's jsx-runtime module. + * @see:[introducing-the-new-jsx-transform](https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.htm) + */ + function generateVNode(type, props, key, __source, __self) { let normalizedProps = {}; From b85968f2098bdad530df51c13f9b670a7fe09dee Mon Sep 17 00:00:00 2001 From: songzheng Date: Mon, 19 Apr 2021 17:46:28 +0800 Subject: [PATCH 08/13] feat: jsx-runtime MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1.jsx-runtime和createElement组织结构保持一致 2.区分环境导出不同jsx-runtime,和react一致 --- packages/rax/jsx-dev-runtime.js | 2 +- packages/rax/jsx-runtime.js | 2 +- .../jsx-runtime.test.js | 11 ++- packages/rax/src/index.js | 1 + packages/rax/src/jsx-runtime.js | 97 +++++++++++++++++++ packages/rax/src/jsx-runtime/index.js | 50 ---------- packages/rax/src/vdom/element.js | 24 ++++- 7 files changed, 125 insertions(+), 62 deletions(-) rename packages/rax/src/{jsx-runtime/__test__ => __tests__}/jsx-runtime.test.js (87%) create mode 100644 packages/rax/src/jsx-runtime.js delete mode 100644 packages/rax/src/jsx-runtime/index.js diff --git a/packages/rax/jsx-dev-runtime.js b/packages/rax/jsx-dev-runtime.js index cc089a669..1ea24f38b 100644 --- a/packages/rax/jsx-dev-runtime.js +++ b/packages/rax/jsx-dev-runtime.js @@ -1 +1 @@ -export {Fragment, jsxDEV} from './src/jsx-runtime'; +export {Fragment, jsxDEV} from './index'; diff --git a/packages/rax/jsx-runtime.js b/packages/rax/jsx-runtime.js index 21d9d072f..6c14c4b90 100644 --- a/packages/rax/jsx-runtime.js +++ b/packages/rax/jsx-runtime.js @@ -1 +1 @@ -export {Fragment, jsx, jsxs} from './src/jsx-runtime'; +export {Fragment, jsx, jsxs, jsxDEV} from './index'; diff --git a/packages/rax/src/jsx-runtime/__test__/jsx-runtime.test.js b/packages/rax/src/__tests__/jsx-runtime.test.js similarity index 87% rename from packages/rax/src/jsx-runtime/__test__/jsx-runtime.test.js rename to packages/rax/src/__tests__/jsx-runtime.test.js index 503fb868b..6ffd38340 100644 --- a/packages/rax/src/jsx-runtime/__test__/jsx-runtime.test.js +++ b/packages/rax/src/__tests__/jsx-runtime.test.js @@ -1,5 +1,8 @@ -import { Component, createElement, createRef } from '../../../index'; -import { jsx, jsxs, jsxDEV, Fragment } from '../'; +import Component from '../vdom/component'; +import createElement from '../createElement'; +import createRef from '../createRef'; +import { jsx, jsxs, jsxDEV } from '../jsx-runtime'; +import Fragment from '../fragment'; describe('Support JSX-Runtime', () => { it('should export all modules needed by importSource', () => { @@ -61,7 +64,7 @@ describe('Support JSX-Runtime', () => { }); it('should set __source and __self', () => { - const vnode = jsx('div', { class: 'foo' }, 'key', 'source', 'self'); + const vnode = jsxDEV('div', { class: 'foo' }, 'key', 'source', 'self'); expect(vnode.__source).toBe('source'); expect(vnode.__self).toBe('self'); }); @@ -72,8 +75,6 @@ describe('Support JSX-Runtime', () => { key: 'key' }); const jsxVNode = jsx('div', { class: 'foo' }, 'key'); - delete jsxVNode.__self; - delete jsxVNode.__source; expect(jsxVNode).toEqual(elementVNode); }); diff --git a/packages/rax/src/index.js b/packages/rax/src/index.js index e6ba641f0..1938aad2a 100644 --- a/packages/rax/src/index.js +++ b/packages/rax/src/index.js @@ -8,6 +8,7 @@ export Fragment from './fragment'; export render from './render'; export Component, { PureComponent } from './vdom/component'; export version from './version'; +export { jsx, jsxs, jsxDEV } from './vdom/jsx-runtime'; import Host from './vdom/host'; import Instance from './vdom/instance'; diff --git a/packages/rax/src/jsx-runtime.js b/packages/rax/src/jsx-runtime.js new file mode 100644 index 000000000..fdd3ce321 --- /dev/null +++ b/packages/rax/src/jsx-runtime.js @@ -0,0 +1,97 @@ +import Host from './vdom/host'; +import Element from './vdom/element'; +import { warning, throwError, throwMinifiedWarn } from './error'; +import { isArray, NOOP } from './types'; +import validateChildKeys from './validateChildKeys'; + +const __DEV__ = process.env.NODE_ENV !== 'production'; + +/** + * This module is adapted to react's jsx-runtime module. + * @see:[introducing-the-new-jsx-transform](https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.htm) + */ +function jsxRuntime(type, props, key, __source, __self) { + let normalizedProps = {}; + let propName; + + // The default value of key and ref of rax element is null + let ref = props && props.ref || null; + key = key || null; + + for (propName in props) { + if (propName !== 'ref') { + normalizedProps[propName] = props[propName]; + } + } + + let defaults; + if (typeof type === 'function' && (defaults = type.defaultProps)) { + for (propName in defaults) + if (normalizedProps[propName] === undefined) { + normalizedProps[propName] = defaults[propName]; + } + } + + return Element(type, key, ref, normalizedProps, Host.owner, __source, __self); +} + + +function _jsxWithValidation(type, props, key, isStaticChildren, __source, __self) { + const elem = jsxRuntime(type, props, key, __source, __self); + + if (type == null) { + if (__DEV__) { + throwError(`Invalid element type, expected a string or a class/function component but got "${type}".`); + } else { + // A empty component replaced avoid break render in production + type = NOOP; + throwMinifiedWarn(0); + } + } + + const children = props && props.children; + if (children !== undefined) { + if (isStaticChildren) { + if (isArray(children)) { + for (let i = 0; i < children.length; i++) { + validateChildKeys(children[i], type); + } + + if (Object.freeze) { + Object.freeze(children); + } + } else { + warning( + 'Rax.jsx: Static children should always be an array. ' + + 'You are likely explicitly calling Rax.jsxs or Rax.jsxDEV. ' + + 'Use the Babel transform instead.', + ); + } + } else { + validateChildKeys(children, type); + } + } + + return elem; +} + +function jsxWithValidation(type, props, key) { + return _jsxWithValidation(type, props, key, false); +} +function jsxsWithValidation(type, props, key) { + return _jsxWithValidation(type, props, key, true); +} +function jsxDEVWithValidation(type, props, key, __source, __self) { + return _jsxWithValidation(type, props, key, true, __source, __self); +} + +const jsx = __DEV__ ? jsxWithValidation : jsxRuntime; +const jsxs = __DEV__ ? jsxsWithValidation : jsxRuntime; +const jsxDEV = __DEV__ ? jsxDEVWithValidation : undefined; + +export { + jsx, + jsxs, + jsxDEV, +}; + diff --git a/packages/rax/src/jsx-runtime/index.js b/packages/rax/src/jsx-runtime/index.js deleted file mode 100644 index 2e275632d..000000000 --- a/packages/rax/src/jsx-runtime/index.js +++ /dev/null @@ -1,50 +0,0 @@ -import { shared, Fragment } from '../../index'; - -const Host = shared.Host; -/** - * This module is adapted to react's jsx-runtime module. - * @see:[introducing-the-new-jsx-transform](https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.htm) - */ - - -function generateVNode(type, props, key, __source, __self) { - let normalizedProps = {}; - let propName; - - // The default value of key and ref of rax element is null - let ref = props && props.ref || null; - key = key || null; - - for (propName in props) { - if (propName !== 'ref') { - normalizedProps[propName] = props[propName]; - } - } - - let defaults; - if (typeof type === 'function' && (defaults = type.defaultProps)) { - for (propName in defaults) - if (normalizedProps[propName] === undefined) { - normalizedProps[propName] = defaults[propName]; - } - } - - return { - type, - props: normalizedProps, - key, - ref, - _owner: Host.owner, - __source, - __self, - }; -} - - -export { - generateVNode as jsx, - generateVNode as jsxs, - generateVNode as jsxDEV, - Fragment, -}; - diff --git a/packages/rax/src/vdom/element.js b/packages/rax/src/vdom/element.js index 056de2f93..27cdf010e 100644 --- a/packages/rax/src/vdom/element.js +++ b/packages/rax/src/vdom/element.js @@ -1,6 +1,6 @@ import checkPropTypes from 'prop-types/checkPropTypes'; -export default function Element(type, key, ref, props, owner) { +export default function Element(type, key, ref, props, owner, __source, __self) { let element = { // Built-in properties that belong on the element type, @@ -33,10 +33,24 @@ export default function Element(type, key, ref, props, owner) { value: false }); - // Props is immutable - if (Object.freeze) { - Object.freeze(props); - } + Object.defineProperty(element, '__source', { + configurable: false, + enumerable: false, + writable: true, + value: __source + }); + + Object.defineProperty(element, '__self', { + configurable: false, + enumerable: false, + writable: true, + value: __self + }); + } + + // Props is immutable + if (Object.freeze) { + Object.freeze(props); } return element; From 4979a61fb45a4a1bd82a5a546270ce2853795bad Mon Sep 17 00:00:00 2001 From: songzheng Date: Mon, 19 Apr 2021 18:57:34 +0800 Subject: [PATCH 09/13] feat: jsx-runtime MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1.jsx-runtime和createElement组织结构保持一致 2.区分环境导出不同jsx-runtime,和react一致 --- packages/rax/src/jsx-runtime.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/rax/src/jsx-runtime.js b/packages/rax/src/jsx-runtime.js index fdd3ce321..bc2bf283e 100644 --- a/packages/rax/src/jsx-runtime.js +++ b/packages/rax/src/jsx-runtime.js @@ -32,7 +32,15 @@ function jsxRuntime(type, props, key, __source, __self) { } } - return Element(type, key, ref, normalizedProps, Host.owner, __source, __self); + return new Element( + type, + key, + ref, + normalizedProps, + Host.owner, + __source, + __self + ); } @@ -92,6 +100,6 @@ const jsxDEV = __DEV__ ? jsxDEVWithValidation : undefined; export { jsx, jsxs, - jsxDEV, + jsxDEV }; From 0c2c2b310e97a82ea023e49ba325d22205eb2325 Mon Sep 17 00:00:00 2001 From: songzheng Date: Mon, 19 Apr 2021 19:09:04 +0800 Subject: [PATCH 10/13] feat: jsx-runtime MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1.jsx-runtime和createElement组织结构保持一致 2.区分环境导出不同jsx-runtime,和react一致 --- packages/rax/src/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/rax/src/index.js b/packages/rax/src/index.js index 1938aad2a..728eb41b2 100644 --- a/packages/rax/src/index.js +++ b/packages/rax/src/index.js @@ -7,8 +7,8 @@ export memo from './memo'; export Fragment from './fragment'; export render from './render'; export Component, { PureComponent } from './vdom/component'; +export { jsx, jsxs, jsxDEV } from './jsx-runtime'; export version from './version'; -export { jsx, jsxs, jsxDEV } from './vdom/jsx-runtime'; import Host from './vdom/host'; import Instance from './vdom/instance'; From 2632b35599b794a474fb74d655c63422a826f82c Mon Sep 17 00:00:00 2001 From: songzheng Date: Mon, 19 Apr 2021 22:41:23 +0800 Subject: [PATCH 11/13] feat: jsx-runtime MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 优化构建体积 --- packages/rax/jsx-dev-runtime.js | 2 +- packages/rax/jsx-runtime.js | 2 +- packages/rax/src/jsx-runtime.js | 96 ++------------------------- packages/rax/src/vdom/element.js | 32 ++++----- packages/rax/src/vdom/jsx.js | 36 ++++++++++ packages/rax/src/vdom/jsxValidator.js | 54 +++++++++++++++ 6 files changed, 109 insertions(+), 113 deletions(-) create mode 100644 packages/rax/src/vdom/jsx.js create mode 100644 packages/rax/src/vdom/jsxValidator.js diff --git a/packages/rax/jsx-dev-runtime.js b/packages/rax/jsx-dev-runtime.js index 1ea24f38b..ddee318bb 100644 --- a/packages/rax/jsx-dev-runtime.js +++ b/packages/rax/jsx-dev-runtime.js @@ -1 +1 @@ -export {Fragment, jsxDEV} from './index'; +export { Fragment, jsxDEV } from './index'; diff --git a/packages/rax/jsx-runtime.js b/packages/rax/jsx-runtime.js index 6c14c4b90..d0f12c53b 100644 --- a/packages/rax/jsx-runtime.js +++ b/packages/rax/jsx-runtime.js @@ -1 +1 @@ -export {Fragment, jsx, jsxs, jsxDEV} from './index'; +export { Fragment, jsx, jsxs, jsxDEV } from './index'; diff --git a/packages/rax/src/jsx-runtime.js b/packages/rax/src/jsx-runtime.js index bc2bf283e..aaa66a638 100644 --- a/packages/rax/src/jsx-runtime.js +++ b/packages/rax/src/jsx-runtime.js @@ -1,100 +1,14 @@ -import Host from './vdom/host'; -import Element from './vdom/element'; -import { warning, throwError, throwMinifiedWarn } from './error'; -import { isArray, NOOP } from './types'; -import validateChildKeys from './validateChildKeys'; - -const __DEV__ = process.env.NODE_ENV !== 'production'; +import { jsxWithValidation, jsxsWithValidation, jsxDEVWithValidation } from "./vdom/jsxValidator"; +import { jsxRuntime as jsxProd } from "./vdom/jsx" /** * This module is adapted to react's jsx-runtime module. * @see:[introducing-the-new-jsx-transform](https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.htm) */ -function jsxRuntime(type, props, key, __source, __self) { - let normalizedProps = {}; - let propName; - - // The default value of key and ref of rax element is null - let ref = props && props.ref || null; - key = key || null; - - for (propName in props) { - if (propName !== 'ref') { - normalizedProps[propName] = props[propName]; - } - } - - let defaults; - if (typeof type === 'function' && (defaults = type.defaultProps)) { - for (propName in defaults) - if (normalizedProps[propName] === undefined) { - normalizedProps[propName] = defaults[propName]; - } - } - - return new Element( - type, - key, - ref, - normalizedProps, - Host.owner, - __source, - __self - ); -} - - -function _jsxWithValidation(type, props, key, isStaticChildren, __source, __self) { - const elem = jsxRuntime(type, props, key, __source, __self); - - if (type == null) { - if (__DEV__) { - throwError(`Invalid element type, expected a string or a class/function component but got "${type}".`); - } else { - // A empty component replaced avoid break render in production - type = NOOP; - throwMinifiedWarn(0); - } - } - - const children = props && props.children; - if (children !== undefined) { - if (isStaticChildren) { - if (isArray(children)) { - for (let i = 0; i < children.length; i++) { - validateChildKeys(children[i], type); - } - - if (Object.freeze) { - Object.freeze(children); - } - } else { - warning( - 'Rax.jsx: Static children should always be an array. ' + - 'You are likely explicitly calling Rax.jsxs or Rax.jsxDEV. ' + - 'Use the Babel transform instead.', - ); - } - } else { - validateChildKeys(children, type); - } - } - - return elem; -} - -function jsxWithValidation(type, props, key) { - return _jsxWithValidation(type, props, key, false); -} -function jsxsWithValidation(type, props, key) { - return _jsxWithValidation(type, props, key, true); -} -function jsxDEVWithValidation(type, props, key, __source, __self) { - return _jsxWithValidation(type, props, key, true, __source, __self); -} +const __DEV__ = process.env.NODE_ENV !== 'production'; -const jsx = __DEV__ ? jsxWithValidation : jsxRuntime; -const jsxs = __DEV__ ? jsxsWithValidation : jsxRuntime; +const jsx = __DEV__ ? jsxWithValidation : jsxProd; +const jsxs = __DEV__ ? jsxsWithValidation : jsxProd; const jsxDEV = __DEV__ ? jsxDEVWithValidation : undefined; export { diff --git a/packages/rax/src/vdom/element.js b/packages/rax/src/vdom/element.js index 27cdf010e..8355f327b 100644 --- a/packages/rax/src/vdom/element.js +++ b/packages/rax/src/vdom/element.js @@ -1,5 +1,14 @@ import checkPropTypes from 'prop-types/checkPropTypes'; +function setBuiltInPropertyDescriptor(element, propertyName, value) { + Object.defineProperty(element, propertyName, { + configurable: false, + enumerable: false, + writable: true, + value: value + }); +} + export default function Element(type, key, ref, props, owner, __source, __self) { let element = { // Built-in properties that belong on the element @@ -26,26 +35,9 @@ export default function Element(type, key, ref, props, owner, __source, __self) } // We make validation flag non-enumerable, so the test framework could ignore it - Object.defineProperty(element, '__validated', { - configurable: false, - enumerable: false, - writable: true, - value: false - }); - - Object.defineProperty(element, '__source', { - configurable: false, - enumerable: false, - writable: true, - value: __source - }); - - Object.defineProperty(element, '__self', { - configurable: false, - enumerable: false, - writable: true, - value: __self - }); + setBuiltInPropertyDescriptor(element, '__validated', false); + setBuiltInPropertyDescriptor(element, '__source', __source); + setBuiltInPropertyDescriptor(element, '__self', __self); } // Props is immutable diff --git a/packages/rax/src/vdom/jsx.js b/packages/rax/src/vdom/jsx.js new file mode 100644 index 000000000..2afcc8d64 --- /dev/null +++ b/packages/rax/src/vdom/jsx.js @@ -0,0 +1,36 @@ +import Host from './host'; +import Element from './element'; + +export function jsxRuntime(type, props, key, __source, __self) { + let normalizedProps = {}; + let propName; + + // The default value of key and ref of rax element is null + let ref = props && props.ref || null; + key = key || null; + + for (propName in props) { + if (propName !== 'ref') { + normalizedProps[propName] = props[propName]; + } + } + + let defaults; + if (typeof type === 'function' && (defaults = type.defaultProps)) { + for (propName in defaults) + if (normalizedProps[propName] === undefined) { + normalizedProps[propName] = defaults[propName]; + } + } + + return new Element( + type, + key, + ref, + normalizedProps, + Host.owner, + __source, + __self + ); +} + diff --git a/packages/rax/src/vdom/jsxValidator.js b/packages/rax/src/vdom/jsxValidator.js new file mode 100644 index 000000000..f6b34739a --- /dev/null +++ b/packages/rax/src/vdom/jsxValidator.js @@ -0,0 +1,54 @@ +import { throwError, throwMinifiedWarn, warning } from "../error"; +import { isArray, NOOP } from "../types"; +import validateChildKeys from "../validateChildKeys"; +import { jsxRuntime } from "./jsx"; + +function _jsxWithValidation(type, props, key, isStaticChildren, __source, __self) { + const elem = jsxRuntime(type, props, key, __source, __self); + + if (type == null) { + if (__DEV__) { + throwError(`Invalid element type, expected a string or a class/function component but got "${type}".`); + } else { + // A empty component replaced avoid break render in production + type = NOOP; + throwMinifiedWarn(0); + } + } + + const children = props && props.children; + if (children !== undefined) { + if (isStaticChildren) { + if (isArray(children)) { + for (let i = 0; i < children.length; i++) { + validateChildKeys(children[i], type); + } + + if (Object.freeze) { + Object.freeze(children); + } + } else { + warning( + 'Rax.jsx: Static children should always be an array. ' + + 'You are likely explicitly calling Rax.jsxs or Rax.jsxDEV. ' + + 'Use the Babel transform instead.', + ); + } + } else { + validateChildKeys(children, type); + } + } + + return elem; +} + + +export function jsxWithValidation(type, props, key) { + return _jsxWithValidation(type, props, key, false); +} +export function jsxsWithValidation(type, props, key) { + return _jsxWithValidation(type, props, key, true); +} +export function jsxDEVWithValidation(type, props, key, __source, __self) { + return _jsxWithValidation(type, props, key, true, __source, __self); +} From b57b66693b007b68847740f028494a6999cc9311 Mon Sep 17 00:00:00 2001 From: songzheng Date: Tue, 20 Apr 2021 10:00:29 +0800 Subject: [PATCH 12/13] feat: jsx-runtime MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修改jsxValidator导出的命名 --- packages/rax/src/vdom/jsxValidator.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/rax/src/vdom/jsxValidator.js b/packages/rax/src/vdom/jsxValidator.js index f6b34739a..1f50e6d13 100644 --- a/packages/rax/src/vdom/jsxValidator.js +++ b/packages/rax/src/vdom/jsxValidator.js @@ -43,12 +43,12 @@ function _jsxWithValidation(type, props, key, isStaticChildren, __source, __self } -export function jsxWithValidation(type, props, key) { +export function jsxWithValidationDynamic(type, props, key) { return _jsxWithValidation(type, props, key, false); } -export function jsxsWithValidation(type, props, key) { +export function jsxWithValidationStatic(type, props, key) { return _jsxWithValidation(type, props, key, true); } -export function jsxDEVWithValidation(type, props, key, __source, __self) { +export function jsxWithValidation(type, props, key, __source, __self) { return _jsxWithValidation(type, props, key, true, __source, __self); } From 22f1efaf61d2a3878221abf78013023b14bc6bb2 Mon Sep 17 00:00:00 2001 From: songzheng Date: Tue, 20 Apr 2021 10:13:06 +0800 Subject: [PATCH 13/13] feat: jsx-runtime MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修改jsxValidator导出的命名 --- packages/rax/src/jsx-runtime.js | 10 +++++----- packages/rax/src/vdom/jsxValidator.js | 10 ++++++---- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/packages/rax/src/jsx-runtime.js b/packages/rax/src/jsx-runtime.js index aaa66a638..431075cb7 100644 --- a/packages/rax/src/jsx-runtime.js +++ b/packages/rax/src/jsx-runtime.js @@ -1,5 +1,5 @@ -import { jsxWithValidation, jsxsWithValidation, jsxDEVWithValidation } from "./vdom/jsxValidator"; -import { jsxRuntime as jsxProd } from "./vdom/jsx" +import { jsxWithValidation, jsxWithValidationDynamic, jsxWithValidationStatic } from './vdom/jsxValidator'; +import { jsxRuntime as jsxProd } from './vdom/jsx'; /** * This module is adapted to react's jsx-runtime module. @@ -7,9 +7,9 @@ import { jsxRuntime as jsxProd } from "./vdom/jsx" */ const __DEV__ = process.env.NODE_ENV !== 'production'; -const jsx = __DEV__ ? jsxWithValidation : jsxProd; -const jsxs = __DEV__ ? jsxsWithValidation : jsxProd; -const jsxDEV = __DEV__ ? jsxDEVWithValidation : undefined; +const jsx = __DEV__ ? jsxWithValidationDynamic : jsxProd; +const jsxs = __DEV__ ? jsxWithValidationStatic : jsxProd; +const jsxDEV = __DEV__ ? jsxWithValidation : undefined; export { jsx, diff --git a/packages/rax/src/vdom/jsxValidator.js b/packages/rax/src/vdom/jsxValidator.js index 1f50e6d13..113e8c3dd 100644 --- a/packages/rax/src/vdom/jsxValidator.js +++ b/packages/rax/src/vdom/jsxValidator.js @@ -1,7 +1,9 @@ -import { throwError, throwMinifiedWarn, warning } from "../error"; -import { isArray, NOOP } from "../types"; -import validateChildKeys from "../validateChildKeys"; -import { jsxRuntime } from "./jsx"; +import { throwError, throwMinifiedWarn, warning } from '../error'; +import { isArray, NOOP } from '../types'; +import validateChildKeys from '../validateChildKeys'; +import { jsxRuntime } from './jsx'; + +const __DEV__ = process.env.NODE_ENV !== 'production'; function _jsxWithValidation(type, props, key, isStaticChildren, __source, __self) { const elem = jsxRuntime(type, props, key, __source, __self);