Skip to content

Commit b238a8c

Browse files
ammmzembrowne
andauthored
fix: fix so that we dont blow up when encountering an "export default… (#4)
* fix: fix so that we dont blow up when encountering an "export default class ..." also adds tests to cover various scenarios * fix: have wrapped classes actually return the class * fix: wrap in standard function instead of arrow function for better compatibility ideally we would be able to have it go through preset-env to get it to transform the arrow functions if necessary, but we dont appear to get that for free the way we are doing this. perhaps it can be investigated in the future * updated readme, added changelog, and prepared for publishing Co-authored-by: Matt Browne <mbrowne@artnet.com>
1 parent 417e5be commit b238a8c

File tree

24 files changed

+3450
-49
lines changed

24 files changed

+3450
-49
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,5 @@ node_modules
22
*.log
33
lib
44
.DS_Store
5+
.idea
6+
*.tgz

CHANGELOG.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
6+
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
7+
8+
## 0.2.0
9+
10+
### Fixed
11+
12+
Fix bug when encountering `export default` with class components
13+
14+
### Added
15+
16+
Test suite
17+
18+
## 0.1.0
19+
20+
Initial version

README.md

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,37 @@
11
# babel-plugin-pure-static-props
22

3-
## DEPRECATED
3+
Fixes an issue with tree shaking that can occur when using static properties on React components using styled-components.
44

5-
This plugin is deprecated in favor of https://github.com/styled-components/babel-plugin-styled-components/pull/248.
6-
It's possible that something other than styled-components might cause a similar issue, in which case this plugin might still be useful, but I won't be maintaining it. (Also, my implementation for babel-plugin-styled-components is a bit more efficient than what I did here.)
5+
This plugin replaces static property assignments on React components (e.g. `MyComponent.defaultProps = {...}`) with `Object.assign()` statements annotated with `/*#__PURE__*/` comments so that tree-shaking will work correctly.
76

8-
---
7+
## Install
98

10-
Fixes an issue with tree shaking that can occur when using static properties on React components using styled-components.
9+
```bash
10+
npm i -D babel-plugin-pure-static-props
11+
```
1112

12-
This plugin replaces static property assignments on React components (e.g. `MyComponent.defaultProps = {...}`) with `Object.assign()` statements annotated with `/*#__PURE__*/` comments so that tree-shaking will work correctly.
13+
Or:
14+
15+
```bash
16+
yarn add -D babel-plugin-pure-static-props
17+
```
18+
19+
Then add the plugin to your Babel config as explained in the [Babel documentation](https://babeljs.io/docs/en/options#plugin-and-preset-options).
20+
21+
Example `babel.config.js`:
22+
23+
```js
24+
module.exports = {
25+
presets: ['@babel/preset-env'],
26+
plugins: [
27+
'@babel/plugin-proposal-class-properties',
28+
'babel-plugin-pure-static-props',
29+
],
30+
}
31+
```
32+
33+
## Note on styled components
34+
35+
The tree-shaking issue with static properties on React components also affects [styled components](https://styled-components.com/). This plugin only addresses tree-shaking for regular React components; it will not work on components created using the `styled` helper.
36+
37+
A fix for styled components is in this PR: https://github.com/styled-components/babel-plugin-styled-components/pull/248.

package.json

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "babel-plugin-pure-static-props",
3-
"version": "0.1.0",
3+
"version": "0.2.0",
44
"description": "Fixes issue with tree shaking that can occur when using static properties on React components using styled-components",
55
"main": "lib/index.js",
66
"files": [
@@ -9,33 +9,42 @@
99
"repository": "https://github.com/mbrowne/babel-plugin-pure-static-props",
1010
"author": "Matt Browne",
1111
"license": "ISC",
12-
"devDependencies": {
13-
"@babel/cli": "^7.5.5",
14-
"@babel/core": "^7.5.5",
15-
"@babel/plugin-proposal-class-properties": "^7.5.5",
16-
"@babel/preset-env": "^7.5.5",
17-
"prettier": "^1.18.2",
18-
"rimraf": "^3.0.0"
19-
},
20-
"dependencies": {
21-
"@babel/helper-annotate-as-pure": "^7.0.0",
22-
"babel-plugin-syntax-jsx": "^6.18.0"
23-
},
2412
"scripts": {
2513
"clean": "rimraf lib",
2614
"style": "prettier --write src/**/*.js",
2715
"build": "babel src -d lib",
2816
"watch": "yarn build -w",
17+
"prepublishOnly": "npm-run-all test build",
2918
"test": "jest",
3019
"test:watch": "yarn test -- --watch",
3120
"prepublish": "yarn clean && yarn build"
3221
},
22+
"dependencies": {
23+
"@babel/helper-annotate-as-pure": "^7.0.0",
24+
"@babel/plugin-syntax-jsx": "^7.12.13"
25+
},
26+
"devDependencies": {
27+
"@babel/cli": "^7.5.5",
28+
"@babel/core": "^7.5.5",
29+
"@babel/plugin-proposal-class-properties": "^7.5.5",
30+
"@babel/preset-env": "^7.5.5",
31+
"babel-plugin-tester": "^10.0.0",
32+
"jest": "^26.6.3",
33+
"npm-run-all": "^4.1.5",
34+
"prettier": "^1.18.2",
35+
"rimraf": "^3.0.0"
36+
},
3337
"keywords": [
3438
"react",
3539
"styled-components",
3640
"tree shaking",
3741
"code splitting",
3842
"static properties",
3943
"babel-plugin"
40-
]
44+
],
45+
"jest": {
46+
"watchPathIgnorePatterns": [
47+
"__fixtures__\\/[^/]+\\/(output|error)\\.js"
48+
]
49+
}
4150
}

src/index.js

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import template from '@babel/template'
2-
import syntax from 'babel-plugin-syntax-jsx'
2+
import syntax from '@babel/plugin-syntax-jsx'
33
import annotateAsPure from '@babel/helper-annotate-as-pure'
44
import isStatelessComponent from './isStatelessComponent'
55
import isReactClass from './isReactClass'
66

7-
const buildIife = template('(() => {\nBODY;\n})();')
7+
const buildIife = template('(function() {\nBODY;\n})();')
88

99
export default function({ types: t }) {
1010
// map of React function components to their static properties
@@ -24,7 +24,8 @@ export default function({ types: t }) {
2424
path.get('superClass'),
2525
path.scope,
2626
{}
27-
)
27+
) &&
28+
path.parentPath.type !== 'BlockStatement'
2829
) {
2930
const hasStaticProperties = path
3031
.get('body.body')
@@ -36,19 +37,37 @@ export default function({ types: t }) {
3637
if (hasStaticProperties) {
3738
const componentNameIdentifier =
3839
path.node.id
39-
path.node.type = 'ClassExpression'
4040
const iife = buildIife({
41-
BODY: path.node,
41+
BODY: [
42+
path.node,
43+
t.ReturnStatement(path.node.id),
44+
],
4245
})
4346
annotateAsPure(iife.expression)
44-
path.replaceWith(
45-
t.VariableDeclaration('const', [
46-
t.VariableDeclarator(
47-
componentNameIdentifier,
48-
iife.expression
49-
),
50-
])
51-
)
47+
const declarators = [
48+
t.VariableDeclarator(
49+
componentNameIdentifier,
50+
iife.expression
51+
),
52+
]
53+
if (
54+
path.parentPath.isExportDefaultDeclaration()
55+
) {
56+
path.parentPath.insertBefore(
57+
t.VariableDeclaration(
58+
'const',
59+
declarators
60+
)
61+
)
62+
path.replaceWith(path.node.id)
63+
} else {
64+
path.replaceWith(
65+
t.VariableDeclaration(
66+
'const',
67+
declarators
68+
)
69+
)
70+
}
5271
}
5372
}
5473
},
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"plugins": [
3+
"@babel/plugin-proposal-class-properties",
4+
[
5+
"../../../src"
6+
]
7+
]
8+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import React from 'react'
2+
3+
export class MyComponent extends React.Component {
4+
render() {
5+
return <div>My Component</div>
6+
}
7+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import React from 'react'
2+
export class MyComponent extends React.Component {
3+
render() {
4+
return <div>My Component</div>
5+
}
6+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import React from 'react'
2+
3+
export function FunctionComponent() {
4+
return <div>My Component</div>
5+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import React from 'react'
2+
export function FunctionComponent() {
3+
return <div>My Component</div>
4+
}

0 commit comments

Comments
 (0)