forked from facebook/react
-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Fresh] Set up infra for runtime and Babel plugin (facebook#15698)
* Add a stub for React Fresh Babel plugin package * Move ReactFresh-test into ReactFresh top level directory * Add a stub for React Fresh Runtime entry point * Extract Fresh runtime from tests into its entry point
- Loading branch information
Showing
13 changed files
with
255 additions
and
107 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# react-fresh | ||
|
||
This is an experimental package for hot reloading. | ||
|
||
**Its API is not as stable as that of React, React Native, or React DOM, and does not follow the common versioning scheme.** | ||
|
||
**Use it at your own risk.** |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
/** | ||
* Copyright (c) Facebook, Inc. and its affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
'use strict'; | ||
|
||
const ReactFreshBabelPlugin = require('./src/ReactFreshBabelPlugin'); | ||
|
||
// This is hacky but makes it work with both Rollup and Jest. | ||
module.exports = ReactFreshBabelPlugin.default || ReactFreshBabelPlugin; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
'use strict'; | ||
|
||
if (process.env.NODE_ENV === 'production') { | ||
module.exports = require('./cjs/react-fresh-babel.production.min.js'); | ||
} else { | ||
module.exports = require('./cjs/react-fresh-babel.development.js'); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
'use strict'; | ||
|
||
if (process.env.NODE_ENV === 'production') { | ||
module.exports = require('./cjs/react-fresh-runtime.production.min.js'); | ||
} else { | ||
module.exports = require('./cjs/react-fresh-runtime.development.js'); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
{ | ||
"name": "react-fresh", | ||
"private": true, | ||
"description": "React is a JavaScript library for building user interfaces.", | ||
"keywords": [ | ||
"react" | ||
], | ||
"version": "0.1.0", | ||
"homepage": "https://reactjs.org/", | ||
"bugs": "https://github.com/facebook/react/issues", | ||
"license": "MIT", | ||
"files": [ | ||
"LICENSE", | ||
"README.md", | ||
"babel.js", | ||
"runtime.js", | ||
"build-info.json", | ||
"cjs/", | ||
"umd/" | ||
], | ||
"main": "index.js", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/facebook/react.git", | ||
"directory": "packages/react" | ||
}, | ||
"engines": { | ||
"node": ">=0.10.0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
/** | ||
* Copyright (c) Facebook, Inc. and its affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
'use strict'; | ||
|
||
const ReactFreshRuntime = require('./src/ReactFreshRuntime'); | ||
|
||
// This is hacky but makes it work with both Rollup and Jest. | ||
module.exports = ReactFreshRuntime.default || ReactFreshRuntime; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
/** | ||
* Copyright (c) Facebook, Inc. and its affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
'use strict'; | ||
|
||
// TODO | ||
export default function(babel) { | ||
return { | ||
visitor: {}, | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
/** | ||
* Copyright (c) Facebook, Inc. and its affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
* | ||
* @flow | ||
*/ | ||
|
||
import type { | ||
Family, | ||
HotUpdate, | ||
} from 'react-reconciler/src/ReactFiberHotReloading'; | ||
|
||
import {REACT_MEMO_TYPE, REACT_FORWARD_REF_TYPE} from 'shared/ReactSymbols'; | ||
|
||
// We never remove these associations. | ||
// It's OK to reference families, but use WeakMap/Set for types. | ||
const allFamiliesByID: Map<string, Family> = new Map(); | ||
const allTypes: WeakSet<any> = new WeakSet(); | ||
const allSignaturesByType: WeakMap<any, string> = new WeakMap(); | ||
// This WeakMap is read by React, so we only put families | ||
// that have actually been edited here. This keeps checks fast. | ||
const familiesByType: WeakMap<any, Family> = new WeakMap(); | ||
|
||
// This is cleared on every prepareUpdate() call. | ||
// It is an array of [Family, NextType] tuples. | ||
let pendingUpdates: Array<[Family, any]> = []; | ||
|
||
export function prepareUpdate(): HotUpdate { | ||
const staleFamilies = new Set(); | ||
const updatedFamilies = new Set(); | ||
|
||
const updates = pendingUpdates; | ||
pendingUpdates = []; | ||
updates.forEach(([family, nextType]) => { | ||
// Now that we got a real edit, we can create associations | ||
// that will be read by the React reconciler. | ||
const prevType = family.current; | ||
familiesByType.set(prevType, family); | ||
familiesByType.set(nextType, family); | ||
family.current = nextType; | ||
|
||
// Determine whether this should be a re-render or a re-mount. | ||
const prevSignature = allSignaturesByType.get(prevType); | ||
const nextSignature = allSignaturesByType.get(nextType); | ||
if (prevSignature !== nextSignature) { | ||
staleFamilies.add(family); | ||
} else { | ||
updatedFamilies.add(family); | ||
} | ||
}); | ||
|
||
return { | ||
familiesByType, | ||
updatedFamilies, | ||
staleFamilies, | ||
}; | ||
} | ||
|
||
export function register(type: any, id: string): void { | ||
if (type === null) { | ||
return; | ||
} | ||
if (typeof type !== 'function' && typeof type !== 'object') { | ||
return; | ||
} | ||
|
||
// This can happen in an edge case, e.g. if we register | ||
// return value of a HOC but it returns a cached component. | ||
// Ignore anything but the first registration for each type. | ||
if (allTypes.has(type)) { | ||
return; | ||
} | ||
allTypes.add(type); | ||
|
||
// Create family or remember to update it. | ||
// None of this bookkeeping affects reconciliation | ||
// until the first prepareUpdate() call above. | ||
let family = allFamiliesByID.get(id); | ||
if (family === undefined) { | ||
family = {current: type}; | ||
allFamiliesByID.set(id, family); | ||
} else { | ||
pendingUpdates.push([family, type]); | ||
} | ||
|
||
// Visit inner types because we might not have registered them. | ||
if (typeof type === 'object' && type !== null) { | ||
switch (type.$$typeof) { | ||
case REACT_FORWARD_REF_TYPE: | ||
register(type.render, id + '$render'); | ||
break; | ||
case REACT_MEMO_TYPE: | ||
register(type.type, id + '$type'); | ||
break; | ||
} | ||
} | ||
} | ||
|
||
export function setSignature(type: any, signature: string): void { | ||
allSignaturesByType.set(type, signature); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
23 changes: 23 additions & 0 deletions
23
packages/react-fresh/src/__tests__/ReactFreshBabelPlugin-test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/** | ||
* Copyright (c) Facebook, Inc. and its affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
'use strict'; | ||
|
||
let babel = require('babel-core'); | ||
let freshPlugin = require('react-fresh/babel'); | ||
|
||
function transform(input, options = {}) { | ||
return babel.transform(input, { | ||
plugins: [[freshPlugin]], | ||
}).code; | ||
} | ||
|
||
describe('ReactFreshBabelPlugin', () => { | ||
it('hello world', () => { | ||
expect(transform(`hello()`)).toMatchSnapshot(); | ||
}); | ||
}); |
3 changes: 3 additions & 0 deletions
3
packages/react-fresh/src/__tests__/__snapshots__/ReactFreshBabelPlugin-test.js.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`ReactFreshBabelPlugin hello world 1`] = `"hello();"`; |
Oops, something went wrong.