Skip to content

Commit ef6fb14

Browse files
committed
add jsx-runtime and jsx-dev-runtime
1 parent 0705b72 commit ef6fb14

File tree

9 files changed

+141
-54
lines changed

9 files changed

+141
-54
lines changed

packages/react/jsx-dev-runtime.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/**
2+
* Copyright (c) Facebook, Inc. and its affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @flow
8+
*/
9+
10+
export {Fragment, jsxDEV} from './src/React';

packages/react/jsx-runtime.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/**
2+
* Copyright (c) Facebook, Inc. and its affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @flow
8+
*/
9+
10+
export {Fragment, jsx, jsxs} from './src/React';

packages/react/npm/jsx-dev-runtime.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
'use strict';
2+
3+
if (process.env.NODE_ENV === 'production') {
4+
module.exports = require('./cjs/react-jsx-dev-runtime.production.min.js');
5+
} else {
6+
module.exports = require('./cjs/react-jsx-dev-runtime.development.js');
7+
}

packages/react/npm/jsx-runtime.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
'use strict';
2+
3+
if (process.env.NODE_ENV === 'production') {
4+
module.exports = require('./cjs/react-jsx-runtime.production.min.js');
5+
} else {
6+
module.exports = require('./cjs/react-jsx-runtime.development.js');
7+
}

packages/react/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414
"build-info.json",
1515
"index.js",
1616
"cjs/",
17-
"umd/"
17+
"umd/",
18+
"jsx-runtime.js",
19+
"jsx-dev-runtime.js"
1820
],
1921
"main": "index.js",
2022
"repository": {

packages/react/src/__tests__/ReactElementJSX-test.js

Lines changed: 63 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
let React;
1313
let ReactDOM;
1414
let ReactTestUtils;
15+
let jsxRuntime;
1516

1617
// NOTE: We're explicitly not using JSX here. This is intended to test
1718
// a new React.jsx api which does not have a JSX transformer yet.
@@ -29,6 +30,7 @@ describe('ReactElement.jsx', () => {
2930
global.Symbol = undefined;
3031

3132
React = require('react');
33+
jsxRuntime = require('react/jsx-runtime');
3234
ReactDOM = require('react-dom');
3335
ReactTestUtils = require('react-dom/test-utils');
3436
});
@@ -45,24 +47,24 @@ describe('ReactElement.jsx', () => {
4547
it('allows static methods to be called using the type property', () => {
4648
class StaticMethodComponentClass extends React.Component {
4749
render() {
48-
return React.jsx('div', {});
50+
return jsxRuntime.jsx('div', {});
4951
}
5052
}
5153
StaticMethodComponentClass.someStaticMethod = () => 'someReturnValue';
5254

53-
const element = React.jsx(StaticMethodComponentClass, {});
55+
const element = jsxRuntime.jsx(StaticMethodComponentClass, {});
5456
expect(element.type.someStaticMethod()).toBe('someReturnValue');
5557
});
5658

5759
it('identifies valid elements', () => {
5860
class Component extends React.Component {
5961
render() {
60-
return React.jsx('div', {});
62+
return jsxRuntime.jsx('div', {});
6163
}
6264
}
6365

64-
expect(React.isValidElement(React.jsx('div', {}))).toEqual(true);
65-
expect(React.isValidElement(React.jsx(Component, {}))).toEqual(true);
66+
expect(React.isValidElement(jsxRuntime.jsx('div', {}))).toEqual(true);
67+
expect(React.isValidElement(jsxRuntime.jsx(Component, {}))).toEqual(true);
6668

6769
expect(React.isValidElement(null)).toEqual(false);
6870
expect(React.isValidElement(true)).toEqual(false);
@@ -83,58 +85,58 @@ describe('ReactElement.jsx', () => {
8385
expect(React.isValidElement(Component)).toEqual(false);
8486
expect(React.isValidElement({type: 'div', props: {}})).toEqual(false);
8587

86-
const jsonElement = JSON.stringify(React.jsx('div', {}));
88+
const jsonElement = JSON.stringify(jsxRuntime.jsx('div', {}));
8789
expect(React.isValidElement(JSON.parse(jsonElement))).toBe(true);
8890
});
8991

9092
it('is indistinguishable from a plain object', () => {
91-
const element = React.jsx('div', {className: 'foo'});
93+
const element = jsxRuntime.jsx('div', {className: 'foo'});
9294
const object = {};
9395
expect(element.constructor).toBe(object.constructor);
9496
});
9597

9698
it('should use default prop value when removing a prop', () => {
9799
class Component extends React.Component {
98100
render() {
99-
return React.jsx('span', {});
101+
return jsxRuntime.jsx('span', {});
100102
}
101103
}
102104
Component.defaultProps = {fruit: 'persimmon'};
103105

104106
const container = document.createElement('div');
105107
const instance = ReactDOM.render(
106-
React.jsx(Component, {fruit: 'mango'}),
108+
jsxRuntime.jsx(Component, {fruit: 'mango'}),
107109
container,
108110
);
109111
expect(instance.props.fruit).toBe('mango');
110112

111-
ReactDOM.render(React.jsx(Component, {}), container);
113+
ReactDOM.render(jsxRuntime.jsx(Component, {}), container);
112114
expect(instance.props.fruit).toBe('persimmon');
113115
});
114116

115117
it('should normalize props with default values', () => {
116118
class Component extends React.Component {
117119
render() {
118-
return React.jsx('span', {children: this.props.prop});
120+
return jsxRuntime.jsx('span', {children: this.props.prop});
119121
}
120122
}
121123
Component.defaultProps = {prop: 'testKey'};
122124

123125
const instance = ReactTestUtils.renderIntoDocument(
124-
React.jsx(Component, {}),
126+
jsxRuntime.jsx(Component, {}),
125127
);
126128
expect(instance.props.prop).toBe('testKey');
127129

128130
const inst2 = ReactTestUtils.renderIntoDocument(
129-
React.jsx(Component, {prop: null}),
131+
jsxRuntime.jsx(Component, {prop: null}),
130132
);
131133
expect(inst2.props.prop).toBe(null);
132134
});
133135

134136
it('throws when changing a prop (in dev) after element creation', () => {
135137
class Outer extends React.Component {
136138
render() {
137-
const el = React.jsx('div', {className: 'moo'});
139+
const el = jsxRuntime.jsx('div', {className: 'moo'});
138140

139141
if (__DEV__) {
140142
expect(function() {
@@ -150,7 +152,7 @@ describe('ReactElement.jsx', () => {
150152
}
151153
}
152154
const outer = ReactTestUtils.renderIntoDocument(
153-
React.jsx(Outer, {color: 'orange'}),
155+
jsxRuntime.jsx(Outer, {color: 'orange'}),
154156
);
155157
if (__DEV__) {
156158
expect(ReactDOM.findDOMNode(outer).className).toBe('moo');
@@ -163,7 +165,7 @@ describe('ReactElement.jsx', () => {
163165
const container = document.createElement('div');
164166
class Outer extends React.Component {
165167
render() {
166-
const el = React.jsx('div', {children: this.props.sound});
168+
const el = jsxRuntime.jsx('div', {children: this.props.sound});
167169

168170
if (__DEV__) {
169171
expect(function() {
@@ -179,7 +181,7 @@ describe('ReactElement.jsx', () => {
179181
}
180182
}
181183
Outer.defaultProps = {sound: 'meow'};
182-
const outer = ReactDOM.render(React.jsx(Outer, {}), container);
184+
const outer = ReactDOM.render(jsxRuntime.jsx(Outer, {}), container);
183185
expect(ReactDOM.findDOMNode(outer).textContent).toBe('meow');
184186
if (__DEV__) {
185187
expect(ReactDOM.findDOMNode(outer).className).toBe('');
@@ -191,11 +193,11 @@ describe('ReactElement.jsx', () => {
191193
it('does not warn for NaN props', () => {
192194
class Test extends React.Component {
193195
render() {
194-
return React.jsx('div', {});
196+
return jsxRuntime.jsx('div', {});
195197
}
196198
}
197199
const test = ReactTestUtils.renderIntoDocument(
198-
React.jsx(Test, {value: +undefined}),
200+
jsxRuntime.jsx(Test, {value: +undefined}),
199201
);
200202
expect(test.props.value).toBeNaN();
201203
});
@@ -204,21 +206,23 @@ describe('ReactElement.jsx', () => {
204206
const container = document.createElement('div');
205207
class Child extends React.Component {
206208
render() {
207-
return React.jsx('div', {children: this.props.key});
209+
return jsxRuntime.jsx('div', {children: this.props.key});
208210
}
209211
}
210212
class Parent extends React.Component {
211213
render() {
212-
return React.jsxs('div', {
214+
return jsxRuntime.jsxs('div', {
213215
children: [
214-
React.jsx(Child, {}, '0'),
215-
React.jsx(Child, {}, '1'),
216-
React.jsx(Child, {}, '2'),
216+
jsxRuntime.jsx(Child, {}, '0'),
217+
jsxRuntime.jsx(Child, {}, '1'),
218+
jsxRuntime.jsx(Child, {}, '2'),
217219
],
218220
});
219221
}
220222
}
221-
expect(() => ReactDOM.render(React.jsx(Parent, {}), container)).toErrorDev(
223+
expect(() =>
224+
ReactDOM.render(jsxRuntime.jsx(Parent, {}), container),
225+
).toErrorDev(
222226
'Child: `key` is not a prop. Trying to access it will result ' +
223227
'in `undefined` being returned. If you need to access the same ' +
224228
'value within the child component, you should pass it as a different ' +
@@ -229,7 +233,10 @@ describe('ReactElement.jsx', () => {
229233
it('warns when a jsxs is passed something that is not an array', () => {
230234
const container = document.createElement('div');
231235
expect(() =>
232-
ReactDOM.render(React.jsxs('div', {children: 'foo'}, null), container),
236+
ReactDOM.render(
237+
jsxRuntime.jsxs('div', {children: 'foo'}, null),
238+
container,
239+
),
233240
).toErrorDev(
234241
'React.jsx: Static children should always be an array. ' +
235242
'You are likely explicitly calling React.jsxs or React.jsxDEV. ' +
@@ -239,7 +246,7 @@ describe('ReactElement.jsx', () => {
239246
});
240247

241248
it('should warn when `key` is being accessed on a host element', () => {
242-
const element = React.jsxs('div', {}, '3');
249+
const element = jsxRuntime.jsxs('div', {}, '3');
243250
expect(
244251
() => void element.props.key,
245252
).toErrorDev(
@@ -255,17 +262,19 @@ describe('ReactElement.jsx', () => {
255262
const container = document.createElement('div');
256263
class Child extends React.Component {
257264
render() {
258-
return React.jsx('div', {children: this.props.ref});
265+
return jsxRuntime.jsx('div', {children: this.props.ref});
259266
}
260267
}
261268
class Parent extends React.Component {
262269
render() {
263-
return React.jsx('div', {
264-
children: React.jsx(Child, {ref: 'childElement'}),
270+
return jsxRuntime.jsx('div', {
271+
children: jsxRuntime.jsx(Child, {ref: 'childElement'}),
265272
});
266273
}
267274
}
268-
expect(() => ReactDOM.render(React.jsx(Parent, {}), container)).toErrorDev(
275+
expect(() =>
276+
ReactDOM.render(jsxRuntime.jsx(Parent, {}), container),
277+
).toErrorDev(
269278
'Child: `ref` is not a prop. Trying to access it will result ' +
270279
'in `undefined` being returned. If you need to access the same ' +
271280
'value within the child component, you should pass it as a different ' +
@@ -292,15 +301,16 @@ describe('ReactElement.jsx', () => {
292301
jest.resetModules();
293302

294303
React = require('react');
304+
jsxRuntime = require('react/jsx-runtime');
295305

296306
class Component extends React.Component {
297307
render() {
298-
return React.jsx('div');
308+
return jsxRuntime.jsx('div');
299309
}
300310
}
301311

302-
expect(React.isValidElement(React.jsx('div', {}))).toEqual(true);
303-
expect(React.isValidElement(React.jsx(Component, {}))).toEqual(true);
312+
expect(React.isValidElement(jsxRuntime.jsx('div', {}))).toEqual(true);
313+
expect(React.isValidElement(jsxRuntime.jsx(Component, {}))).toEqual(true);
304314

305315
expect(React.isValidElement(null)).toEqual(false);
306316
expect(React.isValidElement(true)).toEqual(false);
@@ -321,29 +331,31 @@ describe('ReactElement.jsx', () => {
321331
expect(React.isValidElement(Component)).toEqual(false);
322332
expect(React.isValidElement({type: 'div', props: {}})).toEqual(false);
323333

324-
const jsonElement = JSON.stringify(React.jsx('div', {}));
334+
const jsonElement = JSON.stringify(jsxRuntime.jsx('div', {}));
325335
expect(React.isValidElement(JSON.parse(jsonElement))).toBe(false);
326336
});
327337

328338
it('should warn when unkeyed children are passed to jsx', () => {
329339
const container = document.createElement('div');
330340
class Child extends React.Component {
331341
render() {
332-
return React.jsx('div', {});
342+
return jsxRuntime.jsx('div', {});
333343
}
334344
}
335345
class Parent extends React.Component {
336346
render() {
337-
return React.jsx('div', {
347+
return jsxRuntime.jsx('div', {
338348
children: [
339-
React.jsx(Child, {}),
340-
React.jsx(Child, {}),
341-
React.jsx(Child, {}),
349+
jsxRuntime.jsx(Child, {}),
350+
jsxRuntime.jsx(Child, {}),
351+
jsxRuntime.jsx(Child, {}),
342352
],
343353
});
344354
}
345355
}
346-
expect(() => ReactDOM.render(React.jsx(Parent, {}), container)).toErrorDev(
356+
expect(() =>
357+
ReactDOM.render(jsxRuntime.jsx(Parent, {}), container),
358+
).toErrorDev(
347359
'Warning: Each child in a list should have a unique "key" prop.\n\n' +
348360
'Check the render method of `Parent`. See https://fb.me/react-warning-keys for more information.\n' +
349361
' in Child (created by Parent)\n' +
@@ -356,18 +368,18 @@ describe('ReactElement.jsx', () => {
356368
const container = document.createElement('div');
357369
class Child extends React.Component {
358370
render() {
359-
return React.jsx('div', {});
371+
return jsxRuntime.jsx('div', {});
360372
}
361373
}
362374
class Parent extends React.Component {
363375
render() {
364-
return React.jsx('div', {
365-
children: [React.jsx(Child, {key: '0'})],
376+
return jsxRuntime.jsx('div', {
377+
children: [jsxRuntime.jsx(Child, {key: '0'})],
366378
});
367379
}
368380
}
369381
expect(() =>
370-
ReactDOM.render(React.jsx(Parent, {}), container),
382+
ReactDOM.render(jsxRuntime.jsx(Parent, {}), container),
371383
).toErrorDev(
372384
'Warning: React.jsx: Spreading a key to JSX is a deprecated pattern. ' +
373385
'Explicitly pass a key after spreading props in your JSX call. ' +
@@ -380,21 +392,21 @@ describe('ReactElement.jsx', () => {
380392
const container = document.createElement('div');
381393
class Child extends React.Component {
382394
render() {
383-
return React.jsx('div', {});
395+
return jsxRuntime.jsx('div', {});
384396
}
385397
}
386398
class Parent extends React.Component {
387399
render() {
388-
return React.jsxs('div', {
400+
return jsxRuntime.jsxs('div', {
389401
children: [
390-
React.jsx(Child, {}),
391-
React.jsx(Child, {}),
392-
React.jsx(Child, {}),
402+
jsxRuntime.jsx(Child, {}),
403+
jsxRuntime.jsx(Child, {}),
404+
jsxRuntime.jsx(Child, {}),
393405
],
394406
});
395407
}
396408
}
397409
// TODO: an explicit expect for no warning?
398-
ReactDOM.render(React.jsx(Parent, {}), container);
410+
ReactDOM.render(jsxRuntime.jsx(Parent, {}), container);
399411
});
400412
});

0 commit comments

Comments
 (0)