Packages
Gather some npm packages
webui ---> 一个跨平台的桌面应用的打包程序
使用任何 Web 浏览器或 WebView 作为 GUI,在后端使用支持的任意语言,在前端使用现代 Web 技术,构建一个应用
最简单的例子如下,我们可以通过 webui 支持的后端编程语言,比如 deno 快速启动一个 Web 应用
import { WebUI } from "https://deno.land/x/webui/mod.ts";
const win = new WebUI();
win.show('<html><script src="webui.js"></script> Hello World from Deno! </html>');
await WebUI.wait();竞品比较:
| Tauri / WebView | Qt | WebUI | |
|---|---|---|---|
| Runtime Dependencies on Windows | WebView2 | QtCore, QtGui, QtWidgets | A Web Browser |
| Runtime Dependencies on Linux | GTK3, WebKitGTK | QtCore, QtGui, QtWidgets | A Web Browser |
| Runtime Dependencies on macOS | Cocoa, WebKit | QtCore, QtGui, QtWidgets | A Web Browser |
pinyin ---> 获得汉字的拼音
import pinyin from "pinyin";
console.log(pinyin("中心")); // [ [ 'zhōng' ], [ 'xīn' ] ]
console.log(pinyin("中心", {
heteronym: true, // 启用多音字模式
})); // [ [ 'zhōng', 'zhòng' ], [ 'xīn' ] ]
console.log(pinyin("中心", {
heteronym: true, // 启用多音字模式
segment: true, // 启用分词,以解决多音字问题。默认不开启,使用 true 开启使用 nodejieba 分词库。
}));Pro版:zh-lx/pinyin-pro
lodash-decorators ---> lodash 封装的装饰器
import { Debounce, Memoize } from 'lodash-decorators';
class Person {
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
@Debounce(100)
save(date) {
return this.httpService.post(data);
}
@Memoize(item => item.id)
doSomeHeavyProcessing(arg1, arg2) {}
}unifont ---> 统一字体加载
用于从字体 CDN 和 providers 访问数据的框架无关工具。默认将资源缓存在内存中,也可以使用 unjs/unstorage 缓存到别的地方
import { createUnifont, providers } from 'unifont'
const unifont = await createUnifont([
providers.google(),
])
const fonts = await unifont.resolveFont('Poppins')
console.log(fonts)fontsource ---> 字体资源
还支持 material icon
import "@fontsource/open-sans"; // Defaults to weight 400 with normal variant.
import "@fontsource/open-sans/500.css"; // Weight 500.
import "@fontsource/open-sans/900-italic.css"; // Italic variant.
import "@fontsource/material-icons-sharp";
import "@fontsource/material-icons-two-tone";i18next ---> 语言国际化
国际化库,还可以配合识别浏览器语言的插件使用: i18next/i18next-browser-languageDetector
i18next.init({
lng: 'en',
debug: true,
resources: {
en: {
translation: {
"key": "hello world"
}
}
}
});
document.getElementById('output').innerHTML = i18next.t('key');
i18next
.changeLanguage('de')
.then((t) => {
t('key'); // -> same as i18next.t
});gzip-size ---> 计算gzip压缩后的大小
经常被同时提及的还有另一个算法 -- brotli,brotle 对 Web 资源有着非常高的压缩率
import {gzipSizeSync} from 'gzip-size';
const text = 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.';
console.log(text.length);
//=> 191
console.log(gzipSizeSync(text));
//=> 78interact.js ---> 拖放、多点触控、惯性、捕捉功能
var angle = 0
interact('#rotate-area').gesturable({
listeners: {
move (event) {
var arrow = document.getElementById('arrow')
angle += event.da
arrow.style.transform = 'rotate(' + angle + 'deg)'
document.getElementById('angle-info').textContent =
angle.toFixed(2) + '\u00b0'
}
}
})immutable.js ---> 高效数据结构
用于 Javascript 的不可变持久数据集合,可提高效率和简单性
包括 List、Stack、Map、OrderedMap、Set、OrderedSet 等
const { Map } = require('immutable');
const map1 = Map({ a: 1, b: 2, c: 3 });
const map2 = map1.set('b', 50);
map1.get('b') + ' vs. ' + map2.get('b'); // 2 vs. 50tinybase ---> 一个结构化数据和表格状态的响应式库
const store = createStore()
.setTable('pets', {fido: {species: 'dog'}})
.setCell('pets', 'fido', 'color', 'brown');
console.log(store.getRow('pets', 'fido'));
// -> {species: 'dog', color: 'brown'}
const App1 = () => {
const color = useCell('pets', 'fido', 'color', store);
return <>Color: {color}</>;
};
const app = document.createElement('div');
ReactDOM.render(<App1 />, app);
console.log(app.innerHTML);
// -> 'Color: brown'
store.setCell('pets', 'fido', 'color', 'walnut');
console.log(app.innerHTML);
// -> 'Color: walnut'openapi-typescript ---> 将Swagger OpenAPI规范转为ts类型
$ npx openapi-typescript https://petstore.swagger.io/v2/swagger.json --output petstore.ts
craco ---> 增强 create-react-app
基于已有的create-react-app项目使用,让配置更加灵活,更加方便。
$ npm i @craco/craco"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
}

defu ---> 深度合并对象
和deepmerge不同的是会保留原对象的属性,而不是覆盖它们。
import { defu } from 'defu'
console.log(defu({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } }))
// => { a: { b: 2, c: 3 } }deepmerge ---> 深度合并对象
Object.assign只能合并一级对象,而deepmerge可以合并多级对象。
const x = {
foo: { bar: 3 },
array: [{ does: 'work', too: [ 1, 2, 3 ]}]
}
const y = {
foo: { baz: 4 },
quux: 5,
array: [{ does: 'work', too: [ 4, 5, 6 ] }, { really: 'yes' }]
}
const output = {
foo: { bar: 3, baz: 4},
array: [{ does: 'work',too: [ 1, 2, 3 ] }, { does: 'work', too: [ 4, 5, 6 ] }, { really: 'yes' }],
quux: 5
}
merge(x, y) // => output
Object.assign(x, y) // =>
/*
{
foo: { baz: 4 },
array: [{ does: 'work', too: [4, 5, 6]}, { really: 'yes' }],
quux: 5
}
*/zod ---> 类型校验和提示
像正则表达式的作用,但写起来要轻松许多,校验支持也更加丰富,而且更简单。
import { z } from 'zod'
const mySchema = z.string({
invalid_type_error: 'name必须是字符串',
})
mySchema.parse('123') // '123'
mySchema.parse(123) // throw Error
mySchema.safeParse('123') // { success: true, data: '123' }
mySchema.safeParse(123); // => { success: false; error: ZodError }相似项目:chaijs/chai
turborepo ---> monorepo脚手架
快速创建一个基于React的monorepo项目:
$ npx create-turbo@latest
pako ---> zlib 算法数据压缩
非常快,最终将数据压缩为 Uint8Array 格式
import pako from 'pako';
const test = { my: 'super', puper: [456, 567], awesome: 'pako' };
const compressed = pako.deflate(JSON.stringify(test));
console.log(compressed)
//=> Uint8Array <78, 9C, AB, 56, CA, AD, 54, B2, 52, 2A, 2E, 2D, 48, 2D, 52, D2, 51, 2A, 00, D3, 56, D1, 26, A6, 66, 3A, …>
const restored = JSON.parse(pako.inflate(compressed, { to: 'string' }));lz-string ---> 字符串压缩
压缩后的储存格式仍然是字符串,主要是用于解决例如localStorage等场景下的储存空间不足问题,通过压缩算法进行压缩后再储存。
主要步骤:
- 识别重复字符串:遍历待压缩的数据,寻找重复的字符串。当发现一个重复字符串时,算法会记录该字符串的位置和长度,并将其替换为一个指向先前出现的相同字符串的指针
- 更新字典:在压缩过程中,算法会不断更新一个字典,用于存储先前出现过的字符串及其位置信息。这样,当算法发现一个新的重复字符串时,它可以快速查找并替换为指针
- 输出压缩数据:最终,算法会输出一个包含指针和原始数据的组合,其中指针表示重复字符串的位置和长度,而原始数据表示不重复的部分
import LZString from 'lz-string';
var string = "This is my compression test.";
console.log(string.length); //=>28
var compressed = LZString.compress(string);
console.log(compressed.length); //=> 16
string = LZString.decompress(compressed);
console.log("Sample is: " + string);支持命令行用法:
$ npm install -g lz-string
$ lz-string index.ts > test.txtzustand ---> React状态管理库
相比于Redux:
- 简单
- 使钩子成为消费状态的主要手段
- 不会将您的应用程序包装在上下文提供程序中
- 可以暂时通知组件(不导致渲染)
相似仓库:pmndrs/jotai