Closed zaygraveyard closed 4 years ago
I found a different simpler way to do more or less the same thing.
It only handles imports from htm/react
and htm/preact
async function getHtmPlugin() {
const htm = (await import('babel-plugin-htm')).default;
return function({types: t}, options = {}) {
const pragmaString = options.pragma || 'h';
const pragmaRoot = pragmaString.split('.')[0];
const htmlName = options.tag || 'html';
const preactHSpecifier = t.importSpecifier(
t.identifier(pragmaRoot),
t.identifier('h')
);
return {
name: 'htm-importer',
inherits: htm,
visitor: {
ImportDeclaration(path) {
const {node} = path;
if (node.source.value === 'htm/preact') {
const pragmaImported = node.specifiers.some(
(specifier) =>
specifier.imported.name === 'h' &&
specifier.local.name === pragmaRoot
);
if (pragmaImported) {
node.specifiers = node.specifiers.filter(
(specifier) =>
!(
specifier.imported.name === 'html' &&
specifier.local.name === htmlName
)
);
} else {
node.specifiers = node.specifiers.map(function(specifier) {
if (
specifier.imported.name === 'html' &&
specifier.local.name === htmlName
) {
return preactHSpecifier;
}
return specifier;
});
}
if (node.specifiers.length === 0) {
path.remove();
} else if (
node.specifiers.length === 1 &&
node.specifiers[0].imported.name === 'h'
) {
path.get('source').replaceWith(t.stringLiteral('preact'));
}
} else if (node.source.value === 'htm/react') {
const htmlImported = node.specifiers.some(
(specifier) =>
specifier.imported.name === 'html' &&
specifier.local.name === htmlName
);
if (htmlImported) {
node.specifiers = node.specifiers.filter(
(specifier) =>
!(
specifier.imported.name === 'html' &&
specifier.local.name === htmlName
)
);
path.insertBefore(
t.importDeclaration(
[t.importDefaultSpecifier(t.identifier(pragmaRoot))],
t.stringLiteral('react')
)
);
if (node.specifiers.length === 0) {
path.remove();
}
}
}
},
},
};
};
}
@zaygraveyard this is awesome! I would love to have the functionality supported natively in babel-plugin-htm
if we can!
I think the configuration for this could even be the same as the similar feature in babel-plugin-jsx-to-htm
:
https://github.com/developit/htm/tree/master/packages/babel-plugin-transform-jsx-to-htm#auto-importing-the-tag
@developit thank you! :smile:
I was actually highly inspired by the "Auto-importing the tag" feature when creating the first version
I'll submit a PR integrating the first version into babel-plugin-htm
@developit quick question Do I remove the import of the tag? Or leave it and let the tree-shaker take care of it?
NB: The version above removes the import but doesn't look for the declaration of the tag in the case of const html = htm.bind(h)
PR #131
Closed by #131
First off, thanks for this truly awesome library.
When transpiling my code with the
babel-plugin-htm
plugin, I noticed that the pragma is not imported (in my case I'm usinghtm/preact
and needh
to be imported frompreact
)So I created a wrapper for this plugin that does just that, it works for me but I know it's very rough around the edges.
And thought why not share it with the community, it might be included in upstream