-
Notifications
You must be signed in to change notification settings - Fork 26.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
chore: replace deprecated String.prototype.substr() #35421
chore: replace deprecated String.prototype.substr() #35421
Conversation
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
.substr() is deprecated so we replace it with .slice() which works similarily but isn't deprecated Signed-off-by: Tobias Speicher <rootcommander@gmail.com>
Failing test suitesCommit: 36601c4
Expand output● Custom routes › serverless mode › should handle external beforeFiles rewrite correctly
Read more about building and testing Next.js in contributing.md. |
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that substr
and slice
are not exactly the same.
Consider this example:
const str = 'hello';
console.log(str.substr(0, -1));
console.log(str.slice(0, -1));
Also looks like a test is failing
This is correct. It can sometimes make sense to use As for the failed test I'm not sure why that's happening as it did work with the same code earlier, just missing liting. Might be a test fluke? |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
please do notice that |
Both |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add a rule to eslint? Otherwise we'll likely get substr()
usage again since we merge 150+ PRs each month.
I have created #35499 which adds an ESLint warning when someone wants to use |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
Stats from current PRDefault Build (Increase detected
|
vercel/next.js canary | CommanderRoot/next.js chore/rm-deprecated-substr | Change | |
---|---|---|---|
buildDuration | 16s | 15.6s | -443ms |
buildDurationCached | 6.2s | 6.2s | -95ms |
nodeModulesSize | 467 MB | 467 MB | -166 B |
Page Load Tests Overall increase ✓
vercel/next.js canary | CommanderRoot/next.js chore/rm-deprecated-substr | Change | |
---|---|---|---|
/ failed reqs | 0 | 0 | ✓ |
/ total time (seconds) | 3.205 | 3.135 | -0.07 |
/ avg req/sec | 779.96 | 797.55 | +17.59 |
/error-in-render failed reqs | 0 | 0 | ✓ |
/error-in-render total time (seconds) | 1.384 | 1.364 | -0.02 |
/error-in-render avg req/sec | 1806.5 | 1833.34 | +26.84 |
Client Bundles (main, webpack) Overall decrease ✓
vercel/next.js canary | CommanderRoot/next.js chore/rm-deprecated-substr | Change | |
---|---|---|---|
925.HASH.js gzip | 179 B | 179 B | ✓ |
framework-HASH.js gzip | 42 kB | 42 kB | ✓ |
main-HASH.js gzip | 28 kB | 28 kB | -5 B |
webpack-HASH.js gzip | 1.44 kB | 1.44 kB | ✓ |
Overall change | 71.6 kB | 71.6 kB | -5 B |
Legacy Client Bundles (polyfills)
vercel/next.js canary | CommanderRoot/next.js chore/rm-deprecated-substr | Change | |
---|---|---|---|
polyfills-HASH.js gzip | 31 kB | 31 kB | ✓ |
Overall change | 31 kB | 31 kB | ✓ |
Client Pages
vercel/next.js canary | CommanderRoot/next.js chore/rm-deprecated-substr | Change | |
---|---|---|---|
_app-HASH.js gzip | 1.36 kB | 1.36 kB | ✓ |
_error-HASH.js gzip | 192 B | 192 B | ✓ |
amp-HASH.js gzip | 309 B | 309 B | ✓ |
css-HASH.js gzip | 327 B | 327 B | ✓ |
dynamic-HASH.js gzip | 2.57 kB | 2.57 kB | ✓ |
head-HASH.js gzip | 351 B | 351 B | ✓ |
hooks-HASH.js gzip | 920 B | 920 B | ✓ |
image-HASH.js gzip | 5.48 kB | 5.48 kB | ✓ |
index-HASH.js gzip | 263 B | 263 B | ✓ |
link-HASH.js gzip | 2.26 kB | 2.26 kB | ✓ |
routerDirect..HASH.js gzip | 320 B | 320 B | ✓ |
script-HASH.js gzip | 387 B | 387 B | ✓ |
withRouter-HASH.js gzip | 319 B | 319 B | ✓ |
85e02e95b279..7e3.css gzip | 107 B | 107 B | ✓ |
Overall change | 15.2 kB | 15.2 kB | ✓ |
Client Build Manifests
vercel/next.js canary | CommanderRoot/next.js chore/rm-deprecated-substr | Change | |
---|---|---|---|
_buildManifest.js gzip | 460 B | 460 B | ✓ |
Overall change | 460 B | 460 B | ✓ |
Rendered Page Sizes Overall increase ⚠️
vercel/next.js canary | CommanderRoot/next.js chore/rm-deprecated-substr | Change | |
---|---|---|---|
index.html gzip | 531 B | 531 B | ✓ |
link.html gzip | 544 B | 545 B | |
withRouter.html gzip | 524 B | 525 B | |
Overall change | 1.6 kB | 1.6 kB |
Diffs
Diff for main-HASH.js
@@ -4401,7 +4401,7 @@
return (
(0, _normalizeTrailingSlash).normalizePathTrailingSlash(
"".concat(prefix).concat(pathname)
- ) + path.substr(pathname.length)
+ ) + path.slice(pathname.length)
);
}
function getDomainLocale(path, locale, locales, domainLocales) {
@@ -4534,7 +4534,7 @@
// invalid and will never match a Next.js page/file
var urlProtoMatch = urlAsString.match(/^[a-zA-Z]{1,}:\/\//);
var urlAsStringNoProto = urlProtoMatch
- ? urlAsString.substr(urlProtoMatch[0].length)
+ ? urlAsString.slice(urlProtoMatch[0].length)
: urlAsString;
var urlParts = urlAsStringNoProto.split("?");
if ((urlParts[0] || "").match(/(\/\/|\\)/)) {
@@ -4878,7 +4878,7 @@
if (true) {
// make sure "as" doesn't start with double slashes or else it can
// throw an error as it's considered invalid
- if (as1.substr(0, 2) !== "//") {
+ if (!as1.startsWith("//")) {
// in order for `e.state` to work on the `onpopstate` event
// we have to register the initial route upon initialization
var options1 = {
@@ -6737,7 +6737,7 @@
query = String(querystring.urlQueryToSearchParams(query));
}
var search = urlObj.search || (query && "?".concat(query)) || "";
- if (protocol && protocol.substr(-1) !== ":") protocol += ":";
+ if (protocol && !protocol.endsWith(":")) protocol += ":";
if (
urlObj.slashes ||
((!protocol || slashedProtocols.test(protocol)) && host !== false)
Diff for index.html
@@ -19,7 +19,7 @@
defer=""
></script>
<script
- src="/_next/static/chunks/main-0bf777b4298ee871.js"
+ src="/_next/static/chunks/main-356143d159a72188.js"
defer=""
></script>
<script
Diff for link.html
@@ -19,7 +19,7 @@
defer=""
></script>
<script
- src="/_next/static/chunks/main-0bf777b4298ee871.js"
+ src="/_next/static/chunks/main-356143d159a72188.js"
defer=""
></script>
<script
Diff for withRouter.html
@@ -19,7 +19,7 @@
defer=""
></script>
<script
- src="/_next/static/chunks/main-0bf777b4298ee871.js"
+ src="/_next/static/chunks/main-356143d159a72188.js"
defer=""
></script>
<script
Default Build with SWC (Increase detected ⚠️ )
General Overall decrease ✓
vercel/next.js canary | CommanderRoot/next.js chore/rm-deprecated-substr | Change | |
---|---|---|---|
buildDuration | 19.2s | 19s | -202ms |
buildDurationCached | 6.1s | 6.2s | |
nodeModulesSize | 467 MB | 467 MB | -166 B |
Page Load Tests Overall increase ✓
vercel/next.js canary | CommanderRoot/next.js chore/rm-deprecated-substr | Change | |
---|---|---|---|
/ failed reqs | 0 | 0 | ✓ |
/ total time (seconds) | 3.141 | 3.133 | -0.01 |
/ avg req/sec | 796.03 | 798.06 | +2.03 |
/error-in-render failed reqs | 0 | 0 | ✓ |
/error-in-render total time (seconds) | 1.371 | 1.363 | -0.01 |
/error-in-render avg req/sec | 1822.86 | 1834.46 | +11.6 |
Client Bundles (main, webpack) Overall decrease ✓
vercel/next.js canary | CommanderRoot/next.js chore/rm-deprecated-substr | Change | |
---|---|---|---|
925.HASH.js gzip | 178 B | 178 B | ✓ |
framework-HASH.js gzip | 42.3 kB | 42.3 kB | ✓ |
main-HASH.js gzip | 28.2 kB | 28.2 kB | -2 B |
webpack-HASH.js gzip | 1.45 kB | 1.45 kB | ✓ |
Overall change | 72.1 kB | 72.1 kB | -2 B |
Legacy Client Bundles (polyfills)
vercel/next.js canary | CommanderRoot/next.js chore/rm-deprecated-substr | Change | |
---|---|---|---|
polyfills-HASH.js gzip | 31 kB | 31 kB | ✓ |
Overall change | 31 kB | 31 kB | ✓ |
Client Pages
vercel/next.js canary | CommanderRoot/next.js chore/rm-deprecated-substr | Change | |
---|---|---|---|
_app-HASH.js gzip | 1.35 kB | 1.35 kB | ✓ |
_error-HASH.js gzip | 179 B | 179 B | ✓ |
amp-HASH.js gzip | 313 B | 313 B | ✓ |
css-HASH.js gzip | 324 B | 324 B | ✓ |
dynamic-HASH.js gzip | 2.56 kB | 2.56 kB | ✓ |
head-HASH.js gzip | 351 B | 351 B | ✓ |
hooks-HASH.js gzip | 921 B | 921 B | ✓ |
image-HASH.js gzip | 5.59 kB | 5.59 kB | ✓ |
index-HASH.js gzip | 261 B | 261 B | ✓ |
link-HASH.js gzip | 2.33 kB | 2.33 kB | ✓ |
routerDirect..HASH.js gzip | 322 B | 322 B | ✓ |
script-HASH.js gzip | 388 B | 388 B | ✓ |
withRouter-HASH.js gzip | 317 B | 317 B | ✓ |
85e02e95b279..7e3.css gzip | 107 B | 107 B | ✓ |
Overall change | 15.3 kB | 15.3 kB | ✓ |
Client Build Manifests
vercel/next.js canary | CommanderRoot/next.js chore/rm-deprecated-substr | Change | |
---|---|---|---|
_buildManifest.js gzip | 458 B | 458 B | ✓ |
Overall change | 458 B | 458 B | ✓ |
Rendered Page Sizes
vercel/next.js canary | CommanderRoot/next.js chore/rm-deprecated-substr | Change | |
---|---|---|---|
index.html gzip | 531 B | 531 B | ✓ |
link.html gzip | 546 B | 546 B | ✓ |
withRouter.html gzip | 527 B | 527 B | ✓ |
Overall change | 1.6 kB | 1.6 kB | ✓ |
Diffs
Diff for main-HASH.js
@@ -4401,7 +4401,7 @@
return (
(0, _normalizeTrailingSlash).normalizePathTrailingSlash(
"".concat(prefix).concat(pathname)
- ) + path.substr(pathname.length)
+ ) + path.slice(pathname.length)
);
}
function getDomainLocale(path, locale, locales, domainLocales) {
@@ -4534,7 +4534,7 @@
// invalid and will never match a Next.js page/file
var urlProtoMatch = urlAsString.match(/^[a-zA-Z]{1,}:\/\//);
var urlAsStringNoProto = urlProtoMatch
- ? urlAsString.substr(urlProtoMatch[0].length)
+ ? urlAsString.slice(urlProtoMatch[0].length)
: urlAsString;
var urlParts = urlAsStringNoProto.split("?");
if ((urlParts[0] || "").match(/(\/\/|\\)/)) {
@@ -4878,7 +4878,7 @@
if (true) {
// make sure "as" doesn't start with double slashes or else it can
// throw an error as it's considered invalid
- if (as1.substr(0, 2) !== "//") {
+ if (!as1.startsWith("//")) {
// in order for `e.state` to work on the `onpopstate` event
// we have to register the initial route upon initialization
var options1 = {
@@ -6737,7 +6737,7 @@
query = String(querystring.urlQueryToSearchParams(query));
}
var search = urlObj.search || (query && "?".concat(query)) || "";
- if (protocol && protocol.substr(-1) !== ":") protocol += ":";
+ if (protocol && !protocol.endsWith(":")) protocol += ":";
if (
urlObj.slashes ||
((!protocol || slashedProtocols.test(protocol)) && host !== false)
Diff for index.html
@@ -19,7 +19,7 @@
defer=""
></script>
<script
- src="/_next/static/chunks/main-0bf777b4298ee871.js"
+ src="/_next/static/chunks/main-356143d159a72188.js"
defer=""
></script>
<script
Diff for link.html
@@ -19,7 +19,7 @@
defer=""
></script>
<script
- src="/_next/static/chunks/main-0bf777b4298ee871.js"
+ src="/_next/static/chunks/main-356143d159a72188.js"
defer=""
></script>
<script
Diff for withRouter.html
@@ -19,7 +19,7 @@
defer=""
></script>
<script
- src="/_next/static/chunks/main-0bf777b4298ee871.js"
+ src="/_next/static/chunks/main-356143d159a72188.js"
defer=""
></script>
<script
* test: warn on substr() usage Don't allow any new substr() usage after #35421 Signed-off-by: Tobias Speicher <rootcommander@gmail.com> * Apply suggestions from code review * Use slice in router-utils Co-authored-by: Steven <steven@ceriously.com>
String.prototype.substr() is deprecated so we replace it with String.prototype.slice() which works similarily but isn't deprecated.
.substr() probably isn't going away anytime soon but the change is trivial so it doesn't hurt to do it.
Bug
fixes #number
contributing.md
Feature
fixes #number
contributing.md
Documentation / Examples
yarn lint