Skip to content

Commit c157ff2

Browse files
committed
Create a plugin to inline initial resources
1 parent 94e4d32 commit c157ff2

10 files changed

+190
-55
lines changed

esbuild.js

+34-21
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,32 @@ const esbuild = require("esbuild");
33
const {
44
esbuildProblemMatcherPlugin,
55
} = require("./plugins/esbuildProblemMatchersPlugin");
6-
const { injectInitialScriptPlugin } = require("./plugins/injectInitialScript");
6+
const { injectionPlugin } = require("./plugins/injection-plugin");
77

88
const production = process.argv.includes("--production");
99
const watch = process.argv.includes("--watch");
1010

11+
const commonBuildOptions = {
12+
bundle: true,
13+
format: "esm",
14+
target: "es2020",
15+
minify: production,
16+
sourcesContent: false,
17+
logLevel: "silent",
18+
alias: {
19+
react: "preact/compat",
20+
},
21+
allowOverwrite: true,
22+
};
23+
1124
async function main() {
1225
const contexts = [];
1326
// Build the visualization webview code
1427
contexts.push(
1528
await esbuild.context({
16-
entryPoints: ["src/index.tsx", "src/initial-script.ts"],
17-
bundle: true,
18-
format: "esm",
19-
target: "es2020",
20-
minify: production,
21-
sourcesContent: false,
22-
outdir: "./dist/bundle",
23-
metafile: true,
24-
logLevel: "silent",
25-
alias: {
26-
react: "preact/compat",
27-
},
29+
...commonBuildOptions,
30+
entryPoints: ["src/index.tsx"],
31+
outfile: "./dist/bundle/index.js",
2832
plugins: [
2933
esbuildPluginCopy({
3034
// Resolve relative to the current working directory
@@ -37,7 +41,22 @@ async function main() {
3741
},
3842
],
3943
}),
40-
injectInitialScriptPlugin,
44+
/* add to the end of plugins array */
45+
esbuildProblemMatcherPlugin,
46+
],
47+
}),
48+
);
49+
// Build the initial resources (JS and CSS)
50+
contexts.push(
51+
await esbuild.context({
52+
...commonBuildOptions,
53+
entryPoints: ["src/initial-resources/index.ts"],
54+
outfile: "./dist/bundle/initial.js",
55+
plugins: [
56+
injectionPlugin({
57+
inFile: "src/index.ejs",
58+
outFile: "dist/index.html",
59+
}),
4160
/* add to the end of plugins array */
4261
esbuildProblemMatcherPlugin,
4362
],
@@ -46,19 +65,13 @@ async function main() {
4665
// Build the service worker
4766
contexts.push(
4867
await esbuild.context({
68+
...commonBuildOptions,
4969
entryPoints: ["src/service-worker.ts"],
50-
bundle: true,
51-
format: "esm",
52-
target: "es2020",
53-
minify: production,
54-
sourcesContent: false,
5570
outdir: "./dist",
56-
logLevel: "silent",
5771
plugins: [
5872
/* add to the end of plugins array */
5973
esbuildProblemMatcherPlugin,
6074
],
61-
allowOverwrite: true,
6275
}),
6376
);
6477

package-lock.json

+104
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"license": "ISC",
1414
"devDependencies": {
1515
"@types/node": "^22.7.4",
16+
"ejs": "^3.1.10",
1617
"esbuild": "^0.23.1",
1718
"esbuild-plugin-copy": "^2.1.1",
1819
"preact": "^10.23.2",

plugins/injectInitialScript.js

-24
This file was deleted.

plugins/injection-plugin.js

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
const fs = require("fs");
2+
const ejs = require("ejs");
3+
4+
const pluginName = "injection-plugin";
5+
6+
function injectFile(type, filepath) {
7+
const fileContent = fs.readFileSync(filepath).toString().trim();
8+
switch (type) {
9+
// JS
10+
case "js":
11+
return `<script type="module">${fileContent}</script>`;
12+
// CSS
13+
case "css":
14+
return `<style>${fileContent}</style>`;
15+
// Plaintext
16+
case "text":
17+
return fileContent;
18+
default:
19+
throw new Error(
20+
`${pluginName}: Injection of type "${type}" not supported`,
21+
);
22+
}
23+
}
24+
25+
/**
26+
* @returns {import('esbuild').Plugin}
27+
*/
28+
module.exports.injectionPlugin = function ({ inFile, outFile }) {
29+
return {
30+
name: "injection-plugin",
31+
setup: (build) => {
32+
build.onEnd(() => {
33+
const ejsTemplate = fs.readFileSync(inFile).toString();
34+
const html = ejs.render(ejsTemplate, { injectFile });
35+
fs.writeFileSync(outFile, html);
36+
});
37+
},
38+
};
39+
};

public/index.html src/index.ejs

+9-7
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,14 @@
66
<title>Runic - The Tunic Translation Tool</title>
77

88
<!-- Initial Script -->
9-
<!-- inject:initial-script -->
9+
<%- injectFile("js", "dist/bundle/initial.js") %>
10+
<!-- Initial CSS -->
11+
<%- injectFile("css", "dist/bundle/initial.css") %>
1012

1113
<!-- Preconnect to fonts.gstatic.com -->
1214
<link rel="preconnect" href="fonts.gstatic.com" />
1315

14-
<!-- CSS -->
15-
<link rel="stylesheet" href="./bundle/index.css" />
16-
17-
<!-- JS -->
16+
<!-- Lazy JS -->
1817
<script src="./bundle/index.js" async defer></script>
1918

2019
<!-- Google tag (gtag.js) -->
@@ -84,6 +83,9 @@
8483
/>
8584
</head>
8685
<body>
86+
<!-- Lazy CSS -->
87+
<link rel="stylesheet" href="./bundle/index.css" />
88+
8789
<div class="fancy-orb-background">
8890
<div class="orb orb-red"></div>
8991
<div class="orb orb-green"></div>
@@ -116,8 +118,8 @@ <h2>Runic translator</h2>
116118
<p>
117119
Anything you type in English will be translated to
118120
phonetic, and then converted to Runic.<br />
119-
Put phrases within '<i>@</i>' to display them in
120-
English, like '<i>@The Librarian@</i>'
121+
Put phrases within '<i>&#64;</i>' to display them in
122+
English, like '<i>&#64;The Librarian&#64;</i>'
121123
</p>
122124
</section>
123125
<div class="runic-editor-container"></div>

src/index.tsx

-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
import "./fonts.css";
2-
import "./index.css";
3-
41
import { render } from "preact";
52
import { loadIPADict } from "./ipa";
63
import { RunicEditor } from "components/RunicEditor";
File renamed without changes.
File renamed without changes.

src/initial-script.ts src/initial-resources/index.ts

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import "./fonts.css";
2+
import "./index.css";
3+
14
function setTheme() {
25
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
36
if (mediaQuery.matches) {

0 commit comments

Comments
 (0)