2026.03.02本周知识要点

6 阅读4分钟

1.pnpm publish 发布包

  • 提交代码 git commit -m "xxx"
  • 更改包版本号:pnpm version xxx
    • 正式版本:pnpm version 0.4.2
    • beta版本: pnpm version 0.4.2-beta.1
  • build包产物: pnpm run build
  • 发布包: pnpm publish

2.pnpm link 链接到本地pnpm包测试

  • 包目录中将该包链接到全局供项目调用: pnpm link --global
  • 项目目录中链接到本地包 test-ui:
    • 将package.json文件中 dependecies字段中删除test-ui
    • 然后运行命令: pnpm link test-ui
    • 可以看到package.json文件中dependencies字段添加了包引用: "test-ui": "link:../../../Library/pnpm/global/5/node_modules/test-ui",
  • 每次修改了test-ui包后,运行命令pnpm run build,即可在项目中应用包test-ui最新的更改
  • 全局包链接管理
    • 移除全局的包链接:pnpm uninstall --global test-ui
    • 查看全局的包链接:pnpm list --global

3.html 自定义属性 dataset

关于属性名称限制

在 HTML:

属性名以 data- 开头。它只能包含字母、数字、破折号(-)、句号(.)、冒号(:)和下划线(_)。任意的 ASCII 大写字母(A 到 Z)都会转换为小写。

在 JavaScript:

自定义 data 属性的属性名与没有 data- 前缀的 HTML 属性相同,并且在移除单个破折号(-)后,大写之后的字母以获得属性的“驼峰”命名。

示例:

// html代码
// 自定义属性data-id, data-user,data-date-of-birth
<div id="user" data-id="1234567890" data-user="johndoe" data-date-of-birth>
  John Doe
</div>

// js代码
// 增删改自定义属性
const el = document.querySelector("#user");

// el.id === 'user'
// el.dataset.id === '1234567890'
// el.dataset.user === 'johndoe'
// el.dataset.dateOfBirth === ''

// set a data attribute
el.dataset.dateOfBirth = "1960-10-03";
// Result on JS: el.dataset.dateOfBirth === '1960-10-03'
// Result on HTML: <div id="user" data-id="1234567890" data-user="johndoe" data-date-of-birth="1960-10-03">John Doe</div>

delete el.dataset.dateOfBirth;
// Result on JS: el.dataset.dateOfBirth === undefined
// Result on HTML: <div id="user" data-id="1234567890" data-user="johndoe">John Doe</div>

if (!("someDataAttr" in el.dataset)) {
  el.dataset.someDataAttr = "mydata";
  // Result on JS: 'someDataAttr' in el.dataset === true
  // Result on HTML: <div id="user" data-id="1234567890" data-user="johndoe" data-some-data-attr="mydata">John Doe</div>
}

4.mutationObserver监控dom树变化

可以监听节点属性,子节点的新增删除,子节点属性等。

示例:

// 选择需要观察变动的节点
const targetNode = document.getElementById("some-id");

// 观察器的配置(需要观察什么变动)
const config = { attributes: true, childList: true, subtree: true };

// 当观察到变动时执行的回调函数
const callback = function (mutationsList, observer) {
  // Use traditional 'for loops' for IE 11
  for (let mutation of mutationsList) {
    if (mutation.type === "childList") {
      console.log("A child node has been added or removed.");
    } else if (mutation.type === "attributes") {
      console.log("The " + mutation.attributeName + " attribute was modified.");
    }
  }
};

// 创建一个观察器实例并传入回调函数
const observer = new MutationObserver(callback);

// 以上述配置开始观察目标节点
observer.observe(targetNode, config);

// 之后,可停止观察
observer.disconnect();

5.tts文字转语音

web端本地可以调用的文字转语音服务,优点是无开支,缺点是转出的语音效果呆板。

如果追求好的语音效果,可通过AI大模型转,需要消耗tokens(花钱)。

SpeechSynthesis

语音服务的控制接口;可以用于获取设备上关于可用的合成声音的信息,开始、暂停语音,以及除此之外的其他命令

// 获取语音合成控制器
const synth = window.speechSynthesis;

// 方式1:监听语音加载完成事件
synth.onvoiceschanged = () => {
 // 执行xxx
}
// 获取语音列表
const voices = synth.getVoices();

// 暂停
synth.pause();

// 恢复
synth.resume();

// 取消(清空队列)
synth.cancel();

// 播放语音
synth.speak(utterance);

// 实例属性,只读
synth.pending // 返回 true 如果语音播放队列中还有尚未开始播报的语句

synth.speaking // 返回 true 如果 SpeechSynthesis 对象当前处于暂停状态

synth.paused // 返回 true 如果当前有语句正在被播报(即使处于暂停状态,该属性也返回 true)

SpeechSynthesisUtterance

语音合成请求实例

// 创建语音合成请求实例
const utterance = new SpeechSynthesisUtterance();

// ----- 基础属性配置 -----

  utterance.text = text;           // 要合成的文本

  utterance.lang = 'zh-CN';        // 语言(中文简体)

  utterance.volume = 1;             // 音量:0-1

  utterance.rate = 1;               // 语速:0.1-10(1为正常)

  utterance.pitch = 1;              // 音高:0-2(1为正常)
  
  utterance.voice = selectedVoice || voices[0];  // 语音声音选择
  
  // ----- 事件监听 -----

  // 开始播放

  utterance.onstart = (event) => {
    console.log('▶️ 开始播放:', event.charIndex);
  };

  // 播放结束
  utterance.onend = (event) => {
    console.log('⏹️ 播放完成,总字符数:', event.charIndex);
  };

  // 发生错误
  utterance.onerror = (event) => {
    console.error('❌ 播放错误:', event.error);
  };

  // 暂停
  utterance.onpause = (event) => {
    console.log('⏸️ 已暂停');
  };

  // 恢复
  utterance.onresume = (event) => {
    console.log('▶️ 已恢复');
  };

下面是我试听后筛选出的较优秀的中文音色:

// 较好听的中文声 语音列表

export const defaultVoiceList = [

  // macOS: chrome, edge, 360, firefox, QQ浏览器,终端 默认使用语音

  { name: '婷婷', lang: 'zh-CN' },

  { name: '美嘉', lang: 'zh-TW' },

  // macOS: 部分电脑firefox浏览器 默认使用语音

  { name: 'Tingting', lang: 'zh-CN' },

  { name: 'Meijia', lang: 'zh-TW' },

  // windows: chrome, edge, 360, firefox, QQ, 华为,搜狗浏览器,终端 默认使用语音

  { name: 'Microsoft Yaoyao - Chinese (Simplified, PRC)', lang: 'zh-CN' },

  { name: 'Microsoft Kangkang - Chinese (Simplified, PRC)', lang: 'zh-CN' },

  { name: 'Microsoft Huihui - Chinese (Simplified, PRC)', lang: 'zh-CN' },

]