mirror of
https://github.com/vercel/next.js.git
synced 2026-09-20 02:25:18 +08:00
6324fdba80
<!-- Thanks for opening a PR! Your contribution is much appreciated. To make sure your PR is handled as smoothly as possible we request that you follow the checklist sections below. Choose the right checklist for the change(s) that you're making: ## For Contributors We encourage you to use AI to assist you in researching, creating, and reviewing changes. However, you must review and deeply understand the contributions you are making. For this reason, **pull request descriptions from external contributors must be written by a human**. ### Improving Documentation - Run `pnpm prettier-fix` to fix formatting issues before opening the PR. - Read the Docs Contribution Guide to ensure your contribution follows the docs guidelines: https://nextjs.org/docs/community/contribution-guide ### Fixing a bug - Related issues linked using `fixes #number` - Tests added. See: https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs - Errors have a helpful link attached, see https://github.com/vercel/next.js/blob/canary/contributing.md ### Adding a feature - Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. (A discussion must be opened, see https://github.com/vercel/next.js/discussions/new?category=ideas) - Related issues/discussions are linked using `fixes #number` - e2e tests added (https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs) - Documentation added - Telemetry added. In case of a feature if it's used or not. - Errors have a helpful link attached, see https://github.com/vercel/next.js/blob/canary/contributing.md ### Signed commits - This repository requires verified commit signatures on protected branches. - If this pull request is blocked for unsigned commits, re-sign the commits and force-push the branch. - A `Signed-off-by` line in the commit message is not enough. ## For Maintainers - Minimal description (aim for explaining to someone not on the team to understand the PR) - When linking to a Slack thread, you might want to share details of the conclusion - Link both the Linear (Fixes NEXT-xxx) and the GitHub issues - Add review comments if necessary to explain to the reviewer the logic behind a change ### What? ### Why? ### How? Closes NEXT- Fixes # -->
139 lines
5.3 KiB
TypeScript
139 lines
5.3 KiB
TypeScript
/* eslint-env jest */
|
|
import { transform } from 'next/dist/build/swc'
|
|
import { installBindings } from 'next/dist/build/swc/install-bindings'
|
|
import path from 'path'
|
|
import fsp from 'fs/promises'
|
|
|
|
const swc = async (code) => {
|
|
let output = await transform(code)
|
|
return output.code
|
|
}
|
|
|
|
const trim = (s) => s.join('\n').trim().replace(/^\s+/gm, '')
|
|
|
|
describe('next/swc', () => {
|
|
beforeAll(async () => {
|
|
await installBindings()
|
|
})
|
|
describe('hook_optimizer', () => {
|
|
it('should leave alone array destructuring of hooks', async () => {
|
|
const output = await swc(
|
|
trim`
|
|
import { useState } from 'react';
|
|
const [count, setCount] = useState(0);
|
|
`
|
|
)
|
|
|
|
expect(output).toMatchInlineSnapshot(`
|
|
"function _array_like_to_array(arr, len) {
|
|
if (len == null || len > arr.length) len = arr.length;
|
|
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
return arr2;
|
|
}
|
|
function _array_with_holes(arr) {
|
|
if (Array.isArray(arr)) return arr;
|
|
}
|
|
function _iterable_to_array_limit(arr, i) {
|
|
var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
|
|
if (_i == null) return;
|
|
var _arr = [];
|
|
var _n = true;
|
|
var _d = false;
|
|
var _s, _e;
|
|
try {
|
|
for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
|
|
_arr.push(_s.value);
|
|
if (i && _arr.length === i) break;
|
|
}
|
|
} catch (err) {
|
|
_d = true;
|
|
_e = err;
|
|
} finally{
|
|
try {
|
|
if (!_n && _i["return"] != null) _i["return"]();
|
|
} finally{
|
|
if (_d) throw _e;
|
|
}
|
|
}
|
|
return _arr;
|
|
}
|
|
function _non_iterable_rest() {
|
|
throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
}
|
|
function _sliced_to_array(arr, i) {
|
|
return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
|
|
}
|
|
function _unsupported_iterable_to_array(o, minLen) {
|
|
if (!o) return;
|
|
if (typeof o === "string") return _array_like_to_array(o, minLen);
|
|
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
if (n === "Map" || n === "Set") return Array.from(n);
|
|
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
|
|
}
|
|
import { useState } from 'react';
|
|
var _useState = _sliced_to_array(useState(0), 2), count = _useState[0], setCount = _useState[1];
|
|
"
|
|
`)
|
|
})
|
|
|
|
it('should leave alone array spread of hooks', async () => {
|
|
const output = await swc(
|
|
trim`
|
|
import { useState } from 'react';
|
|
const [...copy] = useState(0);
|
|
`
|
|
)
|
|
|
|
expect(output).toMatchInlineSnapshot(`
|
|
"function _array_like_to_array(arr, len) {
|
|
if (len == null || len > arr.length) len = arr.length;
|
|
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
return arr2;
|
|
}
|
|
function _array_with_holes(arr) {
|
|
if (Array.isArray(arr)) return arr;
|
|
}
|
|
function _iterable_to_array(iter) {
|
|
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) {
|
|
return Array.from(iter);
|
|
}
|
|
}
|
|
function _non_iterable_rest() {
|
|
throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
}
|
|
function _to_array(arr) {
|
|
return _array_with_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_rest();
|
|
}
|
|
function _unsupported_iterable_to_array(o, minLen) {
|
|
if (!o) return;
|
|
if (typeof o === "string") return _array_like_to_array(o, minLen);
|
|
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
if (n === "Map" || n === "Set") return Array.from(n);
|
|
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
|
|
}
|
|
import { useState } from 'react';
|
|
var _useState = _to_array(useState(0)), copy = _useState.slice(0);
|
|
"
|
|
`)
|
|
})
|
|
})
|
|
|
|
describe('private env replacement', () => {
|
|
it('__NEXT_REQUIRED_NODE_VERSION_RANGE is replaced', async () => {
|
|
const pkgDir = path.dirname(require.resolve('next/package.json'))
|
|
const nextEntryContent = await fsp.readFile(
|
|
path.join(pkgDir, 'dist/bin/next'),
|
|
'utf8'
|
|
)
|
|
expect(nextEntryContent).not.toContain(
|
|
'__NEXT_REQUIRED_NODE_VERSION_RANGE'
|
|
)
|
|
expect(nextEntryContent).toMatch(
|
|
/For Next.js, Node.js version "\$\{">=\d+\.\d+\.\d*"\}" is required./
|
|
)
|
|
})
|
|
})
|
|
})
|