UNPKG

babel-plugin-func-wrap

Version:

Wrap the whole script in a function — export as CommonJS, ES Modules, IIFE, or a global variable

97 lines (84 loc) 4.1 kB
import template from '@babel/template'; const templateCjsDefault = `module.exports = function (%%args%%) { %%body%% }`; const templateCjsNamed = `exports.%%name%% = function (%%args%%) { %%body%% }`; const templateEsmDefault = `export default function (%%args%%) { %%body%% }`; const templateEsmNamed = `export function %%name%% (%%args%%) { %%body%% }`; const templateGlobalDefault = `%%body%%`; const templateGlobalNamed = `%%name%% = function (%%args%%) { %%body%% }`; const templateIifeDefault = `(function (%%args%%) { %%body%% })(%%args%%)`; const templateIifeNamed = `%%name%% = function (%%args%%) { %%body%% }(%%args%%)`; function babelPluginTransformGlobals(api, opts) { const { types: t } = api; const run = []; // options const args = [].concat(opts.args || []).map(arg => t.identifier(arg)); const name = 'name' in opts ? String(opts.name) : 'default'; const format = ['cjs', 'esm', 'iife', 'global'].find(format => format === opts.format); const buildTemplate = template(name === 'default' ? format === 'cjs' ? templateCjsDefault : format === 'iife' ? templateIifeDefault : format === 'global' ? templateGlobalDefault : templateEsmDefault : format === 'cjs' ? templateCjsNamed : format === 'iife' ? templateIifeNamed : format === 'global' ? templateGlobalNamed : templateEsmNamed); if (name === 'default' && format === 'global') { throw Error('The "global" option requires a "name"'); } return { name: 'func-wrap', visitor: { ExportDefaultDeclaration(path) { if (!run.includes(this)) { const replacableExport = t.isClassDeclaration(path.node.declaration) || t.isFunctionDeclaration(path.node.declaration); // transform `export default class {} /* more */` // into `class _default {}; /* more */ return _default`, or // transform `export default class Cl {} /* more */` // into `class Cl {}; /* more */ return Cl`, or // transform `export default function () {} /* more */` // into `function _default () {}; /* more */ return _default`, or // transform `export default function fn () {} /* more */` // into `function fn () {}; /* more */ return fn` if (replacableExport) { let name = path.node.declaration.id && path.node.declaration.id.name; // transform `function () {}` into `function _default () {}`, or // transform `class {}` into `class _default {}` if (!name) { path.node.declaration.id = path.scope.generateUidIdentifier('default'); name = path.node.declaration.id.name; } if (name) { path.replaceWith(path.node.declaration); path.parentPath.pushContainer('body', t.returnStatement(t.identifier(name))); } } else if (path.node.declaration) { // transform `export default {} /* more */` // into `class _default {}; /* more */ return _default` const identifier = path.scope.generateUidIdentifier('default'); const { name } = identifier; const variableDeclaration = t.variableDeclaration('const', [t.variableDeclarator(identifier, path.node.declaration)]); const returnStatement = t.returnStatement(t.identifier(name)); path.replaceWith(variableDeclaration); path.parentPath.pushContainer('body', returnStatement); } } }, Program: { exit(path) { if (!run.includes(this)) { run.push(this); const { body } = path.node; const templateOptions = name === 'default' ? { body, args } : { name, body, args }; const ast = buildTemplate(templateOptions); // wrap the whole script in a function path.replaceWith(t.program([ast])); } } } } }; } export default babelPluginTransformGlobals; //# sourceMappingURL=index.mjs.map