1import { transformSync as transform } from '@babel/core';
2import { createFilter } from '@rollup/pluginutils';
3
4import transformTemplateLiterals from '@babel/plugin-transform-template-literals';
5import eliminateClosures from 'babel-plugin-closure-elimination';
6
7const simplifyJSTags = ({ types: t }) => ({
8 visitor: {
9 TaggedTemplateExpression(path) {
10 if (path.node.tag.name !== 'js') return;
11
12 const expressions = path.node.quasi.expressions;
13
14 const quasis = path.node.quasi.quasis.map((x) =>
15 x.value.cooked
16 .replace(/\s*[=(){},;:!]\s*/g, (x) => x.trim())
17 .replace(/\s+/g, ' ')
18 .replace(/^\s+$/g, '')
19 );
20
21 const concat = expressions.reduceRight(
22 (prev, node, i) =>
23 t.binaryExpression(
24 '+',
25 t.stringLiteral(quasis[i]),
26 t.binaryExpression('+', node, prev)
27 ),
28 t.stringLiteral(quasis[quasis.length - 1])
29 );
30
31 path.replaceWith(concat);
32 },
33 },
34});
35
36function simplifyJSTagsPlugin(opts = {}) {
37 const filter = createFilter(opts.include, opts.exclude, {
38 resolve: false,
39 });
40
41 return {
42 name: 'cleanup',
43
44 renderChunk(code, chunk) {
45 if (!filter(chunk.fileName)) {
46 return null;
47 }
48
49 return transform(code, {
50 plugins: [
51 simplifyJSTags,
52 [transformTemplateLiterals, { loose: true }],
53 eliminateClosures,
54 ],
55 babelrc: false,
56 });
57 },
58 };
59}
60
61export default simplifyJSTagsPlugin;