[TypeScript] Try esbuild
Masui Masanori
Posted on April 12, 2023
Intro
This time, I will try esbuild to bundle my client-side TypeScript files.
Because I have used Webpack to bundle files, and I will replace them.
Base project
Index.cshtml
<div>
<div id="message_div"></div>
</div>
<script src="/js/index.page.js"></script>
<script>Page.init("hello");</script>
index.page.ts
import { IndexView } from "./index.view";
let view: IndexView;
export function init(message: string) {
view = new IndexView();
view.updateMessage(message);
}
index.view.ts
export class IndexView {
private messageDiv: HTMLElement;
public constructor() {
this.messageDiv = document.getElementById("message_div") as HTMLElement;
}
public updateMessage(message: string): void {
this.messageDiv.textContent = message;
}
}
Bundling files
I can bundle the TypeScript files by command.
(On Windows, I have to change execution policy to run PowerShell scripts first)
./node_modules/.bin/esbuild ./ts/index.page.ts --bundle --outfile=./wwwroot/js/index.page.js
I also can execute it as a JavaScript file.
indexbuild.mjs
import * as esbuild from 'esbuild';
await esbuild.build({
entryPoints: ['ts/index.page.ts'],
bundle: true,
minify: false,
outfile: 'wwwroot/js/index.page.js',
});
I can execute this by Node.js.
node ./esbuilds/indexbuild.mjs
Calling functions from outside of TypeScript
After bundling the files, I will get an exception because "Page is not defined".
The bundled file like below.
index.page.js
"use strict";
(() => {
// ts/index.view.ts
var IndexView = class {
constructor() {
this.messageDiv = document.getElementById("message_div");
}
updateMessage(message) {
this.messageDiv.textContent = message;
}
};
// ts/index.page.ts
var view;
function init(message) {
view = new IndexView();
view.updateMessage(message);
}
})();
To call the function from outside of the TypeScript, I should declare them as global.
index.page.ts
...
(window as any).init = (message: string) => {
view = new IndexView();
view.updateMessage(message);
}
Index.cshtml
...
<script>init("hello");</script>
Add type declaration
To remove "as any", I will add type declaration files.
global.d.ts
declare global {
interface Window {
Page: IndexPageApi,
};
}
export interface IndexPageApi {
init: (message: string) => void,
}
tsconfig.json
{
"compilerOptions": {
/* Language and Environment */
"target": "es2016",
/* Modules */
"module": "commonjs",
"baseUrl": "./",
"paths": {
"*":["*", "./ts/types/*"]
},
/* Emit */
"noEmit": true,
/* Interop Constraints */
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
/* Type Checking */
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictBindCallApply": true,
"strictPropertyInitialization": true,
"noImplicitThis": true,
"useUnknownInCatchVariables": true,
"alwaysStrict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"exactOptionalPropertyTypes": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedIndexedAccess": true,
"noImplicitOverride": true,
"noPropertyAccessFromIndexSignature": true,
"allowUnusedLabels": true,
"allowUnreachableCode": true,
/* Completeness */
"skipLibCheck": true
}
}
index.page.ts
...
window.Page = {
init(message: string) {
view = new IndexView();
view.updateMessage(message);
}
}
Index.cshtml
...
<script>Page.init("hello");</script>
Resources
💖 💪 🙅 🚩
Masui Masanori
Posted on April 12, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
undefined Practical Implementation of Secure Payment and Password Protection in HarmonyOS Next E-commerce Applications
November 30, 2024
undefined Practical Construction of a Secure Authentication System for Enterprise-Level Applications in HarmonyOS Next
November 30, 2024