Skip to content

Commit

Permalink
feat(react-property): rewrite build svg script
Browse files Browse the repository at this point in the history
No longer generate the following from svg build script:

- attributes.json
- attribute-to-property.json
- boolean-properties.json
- overloaded-boolean-properties.json

The reason is these files have redundant attribute names,
which makes the final bundle size larger than expected.

Also, the svg attribute names are lowercased instead of
camelcased.

Now the following file is generated:

- properties.json

It's similar to `react-dom/lib/SVGDOMPropertyConfig.js`
except redundant attribute to property name mappings
are deleted.

Also, update svg index module to include the injection
properties.
  • Loading branch information
remarkablemark committed Jul 8, 2019
1 parent 8559c38 commit eb7a59b
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 46 deletions.
67 changes: 29 additions & 38 deletions packages/react-property/scripts/build-svg.js
Expand Up @@ -5,17 +5,7 @@ const SVGDOMPropertyConfig = require('react-dom/lib/SVGDOMPropertyConfig');
const { LIB_DIR, SVG_DIR } = require('./constants');

/**
* Creates the DOM property map via injection.
*
* @see https://github.com/facebook/react/blob/15-stable/src/renderers/dom/shared/DOMProperty.js#L57
*/
DOMProperty.injection.injectDOMPropertyConfig(SVGDOMPropertyConfig);

// `autofocus` is removed since it's not an applicable attribute for SVG elements
delete DOMProperty.getPossibleStandardName.autofocus;

/**
* Create output directories (if it does not exist).
* Create output directories (if it doesn't exist).
*/
try {
fs.mkdirSync(LIB_DIR);
Expand All @@ -30,37 +20,38 @@ try {
}

/**
* SVG DOM property config.
* Contains a mapping of React props to HTML attributes.
*
* Contains a mapping of SVG attributes to React props.
* @see https://github.com/facebook/react/blob/15-stable/src/renderers/dom/shared/SVGDOMPropertyConfig.js
*
* @type {Object}
*/
const attributeToProperty = {};

/**
* List of SVG DOM attributes.
*
* @type {Array}
*/
const attributes = [];

Object.keys(DOMProperty.getPossibleStandardName).forEach(attributeName => {
const propertyName = DOMProperty.getPossibleStandardName[attributeName];

if (attributeName !== propertyName) {
attributeToProperty[attributeName] = propertyName;
}

attributes.push(attributeName);
});

fs.writeFileSync(
path.resolve(SVG_DIR, 'attributes.json'),
JSON.stringify(attributes)
);
const properties = {
injection: DOMProperty.injection,

/**
* To avoid duplication, some attributes are omitted as they exist on the HTML config.
*
* @see https://github.com/facebook/react/blob/15-stable/src/renderers/dom/shared/SVGDOMPropertyConfig.js#L17-L33
*/
Properties: SVGDOMPropertyConfig.Properties,

/**
* Remove property when key and value are the same.
*/
DOMAttributeNames: Object.keys(SVGDOMPropertyConfig.DOMAttributeNames).reduce(
(accumulator, key) => {
const value = SVGDOMPropertyConfig.DOMAttributeNames[key];
if (key !== value) {
accumulator[key] = value;
}
return accumulator;
},
{}
)
};

fs.writeFileSync(
path.resolve(SVG_DIR, 'attribute-to-property.json'),
JSON.stringify(attributeToProperty)
path.resolve(SVG_DIR, 'properties.json'),
JSON.stringify(properties)
);
53 changes: 45 additions & 8 deletions packages/react-property/src/svg/index.js
@@ -1,14 +1,51 @@
var attributeToProperty = require('../../lib/svg/attribute-to-property');
var attributes = require('../../lib/svg/attributes');
var properties = require('./properties');

var attributeMap = {};
var injection = properties.injection;
var MUST_USE_PROPERTY = injection.MUST_USE_PROPERTY;
var HAS_BOOLEAN_VALUE = injection.HAS_BOOLEAN_VALUE;
var HAS_NUMERIC_VALUE = injection.HAS_NUMERIC_VALUE;
var HAS_POSITIVE_NUMERIC_VALUE = injection.HAS_POSITIVE_NUMERIC_VALUE;
var HAS_OVERLOADED_BOOLEAN_VALUE = injection.HAS_OVERLOADED_BOOLEAN_VALUE;
var Properties = properties.Properties;
var DOMAttributeNames = properties.DOMAttributeNames;

/**
* @see https://github.com/facebook/react/blob/15-stable/src/renderers/dom/shared/DOMProperty.js#L14-L16
*
* @param {Number} value
* @param {Number} bitmask
* @return {Boolean}
*/
function checkMask(value, bitmask) {
return (value & bitmask) === bitmask;
}

/**
* Config map.
*
* @type {Object}
*/
var config = {};
var attributeName;
var propertyName;
var propConfig;

for (propertyName in Properties) {
attributeName = DOMAttributeNames[propertyName] || propertyName;
propConfig = Properties[propertyName];

for (var i = 0, len = attributes.length; i < len; i++) {
attributeName = attributes[i];
propertyName = attributeToProperty[attributeName] || attributeName;
attributeMap[attributeName] = { propertyName: propertyName };
config[attributeName] = {
attributeName: attributeName,
propertyName: propertyName,
mustUseProperty: checkMask(propConfig, MUST_USE_PROPERTY),
hasBooleanValue: checkMask(propConfig, HAS_BOOLEAN_VALUE),
hasNumericValue: checkMask(propConfig, HAS_NUMERIC_VALUE),
hasPositiveNumericValue: checkMask(propConfig, HAS_POSITIVE_NUMERIC_VALUE),
hasOverloadedBooleanValue: checkMask(
propConfig,
HAS_OVERLOADED_BOOLEAN_VALUE
)
};
}

module.exports = attributeMap;
module.exports = config;

0 comments on commit eb7a59b

Please sign in to comment.