Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bundle DOM renderers into their individual UMD bundles #7164

Merged
merged 4 commits into from
Aug 9, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
26 changes: 24 additions & 2 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,12 +117,31 @@ module.exports = function(grunt) {
'build-modules',
'browserify:addonsMin',
]);
grunt.registerTask('build:dom', [
'build-modules',
'version-check',
'browserify:dom',
]);
grunt.registerTask('build:dom-min', [
'build-modules',
'version-check',
'browserify:domMin',
]);
grunt.registerTask('build:dom-server', [
'build-modules',
'version-check',
'browserify:domServer',
]);
grunt.registerTask('build:dom-server-min', [
'build-modules',
'version-check',
'browserify:domServerMin',
]);
grunt.registerTask('build:npm-react', [
'version-check',
'build-modules',
'npm-react:release',
]);
grunt.registerTask('build:react-dom', require('./grunt/tasks/react-dom'));

var jestTasks = require('./grunt/tasks/jest');
grunt.registerTask('jest:normal', jestTasks.normal);
Expand All @@ -141,7 +160,10 @@ module.exports = function(grunt) {
'browserify:addons',
'browserify:min',
'browserify:addonsMin',
'build:react-dom',
'browserify:dom',
'browserify:domMin',
'browserify:domServer',
'browserify:domServerMin',
'npm-react:release',
'npm-react:pack',
'npm-react-dom:release',
Expand Down
91 changes: 90 additions & 1 deletion grunt/config/browserify.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,30 @@ var grunt = require('grunt');
var UglifyJS = require('uglify-js');
var uglifyify = require('uglifyify');
var derequire = require('derequire');
var aliasify = require('aliasify');
var globalShim = require('browserify-global-shim');
var collapser = require('bundle-collapser/plugin');

var envifyDev = envify({NODE_ENV: process.env.NODE_ENV || 'development'});
var envifyProd = envify({NODE_ENV: process.env.NODE_ENV || 'production'});

var SECRET_INTERNALS_NAME = 'React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED';

var shimSharedModules = globalShim.configure({
'./ReactCurrentOwner': SECRET_INTERNALS_NAME + '.ReactCurrentOwner',
'./ReactComponentTreeHook': SECRET_INTERNALS_NAME + '.ReactComponentTreeHook',
// All these methods are shared are exposed.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you fix that language?

'./ReactElement': 'React',
'./ReactPropTypes': 'React.PropTypes',
'./ReactChildren': 'React.Children',
});

var shimDOMModules = aliasify.configure({
'aliases': {
'./ReactAddonsDOMDependencies': './build/modules/ReactAddonsDOMDependenciesUMDShim.js',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

./ReactAddonsDOMDependencies is already relative to build/modules - Do you need that in the mapping?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is mapping to ReactAddonsDOMDependencies UMDShim , the shim file.

For some reason this is how aliasify works. :) I think it is just mapping the original require path to whatever you give it which is then resolved relative to the package I think.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed the shim part, was asking about the RHS :)

I looked at docs though - let's make that {relative: './ReactAddonsDOMDependenciesUMDShim'} and it'll work and be a bit more future proof (tested locally, it works).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah. neat.

},
});

var SIMPLE_TEMPLATE =
grunt.file.read('./grunt/data/header-template-short.txt');

Expand Down Expand Up @@ -87,6 +106,7 @@ var addons = {
debug: false,
standalone: 'React',
packageName: 'React (with addons)',
transforms: [shimDOMModules],
globalTransforms: [envifyDev],
plugins: [collapser],
after: [derequire, simpleBannerify],
Expand All @@ -100,7 +120,72 @@ var addonsMin = {
debug: false,
standalone: 'React',
packageName: 'React (with addons)',
transforms: [envifyProd, uglifyify],
transforms: [shimDOMModules, envifyProd, uglifyify],
globalTransforms: [envifyProd],
plugins: [collapser],
// No need to derequire because the minifier will mangle
// the "require" calls.

after: [minify, bannerify],
};

// The DOM Builds
var dom = {
entries: [
'./build/modules/ReactDOMUMDEntry.js',
],
outfile: './build/react-dom.js',
debug: false,
standalone: 'ReactDOM',
// Apply as global transform so that we also envify fbjs and any other deps
transforms: [shimSharedModules],
globalTransforms: [envifyDev],
plugins: [collapser],
after: [derequire, simpleBannerify],
};

var domMin = {
entries: [
'./build/modules/ReactDOMUMDEntry.js',
],
outfile: './build/react-dom.min.js',
debug: false,
standalone: 'ReactDOM',
// Envify twice. The first ensures that when we uglifyify, we have the right
// conditions to exclude requires. The global transform runs on deps.
transforms: [shimSharedModules, envifyProd, uglifyify],
globalTransforms: [envifyProd],
plugins: [collapser],
// No need to derequire because the minifier will mangle
// the "require" calls.

after: [minify, bannerify],
};

var domServer = {
entries: [
'./build/modules/ReactDOMServerUMDEntry.js',
],
outfile: './build/react-dom-server.js',
debug: false,
standalone: 'ReactDOMServer',
// Apply as global transform so that we also envify fbjs and any other deps
transforms: [shimSharedModules],
globalTransforms: [envifyDev],
plugins: [collapser],
after: [derequire, simpleBannerify],
};

var domServerMin = {
entries: [
'./build/modules/ReactDOMServerUMDEntry.js',
],
outfile: './build/react-dom-server.min.js',
debug: false,
standalone: 'ReactDOMServer',
// Envify twice. The first ensures that when we uglifyify, we have the right
// conditions to exclude requires. The global transform runs on deps.
transforms: [shimSharedModules, envifyProd, uglifyify],
globalTransforms: [envifyProd],
plugins: [collapser],
// No need to derequire because the minifier will mangle
Expand All @@ -114,4 +199,8 @@ module.exports = {
min: min,
addons: addons,
addonsMin: addonsMin,
dom: dom,
domMin: domMin,
domServer: domServer,
domServerMin: domServerMin,
};
30 changes: 0 additions & 30 deletions grunt/tasks/react-dom.js

This file was deleted.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"private": true,
"version": "16.0.0-alpha",
"devDependencies": {
"aliasify": "^2.0.0",
"art": "^0.10.1",
"async": "^1.5.0",
"babel-cli": "^6.6.5",
Expand Down Expand Up @@ -33,6 +34,7 @@
"babel-traverse": "^6.9.0",
"babylon": "6.8.0",
"browserify": "^13.0.0",
"browserify-global-shim": "^1.0.3",
"bundle-collapser": "^1.1.1",
"coffee-script": "^1.8.0",
"core-js": "^2.2.1",
Expand Down
36 changes: 36 additions & 0 deletions src/addons/ReactAddonsDOMDependencies.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* Copyright 2013-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule ReactAddonsDOMDependencies
*/

'use strict';

var ReactDOM = require('ReactDOM');
var ReactInstanceMap = require('ReactInstanceMap');

exports.getReactDOM = function() {
return ReactDOM;
};

exports.getReactInstanceMap = function() {
return ReactInstanceMap;
};

if (__DEV__) {
var ReactPerf = require('ReactPerf');
var ReactTestUtils = require('ReactTestUtils');

exports.getReactPerf = function() {
return ReactPerf;
};

exports.getReactTestUtils = function() {
return ReactTestUtils;
};
}
17 changes: 15 additions & 2 deletions src/addons/ReactWithAddons.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

var LinkedStateMixin = require('LinkedStateMixin');
var React = require('React');
var ReactAddonsDOMDependencies = require('ReactAddonsDOMDependencies');
var ReactComponentWithPureRenderMixin =
require('ReactComponentWithPureRenderMixin');
var ReactCSSTransitionGroup = require('ReactCSSTransitionGroup');
Expand All @@ -34,8 +35,20 @@ React.addons = {
};

if (__DEV__) {
React.addons.Perf = require('ReactPerf');
React.addons.TestUtils = require('ReactTestUtils');
// For the UMD build we get these lazily from the global since they're tied
// to the DOM renderer and it hasn't loaded yet.
Object.defineProperty(React.addons, 'Perf', {
enumerable: true,
get: function() {
return ReactAddonsDOMDependencies.getReactPerf();
},
});
Object.defineProperty(React.addons, 'TestUtils', {
enumerable: true,
get: function() {
return ReactAddonsDOMDependencies.getReactTestUtils();
},
});
}

module.exports = React;
4 changes: 2 additions & 2 deletions src/addons/transitions/ReactCSSTransitionGroupChild.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
'use strict';

var React = require('React');
var ReactDOM = require('ReactDOM');
var ReactAddonsDOMDependencies = require('ReactAddonsDOMDependencies');

var CSSCore = require('CSSCore');
var ReactTransitionEvents = require('ReactTransitionEvents');
Expand Down Expand Up @@ -54,7 +54,7 @@ var ReactCSSTransitionGroupChild = React.createClass({
},

transition: function(animationType, finishCallback, userSpecifiedDelay) {
var node = ReactDOM.findDOMNode(this);
var node = ReactAddonsDOMDependencies.getReactDOM().findDOMNode(this);

if (!node) {
if (finishCallback) {
Expand Down
10 changes: 5 additions & 5 deletions src/addons/transitions/ReactTransitionGroup.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
'use strict';

var React = require('React');
var ReactInstanceMap = require('ReactInstanceMap');
var ReactAddonsDOMDependencies = require('ReactAddonsDOMDependencies');
var ReactTransitionChildMapping = require('ReactTransitionChildMapping');

var emptyFunction = require('emptyFunction');
Expand Down Expand Up @@ -64,7 +64,7 @@ var ReactTransitionGroup = React.createClass({
if (__DEV__) {
nextChildMapping = ReactTransitionChildMapping.getChildMapping(
nextProps.children,
ReactInstanceMap.get(this)._debugID
ReactAddonsDOMDependencies.getReactInstanceMap().get(this)._debugID
);
} else {
nextChildMapping = ReactTransitionChildMapping.getChildMapping(
Expand Down Expand Up @@ -137,7 +137,7 @@ var ReactTransitionGroup = React.createClass({
if (__DEV__) {
currentChildMapping = ReactTransitionChildMapping.getChildMapping(
this.props.children,
ReactInstanceMap.get(this)._debugID
ReactAddonsDOMDependencies.getReactInstanceMap().get(this)._debugID
);
} else {
currentChildMapping = ReactTransitionChildMapping.getChildMapping(
Expand Down Expand Up @@ -177,7 +177,7 @@ var ReactTransitionGroup = React.createClass({
if (__DEV__) {
currentChildMapping = ReactTransitionChildMapping.getChildMapping(
this.props.children,
ReactInstanceMap.get(this)._debugID
ReactAddonsDOMDependencies.getReactInstanceMap().get(this)._debugID
);
} else {
currentChildMapping = ReactTransitionChildMapping.getChildMapping(
Expand Down Expand Up @@ -218,7 +218,7 @@ var ReactTransitionGroup = React.createClass({
if (__DEV__) {
currentChildMapping = ReactTransitionChildMapping.getChildMapping(
this.props.children,
ReactInstanceMap.get(this)._debugID
ReactAddonsDOMDependencies.getReactInstanceMap().get(this)._debugID
);
} else {
currentChildMapping = ReactTransitionChildMapping.getChildMapping(
Expand Down
16 changes: 5 additions & 11 deletions src/renderers/dom/client/ReactMount.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ function mountComponentIntoNode(
) {
var markerName;
if (ReactFeatureFlags.logTopLevelRenders) {
var wrappedElement = wrapperInstance._currentElement.props;
var wrappedElement = wrapperInstance._currentElement.props.child;
var type = wrappedElement.type;
markerName = 'React mount: ' + (
typeof type === 'string' ? type :
Expand Down Expand Up @@ -235,8 +235,7 @@ if (__DEV__) {
TopLevelWrapper.displayName = 'TopLevelWrapper';
}
TopLevelWrapper.prototype.render = function() {
// this.props is actually a ReactElement
return this.props;
return this.props.child;
};

/**
Expand Down Expand Up @@ -421,14 +420,9 @@ var ReactMount = {
'for your app.'
);

var nextWrappedElement = ReactElement(
var nextWrappedElement = ReactElement.createElement(
TopLevelWrapper,
null,
null,
null,
null,
null,
nextElement
{ child: nextElement }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Time to port devtools to new APIs 😈

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we still going to break the devtools with this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't break devtools but it does start showing the top level wrapper.

I switched this to an explicit flag on the wrapper type and updated devtools to support this new flag:

facebook/react-devtools#407

);

var nextContext;
Expand All @@ -443,7 +437,7 @@ var ReactMount = {

if (prevComponent) {
var prevWrappedElement = prevComponent._currentElement;
var prevElement = prevWrappedElement.props;
var prevElement = prevWrappedElement.props.child;
if (shouldUpdateReactComponent(prevElement, nextElement)) {
var publicInst = prevComponent._renderedComponent.getPublicInstance();
var updatedCallback = callback && function() {
Expand Down