Skip to content
0

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 / WebViewQtWebUI
Runtime Dependencies on WindowsWebView2QtCore, QtGui, QtWidgetsA Web Browser
Runtime Dependencies on LinuxGTK3, WebKitGTKQtCore, QtGui, QtWidgetsA Web Browser
Runtime Dependencies on macOSCocoa, WebKitQtCore, QtGui, QtWidgetsA 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));
//=> 78

interact.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. 50

tinybase ---> 一个结构化数据和表格状态的响应式库

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脚手架

快速创建一个基于Reactmonorepo项目:

$ 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.txt

zustand ---> React状态管理库

相比于Redux:

相似仓库:pmndrs/jotai

Released under the MIT License.