UNPKG

@meteorjs/reify

Version:

Enable ECMAScript 2015 modules in Node today. No caveats. Full stop.

117 lines (99 loc) 3.29 kB
"use strict"; const assert = require("assert"); let namespace; let ibsPropertyName = "isBlockScoped"; let types; let cache; function tryScopedLibDirect() { namespace = require("@babel/types/lib/validators/isBlockScoped"); // If the above import succeeded, then we should replace the .default // property of the isBlockScoped module, instead of .isBlockScoped. ibsPropertyName = "default"; types = types || require("@babel/types"); cache = cache || require("@babel/traverse").default.cache; } function tryScoped() { namespace = require("@babel/types"); types = types || require("@babel/types"); cache = cache || require("@babel/traverse").default.cache; } function tryScopedLib() { namespace = require("@babel/types/lib/validators"); types = types || require("@babel/types"); cache = cache || require("@babel/traverse").default.cache; } function tryUnscoped() { namespace = require("babel-types/lib/validators"); types = types || require("babel-types"); cache = cache || require("babel-traverse").default.cache; } [tryScopedLibDirect, tryScoped, tryScopedLib, tryUnscoped ].some(function (fn) { try { fn(); } catch (e) { return false; } const wrapped = namespace[ibsPropertyName]; assert.strictEqual(typeof wrapped, "function") // Allow types.isBlockScoped to return true for import-related nodes. const wrapper = namespace[ibsPropertyName] = function (node) { return node && types.isImportDeclaration(node) || wrapped.apply(this, arguments); }; // The wrapping can fail if namespace[ibsPropertyName] is a non-writable // property (such as a getter function). if (namespace[ibsPropertyName] !== wrapper) { throw new Error( "Unable to patch @babel/types isBlockScoped function" ); } return true; }); module.exports = function (context) { const compiler = require("../lib/compiler.js"); const transformOptions = { parse: require("../lib/parsers/babel.js").parse }; let madeChanges = false; function transform(node) { const result = compiler.transform(node, transformOptions); if (! result.identical) { madeChanges = true; // If the Reify compiler made any changes, invalidate all existing // Scope objects, so that any variable binding changes made by // compiler.transform will be reflected accurately. cache.clearScope(); } return result; } return { visitor: { Program: { enter(path) { const code = path.hub.file.code; if (typeof code === "string") { transformOptions.moduleAlias = compiler.makeUniqueId("module", code); } transformOptions.finalCompilationPass = false; transformOptions.forceWrapForTopLevelAwait = false Object.assign(transformOptions, this.opts); let visitor = transform(path.node).visitor; transformOptions.forceWrapForTopLevelAwait = visitor.wrapForTopLevelAwait; transformOptions.forceHasTopLevelAwait = visitor.hasTopLevelAwait }, exit(path) { transformOptions.finalCompilationPass = true; const ast = transform(path.node).ast; assert.strictEqual(ast.type, "Program"); } } } }; };