Skip to content

Instantly share code, notes, and snippets.

@surma
Last active July 28, 2020 13:05
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 surma/d1f3066d7202da7e24bf84f3f2d215d8 to your computer and use it in GitHub Desktop.
Save surma/d1f3066d7202da7e24bf84f3f2d215d8 to your computer and use it in GitHub Desktop.
Preloader in Rollup
package-lock.json
build
node_modules
export function exclaim(msg) {
return msg + "!";
}
<!DOCTYPE html>
<script type="module" src="index.js"></script>
setTimeout(async () => {
const { shout } =
Math.random() < 0.5
? await import("./utilsA.js")
: await import("./utilsB.js");
shout("this is index");
}, 1000);
{
"name": "rollup-parallel",
"scripts": {
"build": "rollup -c && cp index.html build/"
}
}
const MARKER = "preloading-import:";
const PLACEHOLDER = "____TOTALLY_A_PLACEHOLDER____";
export default function preload() {
return {
name: "preload",
resolveId(id) {
if (id !== MARKER) {
return;
}
return id;
},
load(id) {
if (id !== MARKER) {
return;
}
return `
const bundleData = ${PLACEHOLDER};
export async function preloadingImport(path, base) {
const deps = new Set([path]);
for(const dep of deps) {
for(const subdep of (bundleData[dep] || [])) {
deps.add(subdep);
}
}
for(const dep of deps) {
const tag = document.createElement("link");
tag.rel = "preload";
tag.as = "script"
tag.crossOrigin = true;
tag.href = dep;
document.head.append(tag);
};
return import(path);
}
`;
},
transform(code, id) {
if (!code.includes("import(")) {
return;
}
if (id === MARKER) {
return;
}
return `
import {preloadingImport} from "${MARKER}";
// Rollup prunes the import because renderDynamicImport()
// didn’t run yet. This is my workaround.
self[Symbol()] = preloadingImport;
${code}
`;
},
renderDynamicImport({ moduleId }) {
if (moduleId === MARKER) {
return;
}
return {
left: "preloadingImport(",
right: ", import.meta.url)"
};
},
generateBundle(options, bundle) {
const bundleData = {};
for (const [fileName, info] of Object.entries(bundle)) {
if (info.type !== "chunk") {
continue;
}
bundleData[fileName] = info.imports;
}
for (const chunk of Object.values(bundle)) {
chunk.code = chunk.code.replace(
PLACEHOLDER,
JSON.stringify(bundleData)
);
}
}
};
}
import preload from "./rollup-plugin-preload.js";
export default {
input: "index.js",
output: {
dir: "build",
format: "esm"
},
plugins: [preload()]
};
import { exclaim } from "./exclaim.js";
export function logCaps(msg) {
if (!msg) return;
console.log(msg.toUpperCase());
}
export function shout(msg) {
logCaps(exclaim(msg));
}
import { exclaim } from "./exclaim.js";
export function logNormal(msg) {
if (!msg) return;
console.log(msg);
}
export function shout(msg) {
logNormal(exclaim(msg));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment