diff --git a/.alexrc b/.alexrc index 157d1da8cca5302..47862f2c80a10d5 100644 --- a/.alexrc +++ b/.alexrc @@ -16,6 +16,7 @@ "hook", "hooks", "host-hostess", - "invalid" + "invalid", + "remains" ] } diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 569ca335626aefe..6e0fcfef8433c92 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -2,9 +2,9 @@ # https://help.github.com/en/articles/about-code-owners * @timneutkens @ijjk @shuding @huozhi -/.github/ @timneutkens @ijjk @shuding @styfle @huozhi @padmaia -/docs/ @timneutkens @ijjk @shuding @styfle @huozhi @padmaia @leerob @lfades @molebox -/examples/ @timneutkens @ijjk @shuding @leerob @lfades @steven-tey +/.github/ @timneutkens @ijjk @shuding @styfle @huozhi @padmaia @balazsorban44 +/docs/ @timneutkens @ijjk @shuding @styfle @huozhi @padmaia @leerob @balazsorban44 +/examples/ @timneutkens @ijjk @shuding @leerob @steven-tey @balazsorban44 # SWC Build (@padmaia) diff --git a/.github/workflows/build_test_deploy.yml b/.github/workflows/build_test_deploy.yml index 7ae30a4ff2bb6af..11d4c02555a88c3 100644 --- a/.github/workflows/build_test_deploy.yml +++ b/.github/workflows/build_test_deploy.yml @@ -68,7 +68,7 @@ jobs: id: cache-build with: path: ./* - key: ${{ github.sha }}-${{ github.run_number }}-${{ github.run_attempt }} + key: ${{ github.sha }}-${{ github.run_number }} lint: runs-on: ubuntu-latest @@ -84,7 +84,7 @@ jobs: id: restore-build with: path: ./* - key: ${{ github.sha }}-${{ github.run_number }}-${{ github.run_attempt }} + key: ${{ github.sha }}-${{ github.run_number }} - run: ./scripts/check-manifests.js - run: yarn lint @@ -119,7 +119,7 @@ jobs: if: ${{needs.build.outputs.docsChange != 'docs only change'}} with: path: ./* - key: ${{ github.sha }}-${{ github.run_number }}-${{ github.run_attempt }} + key: ${{ github.sha }}-${{ github.run_number }} - name: Check if: ${{needs.build.outputs.docsChange != 'docs only change'}} @@ -157,7 +157,7 @@ jobs: id: restore-build with: path: ./* - key: ${{ github.sha }}-${{ github.run_number }}-${{ github.run_attempt }} + key: ${{ github.sha }}-${{ github.run_number }} - run: rm -rf .git && mv .git-bak .git if: ${{needs.build.outputs.docsChange != 'docs only change'}} @@ -190,7 +190,7 @@ jobs: id: restore-build with: path: ./* - key: ${{ github.sha }}-${{ github.run_number }}-${{ github.run_attempt }} + key: ${{ github.sha }}-${{ github.run_number }} - uses: actions/download-artifact@v2 if: ${{needs.build.outputs.docsChange != 'docs only change'}} @@ -230,7 +230,7 @@ jobs: id: restore-build with: path: ./* - key: ${{ github.sha }}-${{ github.run_number }}-${{ github.run_attempt }} + key: ${{ github.sha }}-${{ github.run_number }} - uses: actions/download-artifact@v2 if: ${{needs.build.outputs.docsChange != 'docs only change'}} @@ -281,7 +281,7 @@ jobs: id: restore-build with: path: ./* - key: ${{ github.sha }}-${{ github.run_number }}-${{ github.run_attempt }} + key: ${{ github.sha }}-${{ github.run_number }} - uses: actions/download-artifact@v2 if: ${{needs.build.outputs.docsChange != 'docs only change'}} @@ -335,7 +335,7 @@ jobs: id: restore-build with: path: ./* - key: ${{ github.sha }}-${{ github.run_number }}-${{ github.run_attempt }} + key: ${{ github.sha }}-${{ github.run_number }} - uses: actions/download-artifact@v2 if: ${{needs.build.outputs.docsChange != 'docs only change'}} @@ -386,7 +386,7 @@ jobs: id: restore-build with: path: ./* - key: ${{ github.sha }}-${{ github.run_number }}-${{ github.run_attempt }} + key: ${{ github.sha }}-${{ github.run_number }} - uses: actions/download-artifact@v2 if: ${{needs.build.outputs.docsChange != 'docs only change'}} @@ -440,7 +440,7 @@ jobs: id: restore-build with: path: ./* - key: ${{ github.sha }}-${{ github.run_number }}-${{ github.run_attempt }} + key: ${{ github.sha }}-${{ github.run_number }} - uses: actions/download-artifact@v2 if: ${{needs.build.outputs.docsChange != 'docs only change'}} @@ -481,7 +481,7 @@ jobs: id: restore-build with: path: ./* - key: ${{ github.sha }}-${{ github.run_number }}-${{ github.run_attempt }} + key: ${{ github.sha }}-${{ github.run_number }} - uses: actions/download-artifact@v2 if: ${{needs.build.outputs.docsChange != 'docs only change'}} @@ -525,7 +525,7 @@ jobs: id: restore-build with: path: ./* - key: ${{ github.sha }}-${{ github.run_number }}-${{ github.run_attempt }} + key: ${{ github.sha }}-${{ github.run_number }} - uses: actions/download-artifact@v2 if: ${{needs.build.outputs.docsChange != 'docs only change'}} @@ -566,7 +566,7 @@ jobs: id: restore-build with: path: ./* - key: ${{ github.sha }}-${{ github.run_number }}-${{ github.run_attempt }} + key: ${{ github.sha }}-${{ github.run_number }} - uses: actions/download-artifact@v2 if: ${{needs.build.outputs.docsChange != 'docs only change'}} @@ -611,7 +611,7 @@ jobs: id: restore-build with: path: ./* - key: ${{ github.sha }}-${{ github.run_number }}-${{ github.run_attempt }} + key: ${{ github.sha }}-${{ github.run_number }} - uses: pnpm/action-setup@v2.2.1 with: @@ -659,7 +659,7 @@ jobs: id: restore-build with: path: ./* - key: ${{ github.sha }}-${{ github.run_number }}-${{ github.run_attempt }} + key: ${{ github.sha }}-${{ github.run_number }} - uses: actions/download-artifact@v2 if: ${{needs.build.outputs.docsChange != 'docs only change'}} @@ -709,7 +709,7 @@ jobs: id: restore-build with: path: ./* - key: ${{ github.sha }}-${{ github.run_number }}-${{ github.run_attempt }} + key: ${{ github.sha }}-${{ github.run_number }} - uses: actions/download-artifact@v2 if: ${{needs.build.outputs.docsChange != 'docs only change'}} with: @@ -751,7 +751,7 @@ jobs: id: restore-build with: path: ./* - key: ${{ github.sha }}-${{ github.run_number }}-${{ github.run_attempt }} + key: ${{ github.sha }}-${{ github.run_number }} - uses: actions/download-artifact@v2 if: ${{needs.build.outputs.docsChange != 'docs only change'}} @@ -795,7 +795,7 @@ jobs: id: restore-build with: path: ./* - key: ${{ github.sha }}-${{ github.run_number }}-${{ github.run_attempt }} + key: ${{ github.sha }}-${{ github.run_number }} - uses: actions/download-artifact@v2 if: ${{needs.build.outputs.docsChange != 'docs only change'}} @@ -828,7 +828,7 @@ jobs: id: restore-build with: path: ./* - key: ${{ github.sha }}-${{ github.run_number }}-${{ github.run_attempt }} + key: ${{ github.sha }}-${{ github.run_number }} - uses: actions/download-artifact@v2 if: ${{needs.build.outputs.docsChange != 'docs only change'}} with: @@ -864,7 +864,7 @@ jobs: id: restore-build with: path: ./* - key: ${{ github.sha }}-${{ github.run_number }}-${{ github.run_attempt }} + key: ${{ github.sha }}-${{ github.run_number }} - uses: actions/download-artifact@v2 with: @@ -894,7 +894,7 @@ jobs: id: restore-build with: path: ./* - key: ${{ github.sha }}-${{ github.run_number }}-${{ github.run_attempt }} + key: ${{ github.sha }}-${{ github.run_number }} - uses: actions/download-artifact@v2 with: @@ -1284,7 +1284,7 @@ jobs: id: restore-build with: path: ./* - key: ${{ github.sha }}-${{ github.run_number }}-${{ github.run_attempt }} + key: ${{ github.sha }}-${{ github.run_number }} - name: Setup node uses: actions/setup-node@v2 @@ -1336,7 +1336,7 @@ jobs: id: restore-build with: path: ./* - key: ${{ github.sha }}-${{ github.run_number }}-${{ github.run_attempt }} + key: ${{ github.sha }}-${{ github.run_number }} - name: Setup node if: ${{needs.build.outputs.docsChange != 'docs only change'}} @@ -1413,7 +1413,7 @@ jobs: if: ${{needs.build.outputs.docsChange != 'docs only change'}} with: path: ./* - key: ${{ github.sha }}-${{ github.run_number }}-${{ github.run_attempt }} + key: ${{ github.sha }}-${{ github.run_number }} - name: Set Git Short sha Env if: ${{needs.build.outputs.docsChange != 'docs only change'}} diff --git a/docs/advanced-features/react-18/server-components.md b/docs/advanced-features/react-18/server-components.md index 265dd4cb22e4723..4426f7eda2e7c0d 100644 --- a/docs/advanced-features/react-18/server-components.md +++ b/docs/advanced-features/react-18/server-components.md @@ -32,7 +32,11 @@ To run a component on the server, append `.server.js` to the end of the filename For client components, append `.client.js` to the filename. For example, `./components/avatar.client.js`. -You can then import other server or client components from any server component. Note: a server component **can not** be imported by a client component. Components without "server/client" extensions will be treated as shared components and can be used and rendered by both sides, depending on where it is imported. For example: +Server components can import server components and client components. + +Client components **cannot** import server components. + +Components without a `server` or `client` extension will be treated as shared components and can be imported by server components and client components. For example: ```jsx // pages/home.server.js diff --git a/docs/api-reference/next/router.md b/docs/api-reference/next/router.md index 9c0e78dfd784e0d..c5ae4ffbc56812d 100644 --- a/docs/api-reference/next/router.md +++ b/docs/api-reference/next/router.md @@ -113,8 +113,6 @@ export default function Page() { } ``` -> **Note:** When navigating to the same page in Next.js, the page's state **will not** be reset by default, as the top-level React component is the same. You can manually ensure the state is updated using `useEffect`. - Redirecting the user to `pages/login.js`, useful for pages behind [authentication](/docs/authentication): ```jsx @@ -138,6 +136,58 @@ export default function Page() { } ``` +#### Resetting state after navigation + +When navigating to the same page in Next.js, the page's state **will not** be reset by default as react does not unmount unless the parent component has changed. + +```jsx +// pages/[slug].js +import Link from 'next/link' +import { useState } from 'react' +import { useRouter } from 'next/router' + +export default function Page(props) { + const router = useRouter() + const [count, setCount] = useState(0) + return ( +
+

Page: {router.query.slug}

+

Count: {count}

+ + + one + + two + +
+ ) +} +``` + +In the above example, navigating between `/one` and `/two` **will not** reset the count . The `useState` is maintained between renders because the top-level React component, `Page`, is the same. + +If you do not want this behavior, you have a couple of options: + +1. Manually ensure each state is updated using `useEffect`. In the above example, that could look like: + +```jsx +useEffect(() => { + setCount(0) +}, [router.query.slug]) +``` + +2. Use a React `key` to [tell React to remount the component](https://reactjs.org/docs/lists-and-keys.html#keys). To do this for all pages, you can use a custom app: + +```jsx +// pages/_app.js +import { useRouter } from 'next/router' + +export default function MyApp({ Component, pageProps }) { + const router = useRouter() + return +} +``` + #### With URL object You can use a URL object in the same way you can use it for [`next/link`](/docs/api-reference/next/link.md#with-url-object). Works for both the `url` and `as` parameters: diff --git a/docs/basic-features/data-fetching/get-static-props.md b/docs/basic-features/data-fetching/get-static-props.md index a5a5190fda979f4..e4a29b1c2cb482a 100644 --- a/docs/basic-features/data-fetching/get-static-props.md +++ b/docs/basic-features/data-fetching/get-static-props.md @@ -20,8 +20,8 @@ You should use `getStaticProps` if: - The data required to render the page is available at build time ahead of a user’s request - The data comes from a headless CMS -- The data can be publicly cached (not user-specific) - The page must be pre-rendered (for SEO) and be very fast — `getStaticProps` generates `HTML` and `JSON` files, both of which can be cached by a CDN for performance +- The data can be publicly cached (not user-specific). This condition can be bypassed in certain specific situation by using a Middleware to rewrite the path. ## When does getStaticProps run diff --git a/docs/basic-features/script.md b/docs/basic-features/script.md index 0c2a142c0e81556..d46bb2fe95712dc 100644 --- a/docs/basic-features/script.md +++ b/docs/basic-features/script.md @@ -256,6 +256,8 @@ export default function Home() { } ``` +> **Note: `onLoad` can't be used with the `beforeInteractive` loading strategy.** + Sometimes it is helpful to catch when a script fails to load. These errors can be handled with the `onError` property: ```jsx diff --git a/docs/migrating/from-create-react-app.md b/docs/migrating/from-create-react-app.md index 54bf69da832abe4..6e495410729414b 100644 --- a/docs/migrating/from-create-react-app.md +++ b/docs/migrating/from-create-react-app.md @@ -39,7 +39,7 @@ Here's an example `package.json`: ## Static Assets and Compiled Output -Create React App uses the `public` directory for the [entry HTML file](https://create-react-app.dev/docs/using-the-public-folder), whereas Next.js uses it for static assets. It's possible to add static assets here, but Create React App recommends importing them directly from JavaScript files. +Create React App uses the `public` directory for the [entry HTML file](https://create-react-app.dev/docs/using-the-public-folder) as well as static assets, but Next.js only uses it for static assets. When migrating from Create React App, the location of the `public` directory remains the same. - Move any images, fonts, or other static assets to `public`. - Convert `index.html` (the entry point of your application) to Next.js. Any `` code should be moved to a [custom `_document.js`](/docs/advanced-features/custom-document.md). Any shared layout between all pages should be moved to a [custom `_app.js`](/docs/advanced-features/custom-app.md). @@ -50,7 +50,9 @@ Create React App uses the `public` directory for the [entry HTML file](https://c With Create React App, you're likely using React Router. Instead of using a third-party library, Next.js includes its own [file-system based routing](/docs/routing/introduction.md). -- Convert all `Route` components to new files in the `pages` directory. +- Create a [`pages`](/docs/basic-features/pages.md) directory at the root of your project. +- Then, move the `src/App.js` file to `pages/index.js`. This file is the [index page](https://nextjs.org/docs/routing/introduction#index-routes) of your Next.js application. Populate this file with code that is used to display the index route in your Create React App. +- Convert all other `Route` components to new files in the `pages` directory. - For routes that require dynamic content (e.g. `/blog/:slug`), you can use [Dynamic Routes](/docs/routing/dynamic-routes.md) with Next.js (e.g. `pages/blog/[slug].js`). The value of `slug` is accessible through a [query parameter](/docs/routing/dynamic-routes.md). For example, the route `/blog/first-post` would forward the query object `{ 'slug': 'first-post' }` to `pages/blog/[slug].js` ([learn more here](/docs/basic-features/data-fetching/get-static-paths.md)). For more information, see [Migrating from React Router](/docs/migrating/from-react-router.md). diff --git a/docs/upgrading.md b/docs/upgrading.md index f53b2b6930b0612..9f42281afaed1bc 100644 --- a/docs/upgrading.md +++ b/docs/upgrading.md @@ -12,7 +12,7 @@ The minimum Node.js version has been bumped from 12.0.0 to 12.22.0 which is the ### Upgrade React version to latest -To upgrade you can run the following command: +The minimum required React version is `17.0.2`. To upgrade you can run the following command in the terminal: ``` npm install react@latest react-dom@latest diff --git a/errors/manifest.json b/errors/manifest.json index cad16c91a34458d..20be7781e407bd3 100644 --- a/errors/manifest.json +++ b/errors/manifest.json @@ -649,6 +649,10 @@ { "title": "invalid-getserversideprops-return-value", "path": "/errors/invalid-getserversideprops-return-value.md" + }, + { + "title": "no-assign-module-variable", + "path": "/errors/no-assign-module-variable.md" } ] } diff --git a/errors/no-assign-module-variable.md b/errors/no-assign-module-variable.md new file mode 100644 index 000000000000000..70403e10f83f8a9 --- /dev/null +++ b/errors/no-assign-module-variable.md @@ -0,0 +1,13 @@ +# No assign module variable + +#### Why This Error Occurred + +A value is being assigned to the `module` variable. The `module` variable is already used and it is highly likely that assigning to this variable will cause errors. + +#### Possible Ways to Fix It + +Use a different variable name: + +```js +let myModule = {...} +``` diff --git a/examples/with-emotion-swc/README.md b/examples/with-emotion-swc/README.md index 2b5e1a0af79f8bb..e2eb477229357cb 100644 --- a/examples/with-emotion-swc/README.md +++ b/examples/with-emotion-swc/README.md @@ -23,11 +23,11 @@ Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_mediu Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example: ```bash -npx create-next-app --example with-emotion with-emotion-app +npx create-next-app --example with-emotion-swc with-emotion-swc-app # or -yarn create next-app --example with-emotion with-emotion-app +yarn create next-app --example with-emotion-swc with-emotion-swc-app # or -pnpm create next-app -- --example with-emotion with-emotion-app +pnpm create next-app -- --example with-emotion-swc with-emotion-swc-app ``` Deploy it to the cloud with [Vercel](https://vercel.com/new?utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)). diff --git a/lerna.json b/lerna.json index b7454c3174bd659..021396f1b016d6c 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "12.1.6-canary.0" + "version": "12.1.6-canary.4" } diff --git a/package.json b/package.json index 42ab470b3d61dd9..e675dcd7ac017dd 100644 --- a/package.json +++ b/package.json @@ -167,7 +167,7 @@ "tree-kill": "1.2.2", "tsec": "0.2.1", "turbo": "1.0.28", - "typescript": "4.5.5", + "typescript": "4.6.3", "wait-port": "0.2.2", "web-streams-polyfill": "2.1.1", "webpack": "link:./node_modules/webpack5", diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index b0c774a01e701ee..04f35e5dd4cb7e5 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "12.1.6-canary.0", + "version": "12.1.6-canary.4", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index 694223ad64305ec..2b769db422f3957 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "12.1.6-canary.0", + "version": "12.1.6-canary.4", "description": "ESLint configuration used by NextJS.", "main": "index.js", "license": "MIT", @@ -9,9 +9,9 @@ "directory": "packages/eslint-config-next" }, "dependencies": { - "@next/eslint-plugin-next": "12.1.6-canary.0", + "@next/eslint-plugin-next": "12.1.6-canary.4", "@rushstack/eslint-patch": "1.0.8", - "@typescript-eslint/parser": "5.10.1", + "@typescript-eslint/parser": "5.19.0", "eslint-import-resolver-node": "0.3.4", "eslint-import-resolver-typescript": "2.4.0", "eslint-plugin-import": "2.25.2", diff --git a/packages/eslint-plugin-next/lib/index.js b/packages/eslint-plugin-next/lib/index.js index 295978b671b6fc4..f6036140f0d4b9f 100644 --- a/packages/eslint-plugin-next/lib/index.js +++ b/packages/eslint-plugin-next/lib/index.js @@ -20,6 +20,7 @@ module.exports = { 'no-duplicate-head': require('./rules/no-duplicate-head'), 'inline-script-id': require('./rules/inline-script-id'), 'next-script-for-ga': require('./rules/next-script-for-ga'), + 'no-assign-module-variable': require('./rules/no-assign-module-variable'), }, configs: { recommended: { @@ -45,6 +46,7 @@ module.exports = { '@next/next/no-typos': 1, '@next/next/no-duplicate-head': 2, '@next/next/inline-script-id': 2, + '@next/next/no-assign-module-variable': 2, }, }, 'core-web-vitals': { diff --git a/packages/eslint-plugin-next/lib/rules/no-assign-module-variable.js b/packages/eslint-plugin-next/lib/rules/no-assign-module-variable.js new file mode 100644 index 000000000000000..6b4b6109d71971f --- /dev/null +++ b/packages/eslint-plugin-next/lib/rules/no-assign-module-variable.js @@ -0,0 +1,30 @@ +module.exports = { + meta: { + docs: { + description: `Prohibit assignment to the 'module' variable`, + recommended: true, + url: 'https://nextjs.org/docs/messages/no-assign-module-variable', + }, + }, + + create: function (context) { + return { + VariableDeclaration(node) { + // Checks node.declarations array for variable with id.name of 'module' + const moduleVariableFound = node.declarations.some( + (declaration) => declaration.id.name === 'module' + ) + + // Return early if no 'module' variable is found + if (!moduleVariableFound) { + return + } + + context.report({ + node, + message: `Do not assign to the variable 'module'. See: https://nextjs.org/docs/messages/no-assign-module-variable`, + }) + }, + } + }, +} diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index 281b24031566af2..7e0051667878555 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "12.1.6-canary.0", + "version": "12.1.6-canary.4", "description": "ESLint plugin for NextJS.", "main": "lib/index.js", "license": "MIT", diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index a90f81a286ff07f..81c219f5a0f8168 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "12.1.6-canary.0", + "version": "12.1.6-canary.4", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index 788687637a14d0f..4b98f5dc3f4f302 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "12.1.6-canary.0", + "version": "12.1.6-canary.4", "license": "MIT", "dependencies": { "chalk": "4.1.0", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index 66fdf4e65a31e38..3c40d40139cec09 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "12.1.6-canary.0", + "version": "12.1.6-canary.4", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index 7e51e661b9de934..ee5b8992ff6e577 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "12.1.6-canary.0", + "version": "12.1.6-canary.4", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 42f0b90f5c2aeca..c271fe83c0566b4 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "12.1.6-canary.0", + "version": "12.1.6-canary.4", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index 16d60332e7ac3ef..72fa096f2b97083 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "12.1.6-canary.0", + "version": "12.1.6-canary.4", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index b1a000694915af2..9b81576a1bc4e48 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "12.1.6-canary.0", + "version": "12.1.6-canary.4", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/Cargo.lock b/packages/next-swc/Cargo.lock index f0d115e3af26374..2e86100a737a261 100644 --- a/packages/next-swc/Cargo.lock +++ b/packages/next-swc/Cargo.lock @@ -1853,9 +1853,9 @@ dependencies = [ [[package]] name = "swc" -version = "0.164.0" +version = "0.168.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "661eab0d653f9f4a15ed5f832c4f2cb63823cb8e0aec4bed7f07ec4b73fb2c54" +checksum = "bebce0e8afdc1f95d2ffc68fc0859339ef2a99e82d035e4bb588a335189f6aaa" dependencies = [ "ahash", "anyhow", @@ -1908,9 +1908,9 @@ dependencies = [ [[package]] name = "swc_bundler" -version = "0.133.0" +version = "0.137.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052dafe1f3a9144331ee15f0a3f2c5fe0bb535e19f0bc1ada374b2d0256c314c" +checksum = "4f9841f7675e2d7c5ec72018b4fa030e24f76275583b4a244a439b634f369318" dependencies = [ "ahash", "anyhow", @@ -1957,9 +1957,9 @@ dependencies = [ [[package]] name = "swc_common" -version = "0.17.20" +version = "0.17.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41b22848d9ad250e618289ea94a171392aea86d8d878caf0b1cad4589521b6f7" +checksum = "daac2e6fea713c68d37b29ea5fd6342213ca2915a868f38a3fd4aa6750a9b9f8" dependencies = [ "ahash", "ast_node", @@ -1987,9 +1987,9 @@ dependencies = [ [[package]] name = "swc_css" -version = "0.104.1" +version = "0.104.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9835ebfd7815b71f9b8f2ae95f65defe06692f96b26ef39acbe7d64bd33aa1c4" +checksum = "ac788fd5a430a44f509f86d81d6eb8b5636e8cb0814583ae3cd7a899cc00a78a" dependencies = [ "swc_css_ast", "swc_css_codegen", @@ -2000,9 +2000,9 @@ dependencies = [ [[package]] name = "swc_css_ast" -version = "0.92.0" +version = "0.92.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ee9ad91b962d5713f41a8d2222d1f4c78ee3e1a8f7529427bb7289277e52509" +checksum = "8ec94a0dd1482161701854ea96ff1b89c91ce0e2ec73236cbf4fed76f3a4f53b" dependencies = [ "is-macro", "serde", @@ -2053,9 +2053,9 @@ dependencies = [ [[package]] name = "swc_css_prefixer" -version = "0.100.1" +version = "0.100.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18c5f217ee19b60c74fd3a26eba2d778da094c6f8c6f581142656845491f7051" +checksum = "01f1c4ee283d84879e09f570ad167523a38185e0a95f6e37e46ee214f6494e8d" dependencies = [ "swc_atoms", "swc_common", @@ -2066,10 +2066,13 @@ dependencies = [ [[package]] name = "swc_css_utils" -version = "0.89.0" +version = "0.89.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1590d47d3d254226c4561b31e72347b5ac75ea7a49531d032fda65415b8990f3" +checksum = "2f959c75248f6806d50fd7ab6bada0c6481b3fd872df592abfc1f8b8fb8342dc" dependencies = [ + "once_cell", + "serde", + "serde_json", "swc_atoms", "swc_common", "swc_css_ast", @@ -2090,9 +2093,9 @@ dependencies = [ [[package]] name = "swc_ecma_ast" -version = "0.75.0" +version = "0.76.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72961898fbe56591997e667a1ec6a268383582810351c279a15ec710b6177d33" +checksum = "3b2a73d43c031effb0cf0b57df28fe87f7b6044304e188eb2f832cea964e9c75" dependencies = [ "is-macro", "num-bigint", @@ -2105,9 +2108,9 @@ dependencies = [ [[package]] name = "swc_ecma_codegen" -version = "0.103.0" +version = "0.105.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99ca430d8ea2c8791d1341c4035431c90b87330e39479b4a6dabb4fded124e30" +checksum = "a110ba748bd5a8d373acec3ac9f1be30234ca4bfb2dd0a919e57d2fe16b49ea6" dependencies = [ "bitflags", "memchr", @@ -2137,9 +2140,9 @@ dependencies = [ [[package]] name = "swc_ecma_ext_transforms" -version = "0.65.0" +version = "0.67.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6a1fa7a3c4f26cea3858f9def2ff8c06d014cb9c0c3761847fac9db48f88fe7" +checksum = "96f08daba5c96d76d3ed4e09f3f777e1e31bf7ff3a470a9fbcebabd6a92eebd9" dependencies = [ "phf", "swc_atoms", @@ -2151,9 +2154,9 @@ dependencies = [ [[package]] name = "swc_ecma_lints" -version = "0.31.0" +version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5af16f1f01c10ef7793546a7e414ad2e89f479192eeea3ceb8c6b649f8f47dde" +checksum = "8f9f1a52150bedb00ca116b7cb79c617bd85dc604ad688efea09b8c52392ba84" dependencies = [ "ahash", "auto_impl", @@ -2171,18 +2174,19 @@ dependencies = [ [[package]] name = "swc_ecma_loader" -version = "0.29.0" +version = "0.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9ab69df5d4de425833e02de111f14b5544b39ad9c9b82c97e4835fc55c8f1b6" +checksum = "e719f646201c51964a2c7b2a3dd79fadb563fc6a72454a7bc093d18c4aad44b0" dependencies = [ "ahash", "anyhow", - "dashmap 4.0.2", + "dashmap 5.1.0", "lru", "normpath", "once_cell", "parking_lot", "path-clean", + "pathdiff", "serde", "serde_json", "swc_cached", @@ -2192,9 +2196,9 @@ dependencies = [ [[package]] name = "swc_ecma_minifier" -version = "0.100.5" +version = "0.104.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3351240509020dcfec0442907fff87c7023dd2ff4bf42aefec01a7e38d58babf" +checksum = "0bc0be700ddeae725e08d551eb131b71f25c9d192a49e8106bde7437f070b1cc" dependencies = [ "ahash", "indexmap", @@ -2223,9 +2227,9 @@ dependencies = [ [[package]] name = "swc_ecma_parser" -version = "0.100.2" +version = "0.102.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "890d967031e3e7330cd7892f27d826b7b4f37c7caa19db85c78a0862e1fe3974" +checksum = "cafbcdc30d6d3da9d0829cb5011adf1d40de5d7bdad5b3228a5c978e01c75da3" dependencies = [ "either", "enum_kind", @@ -2243,9 +2247,9 @@ dependencies = [ [[package]] name = "swc_ecma_preset_env" -version = "0.117.0" +version = "0.120.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a37c95c8e7e47a1fd6bf09ff2744fe55570235e8aba2c9373200213ec2ce25" +checksum = "cfcd7b889693d28421959603c68fc219417897164a0c7da2e68852a4bbde033e" dependencies = [ "ahash", "anyhow", @@ -2268,9 +2272,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms" -version = "0.142.0" +version = "0.145.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f20e5e2d8ab843fa0454e049f73f6d99c444a8c0e2320f77028361ab75e2d18e" +checksum = "ca701fb4ad6741e2986faf2411725c61f6003c678880a897bd278f9003a641c1" dependencies = [ "swc_atoms", "swc_common", @@ -2288,9 +2292,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_base" -version = "0.75.0" +version = "0.78.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "404c6ea7ca61ceb2ce1f4ed448d1436a38c31b8c572850f04541c0229c966bbf" +checksum = "d715a9a06f7f2ceed8815877edd94b8198b3316cd2e39ffae6f43d63927abba4" dependencies = [ "better_scoped_tls", "once_cell", @@ -2309,9 +2313,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_classes" -version = "0.63.0" +version = "0.66.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "503f2f6bd0f9e6363a93406753bf64675163423774256a267c85a5d9b5b44b08" +checksum = "1e2a420c3e47fd59ad155874fa64b4b6b29b8c1d0f9ea95193d080b8296c2cd5" dependencies = [ "swc_atoms", "swc_common", @@ -2323,9 +2327,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_compat" -version = "0.89.0" +version = "0.92.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d234c84cee8aeeda2ec60087f65acd420e2475bb334a64bbf988b538c21b31d" +checksum = "be093d8cb4ad41136cf409f62a165642da6e810d35e2e26064c78362f2ca02cf" dependencies = [ "ahash", "arrayvec", @@ -2362,9 +2366,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_module" -version = "0.102.0" +version = "0.105.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c340a0228a9a49240d97a4a4e99a0a61e6613b29b427cc09a60f6ad4dcbf728" +checksum = "7b921ed7a081930439567cb64daccda9fda42a030e825c3b2b9655a6fda3b313" dependencies = [ "Inflector", "ahash", @@ -2386,9 +2390,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_optimization" -version = "0.112.0" +version = "0.115.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4d892a269f4fd26f37967fd8e98d841b379c1f66f2381c84b71f986792562fb" +checksum = "5d418cc7e290861a29ebc340b18f23371baa777e656e6363f9d9daf1a05bc022" dependencies = [ "ahash", "dashmap 5.1.0", @@ -2409,9 +2413,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_proposal" -version = "0.97.0" +version = "0.100.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93d08411e517736b0167f3c9784fe9b98cc09308ae12e6072abd2bb2c2236da2" +checksum = "2761d8ca9bcad79ca01b94538b4c85cc4067ef9ec1aa29432749360b9ae63878" dependencies = [ "either", "serde", @@ -2428,9 +2432,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_react" -version = "0.104.0" +version = "0.107.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43cda44270dfcc95d61582981baddaf53d96c5233ea7384e81cd6e462816c58e" +checksum = "4cd88c2b3e5f278bfe6ffbba985394137da3d711cb482e380d0333ad433679fa" dependencies = [ "ahash", "base64 0.13.0", @@ -2453,9 +2457,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_testing" -version = "0.77.0" +version = "0.80.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4388e2875202996bcd4bbbf3513369a94bf2135d55140fd0ae6c9e90fa3d0fec" +checksum = "ebc7e999de7e6c5c0676d25ea605cfad2212c705089dfa668be9361a90342ff6" dependencies = [ "ansi_term", "anyhow", @@ -2476,9 +2480,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_typescript" -version = "0.107.0" +version = "0.110.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a09397169ed7ce0751a82cb71655f3a4a1fb00d8863aabd5cca9b46eff3dd5f2" +checksum = "04d59f918e31738c105ef60cb33d82410fb0e2fd319e2feb5a994b8baa6eb5ea" dependencies = [ "serde", "swc_atoms", @@ -2492,9 +2496,9 @@ dependencies = [ [[package]] name = "swc_ecma_utils" -version = "0.79.1" +version = "0.81.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44ee8d60b9977f58214af7102dc30855a6754e742afe6d6e26e5bf13883c7b91" +checksum = "54a6b4842755a0874036d3d396809c763d259af62af228b86f0543b59873a563" dependencies = [ "indexmap", "once_cell", @@ -2508,9 +2512,9 @@ dependencies = [ [[package]] name = "swc_ecma_visit" -version = "0.61.0" +version = "0.62.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5ea00a52ba2b971955c62275696d5c59f3cf0cd06db74a66dec378ec9843c78" +checksum = "d97c42c1e769cd4a442fbe91d076e8600fffae6139a90582db78da27613a033e" dependencies = [ "num-bigint", "swc_atoms", @@ -2522,9 +2526,9 @@ dependencies = [ [[package]] name = "swc_ecmascript" -version = "0.143.0" +version = "0.147.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebda93aa6422956c184a9eb5fdb0f0f0ff433169fa15e55ef445e5ad0b5e0abe" +checksum = "84c0c06b61e1a950c99fab54727f37ef1b3098760fb57a89d9d37ecbdfa103c4" dependencies = [ "swc_ecma_ast", "swc_ecma_codegen", diff --git a/packages/next-swc/crates/core/Cargo.toml b/packages/next-swc/crates/core/Cargo.toml index 057f502c92fb11c..8787469487b1127 100644 --- a/packages/next-swc/crates/core/Cargo.toml +++ b/packages/next-swc/crates/core/Cargo.toml @@ -21,16 +21,16 @@ swc_emotion = {path="../emotion"} styled_components = {path="../styled_components"} styled_jsx = {path="../styled_jsx"} modularize_imports = {path="../modularize_imports"} -swc = "0.164.0" +swc = "0.168.0" swc_atoms = "0.2.11" -swc_common = { version = "0.17.19", features = ["concurrent", "sourcemap"] } -swc_ecma_loader = { version = "0.29.0", features = ["node", "lru"] } -swc_ecmascript = { version = "0.143.0", features = ["codegen", "minifier", "optimization", "parser", "react", "transforms", "typescript", "utils", "visit"] } +swc_common = { version = "0.17.21", features = ["concurrent", "sourcemap"] } +swc_ecma_loader = { version = "0.29.1", features = ["node", "lru"] } +swc_ecmascript = { version = "0.147.0", features = ["codegen", "minifier", "optimization", "parser", "react", "transforms", "typescript", "utils", "visit"] } swc_cached = "0.1.1" tracing = { version = "0.1.32", features = ["release_max_level_off"] } [dev-dependencies] -swc_ecma_transforms_testing = "0.77.0" +swc_ecma_transforms_testing = "0.80.0" testing = "0.19.1" walkdir = "2.3.2" diff --git a/packages/next-swc/crates/core/src/next_ssg.rs b/packages/next-swc/crates/core/src/next_ssg.rs index d25891c1700cdc8..2f8987ed2139614 100644 --- a/packages/next-swc/crates/core/src/next_ssg.rs +++ b/packages/next-swc/crates/core/src/next_ssg.rs @@ -13,6 +13,8 @@ use swc_ecmascript::{ visit::{noop_fold_type, Fold}, }; +static SSG_EXPORTS: &[&str; 3] = &["getStaticProps", "getStaticPaths", "getServerSideProps"]; + /// Note: This paths requires running `resolver` **before** running this. pub fn next_ssg(eliminated_packages: Rc>>) -> impl Fold { Repeat::new(NextSsg { @@ -55,9 +57,7 @@ struct State { impl State { #[allow(clippy::wrong_self_convention)] fn is_data_identifier(&mut self, i: &Ident) -> Result { - let ssg_exports = &["getStaticProps", "getStaticPaths", "getServerSideProps"]; - - if ssg_exports.contains(&&*i.sym) { + if SSG_EXPORTS.contains(&&*i.sym) { if &*i.sym == "getServerSideProps" { if self.is_prerenderer { HANDLER.with(|handler| { @@ -132,12 +132,30 @@ impl Fold for Analyzer<'_> { fn fold_export_named_specifier(&mut self, s: ExportNamedSpecifier) -> ExportNamedSpecifier { if let ModuleExportName::Ident(id) = &s.orig { - self.add_ref(id.to_id()); + if !SSG_EXPORTS.contains(&&*id.sym) { + self.add_ref(id.to_id()); + } } s } + fn fold_export_decl(&mut self, s: ExportDecl) -> ExportDecl { + if let Decl::Var(d) = &s.decl { + if d.decls.is_empty() { + return s; + } + + if let Pat::Ident(id) = &d.decls[0].name { + if !SSG_EXPORTS.contains(&&*id.id.sym) { + self.add_ref(id.to_id()); + } + } + } + + s.fold_children_with(self) + } + fn fold_expr(&mut self, e: Expr) -> Expr { let e = e.fold_children_with(self); diff --git a/packages/next-swc/crates/core/tests/fixture/ssg/getStaticProps/issue-31855/input.js b/packages/next-swc/crates/core/tests/fixture/ssg/getStaticProps/issue-31855/input.js new file mode 100644 index 000000000000000..4d2c4d7005d0dd2 --- /dev/null +++ b/packages/next-swc/crates/core/tests/fixture/ssg/getStaticProps/issue-31855/input.js @@ -0,0 +1,16 @@ +export const revalidateInSeconds = 5 * 60; + +export const getStaticProps = async () => { + return { + props: {}, + revalidate: revalidateInSeconds, + }; +}; + +export default function Home({}) { + return ( +
+

Hello World

+
+ ) +} \ No newline at end of file diff --git a/packages/next-swc/crates/core/tests/fixture/ssg/getStaticProps/issue-31855/output.js b/packages/next-swc/crates/core/tests/fixture/ssg/getStaticProps/issue-31855/output.js new file mode 100644 index 000000000000000..64a7370fbd4bf4c --- /dev/null +++ b/packages/next-swc/crates/core/tests/fixture/ssg/getStaticProps/issue-31855/output.js @@ -0,0 +1,5 @@ +export var __N_SSG = true; +export const revalidateInSeconds = 5 * 60; +export default function Home({}) { + return __jsx("div", null, __jsx("p", null, "Hello World")); +}; diff --git a/packages/next-swc/crates/emotion/Cargo.toml b/packages/next-swc/crates/emotion/Cargo.toml index df6db10f587994a..fe025d599e5cb86 100644 --- a/packages/next-swc/crates/emotion/Cargo.toml +++ b/packages/next-swc/crates/emotion/Cargo.toml @@ -19,9 +19,9 @@ regex = "1.5" serde = "1" sourcemap = "6.0.1" swc_atoms = "0.2.11" -swc_common = { version = "0.17.19", features = ["concurrent", "sourcemap"] } -swc_ecmascript = { version = "0.143.0", features = ["codegen", "utils", "visit"] } +swc_common = { version = "0.17.21", features = ["concurrent", "sourcemap"] } +swc_ecmascript = { version = "0.147.0", features = ["codegen", "utils", "visit"] } [dev-dependencies] -swc_ecma_transforms_testing = "0.77.0" +swc_ecma_transforms_testing = "0.80.0" testing = "0.19.1" diff --git a/packages/next-swc/crates/modularize_imports/Cargo.toml b/packages/next-swc/crates/modularize_imports/Cargo.toml index 8175e8abcfaac79..04ec6bf1b35105a 100644 --- a/packages/next-swc/crates/modularize_imports/Cargo.toml +++ b/packages/next-swc/crates/modularize_imports/Cargo.toml @@ -15,8 +15,8 @@ once_cell = "1.8.0" regex = "1.5" serde = "1" swc_cached = "0.1.1" -swc_ecmascript = {version = "0.143.0", features = ["visit"]} +swc_ecmascript = { version = "0.147.0", features = ["visit"] } [dev-dependencies] -swc_ecma_transforms_testing = "0.77.0" +swc_ecma_transforms_testing = "0.80.0" testing = "0.19.1" diff --git a/packages/next-swc/crates/napi/Cargo.toml b/packages/next-swc/crates/napi/Cargo.toml index f1f97094e6e4c38..c49c440e8b78e68 100644 --- a/packages/next-swc/crates/napi/Cargo.toml +++ b/packages/next-swc/crates/napi/Cargo.toml @@ -17,12 +17,12 @@ next-swc = {version = "0.0.0", path = "../core"} once_cell = "1.8.0" serde = "1" serde_json = "1" -swc = "0.164.0" +swc = "0.168.0" swc_atoms = "0.2.11" -swc_bundler = { version = "0.133.0", features = ["concurrent"] } -swc_common = { version = "0.17.19", features = ["concurrent", "sourcemap"] } -swc_ecma_loader = { version = "0.29.0", features = ["node", "lru"] } -swc_ecmascript = { version = "0.143.0", features = ["codegen", "minifier", "optimization", "parser", "react", "transforms", "typescript", "utils", "visit"] } +swc_bundler = { version = "0.137.0", features = ["concurrent"] } +swc_common = { version = "0.17.21", features = ["concurrent", "sourcemap"] } +swc_ecma_loader = { version = "0.29.1", features = ["node", "lru"] } +swc_ecmascript = { version = "0.147.0", features = ["codegen", "minifier", "optimization", "parser", "react", "transforms", "typescript", "utils", "visit"] } swc_node_base = "0.5.2" [build-dependencies] diff --git a/packages/next-swc/crates/styled_components/Cargo.toml b/packages/next-swc/crates/styled_components/Cargo.toml index 058ea0c33a73151..6b85b65f105e96a 100644 --- a/packages/next-swc/crates/styled_components/Cargo.toml +++ b/packages/next-swc/crates/styled_components/Cargo.toml @@ -15,12 +15,12 @@ once_cell = "1.10.0" regex = {version = "1.5.4", features = ["std", "perf"], default-features = false} serde = {version = "1.0.130", features = ["derive"]} swc_atoms = "0.2.11" -swc_common = { version = "0.17.19", features = ["concurrent"] } -swc_ecmascript = { version = "0.143.0", features = ["utils", "visit"] } +swc_common = { version = "0.17.21", features = ["concurrent"] } +swc_ecmascript = { version = "0.147.0", features = ["utils", "visit"] } tracing = "0.1.32" [dev-dependencies] serde_json = "1" -swc_ecma_transforms_testing = "0.77.0" -swc_ecmascript = { version = "0.143.0", features = ["parser", "transforms"] } +swc_ecma_transforms_testing = "0.80.0" +swc_ecmascript = { version = "0.147.0", features = ["parser", "transforms"] } testing = "0.19.1" diff --git a/packages/next-swc/crates/styled_jsx/Cargo.toml b/packages/next-swc/crates/styled_jsx/Cargo.toml index 60867e2241e299a..dd4f8ce3ff4d9f3 100644 --- a/packages/next-swc/crates/styled_jsx/Cargo.toml +++ b/packages/next-swc/crates/styled_jsx/Cargo.toml @@ -11,12 +11,12 @@ version = "0.1.1" [dependencies] easy-error = "1.0.0" -swc_common = {version = "0.17.19", features = ["concurrent", "sourcemap"]} +swc_common = { version = "0.17.21", features = ["concurrent", "sourcemap"] } swc_css = "0.104.1" -swc_css_prefixer = "0.100.0" -swc_ecmascript = {version = "0.143.0", features = ["parser", "minifier", "utils", "visit"]} +swc_css_prefixer = "0.100.4" +swc_ecmascript = { version = "0.147.0", features = ["parser", "minifier", "utils", "visit"] } tracing = "0.1.32" [dev-dependencies] -swc_ecma_transforms_testing = "0.77.0" +swc_ecma_transforms_testing = "0.80.0" testing = "0.19.1" diff --git a/packages/next-swc/crates/styled_jsx/tests/fixture/transform-css-complex-selector/output.js b/packages/next-swc/crates/styled_jsx/tests/fixture/transform-css-complex-selector/output.js index f024b9bc442938e..bcdf0e027c91c19 100644 --- a/packages/next-swc/crates/styled_jsx/tests/fixture/transform-css-complex-selector/output.js +++ b/packages/next-swc/crates/styled_jsx/tests/fixture/transform-css-complex-selector/output.js @@ -3,7 +3,7 @@ export default (()=>

test

- <_JSXStyle id={"713499aa363d6373"}>{"p.jsx-713499aa363d6373 a.jsx-713499aa363d6373 span.jsx-713499aa363d6373{color:red}p.jsx-713499aa363d6373 span{background:blue}p.jsx-713499aa363d6373 a[title=\"'w ' ' t'\"].jsx-713499aa363d6373{margin:auto}p.jsx-713499aa363d6373 span:not(.test){color:green}p.jsx-713499aa363d6373,h1.jsx-713499aa363d6373{color:blue;-webkit-animation:hahaha 3s ease forwards infinite;-moz-animation:hahaha 3s ease forwards infinite;-o-animation:hahaha 3s ease forwards infinite;animation:hahaha 3s ease forwards infinite;-webkit-animation-name:hahaha;-moz-animation-name:hahaha;-o-animation-name:hahaha;animation-name:hahaha;-webkit-animation-delay:100ms;-moz-animation-delay:100ms;-o-animation-delay:100ms;animation-delay:100ms}p.jsx-713499aa363d6373{-webkit-animation:hahaha 1s,hehehe 2s;-moz-animation:hahaha 1s,hehehe 2s;-o-animation:hahaha 1s,hehehe 2s;animation:hahaha 1s,hehehe 2s}p.jsx-713499aa363d6373:hover{color:red}p.jsx-713499aa363d6373::before{color:red}.jsx-713499aa363d6373:hover{color:red}.jsx-713499aa363d6373::before{color:red}.jsx-713499aa363d6373:hover p.jsx-713499aa363d6373{color:red}p.jsx-713499aa363d6373+a.jsx-713499aa363d6373{color:red}p.jsx-713499aa363d6373~a.jsx-713499aa363d6373{color:red}p.jsx-713499aa363d6373>a.jsx-713499aa363d6373{color:red}@keyframes hahaha{from{top:0}to{top:100}}@keyframes hehehe{from{left:0}to{left:100}}@media(min-width:500px){.test.jsx-713499aa363d6373{color:red}}.test.jsx-713499aa363d6373{display:block}.inline-flex.jsx-713499aa363d6373{display:-webkit-inline-box;display:-webkit-inline-flex;display:-moz-inline-box;display:-ms-inline-flexbox;display:inline-flex}.flex.jsx-713499aa363d6373{display:-webkit-box;display:-webkit-flex;display:-moz-box;display:-ms-flexbox;display:flex}.test.jsx-713499aa363d6373{-webkit-box-shadow:0 0 10px black,inset 0 0 5px black;-moz-box-shadow:0 0 10px black,inset 0 0 5px black;box-shadow:0 0 10px black,inset 0 0 5px black}.test[title=\",\"].jsx-713499aa363d6373{display:inline-block}.test.is-status.jsx-713499aa363d6373 .test.jsx-713499aa363d6373{color:red}.a-selector.jsx-713499aa363d6373:hover,.a-selector.jsx-713499aa363d6373:focus{outline:none}"} + <_JSXStyle id={"713499aa363d6373"}>{"p.jsx-713499aa363d6373 a.jsx-713499aa363d6373 span.jsx-713499aa363d6373{color:red}p.jsx-713499aa363d6373 span{background:blue}p.jsx-713499aa363d6373 a[title=\"'w ' ' t'\"].jsx-713499aa363d6373{margin:auto}p.jsx-713499aa363d6373 span:not(.test){color:green}p.jsx-713499aa363d6373,h1.jsx-713499aa363d6373{color:blue;-webkit-animation:hahaha 3s ease forwards infinite;-moz-animation:hahaha 3s ease forwards infinite;-o-animation:hahaha 3s ease forwards infinite;animation:hahaha 3s ease forwards infinite;-webkit-animation-name:hahaha;-moz-animation-name:hahaha;-o-animation-name:hahaha;animation-name:hahaha;-webkit-animation-delay:100ms;-moz-animation-delay:100ms;-o-animation-delay:100ms;animation-delay:100ms}p.jsx-713499aa363d6373{-webkit-animation:hahaha 1s,hehehe 2s;-moz-animation:hahaha 1s,hehehe 2s;-o-animation:hahaha 1s,hehehe 2s;animation:hahaha 1s,hehehe 2s}p.jsx-713499aa363d6373:hover{color:red}p.jsx-713499aa363d6373::before{color:red}.jsx-713499aa363d6373:hover{color:red}.jsx-713499aa363d6373::before{color:red}.jsx-713499aa363d6373:hover p.jsx-713499aa363d6373{color:red}p.jsx-713499aa363d6373+a.jsx-713499aa363d6373{color:red}p.jsx-713499aa363d6373~a.jsx-713499aa363d6373{color:red}p.jsx-713499aa363d6373>a.jsx-713499aa363d6373{color:red}@-webkit-keyframes hahaha{from{top:0}to{top:100}}@-moz-keyframes hahaha{from{top:0}to{top:100}}@-o-keyframes hahaha{from{top:0}to{top:100}}@keyframes hahaha{from{top:0}to{top:100}}@-webkit-keyframes hehehe{from{left:0}to{left:100}}@-moz-keyframes hehehe{from{left:0}to{left:100}}@-o-keyframes hehehe{from{left:0}to{left:100}}@keyframes hehehe{from{left:0}to{left:100}}@media(min-width:500px){.test.jsx-713499aa363d6373{color:red}}.test.jsx-713499aa363d6373{display:block}.inline-flex.jsx-713499aa363d6373{display:-webkit-inline-box;display:-webkit-inline-flex;display:-moz-inline-box;display:-ms-inline-flexbox;display:inline-flex}.flex.jsx-713499aa363d6373{display:-webkit-box;display:-webkit-flex;display:-moz-box;display:-ms-flexbox;display:flex}.test.jsx-713499aa363d6373{-webkit-box-shadow:0 0 10px black,inset 0 0 5px black;-moz-box-shadow:0 0 10px black,inset 0 0 5px black;box-shadow:0 0 10px black,inset 0 0 5px black}.test[title=\",\"].jsx-713499aa363d6373{display:inline-block}.test.is-status.jsx-713499aa363d6373 .test.jsx-713499aa363d6373{color:red}.a-selector.jsx-713499aa363d6373:hover,.a-selector.jsx-713499aa363d6373:focus{outline:none}"}
); diff --git a/packages/next-swc/crates/styled_jsx/tests/fixture/transform-css/output.js b/packages/next-swc/crates/styled_jsx/tests/fixture/transform-css/output.js index 07b23babd4811ca..6f2da186977ec01 100644 --- a/packages/next-swc/crates/styled_jsx/tests/fixture/transform-css/output.js +++ b/packages/next-swc/crates/styled_jsx/tests/fixture/transform-css/output.js @@ -3,7 +3,7 @@ export default (()=>

test

- <_JSXStyle id={"768337a97aceabd1"}>{'html.jsx-768337a97aceabd1{background-image:-webkit-linear-gradient(bottom,rgba(255,255,255,.8),rgba(255,255,255,.8)),url(/static/background.svg);background-image:-moz-linear-gradient(bottom,rgba(255,255,255,.8),rgba(255,255,255,.8)),url(/static/background.svg);background-image:-o-linear-gradient(bottom,rgba(255,255,255,.8),rgba(255,255,255,.8)),url(/static/background.svg);background-image:linear-gradient(0deg,rgba(255,255,255,.8),rgba(255,255,255,.8)),url(/static/background.svg)}p{color:blue}p{color:blue}p,a.jsx-768337a97aceabd1{color:blue}.foo+a{color:red}body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif}p.jsx-768337a97aceabd1{color:red}p.jsx-768337a97aceabd1{color:red}*.jsx-768337a97aceabd1{color:blue}[href="woot"].jsx-768337a97aceabd1{color:red}p.jsx-768337a97aceabd1 a.jsx-768337a97aceabd1 span.jsx-768337a97aceabd1{color:red}p.jsx-768337a97aceabd1 span{background:blue}p.jsx-768337a97aceabd1 a[title="\'w \' \' t\'"].jsx-768337a97aceabd1{margin:auto}p.jsx-768337a97aceabd1 span:not(.test){color:green}p.jsx-768337a97aceabd1,h1.jsx-768337a97aceabd1{color:blue;-webkit-animation:hahaha 3s ease forwards infinite;-moz-animation:hahaha 3s ease forwards infinite;-o-animation:hahaha 3s ease forwards infinite;animation:hahaha 3s ease forwards infinite;-webkit-animation-name:hahaha;-moz-animation-name:hahaha;-o-animation-name:hahaha;animation-name:hahaha;-webkit-animation-delay:100ms;-moz-animation-delay:100ms;-o-animation-delay:100ms;animation-delay:100ms}p.jsx-768337a97aceabd1{-webkit-animation:hahaha 1s,hehehe 2s;-moz-animation:hahaha 1s,hehehe 2s;-o-animation:hahaha 1s,hehehe 2s;animation:hahaha 1s,hehehe 2s}p.jsx-768337a97aceabd1:hover{color:red}p.jsx-768337a97aceabd1::before{color:red}.jsx-768337a97aceabd1:hover{color:red}.jsx-768337a97aceabd1::before{color:red}.jsx-768337a97aceabd1:hover p.jsx-768337a97aceabd1{color:red}p.jsx-768337a97aceabd1+a.jsx-768337a97aceabd1{color:red}p.jsx-768337a97aceabd1~a.jsx-768337a97aceabd1{color:red}p.jsx-768337a97aceabd1>a.jsx-768337a97aceabd1{color:red}@keyframes hahaha{from{top:0}to{top:100}}@keyframes hehehe{from{left:0}to{left:100}}@media(min-width:500px){.test.jsx-768337a97aceabd1{color:red}}.test.jsx-768337a97aceabd1{display:block}.inline-flex.jsx-768337a97aceabd1{display:-webkit-inline-box;display:-webkit-inline-flex;display:-moz-inline-box;display:-ms-inline-flexbox;display:inline-flex}.flex.jsx-768337a97aceabd1{display:-webkit-box;display:-webkit-flex;display:-moz-box;display:-ms-flexbox;display:flex}.test.jsx-768337a97aceabd1{-webkit-box-shadow:0 0 10px black,inset 0 0 5px black;-moz-box-shadow:0 0 10px black,inset 0 0 5px black;box-shadow:0 0 10px black,inset 0 0 5px black}.test[title=","].jsx-768337a97aceabd1{display:inline-block}.test.is-status.jsx-768337a97aceabd1 .test.jsx-768337a97aceabd1{color:red}.a-selector.jsx-768337a97aceabd1:hover,.a-selector.jsx-768337a97aceabd1:focus{outline:none}@media(min-width:1px)and (max-width:768px){[class*="grid__col--"].jsx-768337a97aceabd1{margin-top:12px;margin-bottom:12px}}@media(max-width:64em){.test.jsx-768337a97aceabd1{margin-bottom:1em}@supports(-moz-appearance:none)and (display:contents){.test.jsx-768337a97aceabd1{margin-bottom:2rem}}}'} + <_JSXStyle id={"768337a97aceabd1"}>{'html.jsx-768337a97aceabd1{background-image:-webkit-linear-gradient(bottom,rgba(255,255,255,.8),rgba(255,255,255,.8)),url(/static/background.svg);background-image:-moz-linear-gradient(bottom,rgba(255,255,255,.8),rgba(255,255,255,.8)),url(/static/background.svg);background-image:-o-linear-gradient(bottom,rgba(255,255,255,.8),rgba(255,255,255,.8)),url(/static/background.svg);background-image:linear-gradient(0deg,rgba(255,255,255,.8),rgba(255,255,255,.8)),url(/static/background.svg)}p{color:blue}p{color:blue}p,a.jsx-768337a97aceabd1{color:blue}.foo+a{color:red}body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif}p.jsx-768337a97aceabd1{color:red}p.jsx-768337a97aceabd1{color:red}*.jsx-768337a97aceabd1{color:blue}[href="woot"].jsx-768337a97aceabd1{color:red}p.jsx-768337a97aceabd1 a.jsx-768337a97aceabd1 span.jsx-768337a97aceabd1{color:red}p.jsx-768337a97aceabd1 span{background:blue}p.jsx-768337a97aceabd1 a[title="\'w \' \' t\'"].jsx-768337a97aceabd1{margin:auto}p.jsx-768337a97aceabd1 span:not(.test){color:green}p.jsx-768337a97aceabd1,h1.jsx-768337a97aceabd1{color:blue;-webkit-animation:hahaha 3s ease forwards infinite;-moz-animation:hahaha 3s ease forwards infinite;-o-animation:hahaha 3s ease forwards infinite;animation:hahaha 3s ease forwards infinite;-webkit-animation-name:hahaha;-moz-animation-name:hahaha;-o-animation-name:hahaha;animation-name:hahaha;-webkit-animation-delay:100ms;-moz-animation-delay:100ms;-o-animation-delay:100ms;animation-delay:100ms}p.jsx-768337a97aceabd1{-webkit-animation:hahaha 1s,hehehe 2s;-moz-animation:hahaha 1s,hehehe 2s;-o-animation:hahaha 1s,hehehe 2s;animation:hahaha 1s,hehehe 2s}p.jsx-768337a97aceabd1:hover{color:red}p.jsx-768337a97aceabd1::before{color:red}.jsx-768337a97aceabd1:hover{color:red}.jsx-768337a97aceabd1::before{color:red}.jsx-768337a97aceabd1:hover p.jsx-768337a97aceabd1{color:red}p.jsx-768337a97aceabd1+a.jsx-768337a97aceabd1{color:red}p.jsx-768337a97aceabd1~a.jsx-768337a97aceabd1{color:red}p.jsx-768337a97aceabd1>a.jsx-768337a97aceabd1{color:red}@-webkit-keyframes hahaha{from{top:0}to{top:100}}@-moz-keyframes hahaha{from{top:0}to{top:100}}@-o-keyframes hahaha{from{top:0}to{top:100}}@keyframes hahaha{from{top:0}to{top:100}}@-webkit-keyframes hehehe{from{left:0}to{left:100}}@-moz-keyframes hehehe{from{left:0}to{left:100}}@-o-keyframes hehehe{from{left:0}to{left:100}}@keyframes hehehe{from{left:0}to{left:100}}@media(min-width:500px){.test.jsx-768337a97aceabd1{color:red}}.test.jsx-768337a97aceabd1{display:block}.inline-flex.jsx-768337a97aceabd1{display:-webkit-inline-box;display:-webkit-inline-flex;display:-moz-inline-box;display:-ms-inline-flexbox;display:inline-flex}.flex.jsx-768337a97aceabd1{display:-webkit-box;display:-webkit-flex;display:-moz-box;display:-ms-flexbox;display:flex}.test.jsx-768337a97aceabd1{-webkit-box-shadow:0 0 10px black,inset 0 0 5px black;-moz-box-shadow:0 0 10px black,inset 0 0 5px black;box-shadow:0 0 10px black,inset 0 0 5px black}.test[title=","].jsx-768337a97aceabd1{display:inline-block}.test.is-status.jsx-768337a97aceabd1 .test.jsx-768337a97aceabd1{color:red}.a-selector.jsx-768337a97aceabd1:hover,.a-selector.jsx-768337a97aceabd1:focus{outline:none}@media(min-width:1px)and (max-width:768px){[class*="grid__col--"].jsx-768337a97aceabd1{margin-top:12px;margin-bottom:12px}}@media(max-width:64em){.test.jsx-768337a97aceabd1{margin-bottom:1em}@supports(-moz-appearance:none)and (display:contents){.test.jsx-768337a97aceabd1{margin-bottom:2rem}}}'}
); diff --git a/packages/next-swc/crates/wasm/Cargo.toml b/packages/next-swc/crates/wasm/Cargo.toml index 2e8d5b542d49a09..86f1d51faf38f7e 100644 --- a/packages/next-swc/crates/wasm/Cargo.toml +++ b/packages/next-swc/crates/wasm/Cargo.toml @@ -16,9 +16,9 @@ parking_lot_core = "=0.8.0" path-clean = "0.1" serde = {version = "1", features = ["derive"]} serde_json = "1" -swc = "0.164.0" -swc_common = { version = "0.17.19", features = ["concurrent", "sourcemap"] } -swc_ecmascript = { version = "0.143.0", features = ["codegen", "minifier", "optimization", "parser", "react", "transforms", "typescript", "utils", "visit"] } +swc = "0.168.0" +swc_common = { version = "0.17.21", features = ["concurrent", "sourcemap"] } +swc_ecmascript = { version = "0.147.0", features = ["codegen", "minifier", "optimization", "parser", "react", "transforms", "typescript", "utils", "visit"] } tracing = { version = "0.1.32", features = ["release_max_level_off"] } wasm-bindgen = {version = "0.2", features = ["serde-serialize"]} wasm-bindgen-futures = "0.4.8" diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index 2a1b4b8130298ef..8b54d81d8b3dc6d 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "12.1.6-canary.0", + "version": "12.1.6-canary.4", "private": true, "scripts": { "build-native": "napi build --platform --cargo-name next_swc_napi native", diff --git a/packages/next/build/babel/preset.ts b/packages/next/build/babel/preset.ts index 5b3cff89ff832c6..b493622f29bce54 100644 --- a/packages/next/build/babel/preset.ts +++ b/packages/next/build/babel/preset.ts @@ -93,10 +93,6 @@ export default ( // In production/development this option is set to `false` so that webpack can handle import/export with tree-shaking modules: 'auto', exclude: ['transform-typeof-symbol'], - include: [ - '@babel/plugin-proposal-optional-chaining', - '@babel/plugin-proposal-nullish-coalescing-operator', - ], ...options['preset-env'], } diff --git a/packages/next/build/swc/options.js b/packages/next/build/swc/options.js index eeddb42fa76a24b..8bc1c3cfad4249d 100644 --- a/packages/next/build/swc/options.js +++ b/packages/next/build/swc/options.js @@ -164,13 +164,6 @@ export function getJestSWCOptions({ // Targets the current version of Node.js node: process.versions.node, }, - // we always transpile optional chaining and nullish coalescing - // since it can cause issues with webpack even if the node target - // supports them - include: [ - 'proposal-optional-chaining', - 'proposal-nullish-coalescing-operator', - ], }, module: { type: esm && !isNextDist ? 'es6' : 'commonjs', @@ -219,13 +212,6 @@ export function getLoaderSWCOptions({ // Targets the current version of Node.js node: process.versions.node, }, - // we always transpile optional chaining and nullish coalescing - // since it can cause issues with webpack even if the node target - // supports them - include: [ - 'proposal-optional-chaining', - 'proposal-nullish-coalescing-operator', - ], }, } } else { diff --git a/packages/next/build/utils.ts b/packages/next/build/utils.ts index 4fa14e0815a973b..d9d7a058aaed6ac 100644 --- a/packages/next/build/utils.ts +++ b/packages/next/build/utils.ts @@ -1172,10 +1172,7 @@ export async function copyTracedFiles( if (symlink) { console.log('symlink', path.relative(tracingRoot, symlink)) - await fs.symlink( - path.relative(tracingRoot, symlink), - fileOutputPath - ) + await fs.symlink(symlink, fileOutputPath) } else { await fs.copyFile(tracedFilePath, fileOutputPath) } diff --git a/packages/next/build/webpack-config.ts b/packages/next/build/webpack-config.ts index 9166fefdf48343e..488c64fa5ea7c15 100644 --- a/packages/next/build/webpack-config.ts +++ b/packages/next/build/webpack-config.ts @@ -1211,9 +1211,6 @@ export default async function getBaseWebpackConfig( ...rscCodeCondition, use: { loader: 'next-flight-server-loader', - options: { - extensions: rawPageExtensions, - }, }, }, ] @@ -1225,7 +1222,6 @@ export default async function getBaseWebpackConfig( loader: 'next-flight-server-loader', options: { client: 1, - extensions: rawPageExtensions, }, }, }, diff --git a/packages/next/build/webpack/loaders/next-flight-server-loader.ts b/packages/next/build/webpack/loaders/next-flight-server-loader.ts index 4740a9197e19287..6436f92043f5cfd 100644 --- a/packages/next/build/webpack/loaders/next-flight-server-loader.ts +++ b/packages/next/build/webpack/loaders/next-flight-server-loader.ts @@ -5,9 +5,13 @@ import { buildExports, createClientComponentFilter, createServerComponentFilter, + isNextBuiltinClientComponent, } from './utils' -function createFlightServerRequest(request: string, options: object) { +function createFlightServerRequest( + request: string, + options?: { client: 1 | undefined } +) { return `next-flight-server-loader?${JSON.stringify(options)}!${request}` } @@ -18,7 +22,6 @@ function hasFlightLoader(request: string, type: 'client' | 'server') { async function parseModuleInfo({ resourcePath, source, - extensions, isClientCompilation, isServerComponent, isClientComponent, @@ -27,7 +30,6 @@ async function parseModuleInfo({ resourcePath: string source: string isClientCompilation: boolean - extensions: string[] isServerComponent: (name: string) => boolean isClientComponent: (name: string) => boolean resolver: (req: string) => Promise @@ -57,7 +59,10 @@ async function parseModuleInfo({ const isBuiltinModule_ = builtinModules.includes(path) const resolvedPath = isBuiltinModule_ ? path : await resolver(path) - const isNodeModuleImport_ = resolvedPath.includes('/node_modules/') + const isNodeModuleImport_ = + /[\\/]node_modules[\\/]/.test(resolvedPath) && + // exclude next built-in modules + !isNextBuiltinClientComponent(resolvedPath) return [isBuiltinModule_, isNodeModuleImport_] as const } @@ -71,12 +76,7 @@ async function parseModuleInfo({ imports.push(path) } else { // Shared component. - imports.push( - createFlightServerRequest(path, { - extensions, - client: 1, - }) - ) + imports.push(createFlightServerRequest(path, { client: 1 })) } } @@ -119,7 +119,7 @@ async function parseModuleInfo({ const serverImportSource = isReactImports || isBuiltinModule ? importSource - : createFlightServerRequest(importSource, { extensions }) + : createFlightServerRequest(importSource) transformedSource += importDeclarations transformedSource += JSON.stringify(serverImportSource) @@ -191,7 +191,7 @@ export default async function transformSource( this: any, source: string ): Promise { - const { client: isClientCompilation, extensions } = this.getOptions() + const { client: isClientCompilation } = this.getOptions() const { resourcePath, resolve: resolveFn, context } = this const resolver = (req: string): Promise => { @@ -207,8 +207,8 @@ export default async function transformSource( throw new Error('Expected source to have been transformed to a string.') } - const isServerComponent = createServerComponentFilter(extensions) - const isClientComponent = createClientComponentFilter(extensions) + const isServerComponent = createServerComponentFilter() + const isClientComponent = createClientComponentFilter() const hasAppliedFlightServerLoader = this.loaders.some((loader: any) => { return hasFlightLoader(loader.path, 'server') }) @@ -231,7 +231,6 @@ export default async function transformSource( } = await parseModuleInfo({ resourcePath, source, - extensions, isClientCompilation, isServerComponent, isClientComponent, diff --git a/packages/next/build/webpack/loaders/utils.ts b/packages/next/build/webpack/loaders/utils.ts index 046a9b950e6e4b6..ba2c478b8af9a15 100644 --- a/packages/next/build/webpack/loaders/utils.ts +++ b/packages/next/build/webpack/loaders/utils.ts @@ -1,4 +1,4 @@ -const defaultJsFileExtensions = ['js', 'mjs', 'jsx', 'ts', 'tsx', 'json'] +export const defaultJsFileExtensions = ['js', 'mjs', 'jsx', 'ts', 'tsx'] const imageExtensions = ['jpg', 'jpeg', 'png', 'webp', 'avif'] const nextClientComponents = ['link', 'image', 'head', 'script'] @@ -24,16 +24,14 @@ export function buildExports(moduleExports: any, isESM: boolean) { return ret } -export const createClientComponentFilter = ( - extensions: string[] = defaultJsFileExtensions -) => { +export const createClientComponentFilter = () => { // Special cases for Next.js APIs that are considered as client components: // - .client.[ext] // - next built-in client components // - .[imageExt] const regex = new RegExp( '(' + - `\\.client(\\.(${extensions.join('|')}))?|` + + `\\.client(\\.(${defaultJsFileExtensions.join('|')}))?|` + `next/(${nextClientComponents.join('|')})(\\.js)?|` + `\\.(${imageExtensions.join('|')})` + ')$' @@ -42,7 +40,9 @@ export const createClientComponentFilter = ( return (importSource: string) => regex.test(importSource) } -export const createServerComponentFilter = (extensions: string[]) => { - const regex = new RegExp(`\\.server(\\.(${extensions.join('|')}))?$`) +export const createServerComponentFilter = () => { + const regex = new RegExp( + `\\.server(\\.(${defaultJsFileExtensions.join('|')}))?$` + ) return (importSource: string) => regex.test(importSource) } diff --git a/packages/next/build/webpack/plugins/flight-manifest-plugin.ts b/packages/next/build/webpack/plugins/flight-manifest-plugin.ts index d639b66ecf7e11a..73c82d8b7d322da 100644 --- a/packages/next/build/webpack/plugins/flight-manifest-plugin.ts +++ b/packages/next/build/webpack/plugins/flight-manifest-plugin.ts @@ -23,6 +23,7 @@ type Options = { const PLUGIN_NAME = 'FlightManifestPlugin' +const isClientComponent = createClientComponentFilter() export class FlightManifestPlugin { dev: boolean = false pageExtensions: string[] @@ -64,7 +65,6 @@ export class FlightManifestPlugin { createAsset(assets: any, compilation: any) { const manifest: any = {} - const isClientComponent = createClientComponentFilter(this.pageExtensions) compilation.chunkGroups.forEach((chunkGroup: any) => { function recordModule(id: string, _chunk: any, mod: any) { const resource = mod.resource diff --git a/packages/next/client/dev/dev-build-watcher.js b/packages/next/client/dev/dev-build-watcher.js index 3d3e043eed2cdd2..27a93fc6025df47 100644 --- a/packages/next/client/dev/dev-build-watcher.js +++ b/packages/next/client/dev/dev-build-watcher.js @@ -5,21 +5,14 @@ export default function initializeBuildWatcher( position = 'bottom-right' ) { const shadowHost = document.createElement('div') + const [verticalProperty, horizontalProperty] = position.split('-') shadowHost.id = '__next-build-watcher' // Make sure container is fixed and on a high zIndex so it shows shadowHost.style.position = 'fixed' // Ensure container's position to be top or bottom (default) - if (['top-left', 'top-right'].indexOf(position) > -1) { - shadowHost.style.top = '10px' - } else { - shadowHost.style.bottom = '10px' - } + shadowHost.style[verticalProperty] = '10px' // Ensure container's position to be left or right (default) - if (['bottom-left', 'top-left'].indexOf(position) > -1) { - shadowHost.style.left = '20px' - } else { - shadowHost.style.right = '20px' - } + shadowHost.style[horizontalProperty] = '20px' shadowHost.style.width = 0 shadowHost.style.height = 0 shadowHost.style.zIndex = 99999 @@ -43,7 +36,7 @@ export default function initializeBuildWatcher( shadowRoot.appendChild(container) // CSS - const css = createCss(prefix) + const css = createCss(prefix, { horizontalProperty, verticalProperty }) shadowRoot.appendChild(css) // State @@ -134,13 +127,13 @@ function createContainer(prefix) { return container } -function createCss(prefix) { +function createCss(prefix, { horizontalProperty, verticalProperty }) { const css = document.createElement('style') css.textContent = ` #${prefix}container { position: absolute; - bottom: 10px; - right: 30px; + ${verticalProperty}: 10px; + ${horizontalProperty}: 30px; border-radius: 3px; background: #000; @@ -158,7 +151,7 @@ function createCss(prefix) { display: none; opacity: 0; - transition: opacity 0.1s ease, bottom 0.1s ease; + transition: opacity 0.1s ease, ${verticalProperty} 0.1s ease; animation: ${prefix}fade-in 0.1s ease-in-out; } @@ -167,7 +160,7 @@ function createCss(prefix) { } #${prefix}container.${prefix}building { - bottom: 20px; + ${verticalProperty}: 20px; opacity: 1; } @@ -187,11 +180,11 @@ function createCss(prefix) { @keyframes ${prefix}fade-in { from { - bottom: 10px; + ${verticalProperty}: 10px; opacity: 0; } to { - bottom: 20px; + ${verticalProperty}: 20px; opacity: 1; } } diff --git a/packages/next/client/image.tsx b/packages/next/client/image.tsx index 5eea24447eab361..6a793cdae1cd7b8 100644 --- a/packages/next/client/image.tsx +++ b/packages/next/client/image.tsx @@ -884,6 +884,7 @@ const ImageElement = ({ onLoadingCompleteRef, setBlurComplete, setIntersection, + onLoad, onError, isVisible, ...rest @@ -933,6 +934,9 @@ const ImageElement = ({ onLoadingCompleteRef, setBlurComplete ) + if (onLoad) { + onLoad(event) + } }} onError={(event) => { if (placeholder === 'blur') { diff --git a/packages/next/compiled/use-subscription/index.js b/packages/next/compiled/use-subscription/index.js index 367ff0d5c148f81..94087da0e39deb1 100644 --- a/packages/next/compiled/use-subscription/index.js +++ b/packages/next/compiled/use-subscription/index.js @@ -1,10 +1,10 @@ -(()=>{"use strict";var e={800:e=>{ +(function(){"use strict";var e={800:function(e){ /* object-assign (c) Sindre Sorhus @license MIT */ -var r=Object.getOwnPropertySymbols;var t=Object.prototype.hasOwnProperty;var u=Object.prototype.propertyIsEnumerable;function toObject(e){if(e===null||e===undefined){throw new TypeError("Object.assign cannot be called with null or undefined")}return Object(e)}function shouldUseNative(){try{if(!Object.assign){return false}var e=new String("abc");e[5]="de";if(Object.getOwnPropertyNames(e)[0]==="5"){return false}var r={};for(var t=0;t<10;t++){r["_"+String.fromCharCode(t)]=t}var u=Object.getOwnPropertyNames(r).map((function(e){return r[e]}));if(u.join("")!=="0123456789"){return false}var n={};"abcdefghijklmnopqrst".split("").forEach((function(e){n[e]=e}));if(Object.keys(Object.assign({},n)).join("")!=="abcdefghijklmnopqrst"){return false}return true}catch(e){return false}}e.exports=shouldUseNative()?Object.assign:function(e,n){var a;var i=toObject(e);var s;for(var c=1;c{ +var r=Object.getOwnPropertySymbols;var t=Object.prototype.hasOwnProperty;var u=Object.prototype.propertyIsEnumerable;function toObject(e){if(e===null||e===undefined){throw new TypeError("Object.assign cannot be called with null or undefined")}return Object(e)}function shouldUseNative(){try{if(!Object.assign){return false}var e=new String("abc");e[5]="de";if(Object.getOwnPropertyNames(e)[0]==="5"){return false}var r={};for(var t=0;t<10;t++){r["_"+String.fromCharCode(t)]=t}var u=Object.getOwnPropertyNames(r).map((function(e){return r[e]}));if(u.join("")!=="0123456789"){return false}var n={};"abcdefghijklmnopqrst".split("").forEach((function(e){n[e]=e}));if(Object.keys(Object.assign({},n)).join("")!=="abcdefghijklmnopqrst"){return false}return true}catch(e){return false}}e.exports=shouldUseNative()?Object.assign:function(e,n){var a;var i=toObject(e);var s;for(var c=1;c{ +if(process.env.NODE_ENV!=="production"){(function(){"use strict";var e=t(800);var u=t(522);function useSubscription(r){var t=r.getCurrentValue,n=r.subscribe;var a=u.useState((function(){return{getCurrentValue:t,subscribe:n,value:t()}})),i=a[0],s=a[1];var c=i.value;if(i.getCurrentValue!==t||i.subscribe!==n){c=t();s({getCurrentValue:t,subscribe:n,value:c})}u.useDebugValue(c);u.useEffect((function(){var r=false;var checkForUpdates=function(){if(r){return}var u=t();s((function(r){if(r.getCurrentValue!==t||r.subscribe!==n){return r}if(r.value===u){return r}return e({},r,{value:u})}))};var u=n(checkForUpdates);checkForUpdates();return function(){r=true;u()}}),[t,n]);return c}r.useSubscription=useSubscription})()}},403:function(e,r,t){ /** @license React vundefined * use-subscription.production.min.js * @@ -22,4 +22,4 @@ if(process.env.NODE_ENV!=="production"){(function(){"use strict";var e=t(800);va * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ -var u=t(800),n=t(522);r.useSubscription=function(e){var r=e.getCurrentValue,t=e.subscribe,a=n.useState((function(){return{getCurrentValue:r,subscribe:t,value:r()}}));e=a[0];var i=a[1];a=e.value;if(e.getCurrentValue!==r||e.subscribe!==t)a=r(),i({getCurrentValue:r,subscribe:t,value:a});n.useDebugValue(a);n.useEffect((function(){function b(){if(!e){var n=r();i((function(e){return e.getCurrentValue!==r||e.subscribe!==t||e.value===n?e:u({},e,{value:n})}))}}var e=!1,n=t(b);b();return function(){e=!0;n()}}),[r,t]);return a}},138:(e,r,t)=>{if(process.env.NODE_ENV==="production"){e.exports=t(403)}else{e.exports=t(569)}},522:e=>{e.exports=require("react")}};var r={};function __nccwpck_require__(t){var u=r[t];if(u!==undefined){return u.exports}var n=r[t]={exports:{}};var a=true;try{e[t](n,n.exports,__nccwpck_require__);a=false}finally{if(a)delete r[t]}return n.exports}if(typeof __nccwpck_require__!=="undefined")__nccwpck_require__.ab=__dirname+"/";var t=__nccwpck_require__(138);module.exports=t})(); \ No newline at end of file +var u=t(800),n=t(522);r.useSubscription=function(e){var r=e.getCurrentValue,t=e.subscribe,a=n.useState((function(){return{getCurrentValue:r,subscribe:t,value:r()}}));e=a[0];var i=a[1];a=e.value;if(e.getCurrentValue!==r||e.subscribe!==t)a=r(),i({getCurrentValue:r,subscribe:t,value:a});n.useDebugValue(a);n.useEffect((function(){function b(){if(!e){var n=r();i((function(e){return e.getCurrentValue!==r||e.subscribe!==t||e.value===n?e:u({},e,{value:n})}))}}var e=!1,n=t(b);b();return function(){e=!0;n()}}),[r,t]);return a}},138:function(e,r,t){if(process.env.NODE_ENV==="production"){e.exports=t(403)}else{e.exports=t(569)}},522:function(e){e.exports=require("react")}};var r={};function __nccwpck_require__(t){var u=r[t];if(u!==undefined){return u.exports}var n=r[t]={exports:{}};var a=true;try{e[t](n,n.exports,__nccwpck_require__);a=false}finally{if(a)delete r[t]}return n.exports}if(typeof __nccwpck_require__!=="undefined")__nccwpck_require__.ab=__dirname+"/";var t=__nccwpck_require__(138);module.exports=t})(); \ No newline at end of file diff --git a/packages/next/lib/typescript/writeConfigurationDefaults.ts b/packages/next/lib/typescript/writeConfigurationDefaults.ts index bc67874936d71d5..c534f63154ebb49 100644 --- a/packages/next/lib/typescript/writeConfigurationDefaults.ts +++ b/packages/next/lib/typescript/writeConfigurationDefaults.ts @@ -54,6 +54,12 @@ function getDesiredCompilerOptions( }, moduleResolution: { parsedValue: ts.ModuleResolutionKind.NodeJs, + // All of these values work: + parsedValues: [ + ts.ModuleResolutionKind.NodeJs, + ts.ModuleResolutionKind.Node12, + ts.ModuleResolutionKind.NodeNext, + ], value: 'node', reason: 'to match webpack resolution', }, diff --git a/packages/next/package.json b/packages/next/package.json index 73a3ed62e9e0b2e..89a52da9388fee7 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "12.1.6-canary.0", + "version": "12.1.6-canary.4", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -69,7 +69,7 @@ ] }, "dependencies": { - "@next/env": "12.1.6-canary.0", + "@next/env": "12.1.6-canary.4", "caniuse-lite": "^1.0.30001283", "postcss": "8.4.5", "styled-jsx": "5.0.1" @@ -117,11 +117,11 @@ "@hapi/accept": "5.0.2", "@napi-rs/cli": "2.4.4", "@napi-rs/triples": "1.1.0", - "@next/polyfill-module": "12.1.6-canary.0", - "@next/polyfill-nomodule": "12.1.6-canary.0", - "@next/react-dev-overlay": "12.1.6-canary.0", - "@next/react-refresh-utils": "12.1.6-canary.0", - "@next/swc": "12.1.6-canary.0", + "@next/polyfill-module": "12.1.6-canary.4", + "@next/polyfill-nomodule": "12.1.6-canary.4", + "@next/react-dev-overlay": "12.1.6-canary.4", + "@next/react-refresh-utils": "12.1.6-canary.4", + "@next/swc": "12.1.6-canary.4", "@peculiar/webcrypto": "1.3.1", "@taskr/clear": "1.1.0", "@taskr/esnext": "1.1.0", diff --git a/packages/next/pages/_error.tsx b/packages/next/pages/_error.tsx index 4ce82ff780e5636..0e2449dd1b1353f 100644 --- a/packages/next/pages/_error.tsx +++ b/packages/next/pages/_error.tsx @@ -52,8 +52,26 @@ export default class Error

extends React.Component

{ )}

- {children}
diff --git a/test/integration/react-streaming-and-server-components/switchable-runtime/pages/node-rsc.server.js b/test/integration/react-streaming-and-server-components/switchable-runtime/pages/node-rsc.server.js index 4a725cf2f07041e..aa0133d5f374b5e 100644 --- a/test/integration/react-streaming-and-server-components/switchable-runtime/pages/node-rsc.server.js +++ b/test/integration/react-streaming-and-server-components/switchable-runtime/pages/node-rsc.server.js @@ -13,6 +13,8 @@ export default function Page() { ) } +Page.title = 'node-rsc' + export const config = { runtime: 'nodejs', } diff --git a/test/integration/react-streaming-and-server-components/test/switchable-runtime.test.js b/test/integration/react-streaming-and-server-components/test/switchable-runtime.test.js index eb7462329cfe983..eec271208a27fe4 100644 --- a/test/integration/react-streaming-and-server-components/test/switchable-runtime.test.js +++ b/test/integration/react-streaming-and-server-components/test/switchable-runtime.test.js @@ -38,7 +38,7 @@ async function testRoute(appPort, url, { isStatic, isEdge, isRSC }) { // Should be re-rendered. expect(renderedAt1).toBeLessThan(renderedAt2) } - const customAppServerHtml = '
' + const customAppServerHtml = '
{ isEdge: false, isRSC: true, }) + + const html = await renderViaHTTP(context.appPort, '/node-rsc') + expect(html).toContain('data-title="node-rsc"') }) it('should build /node-rsc-ssr as a dynamic page with the nodejs runtime', async () => { diff --git a/test/integration/tsconfig-verifier/test/index.test.js b/test/integration/tsconfig-verifier/test/index.test.js index 799ca2403d2942e..9b994e7a5199fd1 100644 --- a/test/integration/tsconfig-verifier/test/index.test.js +++ b/test/integration/tsconfig-verifier/test/index.test.js @@ -264,6 +264,52 @@ describe('tsconfig.json verifier', () => { `) }) + it('allows you to set node12 moduleResolution mode', async () => { + expect(await exists(tsConfig)).toBe(false) + + await writeFile( + tsConfig, + `{ "compilerOptions": { "esModuleInterop": false, "moduleResolution": "node12" } }` + ) + await new Promise((resolve) => setTimeout(resolve, 500)) + const { code } = await nextBuild(appDir) + expect(code).toBe(0) + + expect(await readFile(tsConfig, 'utf8')).toMatchInlineSnapshot(` + "{ + \\"compilerOptions\\": { + \\"esModuleInterop\\": true, + \\"moduleResolution\\": \\"node12\\", + \\"target\\": \\"es5\\", + \\"lib\\": [ + \\"dom\\", + \\"dom.iterable\\", + \\"esnext\\" + ], + \\"allowJs\\": true, + \\"skipLibCheck\\": true, + \\"strict\\": false, + \\"forceConsistentCasingInFileNames\\": true, + \\"noEmit\\": true, + \\"incremental\\": true, + \\"module\\": \\"esnext\\", + \\"resolveJsonModule\\": true, + \\"isolatedModules\\": true, + \\"jsx\\": \\"preserve\\" + }, + \\"include\\": [ + \\"next-env.d.ts\\", + \\"**/*.ts\\", + \\"**/*.tsx\\" + ], + \\"exclude\\": [ + \\"node_modules\\" + ] + } + " + `) + }) + it('allows you to extend another configuration file', async () => { expect(await exists(tsConfig)).toBe(false) expect(await exists(tsConfigBase)).toBe(false) diff --git a/test/lib/mocks-require-hook.js b/test/lib/mocks-require-hook.js new file mode 100644 index 000000000000000..7c5eac856312fcc --- /dev/null +++ b/test/lib/mocks-require-hook.js @@ -0,0 +1,24 @@ +const mod = require('module') + +const hookPropertyMap = new Map([ + [ + /node-polyfill-web-streams/, + require.resolve('../__mocks__/node-polyfill-web-streams.js'), + ], +]) + +function matchModule(request) { + for (const [key, value] of hookPropertyMap) { + if (key.test(request)) { + return value + } + } + return null +} + +const resolveFilename = mod._resolveFilename +mod._resolveFilename = function (request, parent, isMain, options) { + const hookResolved = matchModule(request) + if (hookResolved) request = hookResolved + return resolveFilename.call(mod, request, parent, isMain, options) +} diff --git a/test/lib/next-test-utils.js b/test/lib/next-test-utils.js index a33c5970a128b75..589dd66b68993e6 100644 --- a/test/lib/next-test-utils.js +++ b/test/lib/next-test-utils.js @@ -31,7 +31,13 @@ export function initNextServerScript( return new Promise((resolve, reject) => { const instance = spawn( 'node', - [...((opts && opts.nodeArgs) || []), '--no-deprecation', scriptPath], + [ + ...((opts && opts.nodeArgs) || []), + '-r', + require.resolve('./mocks-require-hook'), + '--no-deprecation', + scriptPath, + ], { env, cwd: opts && opts.cwd, @@ -147,7 +153,14 @@ export function runNextCommand(argv, options = {}) { console.log(`Running command "next ${argv.join(' ')}"`) const instance = spawn( 'node', - [...(options.nodeArgs || []), '--no-deprecation', nextBin, ...argv], + [ + ...(options.nodeArgs || []), + '-r', + require.resolve('./mocks-require-hook'), + '--no-deprecation', + nextBin, + ...argv, + ], { ...options.spawnOptions, cwd, @@ -237,7 +250,14 @@ export function runNextCommandDev(argv, stdOut, opts = {}) { return new Promise((resolve, reject) => { const instance = spawn( 'node', - [...nodeArgs, '--no-deprecation', nextBin, ...argv], + [ + ...nodeArgs, + '-r', + require.resolve('./mocks-require-hook'), + '--no-deprecation', + nextBin, + ...argv, + ], { cwd, env, diff --git a/test/production/react-18-streaming-ssr/index.test.ts b/test/production/react-18-streaming-ssr/index.test.ts index 7bc84746ffc5f10..c1be4ac31930d08 100644 --- a/test/production/react-18-streaming-ssr/index.test.ts +++ b/test/production/react-18-streaming-ssr/index.test.ts @@ -11,7 +11,7 @@ describe('react 18 streaming SSR in minimal mode', () => { next = await createNext({ files: { 'pages/index.server.js': ` - export default function Page() { + export default function Page() { return

static streaming

} `, @@ -65,8 +65,15 @@ describe('react 18 streaming SSR with custom next configs', () => { } `, 'pages/hello.js': ` + import Link from 'next/link' + export default function Page() { - return

hello nextjs

+ return ( +
+

hello nextjs

+ home> +
+ ) } `, 'pages/multi-byte.js': ` @@ -114,6 +121,7 @@ describe('react 18 streaming SSR with custom next configs', () => { expect(redirectRes.status).toBe(308) expect(res.status).toBe(200) expect(html).toContain('hello nextjs') + expect(html).toContain('home') }) it('should render multi-byte characters correctly in streaming', async () => { diff --git a/test/unit/eslint-plugin-next/no-assign-module-variable.test.ts b/test/unit/eslint-plugin-next/no-assign-module-variable.test.ts new file mode 100644 index 000000000000000..a58a1b064edb17c --- /dev/null +++ b/test/unit/eslint-plugin-next/no-assign-module-variable.test.ts @@ -0,0 +1,42 @@ +import rule from '@next/eslint-plugin-next/lib/rules/no-assign-module-variable' +import { RuleTester } from 'eslint' +;(RuleTester as any).setDefaultConfig({ + parserOptions: { + ecmaVersion: 2018, + sourceType: 'module', + ecmaFeatures: { + modules: true, + jsx: true, + }, + }, +}) +const ruleTester = new RuleTester() + +ruleTester.run('no-assign-module-variable', rule, { + valid: [ + ` + let myModule = {}; + + export default function MyComponent() { + return <> + } + `, + ], + invalid: [ + { + code: ` + let module = {}; + + export default function MyComponent() { + return <> + } + `, + errors: [ + { + message: + "Do not assign to the variable 'module'. See: https://nextjs.org/docs/messages/no-assign-module-variable", + }, + ], + }, + ], +}) diff --git a/test/unit/next-babel-loader-prod.test.ts b/test/unit/next-babel-loader-prod.test.ts index e8d62bb7a9c6b43..101bdc7faeb8711 100644 --- a/test/unit/next-babel-loader-prod.test.ts +++ b/test/unit/next-babel-loader-prod.test.ts @@ -216,7 +216,6 @@ describe('next-babel-loader', () => { }) const pageFile = path.resolve(dir, 'pages', 'index.js') - const tsPageFile = pageFile.replace(/\.js$/, '.ts') it('should not drop unused exports by default in a page', async () => { const code = await babel( @@ -323,75 +322,5 @@ describe('next-babel-loader', () => { `var __jsx = React.createElement;import "core-js";import { bar } from "a";import baz from "b";import * as React from "react";import { yeet } from "c";import baz3, { cats } from "d";import { c, d } from "e";import { e as ee } from "f";export var __N_SSG = true;export default function () { return __jsx("div", { __self: this, __source: { fileName: _jsxFileName, lineNumber: 1, columnNumber: 326 } }, cats + bar());}` ) }) - - it('should support optional chaining for JS file', async () => { - const code = await babel( - `let hello;` + - `export default () => hello?.world ? 'something' : 'nothing' `, - { - resourcePath: pageFile, - } - ) - expect(code).toMatchInlineSnapshot( - `"let hello;export default (() => hello !== null && hello !== void 0 && hello.world ? 'something' : 'nothing');"` - ) - }) - - it('should support optional chaining for TS file', async () => { - const code = await babel( - `let hello;` + - `export default () => hello?.world ? 'something' : 'nothing' `, - { - resourcePath: tsPageFile, - } - ) - expect(code).toMatchInlineSnapshot( - `"let hello;export default (() => hello !== null && hello !== void 0 && hello.world ? 'something' : 'nothing');"` - ) - }) - - it('should support nullish coalescing for JS file', async () => { - const code = await babel( - `const res = { - status: 0, - nullVal: null, - statusText: '', - - } - const status = res.status ?? 999 - const nullVal = res.nullVal ?? 'another' - const statusText = res.nullVal ?? 'not found' - export default () => 'hello' - `, - { - resourcePath: pageFile, - } - ) - expect(code).toMatchInlineSnapshot( - `"var _res$status, _res$nullVal, _res$nullVal2;const res = { status: 0, nullVal: null, statusText: ''};const status = (_res$status = res.status) !== null && _res$status !== void 0 ? _res$status : 999;const nullVal = (_res$nullVal = res.nullVal) !== null && _res$nullVal !== void 0 ? _res$nullVal : 'another';const statusText = (_res$nullVal2 = res.nullVal) !== null && _res$nullVal2 !== void 0 ? _res$nullVal2 : 'not found';export default (() => 'hello');"` - ) - }) - - it('should support nullish coalescing for TS file', async () => { - const code = await babel( - `const res = { - status: 0, - nullVal: null, - statusText: '', - - } - const status = res.status ?? 999 - const nullVal = res.nullVal ?? 'another' - const statusText = res.nullVal ?? 'not found' - export default () => 'hello' - `, - { - resourcePath: tsPageFile, - } - ) - expect(code).toMatchInlineSnapshot( - `"var _res$status, _res$nullVal, _res$nullVal2;const res = { status: 0, nullVal: null, statusText: ''};const status = (_res$status = res.status) !== null && _res$status !== void 0 ? _res$status : 999;const nullVal = (_res$nullVal = res.nullVal) !== null && _res$nullVal !== void 0 ? _res$nullVal : 'another';const statusText = (_res$nullVal2 = res.nullVal) !== null && _res$nullVal2 !== void 0 ? _res$nullVal2 : 'not found';export default (() => 'hello');"` - ) - }) }) }) diff --git a/test/unit/web-runtime/next-response.test.ts b/test/unit/web-runtime/next-response.test.ts index 293c33af06a87dc..98fe67b08f247af 100644 --- a/test/unit/web-runtime/next-response.test.ts +++ b/test/unit/web-runtime/next-response.test.ts @@ -30,6 +30,7 @@ afterAll(() => { const toJSON = async (response) => ({ body: await response.json(), contentType: response.headers.get('content-type'), + status: response.status, }) it('automatically parses and formats JSON', async () => { @@ -42,6 +43,24 @@ it('automatically parses and formats JSON', async () => { body: { message: 'hello!' }, }) + expect( + await toJSON(NextResponse.json({ status: 'success' }, { status: 201 })) + ).toMatchObject({ + contentType: 'application/json', + body: { status: 'success' }, + status: 201, + }) + + expect( + await toJSON( + NextResponse.json({ error: { code: 'bad_request' } }, { status: 400 }) + ) + ).toMatchObject({ + contentType: 'application/json', + body: { error: { code: 'bad_request' } }, + status: 400, + }) + expect(await toJSON(NextResponse.json(null))).toMatchObject({ contentType: 'application/json', body: null, diff --git a/yarn.lock b/yarn.lock index b3c97dc2ad5d372..d71d22a4ba6ac67 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5472,14 +5472,14 @@ "@typescript-eslint/typescript-estree" "4.29.1" debug "^4.3.1" -"@typescript-eslint/parser@5.10.1": - version "5.10.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.10.1.tgz#4ce9633cc33fc70bc13786cb793c1a76fe5ad6bd" - integrity sha512-GReo3tjNBwR5RnRO0K2wDIDN31cM3MmDtgyQ85oAxAmC5K3j/g85IjP+cDfcqDsDDBf1HNKQAD0WqOYL8jXqUA== - dependencies: - "@typescript-eslint/scope-manager" "5.10.1" - "@typescript-eslint/types" "5.10.1" - "@typescript-eslint/typescript-estree" "5.10.1" +"@typescript-eslint/parser@5.19.0": + version "5.19.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.19.0.tgz#05e587c1492868929b931afa0cb5579b0f728e75" + integrity sha512-yhktJjMCJX8BSBczh1F/uY8wGRYrBeyn84kH6oyqdIJwTGKmzX5Qiq49LRQ0Jh0LXnWijEziSo6BRqny8nqLVQ== + dependencies: + "@typescript-eslint/scope-manager" "5.19.0" + "@typescript-eslint/types" "5.19.0" + "@typescript-eslint/typescript-estree" "5.19.0" debug "^4.3.2" "@typescript-eslint/scope-manager@4.22.0": @@ -5498,13 +5498,13 @@ "@typescript-eslint/types" "4.29.1" "@typescript-eslint/visitor-keys" "4.29.1" -"@typescript-eslint/scope-manager@5.10.1": - version "5.10.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.10.1.tgz#f0539c73804d2423506db2475352a4dec36cd809" - integrity sha512-Lyvi559Gvpn94k7+ElXNMEnXu/iundV5uFmCUNnftbFrUbAJ1WBoaGgkbOBm07jVZa682oaBU37ao/NGGX4ZDg== +"@typescript-eslint/scope-manager@5.19.0": + version "5.19.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.19.0.tgz#97e59b0bcbcb54dbcdfba96fc103b9020bbe9cb4" + integrity sha512-Fz+VrjLmwq5fbQn5W7cIJZ066HxLMKvDEmf4eu1tZ8O956aoX45jAuBB76miAECMTODyUxH61AQM7q4/GOMQ5g== dependencies: - "@typescript-eslint/types" "5.10.1" - "@typescript-eslint/visitor-keys" "5.10.1" + "@typescript-eslint/types" "5.19.0" + "@typescript-eslint/visitor-keys" "5.19.0" "@typescript-eslint/types@4.22.0": version "4.22.0" @@ -5516,10 +5516,10 @@ resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.29.1.tgz#94cce6cf7cc83451df03339cda99d326be2feaf5" integrity sha512-Jj2yu78IRfw4nlaLtKjVaGaxh/6FhofmQ/j8v3NXmAiKafbIqtAPnKYrf0sbGjKdj0hS316J8WhnGnErbJ4RCA== -"@typescript-eslint/types@5.10.1": - version "5.10.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.10.1.tgz#dca9bd4cb8c067fc85304a31f38ec4766ba2d1ea" - integrity sha512-ZvxQ2QMy49bIIBpTqFiOenucqUyjTQ0WNLhBM6X1fh1NNlYAC6Kxsx8bRTY3jdYsYg44a0Z/uEgQkohbR0H87Q== +"@typescript-eslint/types@5.19.0": + version "5.19.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.19.0.tgz#12d3d600d754259da771806ee8b2c842d3be8d12" + integrity sha512-zR1ithF4Iyq1wLwkDcT+qFnhs8L5VUtjgac212ftiOP/ZZUOCuuF2DeGiZZGQXGoHA50OreZqLH5NjDcDqn34w== "@typescript-eslint/typescript-estree@4.22.0": version "4.22.0" @@ -5547,13 +5547,13 @@ semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/typescript-estree@5.10.1": - version "5.10.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.10.1.tgz#b268e67be0553f8790ba3fe87113282977adda15" - integrity sha512-PwIGnH7jIueXv4opcwEbVGDATjGPO1dx9RkUl5LlHDSe+FXxPwFL5W/qYd5/NHr7f6lo/vvTrAzd0KlQtRusJQ== +"@typescript-eslint/typescript-estree@5.19.0": + version "5.19.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.19.0.tgz#fc987b8f62883f9ea6a5b488bdbcd20d33c0025f" + integrity sha512-dRPuD4ocXdaE1BM/dNR21elSEUPKaWgowCA0bqJ6YbYkvtrPVEvZ+zqcX5a8ECYn3q5iBSSUcBBD42ubaOp0Hw== dependencies: - "@typescript-eslint/types" "5.10.1" - "@typescript-eslint/visitor-keys" "5.10.1" + "@typescript-eslint/types" "5.19.0" + "@typescript-eslint/visitor-keys" "5.19.0" debug "^4.3.2" globby "^11.0.4" is-glob "^4.0.3" @@ -5576,12 +5576,12 @@ "@typescript-eslint/types" "4.29.1" eslint-visitor-keys "^2.0.0" -"@typescript-eslint/visitor-keys@5.10.1": - version "5.10.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.10.1.tgz#29102de692f59d7d34ecc457ed59ab5fc558010b" - integrity sha512-NjQ0Xinhy9IL979tpoTRuLKxMc0zJC7QVSdeerXs2/QvOy2yRkzX5dRb10X5woNUdJgU8G3nYRDlI33sq1K4YQ== +"@typescript-eslint/visitor-keys@5.19.0": + version "5.19.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.19.0.tgz#c84ebc7f6c744707a361ca5ec7f7f64cd85b8af6" + integrity sha512-Ym7zZoMDZcAKWsULi2s7UMLREdVQdScPQ/fKWMYefarCztWlHPFVJo8racf8R0Gc8FAEJ2eD4of8As1oFtnQlQ== dependencies: - "@typescript-eslint/types" "5.10.1" + "@typescript-eslint/types" "5.19.0" eslint-visitor-keys "^3.0.0" "@typescript/lib-dom@npm:@types/web": @@ -20667,10 +20667,10 @@ typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" -typescript@4.5.5: - version "4.5.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.5.tgz#d8c953832d28924a9e3d37c73d729c846c5896f3" - integrity sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA== +typescript@4.6.3: + version "4.6.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.3.tgz#eefeafa6afdd31d725584c67a0eaba80f6fc6c6c" + integrity sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw== typescript@^4.1.3: version "4.1.3"