UNPKG

plotly-icons

Version:
155 lines (129 loc) 6.08 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); // the same as before var PREFIX = '__reactstandin__'; var REGENERATE_METHOD = PREFIX + 'regenerateByEval'; var templateOptions = { placeholderPattern: /^([A-Z0-9]+)([A-Z0-9_]+)$/ }; module.exports = function plugin(args) { // This is a Babel plugin, but the user put it in the Webpack config. if (this && this.callback) { throw new Error('React Hot Loader: You are erroneously trying to use a Babel plugin ' + 'as a Webpack loader. We recommend that you use Babel, ' + 'remove "react-hot-loader/babel" from the "loaders" section ' + 'of your Webpack configuration, and instead add ' + '"react-hot-loader/babel" to the "plugins" section of your .babelrc file. ' + 'If you prefer not to use Babel, replace "react-hot-loader/babel" with ' + '"react-hot-loader/webpack" in the "loaders" section of your Webpack configuration. '); } var t = args.types, template = args.template; var buildRegistration = template('reactHotLoader.register(ID, NAME, FILENAME);', templateOptions); var headerTemplate = template('(function () {\n var enterModule = require(\'react-hot-loader\').enterModule;\n enterModule && enterModule(module);\n }())', templateOptions); var evalTemplate = template('this[key]=eval(code);', templateOptions); // We're making the IIFE we insert at the end of the file an unused variable // because it otherwise breaks the output of the babel-node REPL (#359). var buildTagger = template('\n(function () {\n var reactHotLoader = require(\'react-hot-loader\').default;\n var leaveModule = require(\'react-hot-loader\').leaveModule;\n\n if (!reactHotLoader) {\n return;\n }\n\n REGISTRATIONS\n\n leaveModule(module);\n}());\n ', templateOptions); // Gather top-level variables, functions, and classes. // Try our best to avoid variables from require(). // Ideally we only want to find components defined by the user. function shouldRegisterBinding(binding) { var _binding$path = binding.path, type = _binding$path.type, node = _binding$path.node; switch (type) { case 'FunctionDeclaration': case 'ClassDeclaration': case 'VariableDeclaration': return true; case 'VariableDeclarator': { var init = node.init; if (t.isCallExpression(init) && init.callee.name === 'require') { return false; } return true; } default: return false; } } var REGISTRATIONS = Symbol('registrations'); return { visitor: { ExportDefaultDeclaration: function ExportDefaultDeclaration(path, _ref) { var file = _ref.file; // Default exports with names are going // to be in scope anyway so no need to bother. if (path.node.declaration.id) { return; } // Move export default right hand side to a variable // so we can later refer to it and tag it with __source. var id = path.scope.generateUidIdentifier('default'); var expression = t.isExpression(path.node.declaration) ? path.node.declaration : t.toExpression(path.node.declaration); path.insertBefore(t.variableDeclaration('const', [t.variableDeclarator(id, expression)])); path.node.declaration = id; // eslint-disable-line no-param-reassign // It won't appear in scope.bindings // so we'll manually remember it exists. path.parent[REGISTRATIONS].push(buildRegistration({ ID: id, NAME: t.stringLiteral('default'), FILENAME: t.stringLiteral(file.opts.filename) })); }, Program: { enter: function enter(_ref2, _ref3) { var node = _ref2.node, scope = _ref2.scope; var file = _ref3.file; node[REGISTRATIONS] = []; // eslint-disable-line no-param-reassign // Everything in the top level scope, when reasonable, // is going to get tagged with __source. /* eslint-disable guard-for-in,no-restricted-syntax */ for (var id in scope.bindings) { var binding = scope.bindings[id]; if (shouldRegisterBinding(binding)) { node[REGISTRATIONS].push(buildRegistration({ ID: binding.identifier, NAME: t.stringLiteral(id), FILENAME: t.stringLiteral(file.opts.filename) })); } } /* eslint-enable */ }, exit: function exit(_ref4) { var node = _ref4.node; var registrations = node[REGISTRATIONS]; node[REGISTRATIONS] = null; // eslint-disable-line no-param-reassign // inject the code only if applicable if (registrations && registrations.length) { node.body.unshift(headerTemplate()); // Inject the generated tagging code at the very end // so that it is as minimally intrusive as possible. node.body.push(t.emptyStatement()); node.body.push(buildTagger({ REGISTRATIONS: registrations })); node.body.push(t.emptyStatement()); } } }, Class: function Class(classPath) { var classBody = classPath.get('body'); var hasRegenerateMethod = false; var hasMethods = false; classBody.get('body').forEach(function (path) { var node = path.node; // don't apply transform to static class properties if (node.static) { return; } if (node.key.name !== REGENERATE_METHOD) { hasMethods = true; } else { hasRegenerateMethod = true; } }); if (hasMethods && !hasRegenerateMethod) { var regenerateMethod = t.classMethod('method', t.identifier(REGENERATE_METHOD), [t.identifier('key'), t.identifier('code')], t.blockStatement([evalTemplate()])); classBody.pushContainer('body', regenerateMethod); } } } }; };