Patternfly-react: react-tokens build optimizations

Created on 3 Feb 2020  路  6Comments  路  Source: patternfly/patternfly-react

cc @evwilkin @redallen @karelhala

React tokens are currently built into a single file. This causes issues in non-esm environments. Since there were great optimizations for pf4 components packages, which greatly improved bundle sizes of consumer apps (so far it was around 50% - 80%, depends on use-case), I think we can do the same with tokens

Here is an example of how this can affect the build of app using pf4:
Screenshot from 2020-02-03 15-00-43

This is one of the cloud services app. As you can see, react-tokens has almost the same parsed size as react-core.

basically the solution to this would be the same as with the rest of pf4 packages. Build each token into one file (while keeping the index with all tokens), and use absolute import path on pf4 react packages.

The code change would be rather simple. Here are some examples.

Here is something that can be added to the template files

diff --git a/packages/patternfly-4/react-tokens/src/templates/cjs.js b/packages/patternfly-4/react-tokens/src/templates/cjs.js
index 9cc1b1313..683e4f2ff 100644
--- a/packages/patternfly-4/react-tokens/src/templates/cjs.js
+++ b/packages/patternfly-4/react-tokens/src/templates/cjs.js
@@ -3,5 +3,7 @@ const { join } = require('path');
 module.exports = {
   getOutputPath: ({ outDir }) => join(outDir, 'js/index.js'),
   getContent: ({ tokens }) =>
-    Object.keys(tokens).reduce((acc, key) => `${acc}module.exports.${key} = ${JSON.stringify(tokens[key])}\n`, '')
+    Object.keys(tokens).reduce((acc, key) => `${acc}module.exports.${key} = ${JSON.stringify(tokens[key])}\n`, ''),
+  getSingleOutputPath: ({ outDir, tokenName }) => join(outDir, `js/${tokenName}.js`),
+  getSingleContent: ({ tokenValue }) => `module.exports = ${JSON.stringify(tokenValue)}\n`
 };

And in the generating function:

diff --git a/packages/patternfly-4/react-tokens/src/generateTokens.js b/packages/patternfly-4/react-tokens/src/generateTokens.js
index 83d4d3942..1177e8118 100644
--- a/packages/patternfly-4/react-tokens/src/generateTokens.js
+++ b/packages/patternfly-4/react-tokens/src/generateTokens.js
@@ -51,4 +51,7 @@ cssFiles.forEach(filePath => {
 readdirSync(templateDir).forEach(templateFile => {
   const template = require(join(templateDir, templateFile));
   outputFileSync(template.getOutputPath({ outDir }), template.getContent({ tokens }));
+  Object.entries(tokens).forEach(([tokenName, tokenValue]) => {
+    outputFileSync(template.getSingleOutputPath({ outDir, tokenName }), template.getSingleContent({ tokenName, tokenValue }));
+  })
 });

Could you consider something along these lines? Thanks.

bug infrastructure

All 6 comments

Yes, we can create multiple files instead of a singular index.js and we can also rewrite our React imports to use the CJS version like we did with react-icons.

I will start working on it then.

After the changes in linked PR, the tokens basically disappeared from the build. There are chunk sizes from the same app as shown in the description, with the tokens changes:

Screenshot from 2020-02-04 10-34-12

Looking good @Hyperkid123 ! I'll review it sometime today.

Nice job @Hyperkid123 great changes. We should also update the react-tokens readme so that it uses the full import path

3647 is merged, closing.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

SpyTec picture SpyTec  路  3Comments

andrewballantyne picture andrewballantyne  路  4Comments

crackcomm picture crackcomm  路  4Comments

mohd-akram picture mohd-akram  路  3Comments

karelhala picture karelhala  路  5Comments