Skip to content

Instantly share code, notes, and snippets.

@hasparus
Last active January 17, 2020 12:20
Show Gist options
  • Save hasparus/7ee6259477e0cb7b4e00397b16281ad7 to your computer and use it in GitHub Desktop.
Save hasparus/7ee6259477e0cb7b4e00397b16281ad7 to your computer and use it in GitHub Desktop.
vanity babel macro for concise React.lazy components
const UserProfile = React.lazy(() => import("./scenes/UserProfile").then(module => ({
default: module.UserProfile
})));
{
"v": 2,
"parserID": "babylon7",
"toolID": "babel-plugin-macros",
"settings": {
"babylon7": null
},
"versions": {
"babylon7": "7.7.2",
"babel-plugin-macros": "2.6.1"
}
}
import lazy from 'lazy.macro'
const UserProfile = lazy('./scenes/UserProfile');
const { createMacro } = require('babel-plugin-macros');
const last = xs => xs[xs.length - 1];
module.exports = createMacro(({ references, state, babel }) => {
/** @type { typeof references.default } */
const refs = references.lazy || references.default || references;
const t = babel.types;
refs.forEach(referencePath => {
if (!referencePath.parentPath.isCallExpression()) {
throw new Error("must be call expression");
}
const [firstArgumentPath] = referencePath.parentPath.get("arguments");
if (!firstArgumentPath.isStringLiteral()) {
throw new Error("first argument must must be string");
}
const stringValue = firstArgumentPath.node.value;
const componentName = last(stringValue.split("/"));
const callExpr = t.callExpression(
t.memberExpression(t.identifier("React"), t.identifier("lazy")),
[
t.arrowFunctionExpression(
[],
t.callExpression(
t.memberExpression(
t.callExpression(t.import(), [t.stringLiteral(stringValue)]),
t.identifier("then")
),
[
t.arrowFunctionExpression(
[t.identifier("module")],
t.objectExpression([
t.objectProperty(
t.identifier("default"),
t.memberExpression(
t.identifier("module"),
t.identifier(componentName)
)
)
])
)
]
)
)
]
);
firstArgumentPath.parentPath.replaceWith(callExpr);
});
});
@hasparus
Copy link
Author

hasparus commented Jan 16, 2020

@velein This is possible, but I'm not sure if @0ctothorp wouldn't murder us for pushing this.

You can play around with it in AST Explorer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment