Skip to content
This repository has been archived by the owner on May 16, 2022. It is now read-only.

Commit

Permalink
perf(macro): faster Rem value transformation
Browse files Browse the repository at this point in the history
No longer traverse the whole module just to transform Rem values.
  • Loading branch information
z0al committed Nov 26, 2020
1 parent 1f0fed2 commit c9494f3
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 66 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ jobs:
- name: Install dependencies
run: yarn

- name: Build the package
run: yarn build

- name: Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@
"babel-plugin-macros"
],
"scripts": {
"prepare": "bob build",
"build": "rimraf -rf build && bob build",
"lint": "eslint \"**/*.{js,ts,tsx}\"",
"test": "bob build && jest",
"test": "yarn build && jest",
"semantic-release": "semantic-release",
"utils-gen": "ts-node ./scripts/utils-gen.ts",
"bootstrap:example": "yarn --cwd example",
Expand Down Expand Up @@ -69,6 +69,7 @@
"react-native": "^0.63.3",
"react-native-web": "^0.14.8",
"react-test-renderer": "^17.0.1",
"rimraf": "^3.0.2",
"semantic-release": "^17.3.0",
"ts-node": "^9.0.0",
"type-fest": "^0.20.1",
Expand Down
51 changes: 51 additions & 0 deletions src/babel/inject-styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Packages
import * as t from '@babel/types';
import traverse from '@babel/traverse';
import { NodePath } from '@babel/core';

// Ours
import { importStyleSheet, importUtil } from './add-import';

export function injectStyles(
program: NodePath<t.Program>,
stylesVariableId: t.Identifier,
styles: Record<string, Record<string, any>>
) {
// Use StyleSheet.create
// => const styles = StyleSheet.create({...})
const stylesheet = t.variableDeclaration('const', [
t.variableDeclarator(
stylesVariableId,
t.callExpression(
t.memberExpression(
importStyleSheet(program),
t.identifier('create')
),
[t.valueToNode(styles)]
)
),
]);

// Handle Rem values
traverse(stylesheet, {
noScope: true,
StringLiteral: (path) => {
// Replace Rem values with function calls
if (path.node.value.match(/rem/)) {
const remValue = parseFloat(
path.node.value.replace(/rem|\(|\)/g, '')
);

path.replaceWith(
t.callExpression(importUtil(program, 'rem'), [
t.numericLiteral(remValue),
])
);
}
},
});

// Create stylesheet
// => const styles = StyleSheet.create({...})
program.unshiftContainer('body' as any, stylesheet);
}
70 changes: 7 additions & 63 deletions src/macro.ts
Original file line number Diff line number Diff line change
@@ -1,69 +1,14 @@
// Packages
import * as t from '@babel/types';
import traverse from '@babel/traverse';
import { NodePath } from '@babel/core';
import { createMacro, MacroHandler } from 'babel-plugin-macros';

// Ours
import { evalNode } from './babel/eval-node';
import { StyledMacro } from './styling/types';
import { resolveTokens } from './styling/tokens';
import { importUtil } from './babel/add-import';
import { injectStyles } from './babel/inject-styles';
import { DEFAULT_VARIANT } from './styling/utils/defaultVariant';
import { importStyleSheet, importUtil } from './babel/add-import';

const transformRem = (program: NodePath<t.Program>) => {
traverse(program.parent, {
StringLiteral: (path) => {
if (!t.isObjectProperty(path.parent)) {
return;
}

// Transform values only
if (!t.isNodesEquivalent(path.parent.value, path.node)) {
return;
}

const { value } = path.node;

// Replace Rem values with function calls
if (value.match(/rem/)) {
const remValue = parseFloat(value.replace(/rem|\(|\)/g, ''));

// => { style: rem(number) }
path.replaceWith(
t.callExpression(importUtil(program, 'rem'), [
t.numericLiteral(remValue),
])
);
}
},
});
};

const createStyleSheet = (
program: NodePath<t.Program>,
stylesId: t.Identifier,
styles: Record<string, Record<string, any>>
) => {
// Use StyleSheet.create
// => const styles = StyleSheet.create({...})
const stylesheet = t.variableDeclaration('const', [
t.variableDeclarator(
stylesId,
t.callExpression(
t.memberExpression(
importStyleSheet(program),
t.identifier('create')
),
[t.valueToNode(styles)]
)
),
]);

// Create stylesheet
// => const styles = StyleSheet.create({...})
program.unshiftContainer('body' as any, stylesheet);
};

const styledMacro: MacroHandler = ({ references, state }) => {
const program = state.file.path;
Expand All @@ -72,7 +17,9 @@ const styledMacro: MacroHandler = ({ references, state }) => {
const styles: Record<string, Record<string, any>> = {};

// Variable name to be used later with StyleSheet.create
const stylesId = program.scope.generateUidIdentifier('styles');
const stylesVariableId = program.scope.generateUidIdentifier(
'styles'
);

references.default?.forEach((refPath) => {
if (!t.isCallExpression(refPath.parent)) {
Expand Down Expand Up @@ -129,7 +76,7 @@ const styledMacro: MacroHandler = ({ references, state }) => {
// => { style: styles.styleId }
t.objectProperty(
t.identifier('style'),
t.memberExpression(stylesId, styleId)
t.memberExpression(stylesVariableId, styleId)
),
]);
})
Expand Down Expand Up @@ -161,10 +108,7 @@ const styledMacro: MacroHandler = ({ references, state }) => {

// Inject generated styles to the module
if (Object.keys(styles).length > 0) {
createStyleSheet(program, stylesId, styles);

// Convert Rem string literals to function calls
transformRem(program);
injectStyles(program, stylesVariableId, styles);
}
};

Expand Down
2 changes: 1 addition & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -10334,7 +10334,7 @@ rimraf@^2.5.2, rimraf@^2.5.4, rimraf@^2.6.2, rimraf@^2.6.3, rimraf@^2.7.1:
dependencies:
glob "^7.1.3"

rimraf@^3.0.0:
rimraf@^3.0.0, rimraf@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a"
integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==
Expand Down

0 comments on commit c9494f3

Please sign in to comment.