跳到主要内容

jsdiff 使用指南

· 阅读需 3 分钟
素明诚
Full stack development

https://github.com/kpdecker/jsdiff 是一个用于计算文本差异的 JavaScript 库。它可以在浏览器和 Node.js 环境中运行,方便地比较两段文本并获取它们之间的差异信息。

本文将介绍如何在前端项目中使用 jsdiff,并通过一些示例来帮助你快速上手。

安装

你可以通过 pnpm 或 yarn 安装 jsdiff

pnpm install diff
# 或
yarn add diff

在浏览器中,你也可以通过 CDN 引入

<script src="https://unpkg.com/diff/dist/diff.min.js"></script>

基本用法

jsdiff 提供了多种比较文本的方法,常用的有

  • diffChars(oldStr, newStr[, options])按字符比较
  • diffWords(oldStr, newStr[, options])按单词比较
  • diffLines(oldStr, newStr[, options])按行比较

这些方法返回一个差异对象数组,你可以根据这些对象来展示差异。

示例按字符比较

const Diff = require('diff');

const oldStr = 'Hello World';
const newStr = 'Hello Javascript World';

const diff = Diff.diffChars(oldStr, newStr);

diff.forEach((part) => {
// 添加部分用绿色显示,删除部分用红色显示,未变部分用灰色显示
const color = part.added ? 'green' :
part.removed ? 'red' : 'grey';
console.log(part.value, color);
});

输出

Hello  grey
Javascript green
World grey

示例按单词比较

const Diff = require('diff');

const oldStr = 'I love programming.';
const newStr = 'We love coding.';

const diff = Diff.diffWords(oldStr, newStr);

diff.forEach((part) => {
const color = part.added ? 'green' :
part.removed ? 'red' : 'grey';
console.log(part.value, color);
});

输出

We green
I red
love grey
coding. green
programming. red

示例按行比较

const Diff = require('diff');

const oldStr = `Line one
Line two
Line three`;

const newStr = `Line one
Line 2
Line three`;

const diff = Diff.diffLines(oldStr, newStr);

diff.forEach((part) => {
const color = part.added ? 'green' :
part.removed ? 'red' : 'grey';
console.log(part.value, color);
});

输出

Line one
grey
Line two
red
Line 2
green
Line three grey

创建补丁

jsdiff 可以生成统一格式(unified format)的补丁,方便在版本控制中使用。

示例创建补丁

const Diff = require('diff');

const oldStr = 'Hello World';
const newStr = 'Hello Javascript World';

const patch = Diff.createPatch('filename.txt', oldStr, newStr);

console.log(patch);

输出

Index: filename.txt
===================================================================
--- filename.txt
+++ filename.txt
@@ -1,1 +1,1 @@
-Hello World
+Hello Javascript World

应用补丁

你也可以将补丁应用到原始文本上。

示例应用补丁

const Diff = require('diff');

const oldStr = 'Hello World';
const patch = `Index: filename.txt
===================================================================
--- filename.txt
+++ filename.txt
@@ -1,1 +1,1 @@
-Hello World
+Hello Javascript World`;

const newStr = Diff.applyPatch(oldStr, patch);

console.log(newStr);

输出

Hello Javascript World

比较数组

除了字符串,jsdiff 还可以比较数组。

示例比较数组

const Diff = require('diff');

const oldArr = ['apple', 'banana', 'cherry'];
const newArr = ['apple', 'blueberry', 'cherry', 'date'];

const diff = Diff.diffArrays(oldArr, newArr);

diff.forEach((part) => {
const added = part.added ? '+' : '';
const removed = part.removed ? '-' : '';
console.log(`${added}${removed}${part.value}`);
});

输出

apple
-banana
+blueberry
cherry
+date

选项参数

jsdiff 的比较方法可以接受一个可选的 options 对象,常用的选项有

  • ignoreCase忽略大小写
  • ignoreWhitespace忽略空白字符

示例忽略空白字符

const Diff = require('diff');

const oldStr = 'Hello World';
const newStr = 'Hello World';

const diff = Diff.diffWords(oldStr, newStr, { ignoreWhitespace: true });

diff.forEach((part) => {
const color = part.added ? 'green' :
part.removed ? 'red' : 'grey';
console.log(part.value, color);
});

输出

Hello World grey

在浏览器中使用

在浏览器中,你可以直接使用 <script> 标签引入 jsdiff,然后使用全局变量 Diff

<script src="https://unpkg.com/diff/dist/diff.min.js"></script>
<script>
const oldStr = 'Hello World';
const newStr = 'Hello Javascript World';

const diff = Diff.diffWords(oldStr, newStr);

diff.forEach((part) => {
const color = part.added ? 'green' :
part.removed ? 'red' : 'grey';
console.log(part.value, color);
});
</script>

原理

http://www.xmailserver.org/diff2.pdf