Skip to content

Instantly share code, notes, and snippets.

@bellbind
Last active January 29, 2020 07:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bellbind/6f45fdef8b313b36eb8803bfafc8f54b to your computer and use it in GitHub Desktop.
Save bellbind/6f45fdef8b313b36eb8803bfafc8f54b to your computer and use it in GitHub Desktop.
[ES module] test hash fragment and redirected for import.meta.url
<html>
<head>
<meta charset="utf-8">
<link rel="icon" href="data:,">
<script type="module">
import "./main.js";
import "./main-redirected.js";
import "./main-identity.js";
import "./main-fetch-url.js";
</script>
</head>
<body>
Check output on Web Cosole
</body>
</html>
(async () => {
console.log("[fetch response url when HTTP redirected]");
// chrome-81 and firefox-72: all "http://localhost:8000/module.js"
console.log("./module.js", (await fetch("./module.js")).url);
console.log("./module.js#a", (await fetch("./module.js#a")).url);
console.log("./redirect.js#c", (await fetch("./redirect.js#c")).url);
console.log("./redirecte.js", (await fetch("./redirect.js")).url);
console.log("./redirect.js?301#c", (await fetch("./redirect.js?301#c")).url);
console.log("./redirecte.js?301", (await fetch("./redirect.js?301")).url);
})().catch(console.error);
import * as m1 from "./module.js";
import * as m2 from "http://localhost:8000/module.js";
import * as m3 from "http://LOCALHOST:8000/module.js";
import * as m4 from "http://:@LOCALHOST:8000/module.js";
//NOTE: new URL("http://:@LOCALHOST:8000/").href === "http://localhost:8000/"
console.log("[module identity with varied url denotation]");
console.log("m1", m1.url); //=> "http://localhost:8000/module.js"
console.log("m2", m2.url); //=> "http://localhost:8000/module.js"
console.log("m3", m3.url); //=> "http://localhost:8000/module.js"
console.log("m4", m4.url); //=> "http://localhost:8000/module.js"
console.log("m1 === m2", m1 === m2, m1.hash === m2.hash); //=> true true
console.log("m2 === m3", m2 === m3, m2.hash === m3.hash); //=> true true
console.log("m2 === m4", m2 === m4, m2.hash === m4.hash); //=> true true
<html>
<head>
<meta charset="utf-8">
<link rel="icon" href="data:,">
<script type="module">
import "./main.js";
</script>
</head>
<body>
Check output on Web Cosole
</body>
</html>
import * as r1c from "./redirect.js?301#c";
import * as r1 from "./redirect.js?301";
import * as r2 from "./redirect.js?302";
import * as r2c from "./redirect.js?302#c";
console.log("[redirect case of import.meta.url with hash fragment]");
console.log("r1", r1.url); //=> http://localhost:8000/module.js
console.log("r2", r2.url); //=> http://localhost:8000/module.js
console.log("r1c", r1c.url); //=> http://localhost:8000/module.js#c
console.log("r2c", r2c.url); //=> http://localhost:8000/module.js#c
console.log("r1 === r2", r1 === r2, r1.hash === r2.hash); // false false
console.log("r1c === r2c", r1c === r2c, r1c.hash === r2c.hash); // false false
console.log("r1 === r1c", r1 === r1c, r1.hash === r1c.hash); // false false
console.log("r2 === r2c", r2 === r2c, r2.hash === r2c.hash); // false false
console.log("r1.hash", r1.hash()); //=> ""
console.log("r2.hash", r2.hash()); //=> ""
console.log("r1c.hash", r1c.hash()); //=> "#c"
console.log("r2c.hash", r2c.hash()); //=> "#c"
// NOTE: chrome has bug with redirected module: depend on import order
//
// case 1: all import.meta.url has hash when import with hash at first
// import * as r1c from "./redirect.js?301#c";
// import * as r1 from "./redirect.js?301";
//
// case 2: all import.meta.url has no hash when import with no-hash at first
// import * as r2 from "./redirect.js?302";
// import * as r2c from "./redirect.js?302#c";
import * as m1 from "./module.js";
import * as m2 from "./module.js";
import * as a from "./module.js#a";
import * as b from "./module.js#b";
console.log("[hash fragment of import.meta.url]");
// these results based on the spec of import.meta.url and watwag html spec
console.log("m1", m1.url); //=> "http://localhost:8000/module.js"
console.log("m2", m2.url); //=> "http://localhost:8000/module.js"
console.log("a", a.url); //=> "http://localhost:8000/module.js#a"
console.log("b", b.url); //=> "http://localhost:8000/module.js#b"
console.log("m1 === m2", m1 === m2, m1.hash === m2.hash); //=> true true
console.log("m1 === a", m1 === a, m1.hash === a.hash); //=> false false
console.log("a === b", a === b, a.hash === b.hash); //=> false false
console.log("m1.hash", m1.hash()); //=> ""
console.log("a.hash", a.hash()); //=> "#a"
console.log("b.hash", b.hash()); //=> "#b"
// NOTE: chrome <= 81 implementaion is not followed these spec => empty string:
//
// - https://github.com/whatwg/html/issues/5162
// - https://bugs.chromium.org/p/chromium/issues/detail?id=841831
//
// Reason: chrome uses Response.url: hash fragment removed url (currently)
//
// This issue is related that redirected url (browser's, also Response.url)
// keeps original hash fragment or not.
//
// - https://github.com/whatwg/fetch/issues/505
// module members simply return import.meta.url info
export const url = import.meta.url;
export const hash = () => new URL(import.meta.url).hash;
{
"type": "module",
"engines": {"node": ">=13.2.0"},
"scripts": {"start": "node ws.js"}
}
import fs from "fs";
import http from "http";
const server = http.createServer((req, res) => {
console.log(req.method, req.url);
if (["/", "/index.html"].includes(req.url)) {
res.writeHead(200, {"content-type": "text/html;charset=utf-8"});
fs.createReadStream("./index.html").pipe(res);
} else if (/^\/main.*\.js$/.test(req.url)) {
res.writeHead(200, {"content-type": "application/javascript"});
fs.createReadStream(`.${req.url}`).pipe(res);
} else if (/^\/module\.js(?:\?.*)?$/.test(req.url)) {
res.writeHead(200, {"content-type": "application/javascript"});
fs.createReadStream("./module.js").pipe(res);
} else if (/^\/redirect\.js(?:\?.*)?$/.test(req.url)) {
const u = new URL(req.url, "http://localhost/");
const status = u.search ? u.search.slice(1) : 301;
res.writeHead(status, {location: "/module.js"});
res.end();
}
});
server.listen(8000, "0.0.0.0", () => console.log("http://0.0.0.0:8000/"));
@bellbind
Copy link
Author

bellbind commented Jan 29, 2020

Results:

  • Stage 3 import.meta.url feature is yet unstable for hash fragment part
    • it is part of whatwg html spec
    • maybe ok when importing no hash fragment url only
  • On chrome, basically no hash fragment, but import.meta.url has hash when redirected
    • node.js and firefox and safari returns same results based on the spec

How to check:

(node.js >= 13.2 required for node command)

Reference:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment