Skip to content

Commit

Permalink
Support import.meta.url in preconstruct dev
Browse files Browse the repository at this point in the history
  • Loading branch information
emmatown committed Mar 6, 2023
1 parent 57576f9 commit 8d9a272
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .changeset/shaggy-comics-grab.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@preconstruct/cli": patch
"@preconstruct/hook": patch
---

Support `import.meta.url` in `preconstruct dev`
26 changes: 26 additions & 0 deletions packages/cli/src/__tests__/dev.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import spawn from "spawndamnit";
import path from "path";
import * as fs from "fs-extra";
import { pathToFileURL } from "url";
import * as realFs from "fs";
import { getFiles, js, testdir, ts, typescriptFixture } from "../../test-utils";
import dev from "../dev";
Expand Down Expand Up @@ -368,3 +369,28 @@ test("flow and .d.ts", async () => {
export const x = "hello";
`);
});

test("import.meta.url", async () => {
let tmpPath = await testdir({
"package.json": JSON.stringify({
name: "pkg",
main: "dist/pkg.cjs.js",
module: "dist/pkg.esm.js",
}),
"src/index.js": js`
console.log(import.meta.url);
`,
});
await dev(tmpPath);
// i would require it but i don't want jest to do magical things
let { code, stdout } = await spawn("node", [tmpPath], {
env: {
PATH: process.env.PATH,
},
});

expect(code).toBe(0);
expect(stdout.toString()).toBe(
pathToFileURL(path.join(tmpPath, "src/index.js")).toString() + "\n"
);
});
48 changes: 48 additions & 0 deletions packages/cli/src/build/__tests__/basic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1238,3 +1238,51 @@ test("importing css fails with a nice error", async () => {
`[Error: 🎁 @scope/test only .ts, .tsx, .js, .jsx, and .json files can be imported but "./blah.css" is imported in "src/index.js"]`
);
});

test("import.meta.url", async () => {
let dir = await testdir({
"package.json": JSON.stringify({
name: "@scope/test",
main: "dist/scope-test.cjs.js",
module: "dist/scope-test.esm.js",
}),
"src/index.js": ts`
export const a = import.meta.url;
`,
});
await build(dir);
expect(await getDist(dir)).toMatchInlineSnapshot(`
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ dist/scope-test.cjs.dev.js ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
const a = (typeof document === 'undefined' ? new (require('u' + 'rl').URL)('file:' + __filename).href : (document.currentScript && document.currentScript.src || new URL('dist/scope-test.cjs.dev.js', document.baseURI).href));
exports.a = a;
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ dist/scope-test.cjs.js ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
'use strict';
if (process.env.NODE_ENV === "production") {
module.exports = require("./scope-test.cjs.prod.js");
} else {
module.exports = require("./scope-test.cjs.dev.js");
}
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ dist/scope-test.cjs.prod.js ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
const a = (typeof document === 'undefined' ? new (require('u' + 'rl').URL)('file:' + __filename).href : (document.currentScript && document.currentScript.src || new URL('dist/scope-test.cjs.prod.js', document.baseURI).href));
exports.a = a;
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ dist/scope-test.esm.js ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
const a = import.meta.url;
export { a };
`);
});
68 changes: 68 additions & 0 deletions packages/hook/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,76 @@ const path = require("path");

let EXTENSIONS = [".js", ".jsx", ".ts", ".tsx"];

const t = babel.types;

let babelPlugins = [
require.resolve("@babel/plugin-transform-modules-commonjs"),
{
visitor: {
MemberExpression(path) {
if (
path.node.object.type === "MetaProperty" &&
path.node.object.meta.name === "import" &&
path.node.object.property.name === "meta" &&
!path.node.computed &&
path.node.property.name === "url"
) {
path.replaceWith(
t.conditionalExpression(
t.binaryExpression(
"===",
t.unaryExpression("typeof", t.identifier("document")),
t.stringLiteral("undefined")
),
t.memberExpression(
t.callExpression(
t.memberExpression(
t.callExpression(t.identifier("require"), [
t.binaryExpression(
"+",
t.stringLiteral("u"),
t.stringLiteral("rl")
),
]),
t.identifier("pathToFileURL")
),
[t.identifier("__filename")]
),
t.identifier("href")
),
t.logicalExpression(
"||",
t.logicalExpression(
"&&",
t.memberExpression(
t.identifier("document"),
t.identifier("currentScript")
),
t.memberExpression(
t.memberExpression(
t.identifier("document"),
t.identifier("currentScript")
),
t.identifier("src")
)
),
t.memberExpression(
t.newExpression(t.identifier("URL"), [
t.stringLiteral("main.js"),
t.memberExpression(
t.identifier("document"),
t.identifier("baseURI")
),
]),
t.identifier("href")
)
)
)
);
}
},
},
},
];

exports.___internalHook = (distDir, relativeToRoot, relativeToPkgDir) => {
Expand Down

0 comments on commit 8d9a272

Please sign in to comment.