Skip to content

Instantly share code, notes, and snippets.

@pavanpodila
Created October 7, 2019 04:31
Show Gist options
  • Save pavanpodila/130de241c503136458da1bf70bf15010 to your computer and use it in GitHub Desktop.
Save pavanpodila/130de241c503136458da1bf70bf15010 to your computer and use it in GitHub Desktop.
A webpack-loader that reads Component metadata and generates a *.component.json file
const parser = require('@babel/parser');
const traverse = require('@babel/traverse').default;
const generator = require('@babel/generator').default;
module.exports = function(source) {
// Parse to get the AST
const ast = parser.parse(source, {
sourceType: 'module',
plugins: [
'jsx',
[
'decorators',
{
decoratorsBeforeExport: false,
},
],
],
});
// The current context is the loader and contains methods to emitError, emitFile etc.
const loader = this;
// Visit the AST, specifically the ClassDeclaration, which has the decorator
traverse(ast, {
ClassDeclaration: ({ node }) => {
const name = node.id.name;
const result = getMetadata(node.decorators || []);
if (!result) return;
const { decorator, args } = result;
// Strip out the decorator from the AST
node.decorators = node.decorators.filter(x => x !== decorator);
if (node.decorators.length === 0) {
delete node.decorators;
}
const options = {
name,
...args,
env: {
context: loader.context,
},
};
// Validate that the options are correctly specified, such the name, description, thumbnail.
// Also checks that the thumbnail file actually exists
if (!validateOptions(options, name, loader)) return;
loader.emitFile(
`${options.name}.component.json`,
JSON.stringify(options, null, 4),
);
},
});
const { code } = generator(ast);
return code;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment