-
Notifications
You must be signed in to change notification settings - Fork 33
Annotate pure calls with babel plugin to slightly improve tree-shakea… #85
Conversation
As long the core package ( I'll try and find some time tonight to take a closer look, but on the surface everything looks fine here. |
well, this can ofc change in the future, so it might be good to leave the plugin just in case |
hmmm, ok. I think I understand a bit better what this plugin doing now. When a variable is assigned from a function call just by importing a file, this tells the tree shaker that is was a pure call and can be removed. Without it, the variable can be shaken away, but the call, and consequently the function itself, are left behind as it may have had a side-effect worth keeping. Am I close?
Changing class SubspaceProvider extends React.PureComponent {
static get propTypes() {
return {
children: PropTypes.element.isRequired,
mapState: PropTypes.oneOfType([PropTypes.func, PropTypes.string]),
namespace: PropTypes.string,
subspaceDecorator: PropTypes.func
}
}
static get contextTypes() {
return {
store: PropTypes.object.isRequired
}
}
static get childContextTypes() {
return {
store: PropTypes.object
}
}
getChildContext() {
const makeSubspaceDecorator = props => props.subspaceDecorator || subspace(props.mapState, props.namespace)
return {
store: makeSubspaceDecorator(this.props)(this.context.store)
}
}
render() {
return Children.only(this.props.children)
}
} outputs var SubspaceProvider = /*#__PURE__*/function (_React$PureComponent) {
inherits(SubspaceProvider, _React$PureComponent);
function SubspaceProvider() {
classCallCheck(this, SubspaceProvider);
return possibleConstructorReturn(this, _React$PureComponent.apply(this, arguments));
}
SubspaceProvider.prototype.getChildContext = function getChildContext() {
var makeSubspaceDecorator = function makeSubspaceDecorator(props) {
return props.subspaceDecorator || subspace(props.mapState, props.namespace);
};
return {
store: makeSubspaceDecorator(this.props)(this.context.store)
};
};
SubspaceProvider.prototype.render = function render() {
return Children.only(this.props.children);
};
createClass(SubspaceProvider, null, [{
key: 'propTypes',
get: function get$$1() {
return {
children: PropTypes.element.isRequired,
mapState: PropTypes.oneOfType([PropTypes.func, PropTypes.string]),
namespace: PropTypes.string,
subspaceDecorator: PropTypes.func
};
}
}, {
key: 'contextTypes',
get: function get$$1() {
return {
store: PropTypes.object.isRequired
};
}
}, {
key: 'childContextTypes',
get: function get$$1() {
return {
store: PropTypes.object
};
}
}]);
return SubspaceProvider;
}(React.PureComponent); which I think means it can be shaken away, but I'm not sure if that's necessarily a recommended (or valid?) way to define a React component?
I like the idea of helping future me (and others) out and leaving it in for all packages, even if they don't get any immediate benefit from it right now. |
You couldn't be closer :)
Neat trick! didn't think of that, although I'm not sure if using getters for those is a good thing.
👍 |
No, me neither. I don't think I'll worry with it. The reality is, whether you use I'm happy with this and will merge it now. Thanks again :) |
…bility
Truth to be told only 2 packages at the moment benefit from it.
redux-subspace-loop
-namespaced
export is created by a call and it might get dropped if the package stays unusedreact-redux-subspace
-SubspaceProvider
gets correctly annotated, but it cannot be removed because it uses static properties, so the output looks like this:Unfortunately such static assignments prevent dead code removal, because algorithm thinks that
SubspaceProvider
is used.There are 2 ways of "fixing" this problem:
this will let the plugin annotate outer IIFE (inner being a transpiled class) which would contain whole class definition and thus making it dead code droppable.
But ofc this is somewhat ugly and also gives rather rly small benefits - in real world scenarios for this library probably even none.