Skip to content

Commit a1b857c

Browse files
committed
perf: avoid create uncessary overrides for replace
1 parent 6f6cd52 commit a1b857c

5 files changed

Lines changed: 44 additions & 14 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ The differences from [`String.replace`]((https://developer.mozilla.org/en-US/doc
193193
### s.replaceAll( regexpOrString, substitution )
194194

195195
Same as `s.replace`, but replace all matched strings instead of just one.
196-
If `substitution` is a regex, then it must have the global (`g`) flag set, or a `TypeError` is thrown. Matches the behavior of the bultin [`String.property.replaceAll`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replaceAll).
196+
If `substitution` is a regex, then it must have the global (`g`) flag set, or a `TypeError` is thrown. Matches the behavior of the builtin [`String.property.replaceAll`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replaceAll).
197197

198198
### s.remove( start, end )
199199

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s",
3434
"format": "prettier --single-quote --print-width 100 --use-tabs --write src/*.js src/**/*.js",
3535
"lint": "eslint src test && publint",
36+
"lint:fix": "eslint src test --fix",
3637
"prepare": "npm run build",
3738
"prepublishOnly": "npm run lint && rm -rf dist && npm test",
3839
"release": "bumpp -x \"npm run changelog\" --all --commit --tag --push && npm publish",

src/MagicString.js

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -797,21 +797,29 @@ export default class MagicString {
797797
if (searchValue.global) {
798798
const matches = matchAll(searchValue, this.original);
799799
matches.forEach((match) => {
800-
if (match.index != null)
800+
if (match.index != null) {
801+
const replacement = getReplacement(match, this.original);
802+
if (replacement !== match[0]) {
803+
this.overwrite(
804+
match.index,
805+
match.index + match[0].length,
806+
replacement
807+
);
808+
}
809+
}
810+
});
811+
} else {
812+
const match = this.original.match(searchValue);
813+
if (match && match.index != null) {
814+
const replacement = getReplacement(match, this.original);
815+
if (replacement !== match[0]) {
801816
this.overwrite(
802817
match.index,
803818
match.index + match[0].length,
804-
getReplacement(match, this.original),
819+
replacement
805820
);
806-
});
807-
} else {
808-
const match = this.original.match(searchValue);
809-
if (match && match.index != null)
810-
this.overwrite(
811-
match.index,
812-
match.index + match[0].length,
813-
getReplacement(match, this.original),
814-
);
821+
}
822+
}
815823
}
816824
return this;
817825
}
@@ -843,7 +851,9 @@ export default class MagicString {
843851
index !== -1;
844852
index = original.indexOf(string, index + stringLength)
845853
) {
846-
this.overwrite(index, index + stringLength, replacement);
854+
const previous = original.slice(index, index + stringLength);
855+
if (previous !== replacement)
856+
this.overwrite(index, index + stringLength, replacement);
847857
}
848858

849859
return this;

test/MagicString.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1758,6 +1758,25 @@ describe('MagicString', () => {
17581758
new MagicString(code).replace(regex, replacer).toString()
17591759
);
17601760
});
1761+
1762+
it('should ignore non-changed replacements', () => {
1763+
const code = 'a12bc345#$*%';
1764+
const matched = [];
1765+
1766+
const s = new MagicString(code);
1767+
1768+
assert.strictEqual(s.firstChunk, s.lastChunk);
1769+
1770+
s.replace(/(\d)/g, (match, $1) => {
1771+
matched.push($1);
1772+
return match;
1773+
});
1774+
1775+
assert.strictEqual(s.toString(), code);
1776+
assert.deepStrictEqual(matched, ['1', '2', '3', '4', '5']);
1777+
1778+
assert.strictEqual(s.firstChunk, s.lastChunk);
1779+
});
17611780
});
17621781

17631782
describe('replaceAll', () => {

0 commit comments

Comments
 (0)