npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

json-diff-vue

v1.9.1

Published

JSON Diff Vue 组件库 - 同时支持 Vue2 和 Vue3

Readme

JSON Diff Vue

一个支持 Vue 2.0+ 和 Vue 3 的 JSON 差异展示组件库,提供直观的差异可视化展示。

特性

  • 🎯 双版本支持 - 同时支持 Vue 2.0+ 和 Vue 3.x
  • 📦 单包安装 - 一个 npm 包,按需导入对应版本
  • 🎨 多种展示模式 - Normal(平铺)和 Tree(树形)两种模式
  • 🔧 高度可配置 - 字段映射、统计栏、工具栏、展开控制
  • 💪 TypeScript 支持 - 完整的类型定义
  • 🚀 零依赖核心 - 基于 json-diff-toolkit,无额外运行时依赖

安装

npm install json-diff-vue

json-diff-toolkitjson-diff-vue 的依赖,会随 json-diff-vue 自动安装,无需单独安装。

快速开始

Vue 3

// main.ts
import { createApp } from 'vue'
import JsonDiffVue from 'json-diff-vue/vue3'
import 'json-diff-vue/style.css'

createApp(App).use(JsonDiffVue).mount('#app')

Vue 2

// main.ts
import Vue from 'vue'
import JsonDiffVue from 'json-diff-vue/vue2'
import 'json-diff-vue/style.css'

Vue.use(JsonDiffVue)

按需导入

import { DiffViewer } from 'json-diff-vue/vue3'  // Vue 3
import { DiffViewer } from 'json-diff-vue/vue2'  // Vue 2

基本用法

<template>
  <DiffViewer :json1="before" :json2="after" />
</template>

<script setup>
const before = { name: '张三', age: 18 }
const after  = { name: '张三', age: 19, city: '北京' }
</script>

展示模式

Normal 模式(默认)

以列表形式平铺展示所有差异项,每条差异显示路径、类型及新旧值。

<DiffViewer :json1="a" :json2="b" mode="normal" />

Tree 模式

以树形结构还原 JSON 层级,支持展开/折叠,适合深层嵌套的复杂数据。

<DiffViewer :json1="a" :json2="b" mode="tree" :default-expand-all="true" />

Props

| Prop | 类型 | 默认值 | 说明 | |---|---|---|---| | json1 | unknown | — | 必填,原始 JSON | | json2 | unknown | — | 必填,对比 JSON | | mode | 'normal' \| 'tree' | 'normal' | 展示模式 | | config | DiffConfig | {} | 差异检测配置(见下方) | | maxHeight | number \| string | — | 容器最大高度,超出后滚动 | | customClass | string | — | 根元素附加 CSS 类名 | | showStats | boolean | true | 是否显示统计信息栏 | | statsConfig | StatsDisplayConfig | {} | 统计栏显示项配置(见下方) | | fieldMapping | Record<string, string> | {} | 字段路径 → 显示名称映射(见下方) | | showToolbar | boolean | true | Tree 模式:是否显示展开/折叠工具栏 | | defaultExpandAll | boolean | true | Tree 模式:初始展开所有节点 | | defaultExpandedKeys | string[] | [] | Tree 模式:初始展开的节点路径列表 | | truncate | boolean | false | 内容超长时启用省略号截断;默认 false 全量展示 | | showRawData | boolean | false | 是否在差异视图上方展示原始 JSON 数据面板 | | fieldMapper | FieldMapper | — | 动态字段映射函数,优先级高于 fieldMapping(见下方) | | htmlKeys | boolean | false | Tree 模式:以 v-html 渲染映射后的键名,支持 HTML 标签(见下方) | | hideNodes | string[] | [] | 隐藏指定节点行;支持精确路径、标准化路径、*.fieldName;Tree 模式子节点仍渲染(见下方) | | shouldHideNode | NodeHideFilter | — | Tree 模式节点隐藏回调,返回 true 则隐藏节点行,子节点仍渲染 | | shouldHideDiff | DiffHideFilter | — | Normal 模式差异行隐藏回调,返回 true 则隐藏该行 |

暴露方法

通过 ref 可在外部控制 Tree 模式的展开状态:

<DiffViewer ref="viewer" mode="tree" :json1="a" :json2="b" />

<button @click="viewer.expandAll()">全部展开</button>
<button @click="viewer.collapseAll()">全部折叠</button>
// Vue 3 script setup
const viewer = ref()
viewer.value.expandAll()
viewer.value.collapseAll()
// Vue 2 Options API
this.$refs.viewer.expandAll()
this.$refs.viewer.collapseAll()

DiffConfig 差异检测配置

interface DiffConfig {
  ignoreFields?: string[]              // 忽略字段,支持精确路径、通配符、前缀、*.fieldName 四种写法(见下方)
  ignoreNull?: boolean                 // 忽略 null ↔ 非null 的变化,默认 false
  deepEqual?: boolean                  // 深度对比对象/数组,默认 true(false 时用 JSON.stringify 浅比较)
  arrayIdConfig?: Record<string, string> // 对象数组按 ID 字段匹配(见下方)
  arrayCompareMode?: Record<string,    // 数组对比策略(见下方),默认 lcs
    'lcs' | 'index' | { strategy: 'index', matchKeys?: string[] }>
  maxDepth?: number                    // 最大对比深度,默认无限制
}

注意: DiffConfig.format.*(如 format.style: 'arrow')为 json-diff-toolkit 文本格式化 API 的配置项,仅在直接调用 formatDiff() / JsonDiffToolkit 类时有效。DiffViewer 组件自行以 HTML 方式渲染差异,不使用文本格式化器,传入 format.* 不会生效。


ignoreFields 忽略字段

支持四种匹配模式,对含运行时数组标记([id=xxx][0])的路径自动做标准化后再匹配,无需写死 ID:

| 模式 | 示例配置 | 效果 | |---|---|---| | 精确路径 | "user.name" | 仅忽略该字段,其他字段不受影响 | | 后缀通配符 .* | "user.*" | 忽略该节点的所有后代(不含节点本身) | | 前缀路径 | "user" | 忽略该节点本身及所有后代 | | 全局字段名 *.<name> | "*.uTime" | 忽略任意深度的同名字段 |

<DiffViewer
  :json1="a"
  :json2="b"
  :config="{
    ignoreFields: [
      'updatedAt',           // 精确路径:忽略顶层 updatedAt 字段
      'meta.updatedAt',      // 精确路径:仅忽略 meta 下的 updatedAt
      'meta.*',              // 后缀通配符:忽略 meta 下所有字段(含深层后代)
      'meta',                // 前缀路径:忽略 meta 节点本身及全部后代
      '*.uTime',             // 全局字段名:忽略任意深度的 uTime 字段
    ]
  }"
/>

在对象数组中使用(自动标准化,无需写死 ID):

<DiffViewer
  :json1="a"
  :json2="b"
  :config="{
    arrayIdConfig: { nodeList: 'id' },
    ignoreFields: [
      'nodeList.uTime',
      // 匹配 nodeList[id=48488].uTime、nodeList[id=99].uTime 等所有元素的 uTime

      'nodeList.nodeApprover.nodeApprovers.uTime',
      // 匹配深层嵌套路径 nodeList[id=48488].nodeApprover.nodeApprovers[id=74327].uTime

      'nodeList.*',
      // 忽略 nodeList 所有元素的全部字段(nodeList 被新增/删除时仍会上报)

      'nodeList',
      // 忽略 nodeList 节点本身及全部后代(包含新增/删除整个 nodeList 的情况)
    ]
  }"
/>

.* 与前缀路径的区别:

| 配置 | 节点本身被新增/删除 | 字段修改 | |---|---|---| | "nodeList.*" | ✅ 上报 | ❌ 忽略 | | "nodeList" | ❌ 忽略 | ❌ 忽略 |


arrayIdConfig 对象数组 ID 匹配

默认情况下数组使用 LCS(最长公共子序列)算法对比,无法感知元素身份,相同元素的修改可能被识别为"删除旧元素 + 新增新元素"。配置 arrayIdConfig 后,引擎按指定 ID 字段匹配同一元素,正确识别新增、删除、修改。

<DiffViewer
  :json1="a"
  :json2="b"
  :config="{
    arrayIdConfig: {
      users: 'id',           // 顶层数组 users,按元素的 id 字段匹配
      'dept.members': 'userId', // 嵌套数组,按 userId 字段匹配
    }
  }"
/>

深层嵌套数组(key 支持标准化路径,自动命中含运行时 ID 的中间层):

<DiffViewer
  :json1="a"
  :json2="b"
  :config="{
    arrayIdConfig: {
      nodeList: 'id',

      // 配置 nodeList 下的嵌套数组
      // 实际运行时路径为 nodeList[id=48488].nodeApprover.nodeApprovers
      // 无需写死 ID,引擎自动标准化路径后匹配
      'nodeList.nodeApprover.nodeApprovers': 'id',
    }
  }"
/>

数组元素路径格式:配置 arrayIdConfig 后,diff 路径由索引格式变为 ID 格式:

未配置:nodeList[0].uTime、nodeList[1].uTime
已配置:nodeList[id=48488].uTime、nodeList[id=68523].uTime

ID 格式路径可被 ignoreFieldsfieldMapping 的标准化路径直接命中,三者协同工作。


arrayCompareMode 数组对比策略

arrayIdConfig 未命中时,通过 arrayCompareMode 指定数组对比策略。key 写法与 arrayIdConfig 相同,支持精确路径、标准化路径、字段名兜底和 "*" 全局默认四级查找。

| 策略 | 说明 | |---|---| | 'lcs' | 最长公共子序列算法(默认),能识别元素顺序变化 | | 'index' | 按索引一一对比,适合顺序固定的数组 | | { strategy: 'index', matchKeys: [...] } | 按索引对比,同时用指定字段验证同索引元素是否为同一实体;字段值不全相等时整体视为 removed + added |

<DiffViewer
  :json1="a"
  :json2="b"
  :config="{
    arrayCompareMode: {
      'rows': { strategy: 'index', matchKeys: ['type'] },
      // rows[i].type 相同 → 逐字段对比;不同 → 整体替换

      'cells': { strategy: 'index', matchKeys: ['type', 'colSpan'] },
      // 同时验证 type 和 colSpan 两个字段

      'tags': 'index',
      // 按索引对比,不做实体验证

      '*': 'lcs',
      // 其他数组默认 LCS(可省略,lcs 是默认值)
    }
  }"
/>

StatsDisplayConfig 统计栏配置

控制统计栏展示哪些项目以及标签文字:

interface StatsDisplayConfig {
  showAdded?: boolean    // 显示新增数,默认 true
  showRemoved?: boolean  // 显示删除数,默认 true
  showModified?: boolean // 显示修改数,默认 true
  showTotal?: boolean    // 显示差异总计,默认 false
  showMaxDepth?: boolean // 显示最大深度,默认 false
  labels?: {
    added?: string       // 默认 '新增'
    removed?: string     // 默认 '删除'
    modified?: string    // 默认 '修改'
    total?: string       // 默认 '总计'
    maxDepth?: string    // 默认 '最大深度'
  }
}

示例:

<DiffViewer
  :json1="a"
  :json2="b"
  :stats-config="{
    showTotal: true,
    labels: { added: 'Added', removed: 'Removed', modified: 'Changed' }
  }"
/>

fieldMapping 字段映射

将字段路径映射为业务可读的显示名称,支持三级查找优先级:

| 优先级 | key 写法 | 说明 | |---|---|---| | ① 精确路径 | "users[id=1].name" | 完全匹配含 ID 的实际路径,优先级最高 | | ② 作用域路径 | "users.name" | 去掉 [...] 后的标准化路径,匹配该上下文内的字段 | | ③ 字段名 | "name" | 全局匹配任意路径中同名字段 |

<DiffViewer
  :json1="a"
  :json2="b"
  :field-mapping="{
    // ③ 字段名级:全局映射,任意路径下的 uTime 均生效
    uTime: '更新时间',
    cTime: '创建时间',

    // ② 作用域路径级:仅在 nodeList 下的 uTime 使用此名称(覆盖字段名级)
    'nodeList.uTime': '节点更新时间',

    // ② 多级作用域:仅在该嵌套路径下的 uTime 使用此名称(覆盖上层)
    'nodeList.nodeApprover.nodeApprovers.uTime': '审批人更新时间',

    // ② 数组名称映射:[id=xxx] 标记自动保留
    nodeList: '节点列表',        // 显示为 节点列表[id=48488]
    nodeLinkList: '连接线列表',
  }"
/>

实际路径 → 显示结果示例

| 实际路径 | 显示结果 | |---|---| | nodeList[id=48488].uTime | 节点列表[id=48488].节点更新时间 | | nodeList[id=48488].nodeApprover.nodeApprovers[id=74327].uTime | 节点列表[id=48488].nodeApprover.nodeApprovers[id=74327].审批人更新时间 | | nodeLinkList[id=68523].uTime | 连接线列表[id=68523].更新时间(无 nodeLinkList.uTime 配置,回退到字段名级) |

fieldMapper 动态字段映射

fieldMapper 是一个函数 prop,接收字段路径、差异结果和可选的上下文,返回自定义显示名称,优先级高于静态 fieldMapping。适用于需要根据运行时上下文(差异类型、值内容、父级对象字段等)动态决定显示名称的场景。

type FieldMapper = (
  path: string,
  diff: DiffResult,
  context?: FieldMapperContext
) => string | undefined | null

interface FieldMapperContext {
  currentOldValue: unknown  // 当前路径对应的旧值(当前字段/节点本身)
  currentNewValue: unknown  // 当前路径对应的新值
  parentOldValue: unknown   // 父路径对应的旧值(包含当前字段的父对象)
  parentNewValue: unknown   // 父路径对应的新值
  rootOld: unknown          // 完整的旧 JSON 根对象
  rootNew: unknown          // 完整的新 JSON 根对象
}
import type { FieldMapper, FieldMapperContext } from 'json-diff-vue/vue3'
import type { DiffResult } from 'json-diff-toolkit'

示例一:基础路径映射

用函数替代静态 fieldMapping 对象,实现路径 → 显示名称的动态转换:

const pathMap: Record<string, string> = {
  userId:           '用户ID',
  userName:         '用户姓名',
  deptCode:         '部门编码',
  statusCode:       '账号状态',
  'profile.phone':  '手机号',
  'profile.email':  '邮箱',
  remark:           '备注',
}

const basicMapper: FieldMapper = (path) => pathMap[path] ?? null
<DiffViewer :json1="a" :json2="b" :field-mapper="basicMapper" />

示例二:基于差异类型附加状态标记

利用第二个参数 diff,根据差异类型(added / removed / modified)在字段名后动态附加状态标记:

const typeAwareMapper: FieldMapper = (path: string, diff: DiffResult) => {
  const name = pathMap[path]
  if (!name) return null
  const tag = diff.type === 'added'   ? '(新增)'
            : diff.type === 'removed' ? '(删除)'
            : null
  return tag ? name + tag : name
}
<DiffViewer :json1="a" :json2="b" :field-mapper="typeAwareMapper" />

示例三:fieldMapper 与 fieldMapping 协同使用

fieldMapper 只处理部分路径,其余路径返回 null 自动回退到 fieldMapping,两者互补:

// fieldMapper 只覆盖 profile 下的字段
const profileMapper: FieldMapper = (path) => {
  const map: Record<string, string> = {
    'profile.phone':   '📱 手机号',
    'profile.email':   '📧 邮箱地址',
    'profile.address': '📍 所在城市',
  }
  return map[path] ?? null
}

// 其余字段由 fieldMapping 接管
const fieldMapping = {
  userId:     '用户ID',
  userName:   '用户姓名',
  deptCode:   '部门编码',
  statusCode: '账号状态',
}
<DiffViewer
  :json1="a"
  :json2="b"
  :field-mapper="profileMapper"
  :field-mapping="fieldMapping"
/>

示例四:利用 context 访问当前节点 / 父对象数据

context 由组件在调用 toolkit 时自动注入,无需额外配置。常见用途:

  • context.currentOldValue — 当前路径对应的值本身(如 nodeList[id=38945] 路径下就是该节点对象)
  • context.parentOldValue — 父对象(如 nodeList[id=38945].uTime 路径下父对象是该节点,可读取 .name 等兄弟字段)
const nodeMapper: FieldMapper = (path, diff, context) => {
  // 将数组元素节点显示为其 name 字段
  if (path.match(/^nodeList\[/) && path.endsWith(']')) {
    const node = context?.currentOldValue as Record<string, unknown> | undefined
    return node?.name as string | undefined
  }
  // 将子字段路径追加父节点 name 作为前缀
  if (path.match(/^nodeList\[.+\]\.uTime$/)) {
    const parent = context?.parentOldValue as Record<string, unknown> | undefined
    return parent?.name ? `${parent.name} - 更新时间` : '更新时间'
  }
  return undefined
}
<DiffViewer
  :json1="a"
  :json2="b"
  :field-mapper="nodeMapper"
  :field-mapping="fieldMapping"
/>

回退优先级

| 优先级 | 来源 | 触发条件 | |---|---|---| | ① | fieldMapper 返回值 | 返回非空字符串时生效 | | ② | fieldMapping 静态映射 | fieldMapper 返回 null/undefined 时回退 | | ③ | 原始字段名 | 两者均未命中时使用 |

htmlKeys 键名 HTML 渲染

仅 Tree 模式生效

默认情况下,所有键名均以纯文本渲染。开启 htmlKeys 后,fieldMapping 的值和 fieldMapper 的返回值会以 v-html 渲染,可在键名中嵌入 HTML 标签(加粗、着色、角标等)。

注意:

  • htmlKeys 仅影响通过 fieldMapping / fieldMapper 映射后的键名;未命中任何映射的原始 JSON key 始终以纯文本渲染(规避 XSS)
  • HTML 内容由开发者在配置中提供,确保来源可控

示例:加粗显示部分字段

<DiffViewer
  mode="tree"
  :json1="a"
  :json2="b"
  :html-keys="true"
  :field-mapping="{
    name:   '<b>姓名</b>',
    status: '<span style=\"color:#409eff\">状态</span>',
    price:  '价格'
  }"
/>

效果:键名 name 显示为加粗「姓名」,status 显示为蓝色「状态」,price 显示为普通文本「价格」。

示例:与 fieldMapper 结合

fieldMapper 返回的字符串同样支持 HTML,配合 htmlKeys 使用:

const fieldMapper = (path, diff) => {
  if (diff.type === 'added')   return `<span style="color:#67c23a">${path.split('.').pop()}</span>`
  if (diff.type === 'removed') return `<span style="color:#f56c6c">${path.split('.').pop()}</span>`
  return null // 其他字段回退到 fieldMapping
}
<DiffViewer
  mode="tree"
  :json1="a"
  :json2="b"
  :html-keys="true"
  :field-mapper="fieldMapper"
  :field-mapping="{ name: '姓名', age: '年龄' }"
/>

节点行隐藏

通过 hideNodesshouldHideNode(Tree 模式)、shouldHideDiff(Normal 模式)可在渲染阶段隐藏指定节点,不影响底层 diff 计算结果和统计数量。

Tree 模式:隐藏节点行,子节点上浮

被隐藏的容器节点不渲染行,其子节点提升一级直接显示(始终展开,不受折叠状态影响):

隐藏前                    隐藏后(hideNodes: ['user'])
▼ user {...}              name: Alice → Bob
    name: Alice → Bob  →  age: 25 → 26
    age: 25 → 26

hideNodes 路径匹配规则(与 ignoreFields 一致):

| 写法 | 效果 | |---|---| | "user" | 精确匹配路径 user | | "nodeList.info" | 标准化匹配,可命中 nodeList[id=1].info | | "*.uTime" | 全局字段名,匹配任意深度的 uTime 节点 |

<DiffViewer
  mode="tree"
  :json1="a"
  :json2="b"
  :hide-nodes="['wrapper', '*.metadata']"
/>

Tree 模式:回调函数控制

shouldHideNode 可根据节点任意属性动态决定是否隐藏:

<script>
// 隐藏所有未发生变化的容器节点(diffType 为 null)
const shouldHideNode = (node) => node.nodeType !== 'value' && !node.diffType
</script>

<DiffViewer
  mode="tree"
  :json1="a"
  :json2="b"
  :should-hide-node="shouldHideNode"
/>

Normal 模式:隐藏差异行

hideNodesshouldHideDiff 在 Normal 模式下隐藏整条差异行:

<script>
import type { DiffHideFilter } from 'json-diff-vue/vue3'

// 隐藏所有时间戳字段
const shouldHideDiff: DiffHideFilter = (diff) => diff.path.endsWith('Time')
</script>

<DiffViewer
  mode="normal"
  :json1="a"
  :json2="b"
  :hide-nodes="['*.uTime', '*.createTime']"
  :should-hide-diff="shouldHideDiff"
/>

hideNodes 与回调同时生效,任意一个命中即隐藏。

Tree 模式工具栏控制

隐藏内置工具栏,完全由外部控制展开/折叠:

<DiffViewer
  ref="viewer"
  mode="tree"
  :show-toolbar="false"
  :json1="a"
  :json2="b"
/>
<button @click="$refs.viewer.expandAll()">全部展开</button>
<button @click="$refs.viewer.collapseAll()">全部折叠</button>

指定默认展开的路径:

<DiffViewer
  mode="tree"
  :default-expanded-keys="['user', 'user.address']"
  :json1="a"
  :json2="b"
/>

内容截断

默认全量展示所有内容。设置 truncate 可对超长字段启用省略号截断:

<DiffViewer :json1="a" :json2="b" :truncate="true" />

截断范围:Normal 模式值字段(max-width: 300px)、Tree 模式键名(200px)及旧值/新值(240px)。

原始数据展示

设置 showRawData 可在差异视图上方展示双列原始 JSON 面板(左列原始数据、右列修改后数据):

<DiffViewer :json1="a" :json2="b" :show-raw-data="true" />

raw-data 插槽

通过 raw-data 具名插槽可完全自定义原始数据的展示方式,插槽通过 slot props 暴露 json1json2

<DiffViewer :json1="a" :json2="b" :show-raw-data="true">
  <template #raw-data="{ json1, json2 }">
    <div class="my-raw-panel">
      <textarea :value="JSON.stringify(json1, null, 2)" readonly />
      <textarea :value="JSON.stringify(json2, null, 2)" readonly />
    </div>
  </template>
</DiffViewer>

插槽仅在 showRawData="true" 时渲染。提供插槽内容后,内置的双列 JSON 面板会被替换。

样式定制

所有内置 CSS 类名均以 jdv- 为前缀(BEM 规范),可按需覆盖:

/* 修改差异行背景色 */
.jdv-node__row--modified { background: #fff8e1; }
.jdv-normal__item--added  { border-left-color: #4caf50; }

/* 修改统计栏背景 */
.jdv-stats { background: #f0f4ff; }

通过 customClass 附加类名以限定作用域:

<DiffViewer custom-class="my-diff" :json1="a" :json2="b" />
.my-diff .jdv-node__key { color: #1a1a2e; }

TypeScript

import type { DiffViewerProps, DiffStats, StatsDisplayConfig } from 'json-diff-vue/vue3'

兼容性

  • Vue 3.x
  • Vue 2.0+(所有 Vue 2.x 版本,无需 Composition API)
  • 现代浏览器(Chrome / Firefox / Safari / Edge)

打包工具兼容性

| 打包工具 | 支持情况 | |---|---| | Vite 3+ | ✅ | | webpack 5 | ✅ | | webpack 4(Vue CLI 4.x) | ✅ | | Rollup | ✅ |

webpack 4 说明: webpack 4 不支持 package.jsonexports 字段。本包提供了物理代理文件(vue2/index.jsvue3/index.jsstyle.css),webpack 4 会自动通过这些文件加载正确的产物,无需任何额外配置。

更新日志

查看 CHANGELOG.md 了解版本更新历史。

相关项目