Skip to content

Commit

Permalink
bundle all files with esbuild
Browse files Browse the repository at this point in the history
  • Loading branch information
takase1121 committed May 11, 2024
1 parent 378a562 commit 723c891
Show file tree
Hide file tree
Showing 11 changed files with 113 additions and 45 deletions.
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,4 @@ core/install
shell/node_modules
shell/dist

lite-xl/build
lite-xl/.git
lite-xl
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ In general, you will need the following tools:
- A HTTP Server (I use `http-server`, but Python's `http.server` will work with caveats.)
- Git
- Bash (MSYS2 might work but not tested)
- npm (Optional, for prettifying source code)
- npm

Your entry point will be `build.sh`, which can be used to build and deploy the application.
For most people, running `./build.sh` will be sufficient,
Expand Down
9 changes: 6 additions & 3 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,9 @@ main() {
--js-output=bundle.json.js --use-preload-cache --no-node --no-force \
--use-preload-plugins --quiet

# we need to set Module=window.Module to use a global variable
sed -i '1s/^/var Module = window.Module;\n/' lite-xl/lite-xl.js
sed -i '1s/^/var Module = window.Module;\n/' bundle.json.js
popd

# build the shell
Expand All @@ -265,7 +268,7 @@ main() {
else
npm i -D
fi
npm run build
BUNDLE_PATH="$rootdir/$xldir/bundle.json.js" LITE_XL_PATH="$rootdir/$xldir/lite-xl/lite-xl.js" npm run build
popd

# create the distribution
Expand All @@ -276,8 +279,8 @@ main() {

# copy all the files
cp -r "$rootdir/shell/dist/." "$output"
cp "$xldir/lite-xl/lite-xl.js" "$xldir/lite-xl/lite-xl.wasm" "$output/js"
cp "$xldir/bundle.json.js" "$xldir/bundle.json" "$output/js"
cp "$xldir/lite-xl/lite-xl.wasm" "$output/js"
cp "$xldir/bundle.json" "$output"
}

main "$@"
6 changes: 5 additions & 1 deletion cross/30-lite-xl.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ malloc_impl = 'emmalloc'
# e.g. stdout, stderr, fopen, etc. Use another cross file to override this value.
exported_functions = ''

# Exported JS values in Modules.
# We need this because the minification will mangle / remove a bunch of symbols.
exported_js_values = '["FS","ENV","IDBFS","callMain"]'

# Extra link options that can be overridden by other cross files.
extra_link_options = []

Expand All @@ -34,4 +38,4 @@ arch_tuple = 'wasm32-unknown'
wrap_mode = 'nofallback'
force_fallback_for = 'lua,pcre2,freetype2'
c_args = ['-fPIC']
c_link_args = ['-sALLOW_MEMORY_GROWTH=1', '-sINITIAL_MEMORY=' + initial_heap, '-sASYNCIFY', '-sASYNCIFY_ADVISE=' + asyncify_advise, '-sASYNCIFY_STACK_SIZE=' + asyncify_stack_size, '-sASYNCIFY_REMOVE=' + asyncify_ignores, '-sFORCE_FILESYSTEM=1', '-lidbfs.js', '-sEXIT_RUNTIME=1', '-sMALLOC=' + malloc_impl, '-sMAIN_MODULE=2', '-sEXPORTED_FUNCTIONS=' + exported_functions] + extra_link_options
c_link_args = ['-sALLOW_MEMORY_GROWTH=1', '-sINITIAL_MEMORY=' + initial_heap, '-sASYNCIFY', '-sASYNCIFY_ADVISE=' + asyncify_advise, '-sASYNCIFY_STACK_SIZE=' + asyncify_stack_size, '-sASYNCIFY_REMOVE=' + asyncify_ignores, '-sFORCE_FILESYSTEM=1', '-lidbfs.js', '-sEXIT_RUNTIME=1', '-sMALLOC=' + malloc_impl, '-sMAIN_MODULE=2', '-sEXPORTED_FUNCTIONS=' + exported_functions, '-sEXPORTED_RUNTIME_METHODS=' + exported_js_values] + extra_link_options
22 changes: 22 additions & 0 deletions shell/esbuild.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
* @file Runs esbuild.
* @author takase1121
*/

import * as esbuild from "esbuild";
import { env } from "process";

await esbuild.build({
entryPoints: ["js/main.mjs", "css/main.css"],
bundle: true,
sourcemap: true,
minify: true,
target: "es2017",
alias: {
"lite-xl-bundle": env.BUNDLE_PATH,
"lite-xl": env.LITE_XL_PATH,
},
external: ["child_process", "path", "fs"],
logLevel: "info",
outdir: "dist",
});
2 changes: 0 additions & 2 deletions shell/html/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@

<link rel="stylesheet" href="./css/main.css" />
<script src="./js/main.js"></script>
<script src="./js/bundle.json.js"></script>
<script src="./js/lite-xl.js"></script>
</head>

<body>
Expand Down
15 changes: 15 additions & 0 deletions shell/js/env.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* @file Exports Module.FS and Module.ENV.
* @author takase1121
*/

export let FS = {},
ENV = {};

/**
* Loads the FS and ENV object from Module.
*/
export function reloadEmscriptenEnv() {
FS = Module.FS;
ENV = Module.ENV;
}
8 changes: 7 additions & 1 deletion shell/js/fs.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { zip } from "fflate"
/**
* @file Filesystem related utilities.
* @author takase1121
*/

import { zip } from "fflate";
import { FS } from "./env.mjs";

/**
* Splits the path into different segments.
Expand Down
9 changes: 8 additions & 1 deletion shell/js/idbsync.mjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
/**
* Manages syncings from IDBFS to IndexedDB.
* @file Manages syncing between IDBFS and IndexedDB.
* @author takase1121
*/

import { FS } from "./env.mjs";

/**
* Manages syncing from IDBFS to IndexedDB.
*/
export class IDBSync {
constructor(interval = 5000) {
Expand Down
78 changes: 46 additions & 32 deletions shell/js/main.mjs
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
/**
* @file Sets up the environment for running Lite XL.
* @author takase1121
*/

import { ENV, FS, reloadEmscriptenEnv } from "./env.mjs";
import { mkdirp, uploadFiles, downloadFiles } from "./fs.mjs";
import { IDBSync } from "./idbsync.mjs";

const Module = {
// export the Module object explicitly to prevent minifiers from touching it
window.Module = {
preRun: [],
arguments: [],
};

Module.idbSync = new IDBSync();
Module.uploadFiles = uploadFiles;
Module.downloadFiles = downloadFiles;

let storageReady, runtimeReady, started;
const start = () => {
/**
* Starts Lite XL.
*/
function start() {
if (runtimeReady && storageReady && !started) {
started = true;
console.log("Starting Lite XL...");
Expand All @@ -20,19 +26,25 @@ const start = () => {

// set up autosave
Module.idbSync.start();
callMain(Module.arguments);
Module.callMain(Module.arguments);
}
};
}

// export functions accessed by C
Module.idbSync = new IDBSync();
Module.uploadFiles = uploadFiles;
Module.downloadFiles = downloadFiles;

Module.thisProgram = "/usr/bin/lite-xl";
Module.noInitialRun = true;
Module.preRun.push(() => {
reloadEmscriptenEnv();
ENV.LITE_SCALE = window.devicePixelRatio.toString();
ENV.LITE_XL_RUNTIME = "core.wasm_core";

// mount IDBFS in home folder
mkdirp("/home/web_user");
FS.mount(IDBFS, {}, "/home/web_user");
FS.mount(Module.IDBFS, {}, "/home/web_user");
FS.syncfs(true, (e) => {
if (e) {
console.error("syncfs(true) failed: ", e);
Expand All @@ -52,10 +64,28 @@ Module.onRuntimeInitialized = () => {
runtimeReady = true;
start();
};
Module.locateFile = (name, prefix) => prefix + (name.endsWith(".json") ? "js/" + name : name);

/**
* Writes a string as a series of keyboard events.
* @param {InputEvent|CompositionEvent} e
*/
function addInput(e) {
if (e.data) {
// emulate keypress events
for (const char of [...e.data]) {
window.dispatchEvent(
new KeyboardEvent("keypress", {
key: char,
isComposing: e.isComposing,
charCode: char.charCodeAt(char.length - 1),
})
);
}
}
}

// attach canvas to module
window.onload = () => {
window.addEventListener("load", () => {
const status = document.getElementById("status");
Module.canvas = document.getElementById("canvas");
Module.canvas.oncontextmenu = (e) => e.preventDefault();
Expand All @@ -66,25 +96,6 @@ window.onload = () => {
// hook up our text input
const textInput = document.getElementById("textinput");

/**
* Writes a string
* @param {InputEvent|CompositionEvent} e
*/
function addInput(e) {
if (e.data) {
// emulate keypress events
for (const char of [...e.data]) {
window.dispatchEvent(
new KeyboardEvent("keypress", {
key: char,
isComposing: e.isComposing,
charCode: char.charCodeAt(char.length - 1),
})
);
}
}
}

// ignore composition text, only get end result
textInput.addEventListener("compositionend", addInput);
textInput.addEventListener("input", (e) => {
Expand All @@ -98,6 +109,9 @@ window.onload = () => {
window.dispatchEvent(new KeyboardEvent("keyup", ev));
} else if (!e.isComposing) addInput(e);
});
};
});

window.Module = Module;
// require the bundle loader and lite-xl itself, the actual paths are
// handled by esbuild script itself.
require("lite-xl");
require("lite-xl-bundle");
4 changes: 2 additions & 2 deletions shell/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
"main": "index.html",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"format": "prettier -w **/*.js **/*.css **/*.html",
"build:bundle": "esbuild js/main.mjs css/main.css --bundle --sourcemap --minify --outdir=dist --target=es2017",
"format": "prettier -w **/*.mjs **/*.css **/*.html",
"build:bundle": "node esbuild.mjs",
"build:html": "cp -r html/. favicon.png dist",
"build": "npm run build:bundle && npm run build:html"
},
Expand Down

0 comments on commit 723c891

Please sign in to comment.