From 1e0b6494857c536ddba8428da680b63d193224ca Mon Sep 17 00:00:00 2001 From: Logan Smyth Date: Tue, 14 Aug 2018 16:11:19 -0700 Subject: [PATCH] Allow transform-runtime to insert runtime references with absolute paths. (#8435) --- .../src/index.js | 16 +++-- .../package.json | 4 +- .../src/index.js | 58 ++++++++++++++++--- .../absoluteRuntime/relative/input.js | 1 + .../absoluteRuntime/relative/options.json | 6 ++ .../absoluteRuntime/relative/output.js | 7 +++ .../fixtures/absoluteRuntime/true/input.js | 1 + .../absoluteRuntime/true/options.json | 6 ++ .../fixtures/absoluteRuntime/true/output.js | 7 +++ 9 files changed, 91 insertions(+), 15 deletions(-) create mode 100644 packages/babel-plugin-transform-runtime/test/fixtures/absoluteRuntime/relative/input.js create mode 100644 packages/babel-plugin-transform-runtime/test/fixtures/absoluteRuntime/relative/options.json create mode 100644 packages/babel-plugin-transform-runtime/test/fixtures/absoluteRuntime/relative/output.js create mode 100644 packages/babel-plugin-transform-runtime/test/fixtures/absoluteRuntime/true/input.js create mode 100644 packages/babel-plugin-transform-runtime/test/fixtures/absoluteRuntime/true/options.json create mode 100644 packages/babel-plugin-transform-runtime/test/fixtures/absoluteRuntime/true/output.js diff --git a/packages/babel-helper-transform-fixture-test-runner/src/index.js b/packages/babel-helper-transform-fixture-test-runner/src/index.js index 118d668a0a..6b32b4933e 100644 --- a/packages/babel-helper-transform-fixture-test-runner/src/index.js +++ b/packages/babel-helper-transform-fixture-test-runner/src/index.js @@ -6,6 +6,7 @@ import sourceMap from "source-map"; import { codeFrameColumns } from "@babel/code-frame"; import defaults from "lodash/defaults"; import includes from "lodash/includes"; +import escapeRegExp from "lodash/escapeRegExp"; import * as helpers from "./helpers"; import extend from "lodash/extend"; import merge from "lodash/merge"; @@ -180,7 +181,7 @@ function run(task) { function getOpts(self) { const newOpts = merge( { - cwd: path.dirname(self.filename), + cwd: path.dirname(self.loc), filename: self.loc, filenameRelative: self.filename, sourceFileName: self.filename, @@ -235,10 +236,15 @@ function run(task) { const expectCode = expected.code; if (!execCode || actualCode) { result = babel.transform(actualCode, getOpts(actual)); + const expectedCode = result.code.replace( + escapeRegExp(path.resolve(__dirname, "../../../")), + "", + ); + checkDuplicatedNodes(result.ast); if ( !expected.code && - result.code && + expectedCode && !opts.throws && fs.statSync(path.dirname(expected.loc)).isDirectory() && !process.env.CI @@ -249,7 +255,7 @@ function run(task) { ); console.log(`New test file created: ${expectedFile}`); - fs.writeFileSync(expectedFile, `${result.code}\n`); + fs.writeFileSync(expectedFile, `${expectedCode}\n`); if (expected.loc !== expectedFile) { try { @@ -257,7 +263,7 @@ function run(task) { } catch (e) {} } } else { - actualCode = result.code.trim(); + actualCode = expectedCode.trim(); try { expect(actualCode).toEqualFile({ filename: expected.loc, @@ -267,7 +273,7 @@ function run(task) { if (!process.env.OVERWRITE) throw e; console.log(`Updated test file: ${expected.loc}`); - fs.writeFileSync(expected.loc, `${result.code}\n`); + fs.writeFileSync(expected.loc, `${expectedCode}\n`); } if (actualCode) { diff --git a/packages/babel-plugin-transform-runtime/package.json b/packages/babel-plugin-transform-runtime/package.json index 252addde41..be9c90a659 100644 --- a/packages/babel-plugin-transform-runtime/package.json +++ b/packages/babel-plugin-transform-runtime/package.json @@ -10,7 +10,8 @@ ], "dependencies": { "@babel/helper-module-imports": "7.0.0-rc.1", - "@babel/helper-plugin-utils": "7.0.0-rc.1" + "@babel/helper-plugin-utils": "7.0.0-rc.1", + "resolve": "^1.8.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" @@ -21,6 +22,7 @@ "@babel/helpers": "7.0.0-rc.1", "@babel/plugin-transform-runtime": "7.0.0-rc.1", "@babel/preset-env": "7.0.0-rc.1", + "@babel/runtime": "7.0.0-rc.1", "@babel/template": "7.0.0-rc.1", "@babel/types": "7.0.0-beta.53" } diff --git a/packages/babel-plugin-transform-runtime/src/index.js b/packages/babel-plugin-transform-runtime/src/index.js index 0e0f616afd..757ec333a4 100644 --- a/packages/babel-plugin-transform-runtime/src/index.js +++ b/packages/babel-plugin-transform-runtime/src/index.js @@ -1,10 +1,31 @@ +import path from "path"; +import resolve from "resolve"; import { declare } from "@babel/helper-plugin-utils"; import { addDefault, isModule } from "@babel/helper-module-imports"; import { types as t } from "@babel/core"; import definitions from "./definitions"; -export default declare((api, options) => { +function resolveAbsoluteRuntime(moduleName: string, dirname: string) { + try { + return path.dirname( + resolve.sync(`${moduleName}/package.json`, { basedir: dirname }), + ); + } catch (err) { + if (err.code !== "MODULE_NOT_FOUND") throw err; + + throw Object.assign( + new Error(`Failed to resolve "${moduleName}" relative to "${dirname}"`), + { + code: "BABEL_RUNTIME_NOT_FOUND", + runtime: moduleName, + dirname, + }, + ); + } +} + +export default declare((api, options, dirname) => { api.assertVersion(7); const { @@ -13,6 +34,7 @@ export default declare((api, options) => { regenerator: useRuntimeRegenerator = true, useESModules = false, version: runtimeVersion = "7.0.0-beta.0", + absoluteRuntime = false, } = options; if (typeof useRuntimeRegenerator !== "boolean") { @@ -28,6 +50,14 @@ export default declare((api, options) => { "The 'useESModules' option must be undefined, or a boolean.", ); } + if ( + typeof absoluteRuntime !== "boolean" && + typeof absoluteRuntime !== "string" + ) { + throw new Error( + "The 'absoluteRuntime' option must be undefined, a boolean, or a string.", + ); + } if ( corejsVersion !== false && (typeof corejsVersion !== "number" || corejsVersion !== 2) && @@ -71,7 +101,9 @@ export default declare((api, options) => { if (has(options, "moduleName")) { throw new Error( "The 'moduleName' option has been removed. @babel/transform-runtime " + - "no longer supports arbitrary runtimes.", + "no longer supports arbitrary runtimes. If you were using this to " + + "set an absolute path for Babel's standard runtimes, please use the " + + "'absoluteRuntime' option.", ); } @@ -83,6 +115,14 @@ export default declare((api, options) => { const HEADER_HELPERS = ["interopRequireWildcard", "interopRequireDefault"]; + let modulePath = moduleName; + if (absoluteRuntime !== false) { + modulePath = resolveAbsoluteRuntime( + moduleName, + path.resolve(dirname, absoluteRuntime === true ? "." : absoluteRuntime), + ); + } + return { pre(file) { if (useRuntimeHelpers) { @@ -106,7 +146,7 @@ export default declare((api, options) => { isInteropHelper && !isModule(file.path) ? 4 : undefined; return this.addDefaultImport( - `${moduleName}/${helpersDir}/${name}`, + `${modulePath}/${helpersDir}/${name}`, name, blockHoist, ); @@ -144,7 +184,7 @@ export default declare((api, options) => { if (node.name === "regeneratorRuntime" && useRuntimeRegenerator) { path.replaceWith( this.addDefaultImport( - `${moduleName}/regenerator`, + `${modulePath}/regenerator`, "regeneratorRuntime", ), ); @@ -160,7 +200,7 @@ export default declare((api, options) => { // Symbol() -> _core.Symbol(); new Promise -> new _core.Promise path.replaceWith( this.addDefaultImport( - `${moduleName}/core-js/${definitions.builtins[node.name]}`, + `${modulePath}/core-js/${definitions.builtins[node.name]}`, node.name, ), ); @@ -183,7 +223,7 @@ export default declare((api, options) => { path.replaceWith( t.callExpression( this.addDefaultImport( - `${moduleName}/core-js/get-iterator`, + `${modulePath}/core-js/get-iterator`, "getIterator", ), [callee.object], @@ -201,7 +241,7 @@ export default declare((api, options) => { path.replaceWith( t.callExpression( this.addDefaultImport( - `${moduleName}/core-js/is-iterable`, + `${modulePath}/core-js/is-iterable`, "isIterable", ), [path.node.right], @@ -243,7 +283,7 @@ export default declare((api, options) => { path.replaceWith( this.addDefaultImport( - `${moduleName}/core-js/${methods[prop.name]}`, + `${modulePath}/core-js/${methods[prop.name]}`, `${obj.name}$${prop.name}`, ), ); @@ -262,7 +302,7 @@ export default declare((api, options) => { path.replaceWith( t.memberExpression( this.addDefaultImport( - `${moduleName}/core-js/${definitions.builtins[obj.name]}`, + `${modulePath}/core-js/${definitions.builtins[obj.name]}`, obj.name, ), node.property, diff --git a/packages/babel-plugin-transform-runtime/test/fixtures/absoluteRuntime/relative/input.js b/packages/babel-plugin-transform-runtime/test/fixtures/absoluteRuntime/relative/input.js new file mode 100644 index 0000000000..4e6a6de653 --- /dev/null +++ b/packages/babel-plugin-transform-runtime/test/fixtures/absoluteRuntime/relative/input.js @@ -0,0 +1 @@ +class Foo {} diff --git a/packages/babel-plugin-transform-runtime/test/fixtures/absoluteRuntime/relative/options.json b/packages/babel-plugin-transform-runtime/test/fixtures/absoluteRuntime/relative/options.json new file mode 100644 index 0000000000..126af9dc11 --- /dev/null +++ b/packages/babel-plugin-transform-runtime/test/fixtures/absoluteRuntime/relative/options.json @@ -0,0 +1,6 @@ +{ + "plugins": [ + "transform-classes", + ["transform-runtime", { "absoluteRuntime": "./subfolder" }] + ] +} diff --git a/packages/babel-plugin-transform-runtime/test/fixtures/absoluteRuntime/relative/output.js b/packages/babel-plugin-transform-runtime/test/fixtures/absoluteRuntime/relative/output.js new file mode 100644 index 0000000000..e783188c9e --- /dev/null +++ b/packages/babel-plugin-transform-runtime/test/fixtures/absoluteRuntime/relative/output.js @@ -0,0 +1,7 @@ +var _classCallCheck = require("/packages/babel-plugin-transform-runtime/node_modules/@babel/runtime/helpers/classCallCheck"); + +let Foo = function Foo() { + "use strict"; + + _classCallCheck(this, Foo); +}; diff --git a/packages/babel-plugin-transform-runtime/test/fixtures/absoluteRuntime/true/input.js b/packages/babel-plugin-transform-runtime/test/fixtures/absoluteRuntime/true/input.js new file mode 100644 index 0000000000..4e6a6de653 --- /dev/null +++ b/packages/babel-plugin-transform-runtime/test/fixtures/absoluteRuntime/true/input.js @@ -0,0 +1 @@ +class Foo {} diff --git a/packages/babel-plugin-transform-runtime/test/fixtures/absoluteRuntime/true/options.json b/packages/babel-plugin-transform-runtime/test/fixtures/absoluteRuntime/true/options.json new file mode 100644 index 0000000000..a8370f48c3 --- /dev/null +++ b/packages/babel-plugin-transform-runtime/test/fixtures/absoluteRuntime/true/options.json @@ -0,0 +1,6 @@ +{ + "plugins": [ + "transform-classes", + ["transform-runtime", { "absoluteRuntime": true }] + ] +} diff --git a/packages/babel-plugin-transform-runtime/test/fixtures/absoluteRuntime/true/output.js b/packages/babel-plugin-transform-runtime/test/fixtures/absoluteRuntime/true/output.js new file mode 100644 index 0000000000..e783188c9e --- /dev/null +++ b/packages/babel-plugin-transform-runtime/test/fixtures/absoluteRuntime/true/output.js @@ -0,0 +1,7 @@ +var _classCallCheck = require("/packages/babel-plugin-transform-runtime/node_modules/@babel/runtime/helpers/classCallCheck"); + +let Foo = function Foo() { + "use strict"; + + _classCallCheck(this, Foo); +};