分类: 前端

  • VSCode + GitHub Copilot 实战使用

    过去我习惯通过 GPT、豆包等网页工具获取 AI 协助,但自从改用 VSCode 搭配 GitHub Copilot 后,切身感受到了 AI 辅助开发的强大。它不仅能省去大量重复编码的工作,更能在遇到技术卡点时快速响应,甚至独立追踪分析并解决问题。

    一、环境搭建与基础配置

    1.1 插件安装流程

    1. 核心插件安装:在 VSCode 扩展市场搜索 GitHub Copilot 和 GitHub Copilot Chat,完成安装并重启编辑器;二者需搭配使用,前者负责内联代码补全,后者提供交互式对话调试。

    2. 账号授权:登录已开通 Copilot 订阅的 GitHub 账号,完成编辑器与 GitHub 的权限绑定,确保网络环境可正常访问 GitHub 服务。

    3. 基础启用检查:右下角出现 Copilot 图标即代表激活成功,可通过图标快速开启/关闭补全、查看用量、进入设置面板。

    1.2 关键配置优化

    为兼顾效率与代码质量,针对性调整以下设置(文件 → 首选项 → 设置,搜索 Copilot 关键词):

    • 代码补全延迟:调低响应延迟,避免频繁手动触发补全,提升流畅度

    • 启用记忆功能:开启 github.copilot.chat.copilotMemory.enabled,让 Copilot 记住项目编码规范、命名风格,减少重复调教

    • 过滤无关建议:关闭非当前项目语言的冗余补全,降低干扰

    • 快捷键自定义:绑定常用快捷键(接受建议、切换下一条、手动触发补全),提升操作速度

    二、核心功能实战用法

    2.1 内联代码补全(高频场景)

    这是 Copilot 最基础也最实用的能力,贴合手写代码节奏,无需打断思路:

    • 单行/多行补全:输入函数名、注释或关键逻辑,Copilot 自动预判后续代码,按 Tab 接受建议,Alt/Option + ]/[ 切换备选方案。

    • 批量代码生成:编写清晰的单行注释(如 // 封装 axios 请求拦截器,统一处理 token 和报错),Copilot 可直接生成完整可运行的函数块。

    • 语法适配:支持主流编程语言(JavaScript/TypeScript、Python、Java、Go等),自动适配项目的代码风格、缩进规则、变量命名。

    2.2 Copilot Chat 交互式开发(进阶效率)

    通过侧边栏聊天窗口,实现代码解读、调试、重构一站式操作,核心用法:

    • 代码解释:选中晦涩代码,右键选择「Ask Copilot」,快速理清逻辑、梳理参数含义,适合接手旧项目。

    • BUG 定位与修复:粘贴报错信息 + 异常代码片段,Copilot 自动分析报错原因,给出修复方案并标注修改点。

    • 代码重构:指令式提问(如「将这段回调函数改写为 Promise/async await」「优化这段代码的可读性,添加注释并拆分函数」),批量优化冗余代码。

    • 文档与注释生成:一键生成 JSDoc、函数注释、接口说明,规范代码文档,减少手动编写工作量。

    2.3 高阶场景拓展

    • 测试用例生成:针对业务函数,自动生成单元测试代码,覆盖正常、异常、边界场景,提升测试效率。

    • Git 提交信息/PR 描述:基于代码变更,自动生成规范的 commit 信息,省去文案梳理时间。

    • 终端命令辅助:直接询问常用命令(如 Docker 部署、npm 脚本、Linux 操作),快速获取可复制执行的指令。

    三、使用心得与效率提升技巧

    核心原则:清晰的指令 = 高质量的结果

    • 精准描述需求:避免模糊提问,用「做什么+语言+规范」的句式提问,例如「用 TypeScript 编写一个防抖函数,支持立即执行和取消功能,符合 ES6+ 规范」。

    • 上下文投喂:涉及项目全局逻辑时,先粘贴依赖代码或配置项,让 Copilot 基于项目上下文生成适配代码,避免通用化模板。

    • 分步调教:复杂功能分步骤生成,先搭框架,再补逻辑,最后优化细节,降低出错率。

    • 代码必校验:Copilot 生成代码需逐行审核,重点校验逻辑漏洞、边界情况、依赖引入,杜绝直接照搬上线。

    • 快捷键固化:养成快捷键操作习惯,减少鼠标点击,最大化提升编码速度。

    四、常见问题与避坑总结

    4.1 常见问题排查

    • 补全不生效/无响应:检查 GitHub 登录状态、网络连通性、插件是否启用,重启 VSCode 或重新授权即可解决。

    • 建议质量差/不符合规范:补充项目上下文、细化指令,开启记忆功能让 Copilot 适配项目风格,避免过度依赖通用建议。

    • 卡顿/延迟高:关闭无关扩展,调低补全延迟,限制 Copilot 同时分析的文件数量。

    4.2 避坑要点

    • 严禁直接使用未审核的生成代码上线,尤其是涉及数据处理、权限校验、安全逻辑的代码。

    • 注意代码版权与合规性,商业项目需甄别生成代码的来源,避免侵权风险。

    • 不要过度依赖 Copilot,核心业务逻辑需自主设计,AI 仅作为效率工具辅助编码。

    五、总结与后续规划

    VSCode + Copilot 组合极大缩短了重复代码编写时间,降低了技术卡点的解决成本,日均编码效率提升约 40%,尤其适合快速迭代、原型开发、代码规范化场景。

    后续将进一步探索 Copilot 智能体模式、MCP 工具集成、团队共享规范等高阶能力,把 AI 辅助融入全开发流程,同时强化代码审核机制,兼顾效率与质量。

  • Vue 3.0 核心特性技术日志

    作为从 Vue 1.0 一路使用过来的开发者,Vue 3.0 并非简单的版本迭代,而是在核心架构、性能、开发体验上的全面升级,同时兼容了 2.x 的大部分核心思想,既保留了我们熟悉的开发范式,又解决了 2.x 长期存在的痛点。以下从核心架构、语法特性、性能优化、工程化等维度,结合 2.x 对比梳理关键变化。

    一、核心架构:从 Options API 到 Composition API

    1. Vue 2.x:Options API 为主

    Vue 2.x 采用「选项式 API」,将代码按 datamethodscomputedwatch生命周期钩子 等选项划分,优点是上手简单,但存在明显痛点:

    • 逻辑碎片化:一个业务逻辑(如「用户登录状态管理」)的代码会分散在 data(状态)、methods(方法)、watch(监听)、mounted(初始化)等多个选项中,组件越大,逻辑越难追踪;
    • 代码复用受限:mixins 是主要复用方式,但存在命名冲突、来源不清晰、逻辑依赖隐晦的问题;
    • TypeScript 支持薄弱:Options API 天生不契合 TS 的类型推导,需要额外的类型声明,开发体验差。

    2. Vue 3.0:Composition API(组合式 API)+ 保留 Options API

    Vue 3.0 推出「组合式 API」,核心是 setup 函数(组件的入口),允许按业务逻辑维度组织代码,而非按选项类型:

    
    <template>
    
    <div>{{ count }}</div>
      <button @click="increment">+1</button>
    </template>
    
    <script setup>
    // Vue 3.0 组合式 API(<script setup> 语法糖)
    import { ref, computed, onMounted } from 'vue'
    
    // 状态定义(替代 2.x 的 data)
    const count = ref(0)
    
    // 方法定义(替代 2.x 的 methods)
    const increment = () => {
      count.value++
    }
    
    // 计算属性(替代 2.x 的 computed)
    const doubleCount = computed(() => count.value * 2)
    
    // 生命周期(替代 2.x 的 mounted)
    onMounted(() => {
      console.log('组件挂载完成,count 初始值:', count.value)
    })
    </script>

    核心优势

    • 逻辑聚合:一个业务逻辑的所有代码(状态、方法、监听、生命周期)可集中写在一处,组件结构更清晰;
    • 灵活复用:通过「组合函数(Composables)」复用逻辑(如 useUser()useRequest()),替代 mixins,解决命名冲突和依赖问题;
    • 完美支持 TS:基于函数式的写法天然契合 TS 类型推导,无需额外声明即可获得完整的类型提示。

    兼容说明:Vue 3.0 完全保留 Options API,2.x 的代码可直接迁移(仅需少量适配),支持「渐进式升级」—— 既可以在老组件中继续用 Options API,也可以在新组件中用 Composition API。

    二、响应式系统:从 Object.defineProperty 到 Proxy

    1. Vue 2.x:响应式的痛点

    Vue 2.x 基于 Object.defineProperty 实现响应式,存在天然限制:

    • 无法监听数组下标修改(如 arr[0] = 1)和数组长度修改(如 arr.length = 0),需通过 Vue.set/this.$set 或数组变异方法(push/splice)触发更新;
    • 无法监听对象新增属性/删除属性(如 this.obj.newKey = 1),同样需要 Vue.set/this.$delete
    • 响应式初始化时需要递归遍历对象,性能随对象层级加深下降。

    2. Vue 3.0:Proxy 重构响应式

    Vue 3.0 改用 ES6 的 Proxy 实现响应式,彻底解决上述问题:

    • 原生支持监听数组下标/长度修改、对象新增/删除属性,无需 $set/$delete
    • 非侵入式:无需修改原对象,而是代理对象,初始化时无需递归遍历(懒代理,访问属性时才递归),性能大幅提升;
    • 支持 RefReactive 两种响应式方式:
      • ref:用于基础类型(字符串、数字等),通过 .value 访问(模板中自动解包,无需 .value);
      • reactive:用于对象/数组,返回代理对象,直接访问属性即可。

    示例对比

    // Vue 2.x
    export default {
      data() {
        return {
          arr: [1, 2, 3],
          obj: { name: 'Vue2' }
        }
      },
      methods: {
        updateData() {
          // 无效:无法监听数组下标修改
          this.arr[0] = 100
          // 有效:需用 $set
          this.$set(this.arr, 0, 100)
    
          // 无效:无法监听对象新增属性
          this.obj.age = 3
          // 有效:需用 $set
          this.$set(this.obj, 'age', 3)
        }
      }
    }
    
    // Vue 3.0(Composition API)
    import { ref, reactive } from 'vue'
    const arr = ref([1, 2, 3])
    const obj = reactive({ name: 'Vue3' })
    
    const updateData = () => {
      // 有效:原生支持数组下标修改
      arr.value[0] = 100
      // 有效:原生支持对象新增属性
      obj.age = 3
    }

    三、性能优化:体积、渲染、编译全方位提升

    1. 体积更小

    • Vue 2.x 运行时体积约 22KB(gzip);
    • Vue 3.0 通过「树形摇树(Tree-shaking)」重构核心代码,仅引入使用的功能(如仅用响应式、不用编译器),最小体积约 10KB(gzip),体积减少 50% 以上。

    2. 渲染更快

    • 虚拟 DOM 重构:Vue 3.0 优化了虚拟 DOM 的生成和对比算法,引入「静态标记」—— 对模板中不变的节点(如纯文本、静态标签)做标记,对比时直接跳过,渲染性能提升约 55%;
    • 编译优化:Vue 3.0 的模板编译器会提前分析模板结构,生成更高效的渲染函数,更新性能提升约 133%。

    3. 内存占用更低

    Vue 3.0 优化了组件实例的内存占用,同场景下内存使用减少约 50%。

    四、其他关键变化(对比 Vue 2.x)

    1. 生命周期钩子

    Vue 3.0 保留了 2.x 的生命周期概念,但命名略有调整(Composition API 中),且新增 setup 替代 beforeCreatecreated Vue 2.x Vue 3.0(Composition API) 说明
    beforeCreate setup(开始) setup 执行时,组件实例未创建
    created setup(结束) setup 执行完,组件实例已创建
    beforeMount onBeforeMount 挂载前
    mounted onMounted 挂载后
    beforeUpdate onBeforeUpdate 更新前
    updated onUpdated 更新后
    beforeDestroy onBeforeUnmount 卸载前(命名更语义化)
    destroyed onUnmounted 卸载后(命名更语义化)

    2. 模板语法

    • 支持多根节点:Vue 2.x 模板要求唯一根节点,3.0 支持多根节点(Fragment),无需包裹 `
      `;
    • 更灵活的 v-model:Vue 2.x 中 v-model 本质是 value + input 事件,3.0 支持自定义绑定属性和事件,且支持多个 v-model:

      <!-- Vue 2.x:仅能绑定一个 v-model,且固定 value/input -->
      <Child v-model="name" />
      
      <!-- Vue 3.0:支持多个 v-model,自定义属性和事件 -->
      <Child v-model:name="name" v-model:age="age" />
    • 移除 filter:Vue 3.0 废弃了 2.x 的 filter 过滤器,推荐用计算属性或方法替代(减少 API 复杂度)。

    3. 全局 API 调整

    Vue 2.x 的全局 API(如 Vue.componentVue.directive)会污染全局环境,3.0 改为「实例化 API」:

    // Vue 2.x
    import Vue from 'vue'
    Vue.component('MyComponent', { /* ... */ })
    Vue.directive('my-dir', { /* ... */ })
    new Vue({ el: '#app' })
    
    // Vue 3.0
    import { createApp } from 'vue'
    const app = createApp({ /* 根组件 */ })
    app.component('MyComponent', { /* ... */ })
    app.directive('my-dir', { /* ... */ })
    app.mount('#app')

    优势:多个 Vue 实例可独立配置,避免全局配置冲突(如多应用嵌入场景)。

    4. 废弃/不推荐的特性

    • 废弃 Vue.prototype:改用 app.config.globalProperties 挂载全局属性;
    • 废弃 $on/$off/$once:移除实例事件总线,推荐用第三方库(如 mitt)替代;
    • 不推荐 filters:用计算属性/方法替代;
    • 不推荐 mixins:用 Composition API 的组合函数替代。

    五、迁移建议(从 Vue 2.x 到 3.0)

    1. 渐进式迁移:先保留 Options API,逐步在新功能中使用 Composition API,降低迁移成本;
    2. 工具适配:升级脚手架到 Vite(Vue 3.0 推荐)或 Vue CLI 5+,安装 @vue/compat 兼容包,可临时兼容 2.x 代码;
    3. 重点检查
      • 替换 Vue.set/$setVue.delete/$delete(3.0 无需);
      • 调整生命周期钩子(如 beforeDestroyonBeforeUnmount);
      • 替换 filter 为计算属性/方法;
    4. TypeScript 接入:新组件建议用 <script setup lang="ts">,充分利用 3.0 的 TS 优势。

    总结

    1. 核心架构:Vue 3.0 的 Composition API 解决了 2.x Options API 逻辑碎片化、复用难、TS 支持差的问题,同时兼容 2.x 写法,支持渐进式升级;
    2. 响应式系统:基于 Proxy 重构,彻底解决 2.x Object.defineProperty 无法监听数组/对象新增属性的痛点,性能和易用性大幅提升;
    3. 性能与体验:体积更小、渲染更快,模板语法更灵活(多根节点、多 v-model),全局 API 更合理,是对 Vue 2.x 核心痛点的全面优化,同时保留了 Vue 一贯的「易用、渐进式」设计理念。
  • 【CSS】动画性能优化

    60fps 与设备刷新率

    目前大多数设备的屏幕刷新率为60fps(Frame per Second),即每秒60帧。因此,如果在页面中有一个动画或渐变效果,或者用户正在滚动页面,那么浏览器渲染动画或页面的每一帧的速率也需要跟设备屏幕的刷新率保持一致,即每一帧要在16毫秒(1S/60 = 16.66ms)之内完成。如果无法完成,由于帧率的下降会导致内容在屏幕上抖动。此现象通常称为卡顿,会对用户体验产生负面影响。

    浏览器渲染

    在讲性能之前,我们需要先对浏览器渲染页面有一个基础的理解。

    css 图层

    浏览器在渲染一个页面时,会将页面分为很多个图层,图层有大有小,每个图层上有一个或多个节点。需要注意的是,如果图层中某个元素需要重绘,那么整个图层都需要重绘(关于重绘下面会讲到)。

    渲染过程

    简单来说,浏览器的渲染过程其实就是将页面转换成像素显示到屏幕上,大致有如下几个步骤: 渲染过程流程图

    • JavaScript操作: 一般来说,我们会使用 JavaScript 来实现一些交互操作。比如用往页面里添加一些元素,切换显示隐藏等。
    • style 样式计算: 该过程根据 css 选择器,获取每个元素匹配的 css 样式并计算其最终应用样式。
    • Layout 布局:该过程计算元素要占据的空间大小及其在屏幕的位置。网页的布局模式意味着一个元素可能影响其他元素,例如 <body> 元素的宽度一般会影响其子元素的宽度以及树中各处的节点,因此对于浏览器来说,布局是经常发生的。
    • Paint 绘制:本质上就是填充像素的过程。包括绘制文字、颜色、图像、边框和阴影等。也就是绘制元素所有的可视效果。
    • Composite 渲染层合并:在每个层上完成绘制过程之后,浏览器会将所有层按照合理的顺序合并成一个图层,然后显示在屏幕上如果我们需要提高动画的性能,需要做的就是减少浏览器在动画运行时所需要做的工作。当 css 在进行动画时,其不同属性值引起的改变,重新渲染可能会有三种执行路径:
      1. layout -> paint -> composite
      2. paint -> composite
      3. composite 很明显,最短路径的 C 动画性能是最高的,所以我们在使用动画的时候就得考虑使用什么属性,以尽量减少执行路径。

    动画属性

    css 的属性大致分为三类:布局类(layout),绘制类(paint),合成类(composite)。

    重排(reflow)

    由元素的布局类属性改变所触发的行为过程,我们称为 reflow,也叫做 relayout(重新布局)。当某个节点 reflow 时会重新计算节点的尺寸和位置,还可能会引起其它节点的 reflow。

    该系列属性的改变,会执行路径 A 进行重新渲染,所以性能是最差的。(这充分说明,重排会引起重绘)

    触发重排的属性

    • 盒子模型相关属性会触发重布局:

      • width
      • height
      • padding
      • margin
      • display
      • border-width
      • border
      • min-height
    • 定位属性及浮动也会触发重布局:

      • top
      • bottom
      • left
      • right
      • position
      • float
      • clear
    • 改变节点内部文字结构也会触发重布局:

      • text-align
      • overflow-y
      • font-weight
      • overflow
      • font-family
      • line-height
      • vertival-align
      • white-space
      • font-size

    重绘(repaint)

    由绘制类属性改变触发节点重新绘制其可视效果的过程,我们称为 repaint。 该系列属性的改变,会执行路径 B,所以性能一般。

    修改时只触发重绘的属性有:

    • color
    • border-style
    • border-radius
    • visibility
    • text-decoration
    • background
    • background-image
    • background-position
    • background-repeat
    • background-size
    • outline-color
    • outline
    • outline-style
    • outline-width
    • box-shadow

    上面的属性由于不会修改节点的大小和位置,因此不会触发重排,其只是改变了节点内部的渲染效果,所以只会进行重绘以下的步骤。

    composite

    目前只有两个属性属于 composite 类:

    • transform
    • opactiy

    优化技巧

    减少动画元素

    减少动画元素是动画性能优化中首先需要完成的。通过审查页面动画 DOM 元素结构,去除不必要的动画元素,减少元素的数量,相应地会减少布页面局和绘制的时间。

    尽量使用 fixed、absolute 定位

    对于动画元素,尽量使用用 fixed、absolute 定位方式,避免影响到其他节点重排。

    尽量只改变 transform 和 opacity

    能用 transform、opacity 优先使用,其属性的改变不会发生重排和重绘。如位移操作的,可以使用translate 来实现,渐隐渐现效果可以使用 opacity 属性来实现。

    恰当开启硬件加速效果

    对动画元素应用

    transform: translate3d(0, 0, 0);
    /* transform: translateZ(0); */
    will-change: transform;

    等来开启硬件加速。通常开启硬件加速可以让动画变得更加流畅。但这里需注意,在不需要的时候需去掉避免过多的内存消耗。

  • 【React】学习笔记-基础篇

    虚拟 DOM 的原理是什么?为什么比直接操作 DOM 高效?

    • 虚拟 DOM 是一个轻量的 JS 对象,用来描述真实 DOM 的层次和属性。
    • 通过 Diff 算法最小化 DOM 操作,减少重绘和回流。

    JSX 是什么?和普通 JavaScript 的区别?

    • JSX 是语法糖,最终会被 Babel 编译为 React.createElement() 调用。

    数据流

    • 单向数据流,自上而下传递。
    • 父组件通过 props 把数据传递给子组件;
    • 子组件可以通过回调函数通知父组件。

    Props

    • PropTypes 定义类型
    • defaultProps 定义默认值
    • this.props.children 表示组件的所有子节点
    • 不要把 props 复制到 state 中,要尽可能把 props 当作数据源(避免反模式)

    高阶组件(HOC)

    • 用于复用组件逻辑。本质上是一个函数,通过接收一个组件并返回一个新组件

    PureComponent 和 React.memo

    • PureComponent 会对 props 和 state 进行浅比较
    • memo 只对 props 进行浅比较

    `

    ` 和 “ (空标签)的区别 – 只有 ` ` 可以带 key 属性,这在列表渲染时非常重要 #### 类组件和函数组件的区别? – 语法与结构 “`js class MyComponent extends React.Component { render() { return
    Hello, {this.props.name}
    ; } } function MyComponent(props) { return
    Hello, {props.name}
    ; } “` – 状态管理 – 类组件通过 `this.state` 定义状态,`this.setState()` 更新状态 – 函数组件使用 Hooks 的 `useState` 管理状态 – 生命周期与副作用 – 类组件通过生命周期处理副作用 – 函数组件通过 `useEffect` 替代生命周期 – `this` 的绑定问题 – 类组件通过手动绑定事件函数的 `this` “`js class Button extends React.Component { handleClick() { console.log(this); } // this 可能为 undefined render() { return ; } } “` – 函数组件没有 this,直接访问 props 和状态 “`js function Button() { const handleClick = () => console.log(“No this!”); return ; } “` – 性能优化 – 类组件使用 `shouldComponentUpdate` 或 `PureComponent` 避免不必要的渲染 – 函数组件使用 `React.memo` 进行浅比较 ### 【状态管理】 #### React 中的状态提升(Lifting State Up)是什么? – 把状态提升到父组件进行管理,子组件通过 props 读取数据。 #### Context API 的作用?如何避免不必要的渲染? – Context(上下文) 是 React 提供的跨层级组件数据传递方案,用于解决多层组件嵌套时(逐层传递 props)的问题。 – 核心作用 – 跨组件共享数据(如主题、用户信息、全局配置等) – 避免中间组件透传 props(减少冗余代码) #### MobX / Redux – 全局状态管理,把状态抽离到组件之外。 **Redux** * 工作流程: 1. 定义 Store:集中管理全局状态(createStore)。 2. 派发 Action:组件通过 dispatch(action) 发出状态修改请求(action 是一个描述“发生了什么”的普通对象)。 3. 执行 Reducer:根据 action.type,纯函数 reducer 计算新状态(不可变更新)。 4. 更新视图:Store 通知订阅者(如 React 组件),触发重新渲染。 * 核心概念: – 单向数据流:View → Action → Reducer → Store → View – 三大原则:单一数据源、状态只读、纯函数修改。 * 总结: – 组件 dispatch → Reducer 处理 → Store 更新 → 视图同步 **MobX** * 工作流程: 1. 定义 Observable State:用 @observable 或 makeObservable 标记可变状态。 2. 修改 State:在 @action 函数中更新状态(直接赋值/修改对象属性)。 3. 自动追踪依赖:组件用 observer 包裹,自动订阅其依赖的状态。 4. 触发更新:状态变化时,依赖它的组件自动重渲染。 * 核心概念: – 响应式编程:像 Excel 公式一样自动更新(无需手动 dispatch/reducer)。 – 直接修改状态(但通过 action 规范变更)。 * 总结: – 响应式状态,自动追踪依赖,修改即更新 ### 【性能优化】 #### React 的渲染机制是怎样的?如何避免不必要的渲染? – 使用 React.memo、useMemo、useCallback、避免内联对象/函数。 #### React 的 key 属性有什么作用? – 帮助 React 识别元素变化,优化列表渲染。 #### 实现代码分割(Code Splitting) – 动态 import() 语法 – 动态 import() 是 ES2020 引入的语法,返回一个 Promise: “`js // 普通模块中使用 import(“./math”).then(math => { console.log(math.add(16, 26)); }); // React 组件中使用 import(“./OtherComponent”).then(OtherComponent => { // 使用加载的组件 }); “` – React.lazy + Suspense – React.lazy 和 Suspense 来实现组件的懒加载: “`js import React, { Suspense } from ‘react’; const OtherComponent = React.lazy(() => import(‘./OtherComponent’)); function MyComponent() { return (
    Loading…
    }> ); } “`
  • WEB前端-JS篇

    小数精度处理

    • 使用 toFixed 取后几位小数
    • 把小数转为整数再进行运算
    • 使用精度运算库,如:big.js

    for…infor…of 的区别

    • for-in 历遍对象,通常获取 key(类似 Object.keys)
    • for-of 历遍可迭代对象,如 ArrayMapSet

    任务队列(Task Queue)

    • 先执行同步再执行异步
    • 核心作用:处理异步代码的调度和执行
    • 宏任务:setTimeoutsetIntervalI/O
    • 微任务:Promise 回调(.then / .catch/ .finally)、MutationObserver 回调等
    • 微任务优先级高于宏任务
    • 调用 fetch 会同步执行并立即返回一个 promise

    call | apply | bind

    均用于改变函数内部 this 的指向

    const obj = { name: "Alice" };
    
    function greet() {
      console.log(`Hello, ${this.name}!`);
    }
    
    greet.call(obj);      // Hello, Alice!
    greet.apply(obj);     // Hello, Alice!
    const boundGreet = greet.bind(obj);
    boundGreet();         // Hello, Alice!

    ES 新特性:

    变量声明

    letconst

    箭头函数

    简化函数语法,自动绑定 this

    模板字符串

    `Hello ${name}`

    解构赋值

    const { age, name } = user;
    const [first, second] = [1, 2];

    默认参数

    扩展运算符

    const arr1 = [1, 2];
    const arr2 = [...arr1, 3]; // [1, 2, 3]; // 合并数组
    const objCopy = { ...originalObj }; // 合并对象

    Promise 和 异步处理

    Promise.all – 等待所有 Promise 对象都执行完成 Promise.race – 返回第一个完成的 Promise(无论成功失败) Promise.any – 返回第一个成功的 Promise

    模块化:importexport

    Set, Map

    let s = new Set(); s.add(‘a’).add(‘b’)
    let m = new Map(); m.set(’age’, 16)

    数组的 includes,检查是否包含某元素

    async / await

    底层实现机制: async/await 的核心是通过 Generator 函数和自动执行器实现的:

    1. async 函数本质上是一个返回 Promise 的 Generator 函数;
    2. await 相当于 yield,暂停函数执行;
    3. 有一个自动执行器负责处理 Promise 的 resolve/reject 并继续执行。

    Generator 函数的语法糖,省去手动 next() 的步骤

    Object.values() 和 Object.entries()

    Object.values({ a: 1, b: 2 }); // [1, 2]
    Object.entries({ a: 1, b: 2 }); // [["a", 1], ["b", 2]]

    字符串填充:padStart() 和 padEnd()

    "5".padStart(2, "0"); // "05"

    空值合并运算符

    const value = input ?? "default";

    动态导入模块

    const module = await import('./module.js')

    replaceAll 替换所有匹配的子串

    "a.b.c".replaceAll(".", "-"); // "a-b-c"

    require 和 import

    • 分别属于 CommonJS 和 ES 两种不同模块系统
    • require 动态加载,运行时解析
    • import 静态加载,编译时解析
    • Proxy
      • 数据绑定与响应式系统:通过 set 拦截属性赋值,触发副作用(如重新渲染)
      • 属性访问控制和校验:限制对象属性的访问或赋值

    微信小程序:

    OpenID & UnionID

    OpenID

    • 用户在当前小程序中的唯一标识
    • 用途:用于识别用户在当前小程序内的身份(如用户数据存储、业务逻辑处理)
    • 获取:通过 wx.login() 获取 code,后端用 code 调用微信接口换取 OpenID

    UnionID

    • 用户在微信的唯一标识
    • 用途:实现跨小程序、公众号用户身份统一
    • 获取:通过 wx.getUserInfo() 获取 encryptedData, iv,发送到后端解密,或者通过按钮触发授权

    性能优化:

    1. 文本压缩(css, js, html)
    2. 图片压缩
    3. 合并资源(合并文本、雪碧图)
    4. 图片懒加载
    5. 合并请求
    6. 缓存资源(设置浏览器头、设置 html head)
    7. 使用 CDN
    8. gzip 压缩
    9. 减少 DOM 操作
    10. CSS 样式置顶、JS 脚本置底
    11. 防抖和节流
      • 防抖:保证N秒内执行一次,如果N秒内触发将再执行并重新计算时间
      • 节流:保证N秒内只能触发一次
  • WEB前端-CSS篇

    CSS3 新增属性

    1. 选择器(Selectors)

    CSS3 新增了许多强大的选择器,可以更精确地匹配元素。

    选择器 示例 描述
    属性选择器 input[type="text"] 匹配具有特定属性的元素
    结构伪类 :nth-child(n) 匹配第 n 个子元素
    :first-of-type 匹配同类型的第一个元素
    :last-child 匹配最后一个子元素
    :not(selector) 排除匹配的元素
    UI 伪类 :checked 匹配被选中的表单元素(如复选框)
    :disabled 匹配禁用的表单元素
    :enabled 匹配可用的表单元素
    目标伪类 :target 匹配当前 URL 的锚点目标元素

    2. 盒模型(Box Model)

    CSS3 提供了更灵活的盒模型控制方式。

    属性 描述
    box-sizing: border-box 使 widthheight 包含 paddingborder
    resize 允许用户调整元素大小(bothhorizontalvertical
    outline-offset 设置轮廓(outline)与边框的偏移距离

    3. 背景与边框(Background & Border)

    CSS3 增强了背景和边框的样式控制。

    背景(Background)

    属性 描述
    background-size 控制背景图片大小(covercontain100% 100%
    background-clip 定义背景绘制区域(border-boxpadding-boxcontent-box
    background-origin 定义背景定位的基准区域
    background-attachment: local 背景随内容滚动
    background: url(img1.png), url(img2.png); 多背景

    边框(Border)

    属性 描述
    border-radius 圆角边框(border-radius: 10px;
    box-shadow 盒子阴影(box-shadow: 5px 5px 10px #888;
    border-image 使用图片作为边框(border-image: url(border.png) 30 round;

    4. 渐变(Gradients)

    CSS3 支持线性渐变和径向渐变。

    类型 示例 描述
    线性渐变 background: linear-gradient(to right, red, blue); 从左到右渐变
    径向渐变 background: radial-gradient(circle, red, yellow); 从中心向外渐变
    重复渐变 background: repeating-linear-gradient(45deg, red, red 10px, blue 10px, blue 20px); 重复渐变

    5. 过渡(Transitions)

    CSS3 过渡允许属性在一定时间内平滑变化。

    属性 描述
    transition-property 指定过渡的属性(如 widthopacity
    transition-duration 过渡持续时间(如 1s
    transition-timing-function 过渡速度曲线(easelinearcubic-bezier()
    transition-delay 过渡延迟时间
    简写 transition: width 1s ease 0.5s;

    6. 动画(Animations)

    CSS3 动画比过渡更强大,支持关键帧控制。

    属性 描述
    @keyframes 定义动画关键帧
    animation-name 指定动画名称
    animation-duration 动画持续时间
    animation-timing-function 动画速度曲线
    animation-delay 动画延迟时间
    animation-iteration-count 动画播放次数(infinite 表示无限循环)
    animation-direction 动画方向(normalreversealternate
    animation-fill-mode 动画结束后保持状态(forwardsbackwards
    简写 animation: move 2s ease infinite;

    示例:

    @keyframes move {
      0% { transform: translateX(0); }
      100% { transform: translateX(100px); }
    }
    div {
      animation: move 2s ease infinite;
    }

    7. 变形(Transforms)

    CSS3 变形允许对元素进行 2D/3D 变换。

    2D 变形:

    属性 描述
    transform: translate(x, y) 移动元素
    transform: rotate(45deg) 旋转元素
    transform: scale(1.5) 缩放元素
    transform: skew(30deg) 倾斜元素
    组合变换 transform: rotate(45deg) scale(1.2);

    3D 变形:

    属性 描述
    transform: translate3d(x, y, z) 3D 移动
    transform: rotateX(45deg) 绕 X 轴旋转
    transform: perspective(500px) 设置 3D 透视距离

    8. 弹性布局(Flexbox)

    CSS3 Flexbox 提供更灵活的布局方式。

    属性 描述
    display: flex 启用 Flex 布局
    flex-direction 主轴方向(rowcolumn
    justify-content 主轴对齐方式(centerspace-between
    align-items 交叉轴对齐方式(centerstretch
    flex-wrap 是否换行(wrapnowrap
    flex-grow 定义项目的放大比例
    flex-shrink 定义项目的缩小比例
    flex-basis 定义项目的初始大小

    9. 网格布局(Grid)

    CSS3 Grid 提供二维布局系统。

    属性 描述
    display: grid 启用 Grid 布局
    grid-template-columns 定义列宽(如 1fr 2fr
    grid-template-rows 定义行高
    grid-gap 定义行列间距
    grid-column / grid-row 定义项目占据的网格区域
    <!DOCTYPE html>
    <html>
    <head>
    
    <style>
            .grid-container {
                display: grid;
                grid-template-columns: 100px 200px auto; /* 三列:固定100px,固定200px,剩余空间 */
                gap: 10px;
                background-color: #2196F3;
                padding: 10px;
            }
    
            .grid-item {
                background-color: rgba(255, 255, 255, 0.8);
                border: 1px solid rgba(0, 0, 0, 0.8);
                padding: 20px;
                font-size: 30px;
                text-align: center;
            }
        </style>
    </head>
    <body>
        <div class="grid-container">
            <div class="grid-item">1</div>
            <div class="grid-item">2</div>
            <div class="grid-item">3</div>  
            <div class="grid-item">4</div>
            <div class="grid-item">5</div>
            <div class="grid-item">6</div>  
            <div class="grid-item">7</div>
            <div class="grid-item">8</div>
            <div class="grid-item">9</div>  
        </div>
    </body>
    </html>

    10. 媒体查询(Media Queries)

    CSS3 媒体查询允许针对不同设备应用不同样式。

    /* 屏幕宽度小于 600px 时生效 */
    @media (max-width: 600px) {
      body { background: lightblue; }
    }

    BEM 命名规范

    BEM(Block-Element-Modifier)是一种流行的 CSS 命名方法论,旨在提高代码可读性、可维护性和可复用性。其核心思想是通过模块化的方式组织 CSS 类名,避免样式冲突。

    1. BEM 基本结构

    BEM 将界面拆分为三个部分: 部分 描述 示例
    Block 独立的、可复用的组件(如按钮、卡片、导航栏)。 .btn.card
    Element 属于 Block 的子元素,不能单独使用(如按钮的图标、卡片的标题)。 .btn__icon.card__title
    Modifier 表示 Block 或 Element 的状态或变体(如禁用按钮、大号卡片)。 .btn--disabled.card--large

    2. 命名规则

    (1) Block(块)
    • 使用单一单词短横线连接-)的命名方式。
    • 代表一个独立的组件,不依赖其他元素。
    .header { ... }       /* 页眉 */
    .menu { ... }         /* 菜单 */
    .search-box { ... }   /* 搜索框 */
    (2) Element(元素)
    • 格式:Block名称__Element名称双下划线 __ 连接)。
    • 表示属于 Block 的一部分,不能脱离 Block 使用。
    .menu__item { ... }          /* 菜单项 */
    .search-box__input { ... }   /* 搜索框的输入框 */
    .card__title { ... }         /* 卡片的标题 */
    (3) Modifier(修饰符)
    • 格式:Block--ModifierBlock__Element--Modifier双短横线 -- 连接)。
    • 表示 Block 或 Element 的不同状态或样式变体。
    .button--primary { ... }     /* 主要按钮 */
    .button--disabled { ... }    /* 禁用按钮 */
    .menu__item--active { ... }  /* 当前选中的菜单项 */

    3. 实际代码示例

    HTML 结构

    <!-- Block: card -->
    <div class="card card--highlight">
      <!-- Element: card 的子元素 -->
      <h2 class="card__title">标题</h2>
      <p class="card__content">内容...</p>
      <!-- 带 Modifier 的 Element -->
      <button class="card__button card__button--large">点击</button>
    </div>

    CSS 样式

    /* Block */
    .card { 
      border: 1px solid #ccc;
      padding: 16px;
    }
    
    /* Modifier: 高亮卡片 */
    .card--highlight {
      background: #f5f5f5;
    }
    
    /* Element: 卡片标题 */
    .card__title {
      font-size: 18px;
      color: #333;
    }
    
    /* Element: 卡片按钮 */
    .card__button {
      padding: 8px 16px;
    }
    
    /* Modifier: 大号按钮 */
    .card__button--large {
      padding: 12px 24px;
    }
  • WEB前端-HTML篇

    新增标签元素

    标签类别 具体标签
    语义化结构标签 header、footer、nav、main、article、section、aside、figure、figcaption、time、mark
    多媒体标签 audio、video、source、track、canvas、svg
    表单增强元素 datalist、output、meter、progress
    新增 Input 类型 input(date)、input(datetime)、input(email)、input(number)、input(range)、input(tel)、input(color)、input(time)、input(url)、input(search)
    其它标签 details、summary、dialog、template

    本地存储

    生命周期:

    • cookie 可设置过期时间
    • localStorage 永久存储
    • sessionStorage 关闭标签页自动清除

    存储大小:

    • cookie 4KB
    • sessionStorage 5MB – 10MB
    • localStorage 5MB – 10MB

    作用域:

    • cookie:可设置 Domain 和 Path,控制哪些域名和路径可以访问
    • localStorage:同源策略下的所有窗口和标签页共享
    • sessionStorage:仅当前标签页有效,即使同源的其他标签页也无法访问

    以下是整理成 Markdown 表格的浏览器存储特性对比:

    特性 Cookie localStorage sessionStorage
    生命周期 可设置过期时间(Expires/Max-Age 永久存储,除非手动清除 关闭标签页后自动清除
    存储大小 约 4KB 5MB – 10MB(不同浏览器可能有差异) 5MB – 10MB(同 localStorage)
    作用域 通过 DomainPath 控制访问范围 同源策略下的所有窗口/标签页共享 仅当前标签页有效,同源其他标签页不可访问
    数据发送 每次请求自动携带在 HTTP 头部 不自动发送,仅客户端存储 不自动发送,仅客户端存储
    API 易用性 需手动解析字符串 直接使用 setItem()/getItem() 等操作 同 localStorage

    补充说明

    • 同源策略:协议、域名、端口必须完全相同。
    • 安全建议:
      • Cookie 敏感数据建议设置 HttpOnlySecure 属性。
      • 大容量数据优先使用 localStoragesessionStorage
      • sessionStorage 适合临时数据(如表单填写中途防止丢失)。

    <script> 加载方式

    <!-- 默认加载:同步阻塞 HTML 解析 -->
    <script src="script.js"></script>
    <!-- defer 加载:延迟执行,直至 DOM 解析完成后 -->
    <script defer src="script.js"></script>
    <!-- async 加载:异步引入,下载完成后立即执行 -->
    <script async src="script.js"></script>

    加载说明

    • 默认:<script> 同步加载,阻塞 HTML 解析和渲染
    • defer:<script> 延迟执行,DOM 解析完成后按顺序执行
    • async:<script> 异步加载,下载完成后立即执行(执行顺序不固定)
  • 【Typescript】接口、类

    接口

    TypeScript的核心原则之一是对值所具有的结构进行类型检查。

    interface LabelledValue {
      label: string;
    }
    
    function printLabel(labelledObj: LabelledValue) {
      console.log(labelledObj.label);
    }
    
    let myObj = {size: 10, label: "Size 10 Object"};
    printLabel(myObj);

    可选属性

    interface SquareConfig {
        width: number
        height: number
        color?: string // 可选属性
    }

    只读属性

    只能在刚创建时修改其值

    interface Point {
        readonly x: number;
        readonly y: number;
    }

    额外的属性检查

    如果 SquareConfig带有上面定义的类型的color和width属性,并且还会带有任意数量的其它属性,可以这样定义:

    interface SquareConfig {
        width: number
        color?: string
        [propName: string]: any
    }

    函数类型

    interface SearchFunc {
      (source: string, subString: string): boolean
    }
    
    // 对于函数类型的类型检查来说,函数的参数名不需要与接口里定义的名字相匹配。 
    let mySearch: SearchFunc;
    mySearch = function(src: string, sub: string): boolean {
      let result = src.search(sub);
      return result > -1;
    }

    可索引的类型

    interface StringArray {
      [index: number]: string;
    }
    
    let myArray: StringArray;
    myArray = ["Bob", "Fred"];
    
    let myStr: string = myArray[0];

    类类型

    interface ClockInterface {
        currentTime: Date;
        setTime(d: Date);
    }
    
    // 通过 implements 描述
    class Clock implements ClockInterface {
        currentTime: Date;
        setTime(d: Date) {
            this.currentTime = d;
        }
        constructor(h: number, m: number) { }
    }

    继承接口

    interface Shape {
        color: string;
    }
    
    interface PenStroke {
        penWidth: number;
    }
    
    interface Square extends Shape, PenStroke {
        sideLength: number;
    }
    
    let square = 
    <Square>{};
    square.color = "blue"
    square.sideLength = 10
    square.penWidth = 5

    混合类型

    一个对象可以同时做为函数和对象使用,并带有额外的属性

    interface Counter {
        (start: number): string;
        interval: number;
        reset(): void;
    }
    
    function getCounter(): Counter {
        let counter = 
    <Counter>function (start: number) { };
        counter.interval = 123;
        counter.reset = function () { };
        return counter;
    }
    
    let c = getCounter();
    c(10);
    c.reset();
    c.interval = 5.0;

    class Animal {
        move(distanceInMeters: number = 0) {
            console.log(`Animal moved ${distanceInMeters}m.`);
        }
    }
    
    class Dog extends Animal {
        bark() {
            console.log('Woof! Woof!');
        }
    }
    
    const dog = new Dog();
    dog.bark();
    dog.move(10);
    dog.bark();

    继承

    通过 extends 关键字

    class Animal {
        name: string;
        constructor(theName: string) { this.name = theName; }
        move(distanceInMeters: number = 0) {
            console.log(`${this.name} moved ${distanceInMeters}m.`);
        }
    }
    
    class Snake extends Animal {
        constructor(name: string) { super(name); }
        move(distanceInMeters = 5) {
            console.log("Slithering...");
            super.move(distanceInMeters);
        }
    }

    公共,私有与受保护的修饰符

    public(默认)

    在TypeScript里,成员都默认为 public。

    class Animal {
        public name: string;
    }
    private

    当成员被标记成private时,它就不能在声明它的类的外部访问。

    class Animal {
        private name: string
        constructor(theName: string) { this.name = theName; }
    }
    
    new Animal('Cat').name // 错误: 'name' 是私有的.
    protected

    protected与private修饰符的行为很相似,但有一点不同, protected成员在派生类中仍然可以访问。

    class Person {
        protected name: string
        constructor(name: string) { this.name = name }
    }
    
    class Employee extends Person {
        private department: string
        public getElevatorPitch() {
            return `my name is ${this.name} and I work in ${this.department}.`
        }
    }
    
    let dick = new Employee("Howard", "Sales")
    console.log(dick.getElevatorPitch());
    console.log(dick.name); // 错误

    readonly修饰符

    readonly关键字将属性设置为只读的。 只读属性必须在声明时或构造函数里被初始化。

    class Octopus {
        readonly name: string;
        constructor (theName: string) {
            this.name = theName;
        }
    }
    let dad = new Octopus("Man with the 8 strong legs");
    dad.name = "Man with the 3-piece suit"; // 错误! name 是只读的.

    存取器

    TypeScript支持通过getters/setters来截取对对象成员的访问。

    let passcode = "secret passcode";
    
    class Employee {
        private _fullName: string;
    
        get fullName(): string {
            return this._fullName;
        }
    
        set fullName(newName: string) {
            if (passcode && passcode == "secret passcode") {
                this._fullName = newName;
            }
            else {
                console.log("Error: Unauthorized update of employee!");
            }
        }
    }
    
    let employee = new Employee();
    employee.fullName = "Bob Smith";
    if (employee.fullName) {
        alert(employee.fullName);
    }

    抽象类

    抽象类做为其它派生类的基类使用。 它们一般不会直接被实例化。

    abstract class Department { ... }
    class AccountingDepartment extends Department { ... }
    
    let department: Department // 允许创建一个对抽象类型的引用
    department = new Department() // 错误: 不能创建一个抽象类的实例
    department = new AccountingDepartment() // 允许对一个抽象子类进行实例化和赋值
  • 【JS】小数精度处理技巧

    JavaScript 使用 IEEE 754 双精度浮点数表示所有数字,这会导致一些常见的小数精度问题,例如 0.1 + 0.2 !== 0.3。以下是处理 JavaScript 小数精度的常用技巧:

    1. 四舍五入方法

    // toFixed方法(返回字符串)
    let num = 0.1 + 0.2; // 0.30000000000000004
    let fixed = num.toFixed(2); // "0.30"
    
    // 使用Math.round四舍五入
    function round(value, decimals) {
      return Number(Math.round(value + 'e' + decimals) + 'e-' + decimals);
    }
    round(1.005, 2); // 1.01

    2. 精度运算库

    使用专门的数学库处理精确计算:

    • decimal.js —— 功能相对简单,适合基本的高精度计算需求
    • big.js —— 支持三角函数、指数、对数等高级数学运算
    // 使用decimal.js示例
    import Decimal from 'decimal.js';
    let sum = new Decimal(0.1).add(new Decimal(0.2)); // 0.3

    3. 整数运算技巧

    将小数转换为整数进行计算,再转换回去:

    function add(num1, num2) {
      const multiplier = Math.pow(10, Math.max(getDecimalLength(num1), getDecimalLength(num2)));
      return (num1 * multiplier + num2 * multiplier) / multiplier;
    }
    
    function getDecimalLength(num) {
      const decimalStr = num.toString().split('.')[1];
      return decimalStr ? decimalStr.length : 0;
    }

    4. 比较数字时的容差方法

    function numbersEqual(a, b, tolerance = 1e-10) {
      return Math.abs(a - b) < tolerance;
    }

    5. 格式化显示

    // 使用Intl.NumberFormat
    const formatter = new Intl.NumberFormat('en-US', {
      minimumFractionDigits: 2,
      maximumFractionDigits: 2
    });
    formatter.format(0.1 + 0.2); // "0.30"

    6. 避免常见陷阱

    • 不要直接比较浮点数
    • 对于货币计算,通常使用整数表示分(如用100表示1.00元)
    • 大整数计算考虑使用BigInt类型

    对于简单的显示问题,toFixed可能足够;对于复杂的财务计算,建议使用专门的库。

  • 【NPM】package.json 参数详解

    package.json 必须是纯 JSON 格式,而不仅仅是一个 JavaScript 对象字面量。

    name 和 version

    Name 和 version 字段是 package.json 文件中最重要的字段。这是必须的字段,如果你的 npm 包没有指定这两个字段,将无法被安装。name 和 version 字段被假定组合成一个唯一的标识符。包内容的更改和包版本的更改是同步的。

    description

    npm 包的描述,description 是一个字符串。它可以帮助人们在使用 npm search 时找到这个包。

    keywords

    npm 包的关键字,keywords 是一个字符串的数组。它可以帮助人们在使用 npm search 时找到这个包。

    homepage

    项目主页的 url

    bugs

    改项目的 issue 跟踪页面或这报告 issue 的 email 地址。这对使用这个包遇到问题的用户会有帮助。

    license

    证书许可。SPDX表达式:

    { "license": "ISC" }
    { "license": "(MIT OR Apache-2.0)" }

    通常我们不希望授权别人以任何形式使用的私有包或未发布包,可以这样写:

    { "license": "UNLICENSED”}

    或者设置

    { "private": true }

    author, contributors

    关于人的字段

    files

    files 字段是一个被项目包含的文件名数组,如果你在里面放一个文件夹名,那么这个文件夹中的所有文件都会被包含进项目中(除非是那些在其他规则中被忽略的文件)。

    main

    Main 字段指定了模块的入口程序文件。就是说,如果你的模块名叫 "foo",用户安装了它,并且调用了 require("foo"),则这个main字段指定的模块的导出对象会被返回。 例如 node_modules 中引入的模块指定主入口文件。

    bin

    许多包有一个或多个可执行文件希望被安装到系统路径。提供一个bin字段,它是一个命令名和本地文件名的映射。在安装时,如果是全局安装,npm将会使用符号链接把这些文件链接到prefix/bin,如果是本地安装,会链接到 ./node_modules/.bin/。

    比如,要使用myapp作为命令时可以这么做:

    { "bin" : { "myapp" : "./cli.js" } }

    当安装完毕myapp,npm会从cli.js文件创建一个到/usr/local/bin/myapp的符号链接(这使你可以直接在命令行执行myapp)。

    man

    指定一个单一的文件名或一个文件名数组来让man程序使用。如果只给man字段提供一个文件,则安装完毕后,它就是 man 的结果,这和此文件名无关。

    directories

    CommonJS Packages 规范说明了几种你可以用 directories 对象来标示你的包结构的方法(lib、bin、man、doc、example)。

    repository

    指明你的代码被托管在何处,这对那些想要参与到这个项目中的人来说很有帮助。如果 git 仓库在 github 上,用 npm docs 命令将会找到你。

    scripts

    scripts 字段是一个由脚本命令组成的字典,这些命令运行在包的各个生命周期中。这里的键是生命周期事件名,值是要运行的命令。

    config

    config 字段是一个对象,可以用来配置包脚本中的跨版本参数。

    dependencies

    dependencies 字段是一个对象,它指定了依赖的包名和其版本范围的映射。版本范围是个有一个或多个空白分隔描述符的字符串。dependencies 字段还可以用 tarball 或者 git URL。

    (请不要将测试或过渡性的依赖放到 dependencies 中)

    devDependencies

    如果有人计划在他们的项目中下载和使用你的模块,但他们可能并不想或并不需要你开发所使用的外部测试和文档框架。 在这种情况下,最好将这些附加的项放在 devDependencies 中。即开发模式下的依赖。

    peerDependencies

    在某些情况下,当一个主机无法 require 依赖包时,你会想要告诉它还有哪些工具或库与这个依赖包兼容。这通常被成为一个插件。尤其是在 host 文档中声明的模块会暴露一个特定的接口。

    bundledDependencies

    在发布包时,包名的数组会被打包进去。

    optionalDependencies

    如果一个依赖项可用,但希望在这个依赖项无法被找到或者安装时失败npm还能继续处理(不中断),那么你可以把它放在 optionalDependencies中。和 dependencies 一样,optionalDependencies 是一个包名和版本号或 url 的映射。区别在于 optionalDependencies 中的依赖构建失败时不会导致 npm 整体安装失败。

    engines

    你可以指定node的工作版本:

    { "engines": { "node": ">=0.10.3 <0.12" } }

    os

    可以指定模块运行的操作系统:"os" : [ "darwin", "linux" ] 也可以使用操作系统黑名单来替代白名单,只要在前面加个’!’:

    { "os": [ "!win32" ] }

    cpu

    指明只能运行在特定的 cpu 架构上

    preferGlobal

    如果你的包是一个需要进行全局安装的命令行应用,需要设置 preferGlobal为true,如果这个包被本地安装会报出一个警告。 这个选项并不会阻止用户本地安装这个包,但这么做确实能在包未按照预期被安装造成诸多麻烦时提供一些提示。

    private

    如果你在包的 package.json 中设置” private": true “,则 npm 会拒绝发布它。这是防止私有包被以外发布的一种方法。

    publishConfig

    这是一个在 publish-time 时会用到的配置集合。当你想设置 tag、registry 或] access 时特别有用,所以你可以确保一个给定的包无法在没有被打上"latest"标记时就被发布到全局公共的registry。 任何配置都可以被覆盖,当然可能只有"tag", "registry" 和 "access" 和发布意图有关。