From 92ffff415f64eee2a199ff77f5876b8758679f20 Mon Sep 17 00:00:00 2001 From: Nick Heiner Date: Tue, 17 May 2022 17:19:46 -0400 Subject: [PATCH] Pass filename to `importInterop` method (#14456) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Nick Heiner Co-authored-by: Nicolò Ribaudo --- .../src/index.ts | 3 + .../src/normalize-and-load-metadata.ts | 10 +- .../src/index.ts | 1 + .../test/importInterop-function.js | 114 ++++++++++----- .../src/index.ts | 1 + .../test/importInterop-function.js | 100 +++++++++---- .../src/index.ts | 1 + .../test/importInterop-function.js | 138 +++++++++++------- 8 files changed, 247 insertions(+), 121 deletions(-) diff --git a/packages/babel-helper-module-transforms/src/index.ts b/packages/babel-helper-module-transforms/src/index.ts index 7dcdfd017bfa..5001699b619e 100644 --- a/packages/babel-helper-module-transforms/src/index.ts +++ b/packages/babel-helper-module-transforms/src/index.ts @@ -58,6 +58,7 @@ export function rewriteModuleStatementsAndPrepareHeader( importInterop = noInterop ? "none" : "babel", lazy, esNamespaceOnly, + filename, constantReexports = loose, enumerableModuleMeta = loose, @@ -72,6 +73,7 @@ export function rewriteModuleStatementsAndPrepareHeader( noInterop?; lazy?; esNamespaceOnly?; + filename: string | undefined; constantReexports?; enumerableModuleMeta?; noIncompleteNsImportDetection?: boolean; @@ -86,6 +88,7 @@ export function rewriteModuleStatementsAndPrepareHeader( initializeReexports: constantReexports, lazy, esNamespaceOnly, + filename, }); if (!allowTopLevelThis) { diff --git a/packages/babel-helper-module-transforms/src/normalize-and-load-metadata.ts b/packages/babel-helper-module-transforms/src/normalize-and-load-metadata.ts index 0fac804b8f21..bd2941fba21f 100644 --- a/packages/babel-helper-module-transforms/src/normalize-and-load-metadata.ts +++ b/packages/babel-helper-module-transforms/src/normalize-and-load-metadata.ts @@ -89,9 +89,13 @@ export function validateImportInteropOption( return importInterop; } -function resolveImportInterop(importInterop, source) { +function resolveImportInterop( + importInterop, + source, + filename: string | undefined, +) { if (typeof importInterop === "function") { - return validateImportInteropOption(importInterop(source)); + return validateImportInteropOption(importInterop(source, filename)); } return importInterop; } @@ -108,6 +112,7 @@ export default function normalizeModuleAndLoadMetadata( initializeReexports = false, lazy = false, esNamespaceOnly = false, + filename, }, ): ModuleMetadata { if (!exportName) { @@ -136,6 +141,7 @@ export default function normalizeModuleAndLoadMetadata( const resolvedInterop = resolveImportInterop( importInterop, metadata.source, + filename, ); if (resolvedInterop === "none") { diff --git a/packages/babel-plugin-transform-modules-amd/src/index.ts b/packages/babel-plugin-transform-modules-amd/src/index.ts index 3d7bd31a6e1d..a22064354549 100644 --- a/packages/babel-plugin-transform-modules-amd/src/index.ts +++ b/packages/babel-plugin-transform-modules-amd/src/index.ts @@ -134,6 +134,7 @@ export default declare((api, options: Options) => { allowTopLevelThis, importInterop, noInterop, + filename: this.file.opts.filename, }, ); diff --git a/packages/babel-plugin-transform-modules-amd/test/importInterop-function.js b/packages/babel-plugin-transform-modules-amd/test/importInterop-function.js index 856ee6dbd0cc..8a653d902dca 100644 --- a/packages/babel-plugin-transform-modules-amd/test/importInterop-function.js +++ b/packages/babel-plugin-transform-modules-amd/test/importInterop-function.js @@ -1,43 +1,81 @@ import * as babel from "@babel/core"; import transformAmd from "../lib/index.js"; import externalHelpers from "@babel/plugin-external-helpers"; +import path from "path"; -it("'importInterop' accepts a function", function () { - const code = ` - import a from "a"; - import b from "b"; - import c from "c"; - - a(); - b(); - c(); - `; - - const importInterop = source => { - if (source === "a") return "babel"; - else if (source === "b") return "node"; - else if (source === "c") return "none"; - }; - - const output = babel.transformSync(code, { - configFile: false, - ast: false, - plugins: [ - [externalHelpers, { helperVersion: "7.100.0" }], - [transformAmd, { importInterop }], - ], - }).code; - - expect(output).toMatchInlineSnapshot(` - "define([\\"a\\", \\"b\\", \\"c\\"], function (_a, _b, _c) { - \\"use strict\\"; - - _a = babelHelpers.interopRequireDefault(_a); - (0, _a.default)(); - - _b(); - - (0, _c.default)(); - });" - `); +describe("'importInterop'", () => { + function transform(code, importInterop, filename) { + return babel.transformSync(code, { + configFile: false, + filename, + ast: false, + plugins: [ + [externalHelpers, { helperVersion: "7.100.0" }], + [transformAmd, { importInterop }], + ], + }).code; + } + + it("'importInterop' accepts a function", () => { + const code = ` + import a from "a"; + import b from "b"; + import c from "c"; + + a(); + b(); + c(); + `; + + const importInterop = source => { + if (source === "a") return "babel"; + else if (source === "b") return "node"; + else if (source === "c") return "none"; + }; + + expect(transform(code, importInterop)).toMatchInlineSnapshot(` + "define([\\"a\\", \\"b\\", \\"c\\"], function (_a, _b, _c) { + \\"use strict\\"; + + _a = babelHelpers.interopRequireDefault(_a); + (0, _a.default)(); + + _b(); + + (0, _c.default)(); + });" + `); + }); + + it("gets called with the filename if present", () => { + const code = ` + import a from "a"; + import b from "b"; + `; + + const importInterop = jest.fn(() => "babel"); + + const filename = "path/to/fake-filename.js"; + + transform(code, importInterop, filename); + + expect(importInterop).toHaveBeenCalledTimes(2); + expect(importInterop).toHaveBeenCalledWith("a", path.resolve(filename)); + expect(importInterop).toHaveBeenCalledWith("b", path.resolve(filename)); + }); + + it("gets called with undefined if the filename is not present", () => { + const code = ` + import a from "a"; + import b from "b"; + `; + + const importInterop = jest.fn(() => "babel"); + + transform(code, importInterop); + + expect(importInterop).toHaveBeenCalledTimes(2); + expect(importInterop).toHaveBeenCalledWith("a", undefined); + expect(importInterop).toHaveBeenCalledWith("b", undefined); + }); }); diff --git a/packages/babel-plugin-transform-modules-commonjs/src/index.ts b/packages/babel-plugin-transform-modules-commonjs/src/index.ts index 3debdf1fc1ac..98d47ba84b68 100644 --- a/packages/babel-plugin-transform-modules-commonjs/src/index.ts +++ b/packages/babel-plugin-transform-modules-commonjs/src/index.ts @@ -225,6 +225,7 @@ export default declare((api, options: Options) => { ? mjsStrictNamespace : strictNamespace, noIncompleteNsImportDetection, + filename: this.file.opts.filename, }, ); diff --git a/packages/babel-plugin-transform-modules-commonjs/test/importInterop-function.js b/packages/babel-plugin-transform-modules-commonjs/test/importInterop-function.js index 17e890da0084..aec4e52b6787 100644 --- a/packages/babel-plugin-transform-modules-commonjs/test/importInterop-function.js +++ b/packages/babel-plugin-transform-modules-commonjs/test/importInterop-function.js @@ -1,46 +1,84 @@ import * as babel from "@babel/core"; import transformCommonjs from "../lib/index.js"; import externalHelpers from "@babel/plugin-external-helpers"; +import path from "path"; -it("'importInterop' accepts a function", function () { - const code = ` - import a from "a"; - import b from "b"; - import c from "c"; +describe("'importInterop'", () => { + function transform(code, importInterop, filename) { + return babel.transformSync(code, { + configFile: false, + filename, + ast: false, + plugins: [ + [externalHelpers, { helperVersion: "7.100.0" }], + [transformCommonjs, { importInterop }], + ], + }).code; + } - a(); - b(); - c(); - `; + it("'importInterop' accepts a function", () => { + const code = ` + import a from "a"; + import b from "b"; + import c from "c"; - const importInterop = source => { - if (source === "a") return "babel"; - else if (source === "b") return "node"; - else if (source === "c") return "none"; - }; + a(); + b(); + c(); + `; - const output = babel.transformSync(code, { - configFile: false, - ast: false, - plugins: [ - [externalHelpers, { helperVersion: "7.100.0" }], - [transformCommonjs, { importInterop }], - ], - }).code; + const importInterop = source => { + if (source === "a") return "babel"; + else if (source === "b") return "node"; + else if (source === "c") return "none"; + }; - expect(output).toMatchInlineSnapshot(` - "\\"use strict\\"; + expect(transform(code, importInterop)).toMatchInlineSnapshot(` + "\\"use strict\\"; - var _a = babelHelpers.interopRequireDefault(require(\\"a\\")); + var _a = babelHelpers.interopRequireDefault(require(\\"a\\")); - var _b = require(\\"b\\"); + var _b = require(\\"b\\"); - var _c = require(\\"c\\"); + var _c = require(\\"c\\"); - (0, _a.default)(); + (0, _a.default)(); - _b(); + _b(); - (0, _c.default)();" - `); + (0, _c.default)();" + `); + }); + + it("gets called with the filename if present", () => { + const code = ` + import a from "a"; + import b from "b"; + `; + + const importInterop = jest.fn(() => "babel"); + + const filename = "path/to/fake-filename.js"; + + transform(code, importInterop, filename); + + expect(importInterop).toHaveBeenCalledTimes(2); + expect(importInterop).toHaveBeenCalledWith("a", path.resolve(filename)); + expect(importInterop).toHaveBeenCalledWith("b", path.resolve(filename)); + }); + + it("gets called with undefined if the filename is not present", () => { + const code = ` + import a from "a"; + import b from "b"; + `; + + const importInterop = jest.fn(() => "babel"); + + transform(code, importInterop); + + expect(importInterop).toHaveBeenCalledTimes(2); + expect(importInterop).toHaveBeenCalledWith("a", undefined); + expect(importInterop).toHaveBeenCalledWith("b", undefined); + }); }); diff --git a/packages/babel-plugin-transform-modules-umd/src/index.ts b/packages/babel-plugin-transform-modules-umd/src/index.ts index 456772e8563b..955e23ac9ee4 100644 --- a/packages/babel-plugin-transform-modules-umd/src/index.ts +++ b/packages/babel-plugin-transform-modules-umd/src/index.ts @@ -173,6 +173,7 @@ export default declare((api, options: Options) => { allowTopLevelThis, noInterop, importInterop, + filename: this.file.opts.filename, }, ); diff --git a/packages/babel-plugin-transform-modules-umd/test/importInterop-function.js b/packages/babel-plugin-transform-modules-umd/test/importInterop-function.js index a10776d04680..08b9d80dae67 100644 --- a/packages/babel-plugin-transform-modules-umd/test/importInterop-function.js +++ b/packages/babel-plugin-transform-modules-umd/test/importInterop-function.js @@ -1,55 +1,93 @@ import * as babel from "@babel/core"; import transformUmd from "../lib/index.js"; import externalHelpers from "@babel/plugin-external-helpers"; +import path from "path"; -it("'importInterop' accepts a function", function () { - const code = ` - import a from "a"; - import b from "b"; - import c from "c"; - - a(); - b(); - c(); - `; - - const importInterop = source => { - if (source === "a") return "babel"; - else if (source === "b") return "node"; - else if (source === "c") return "none"; - }; - - const output = babel.transformSync(code, { - configFile: false, - ast: false, - plugins: [ - [externalHelpers, { helperVersion: "7.100.0" }], - [transformUmd, { importInterop }], - ], - }).code; - - expect(output).toMatchInlineSnapshot(` - "(function (global, factory) { - if (typeof define === \\"function\\" && define.amd) { - define([\\"a\\", \\"b\\", \\"c\\"], factory); - } else if (typeof exports !== \\"undefined\\") { - factory(require(\\"a\\"), require(\\"b\\"), require(\\"c\\")); - } else { - var mod = { - exports: {} - }; - factory(global.a, global.b, global.c); - global.unknown = mod.exports; - } - })(typeof globalThis !== \\"undefined\\" ? globalThis : typeof self !== \\"undefined\\" ? self : this, function (_a, _b, _c) { - \\"use strict\\"; - - _a = babelHelpers.interopRequireDefault(_a); - (0, _a.default)(); - - _b(); - - (0, _c.default)(); - });" - `); +describe("'importInterop'", () => { + function transform(code, importInterop, filename) { + return babel.transformSync(code, { + configFile: false, + filename, + ast: false, + plugins: [ + [externalHelpers, { helperVersion: "7.100.0" }], + [transformUmd, { importInterop }], + ], + }).code; + } + + it("'importInterop' accepts a function", () => { + const code = ` + import a from "a"; + import b from "b"; + import c from "c"; + + a(); + b(); + c(); + `; + + const importInterop = source => { + if (source === "a") return "babel"; + else if (source === "b") return "node"; + else if (source === "c") return "none"; + }; + + expect(transform(code, importInterop)).toMatchInlineSnapshot(` + "(function (global, factory) { + if (typeof define === \\"function\\" && define.amd) { + define([\\"a\\", \\"b\\", \\"c\\"], factory); + } else if (typeof exports !== \\"undefined\\") { + factory(require(\\"a\\"), require(\\"b\\"), require(\\"c\\")); + } else { + var mod = { + exports: {} + }; + factory(global.a, global.b, global.c); + global.unknown = mod.exports; + } + })(typeof globalThis !== \\"undefined\\" ? globalThis : typeof self !== \\"undefined\\" ? self : this, function (_a, _b, _c) { + \\"use strict\\"; + + _a = babelHelpers.interopRequireDefault(_a); + (0, _a.default)(); + + _b(); + + (0, _c.default)(); + });" + `); + }); + + it("gets called with the filename if present", () => { + const code = ` + import a from "a"; + import b from "b"; + `; + + const importInterop = jest.fn(() => "babel"); + + const filename = "path/to/fake-filename.js"; + + transform(code, importInterop, filename); + + expect(importInterop).toHaveBeenCalledTimes(2); + expect(importInterop).toHaveBeenCalledWith("a", path.resolve(filename)); + expect(importInterop).toHaveBeenCalledWith("b", path.resolve(filename)); + }); + + it("gets called with undefined if the filename is not present", () => { + const code = ` + import a from "a"; + import b from "b"; + `; + + const importInterop = jest.fn(() => "babel"); + + transform(code, importInterop); + + expect(importInterop).toHaveBeenCalledTimes(2); + expect(importInterop).toHaveBeenCalledWith("a", undefined); + expect(importInterop).toHaveBeenCalledWith("b", undefined); + }); });