Web front-end toolkit based on TypeScript
npm install web-utility
index.html
<head>
<script src="https://polyfill.web-cell.dev/feature/Regenerator.js"></script>
<script src="https://polyfill.web-cell.dev/feature/TextEncoder.js"></script>
<script src="https://polyfill.web-cell.dev/feature/URL.js"></script>
<script src="https://polyfill.web-cell.dev/feature/ScrollBehavior.js"></script>
<script src="https://polyfill.web-cell.dev/feature/IntersectionObserver.js"></script>
</head>
tsconfig.json
{
"compilerOptions": {
"module": "ES2021",
"moduleResolution": "Node",
"downlevelIteration": true,
"lib": ["ES2021", "DOM", "DOM.Iterable"]
}
}
import { cache } from 'web-utility';
const getToken = cache(async (cleaner, code) => {
const { access_token, expires_in } = await (
await fetch(`https://example.com/access_token?code=${code}`)
).json();
setTimeout(cleaner, expires_in * 1000);
return access_token;
}, 'Get Token');
Promise.all([getToken('xxx'), getToken('yyy')]).then(([first, second]) =>
console.assert(
first === second,
'Getting token for many times should return the same before deadline'
)
);
import { parseDOM, walkDOM, stringifyDOM } from 'web-utility';
const [root] = parseDOM('<a>Hello, <b>Web</b>!</a>');
var count = 0;
for (const { nodeName, nodeType, dataset } of walkDOM(root)) {
console.log(nodeName);
if (nodeType === Node.ELEMENT_NODE) dataset.id = ++count;
}
console.log(stringifyDOM(root)); // '<a data-id="1">Hello, <b data-id="2">Web</b>!</a>'
import { delegate } from 'web-utility';
document.addEventListener(
'click',
delegate('a[href]', (event, link) => {
event.preventDefault();
console.log(link.href);
})
);
index.ts
import { createMessageServer } from 'web-utility';
createMessageServer({
preset: () => ({ test: 1 })
});
iframe.ts
import { createMessageClient } from 'web-utility';
const request = createMessageClient(globalThis.parent);
(async () => {
console.log(await request('preset')); // { test: 1 }
})();
import { serviceWorkerUpdate } from 'web-utility';
const { serviceWorker } = window.navigator;
serviceWorker
?.register('/sw.js')
.then(serviceWorkerUpdate)
.then(worker => {
if (window.confirm('New version of this Web App detected, update now?'))
// Trigger the message callback listened in the Service Worker
// generated by Workbox CLI
worker.postMessage({ type: 'SKIP_WAITING' });
});
serviceWorker?.addEventListener('controllerchange', () =>
window.location.reload()
);
source/i18n/en-US.ts
export enum en_US {
title = 'Title',
name = 'Name'
}
source/i18n/zh-CN.ts
export enum zh_CN {
title = '标题',
name = '名称'
}
source/index.tsx
import { render, createCell } from 'web-cell';
import { documentReady, bootI18n, textJoin } from 'web-utility';
import { en_US } from './i18n/en-US';
import { zh_CN } from './i18n/zh-CN';
console.log(
navigator.languages.includes('zh-CN'), // true
document.documentElement.lang // ''
);
const { language, words } = bootI18n({
'en-US': en_US,
'zh-CN': zh_CN
});
documentReady.then(() =>
render(
<h1>{textJoin(words.title, words.name, 'test', 'example')}</h1>
// <h1>标题名称 test example</h1>
);
);
If you are looking for a simple alternative of Mocha or Jest, just use these Test Utility methods with ts-node
:
npx ts-node index.spec.ts
index.spec.ts
import { describe, it } from 'web-utility';
class App {
name = 'test';
static create() {
return new App();
}
}
describe('My module', async () => {
const app = await it('should create an App object', async expect => {
const app = App.create();
expect(app instanceof App);
return app;
});
await it('should init an App name', expect => {
expect(app.name === 'test');
});
});