diff --git a/.github/workflows/build_test_deploy.yml b/.github/workflows/build_test_deploy.yml index 37b71a4632f0..fe8dfad1dc11 100644 --- a/.github/workflows/build_test_deploy.yml +++ b/.github/workflows/build_test_deploy.yml @@ -9,7 +9,7 @@ name: Build, test, and deploy env: NAPI_CLI_VERSION: 2.7.0 TURBO_VERSION: 1.3.2-canary.1 - RUST_TOOLCHAIN: nightly-2022-02-23 + RUST_TOOLCHAIN: nightly-2022-06-12 PNPM_VERSION: 7.2.1 jobs: diff --git a/docs/advanced-features/middleware.md b/docs/advanced-features/middleware.md index 8f65f84a22f1..3a53fa223235 100644 --- a/docs/advanced-features/middleware.md +++ b/docs/advanced-features/middleware.md @@ -90,6 +90,19 @@ export const config = { > **Note:** The `matcher` values need to be constants so they can be statically analyzed at build-time. Dynamic values such as variables will be ignored. +Configured matchers: + +1. MUST start with `/` +1. can include named parameters: `/about/:path` matches `/about/a` and `/about/b` but not `/about/a/c` +1. can have modifiers on named parameters (starting with `:`): `/about/:path*` matches `/about/a/b/c` because `*` is _zero or more_. `?` is _zero or one_ and `+` _one or more_ +1. can use regular expression enclosed in parenthesis: `/about/(.*)` is the same as `/about/:path*` + +Read more details on [path-to-regexp](https://github.com/pillarjs/path-to-regexp#path-to-regexp-1) documentation. + +> **Note:** For backward compatibility, Next.js always considers `/public` as `/public/index`. Therefore, a matcher of `/public/:path` will match. + +> **Note:** It is not possible to exclude middleware from matching static path starting with `_next/`. This allow enforcing security with middleware. + ### Conditional Statements ```typescript diff --git a/errors/middleware-upgrade-guide.md b/errors/middleware-upgrade-guide.md index 8c04cc6c4f3b..94af0bceeae5 100644 --- a/errors/middleware-upgrade-guide.md +++ b/errors/middleware-upgrade-guide.md @@ -388,4 +388,4 @@ Prior to Next.js `v12.2`, Middleware was not executed for `_next` requests. For cases where Middleware is used for authorization, you should migrate to use `rewrite`/`redirect` to Pages that show an authorization error, login forms, or to an API Route. -See [No Reponse Body](#no-response-body) for an example of how to migrate to use `rewrite`/`redirect`. +See [No Response Body](#no-response-body) for an example of how to migrate to use `rewrite`/`redirect`. diff --git a/examples/cms-sanity/lib/sanity.server.js b/examples/cms-sanity/lib/sanity.server.js index 259d11888a8d..afa862ce523d 100644 --- a/examples/cms-sanity/lib/sanity.server.js +++ b/examples/cms-sanity/lib/sanity.server.js @@ -12,7 +12,7 @@ export const previewClient = createClient({ ...sanityConfig, useCdn: false, // Fallback to using the WRITE token until https://www.sanity.io/docs/vercel-integration starts shipping a READ token. - // As this client only exists on the server and the token is never shared with the browser, we ddon't risk escalating permissions to untrustworthy users + // As this client only exists on the server and the token is never shared with the browser, we don't risk escalating permissions to untrustworthy users token: process.env.SANITY_API_READ_TOKEN || process.env.SANITY_API_WRITE_TOKEN, }) diff --git a/examples/middleware-matcher/.gitignore b/examples/middleware-matcher/.gitignore new file mode 100755 index 000000000000..c87c9b392c02 --- /dev/null +++ b/examples/middleware-matcher/.gitignore @@ -0,0 +1,36 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# local env files +.env*.local + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/examples/middleware-matcher/README.md b/examples/middleware-matcher/README.md new file mode 100755 index 000000000000..6eed41451fef --- /dev/null +++ b/examples/middleware-matcher/README.md @@ -0,0 +1,37 @@ +# Middleware + +This example shows how to configure your [Next.js Middleware](https://nextjs.org/docs/advanced-features/middleware) to only match specific pages. + +The index page ([`pages/index.js`](pages/index.js)) has a list of links to dynamic pages, which will tell whether they were matched or not. + +The Middleware file ([`middleware.js`](middleware.js)) has a special `matcher` configuration key, allowing you to fine-grained control [matched pages](https://nextjs.org/docs/advanced-features/middleware#matcher). + +Please keep in mind that: + +1. Middleware always runs first +1. Middleware always matches `_next` routes on server side +1. matcher must always starts with a '/' + +## Deploy your own + +Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example): + +[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/git/external?repository-url=https://github.com/vercel/next.js/tree/canary/examples/middleware-matcher&project-name=middleware-matcher&repository-name=middleware-matcher) + +## How to use + +Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init), [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/), or [pnpm](https://pnpm.io) to bootstrap the example: + +```bash +npx create-next-app --example middleware-matcher middleware-matcher-app +``` + +```bash +yarn create next-app --example middleware-matcher middleware-matcher-app +``` + +```bash +pnpm create next-app --example middleware-matcher middleware-matcher-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/examples/middleware-matcher/middleware.js b/examples/middleware-matcher/middleware.js new file mode 100644 index 000000000000..2d555ddfa773 --- /dev/null +++ b/examples/middleware-matcher/middleware.js @@ -0,0 +1,15 @@ +import { NextResponse } from 'next/server' + +export default function middleware(req) { + const { pathname } = new URL(req.url) + const response = NextResponse.next() + response.headers.set( + 'set-cookie', + `middleware-slug=${pathname.slice(1)}; Path=${pathname}` + ) + return response +} + +export const config = { + matcher: ['/public/disclaimer', '/((?!public|static).*)'], +} diff --git a/examples/middleware-matcher/package.json b/examples/middleware-matcher/package.json new file mode 100644 index 000000000000..0607e92b35c2 --- /dev/null +++ b/examples/middleware-matcher/package.json @@ -0,0 +1,13 @@ +{ + "private": true, + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start" + }, + "dependencies": { + "next": "latest", + "react": "latest", + "react-dom": "latest" + } +} diff --git a/examples/middleware-matcher/pages/[...slug].jsx b/examples/middleware-matcher/pages/[...slug].jsx new file mode 100644 index 000000000000..20b053f7f066 --- /dev/null +++ b/examples/middleware-matcher/pages/[...slug].jsx @@ -0,0 +1,29 @@ +import { useRouter } from 'next/router' + +function hasMiddlewareMatched(slug) { + const values = + (typeof document !== 'undefined' ? document.cookie : '') + .split(';') + .map((pair) => pair.split('=')) + .filter(([key]) => key === 'middleware-slug') + .map(([, value]) => value.trim()) ?? [] + return values.some((value) => value === slug?.join('/')) +} + +export const ContentPage = (props) => { + const { + query: { slug }, // slug is an array of path segments + } = useRouter() + return ( + <> +

+ {hasMiddlewareMatched(slug) + ? 'Middleware matched!' + : 'Middleware ignored me'} +

+ {'<-'} back + + ) +} + +export default ContentPage diff --git a/examples/middleware-matcher/pages/index.jsx b/examples/middleware-matcher/pages/index.jsx new file mode 100755 index 000000000000..e99713f6d504 --- /dev/null +++ b/examples/middleware-matcher/pages/index.jsx @@ -0,0 +1,30 @@ +const Home = () => { + const matching = ['/about', '/about/topic/cats', '/public/disclaimer'] + const notMatching = ['/public', '/public/disclaimer/nested', '/static'] + return ( +
+

Middleware matching

+

The current middleware configuration is:

+
+        export const config = {'{'}
+        
+ {' '}matcher: [
+ {' '}'/public/disclaimer', // match a single, specific page +
+ {' '}'/((?!public|static).*) // match all pages not starting with + 'public' or 'static'
+ {' '}]
+ {'}'} +
+ +
+ ) +} + +export default Home diff --git a/examples/with-styled-components-babel/package.json b/examples/with-styled-components-babel/package.json index 73fccf597a88..a88dcbeed7fe 100644 --- a/examples/with-styled-components-babel/package.json +++ b/examples/with-styled-components-babel/package.json @@ -7,16 +7,16 @@ }, "dependencies": { "next": "latest", - "react": "^17.0.2", - "react-dom": "^17.0.2", - "react-is": "^17.0.2", - "styled-components": "^5.2.3" + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-is": "^18.2.0", + "styled-components": "^5.3.5" }, "devDependencies": { - "@types/node": "17.0.24", - "@types/react": "^17.0.2", - "@types/styled-components": "5.1.25", - "babel-plugin-styled-components": "^1.12.0", - "typescript": "4.6.3" + "@types/node": "18.7.14", + "@types/react": "^18.0.18", + "@types/styled-components": "5.1.26", + "babel-plugin-styled-components": "^2.0.7", + "typescript": "4.8.2" } } diff --git a/examples/with-styled-components-babel/pages/_document.tsx b/examples/with-styled-components-babel/pages/_document.tsx index 8f22e1b2425b..a336181f74c9 100644 --- a/examples/with-styled-components-babel/pages/_document.tsx +++ b/examples/with-styled-components-babel/pages/_document.tsx @@ -18,12 +18,12 @@ export default class MyDocument extends Document { const initialProps = await Document.getInitialProps(ctx) return { ...initialProps, - styles: [ + styles: ( <> {initialProps.styles} {sheet.getStyleElement()} - , - ], + + ), } } finally { sheet.seal() diff --git a/lerna.json b/lerna.json index 044691dcebb3..f5485fa63466 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "12.2.6-canary.8" + "version": "12.2.6-canary.9" } diff --git a/package.json b/package.json index aec953b938e1..5f5ac0dfcb40 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,7 @@ "@svgr/webpack": "5.5.0", "@swc/cli": "0.1.55", "@swc/core": "1.2.203", - "@swc/helpers": "0.4.2", + "@swc/helpers": "0.4.11", "@testing-library/react": "13.0.0", "@types/cheerio": "0.22.16", "@types/fs-extra": "8.1.0", diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index 8068c3d98951..c5c0f9e8f99a 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.2.6-canary.8", + "version": "12.2.6-canary.9", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index 6d7a4af660cb..d9d43b0845b8 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.2.6-canary.8", + "version": "12.2.6-canary.9", "description": "ESLint configuration used by NextJS.", "main": "index.js", "license": "MIT", @@ -9,7 +9,7 @@ "directory": "packages/eslint-config-next" }, "dependencies": { - "@next/eslint-plugin-next": "12.2.6-canary.8", + "@next/eslint-plugin-next": "12.2.6-canary.9", "@rushstack/eslint-patch": "^1.1.3", "@typescript-eslint/parser": "^5.21.0", "eslint-import-resolver-node": "^0.3.6", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index 55032e96a498..085397934423 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.2.6-canary.8", + "version": "12.2.6-canary.9", "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 6487021d65b2..bfe8796e163e 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.2.6-canary.8", + "version": "12.2.6-canary.9", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index b85a1b7d9f4e..6e8128fa1b7f 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "12.2.6-canary.8", + "version": "12.2.6-canary.9", "license": "MIT", "dependencies": { "chalk": "4.1.0", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index 11322dbe40fe..8cecf631cb80 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "12.2.6-canary.8", + "version": "12.2.6-canary.9", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index 245fe78a3c1a..b26765dc9bb0 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "12.2.6-canary.8", + "version": "12.2.6-canary.9", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 4ba2fcfa1983..611894e994ea 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.2.6-canary.8", + "version": "12.2.6-canary.9", "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 4b3e6677264f..263460df95b4 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.2.6-canary.8", + "version": "12.2.6-canary.9", "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 9e7f7819cf26..bf69ee95eb36 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.2.6-canary.8", + "version": "12.2.6-canary.9", "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 52433026a068..23b20de523e3 100644 --- a/packages/next-swc/Cargo.lock +++ b/packages/next-swc/Cargo.lock @@ -59,9 +59,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.56" +version = "1.0.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4361135be9122e0870de935d7c439aef945b9f9ddd4199a553b5270b49c82a27" +checksum = "1485d4d2cc45e7b201ee3767015c96faa5904387c9d87c6efdd0fb511f12d305" [[package]] name = "arrayref" @@ -160,6 +160,24 @@ dependencies = [ "scoped-tls", ] +[[package]] +name = "binding_macros" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "148582743dcb4f3a872f6275a412e8e0c1b64023790fa33c8590e98e7b81d40e" +dependencies = [ + "anyhow", + "console_error_panic_hook", + "js-sys", + "once_cell", + "swc", + "swc_common", + "swc_ecma_ast", + "swc_ecma_transforms", + "wasm-bindgen", + "wasm-bindgen-futures", +] + [[package]] name = "bitflags" version = "1.3.2" @@ -670,7 +688,16 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4eeac5c5edb79e4e39fe8439ef35207780a11f69c52cbe424ce3dfad4cb78de6" dependencies = [ - "enum-iterator-derive", + "enum-iterator-derive 0.7.0", +] + +[[package]] +name = "enum-iterator" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91a4ec26efacf4aeff80887a175a419493cb6f8b5480d26387eb0bd038976187" +dependencies = [ + "enum-iterator-derive 1.1.0", ] [[package]] @@ -684,6 +711,17 @@ dependencies = [ "syn", ] +[[package]] +name = "enum-iterator-derive" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "828de45d0ca18782232dfb8f3ea9cc428e8ced380eb26a520baaacfc70de39ce" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "enum_kind" version = "0.2.1" @@ -891,6 +929,18 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "getset" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e45727250e75cc04ff2846a66397da8ef2b3db8e40e0cef4df67950a07621eb9" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "gimli" version = "0.26.1" @@ -1488,9 +1538,7 @@ dependencies = [ "once_cell", "regex", "serde", - "swc_cached", - "swc_ecma_transforms_testing", - "swc_ecmascript", + "swc_core", "testing", ] @@ -1575,20 +1623,11 @@ dependencies = [ "serde_json", "styled_components", "styled_jsx", - "swc", - "swc_atoms", - "swc_cached", - "swc_common", - "swc_ecma_loader", - "swc_ecma_transforms_testing", - "swc_ecmascript", + "swc_core", "swc_emotion", - "swc_plugin_runner", "testing", "tracing", "walkdir", - "wasmer", - "wasmer-wasi", ] [[package]] @@ -1606,20 +1645,11 @@ dependencies = [ "sentry", "serde", "serde_json", - "swc", - "swc_atoms", - "swc_bundler", - "swc_common", - "swc_ecma_loader", - "swc_ecmascript", - "swc_node_base", - "swc_plugin_runner", + "swc_core", "tracing", "tracing-chrome", "tracing-futures", "tracing-subscriber", - "wasmer", - "wasmer-wasi", ] [[package]] @@ -2018,9 +2048,9 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" [[package]] name = "preset_env_base" -version = "0.2.4" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f68dc2366d2258e280ad44221403aa0af50868b3e6dc1cb9fb14a302cc01948" +checksum = "79525f471165bbd66b40e93c54a2c98bb51ebb27497d6c97c5cc3441aaec5508" dependencies = [ "ahash", "anyhow", @@ -2078,11 +2108,11 @@ checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" [[package]] name = "proc-macro2" -version = "1.0.36" +version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" +checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab" dependencies = [ - "unicode-xid", + "unicode-ident", ] [[package]] @@ -2113,9 +2143,9 @@ checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" [[package]] name = "quote" -version = "1.0.15" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145" +checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" dependencies = [ "proc-macro2", ] @@ -2410,9 +2440,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.6" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f" +checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8" [[package]] name = "ryu" @@ -2589,7 +2619,7 @@ dependencies = [ "serde", "serde_json", "thiserror", - "time 0.3.11", + "time 0.3.13", "url", "uuid", ] @@ -2906,10 +2936,7 @@ dependencies = [ "regex", "serde", "serde_json", - "swc_atoms", - "swc_common", - "swc_ecma_transforms_testing", - "swc_ecmascript", + "swc_core", "testing", "tracing", ] @@ -2919,11 +2946,7 @@ name = "styled_jsx" version = "0.15.0" dependencies = [ "easy-error", - "swc_common", - "swc_css", - "swc_css_prefixer", - "swc_ecma_transforms_testing", - "swc_ecmascript", + "swc_core", "testing", "tracing", ] @@ -2964,9 +2987,9 @@ dependencies = [ [[package]] name = "swc" -version = "0.214.9" +version = "0.224.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66de60ec56727a44e40752aa324bb02a67467d941f60c37be99ad11fbb61446c" +checksum = "a6cc8d2e59e8d7a2650ea97193aaf50e4b1aa940e0476522a97e4913f63620ef" dependencies = [ "ahash", "anyhow", @@ -3013,11 +3036,10 @@ dependencies = [ [[package]] name = "swc_atoms" -version = "0.4.8" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "454bf2d73485f6c4af9c91e70ce4fd4f17e9294d37b9f2037a3c4c2fe54b598d" +checksum = "8fb43a79c8affc20f5d52b7db093399585ce87674427adc60843dbc8ec242608" dependencies = [ - "bytecheck", "once_cell", "rkyv", "rustc-hash", @@ -3028,9 +3050,9 @@ dependencies = [ [[package]] name = "swc_bundler" -version = "0.177.4" +version = "0.185.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8f7d7f3b5b735aee329ed2b7a117d8e4163d4d3410bfe2b19db9b21fa398115" +checksum = "00a67427e87cddb6a9502530c966d22f7099cb42783a50712a2ec3cc05ded7f9" dependencies = [ "ahash", "anyhow", @@ -3062,9 +3084,9 @@ dependencies = [ [[package]] name = "swc_cached" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "395389d54bea607246bb4a400b9b3df2e55adfe8fcce7965a5b99fed7816cf4d" +checksum = "96395ee002185e0b4bc9fa88e21b7065e77e9795d7e35dfcb02fc8085b5cd1ce" dependencies = [ "ahash", "anyhow", @@ -3077,9 +3099,9 @@ dependencies = [ [[package]] name = "swc_common" -version = "0.27.11" +version = "0.27.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "056ad401259d209007ecc55d18b2a539091eed3315846e1d923140499af08aed" +checksum = "cba38a2f1291fcf3f78f357802b8cec72ecf5e95808e9d937783e60cd3570b93" dependencies = [ "ahash", "anyhow", @@ -3111,9 +3133,9 @@ dependencies = [ [[package]] name = "swc_config" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8bb05ef56c14b95dd7e62e95960153af811b9a447287f1f6ca59f1337fb83d4" +checksum = "fc17721410f3f12aeb42dcb99528350adf122681ab4796e48c2cfc0bda0c752c" dependencies = [ "anyhow", "indexmap", @@ -3136,23 +3158,48 @@ dependencies = [ ] [[package]] -name = "swc_css" -version = "0.120.0" +name = "swc_core" +version = "0.20.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d3025a9f4c123dfc5976940e9aa986ff06162f5e9b81601fa34dfab9bcc734d" +checksum = "30e3327c208ae240cb71b1da1a660e2cdffb4b3316f402c75c9ebc979dc563b2" dependencies = [ + "binding_macros", + "swc", + "swc_atoms", + "swc_bundler", + "swc_cached", + "swc_common", "swc_css_ast", "swc_css_codegen", "swc_css_parser", - "swc_css_utils", + "swc_css_prefixer", "swc_css_visit", + "swc_ecma_ast", + "swc_ecma_codegen", + "swc_ecma_loader", + "swc_ecma_minifier", + "swc_ecma_parser", + "swc_ecma_transforms_base", + "swc_ecma_transforms_optimization", + "swc_ecma_transforms_react", + "swc_ecma_transforms_testing", + "swc_ecma_transforms_typescript", + "swc_ecma_utils", + "swc_ecma_visit", + "swc_node_base", + "swc_plugin_proxy", + "swc_plugin_runner", + "swc_trace_macro", + "vergen", + "wasmer", + "wasmer-wasi", ] [[package]] name = "swc_css_ast" -version = "0.107.1" +version = "0.110.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "102e00c896dcbbd27f079df342f65ad685a3652ff20c93f8980380956bdc02e4" +checksum = "a509e0985a7f9fad59ffe2fca9c32e50f18d443a100b45e0caf3dcfdad3ffbcf" dependencies = [ "is-macro", "serde", @@ -3163,9 +3210,9 @@ dependencies = [ [[package]] name = "swc_css_codegen" -version = "0.117.0" +version = "0.120.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea1374bffa56f07d14184d0ed7de1725d71c44c5e10d13347ba58e3b87dad5f" +checksum = "7285b5dcc1c196f8798f4391f94b7f97fc097c371d99337775ef07f2779682a6" dependencies = [ "auto_impl", "bitflags", @@ -3192,9 +3239,9 @@ dependencies = [ [[package]] name = "swc_css_parser" -version = "0.116.0" +version = "0.119.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98db1b019681e34f3b5755d1f8e79c1716ceb77eda78219f9ee1cf95c6dfbda7" +checksum = "680fc749baaf53a0ebb5ba09482c43701b3d523ab823005376e39cfb3e4ca213" dependencies = [ "bitflags", "lexical", @@ -3206,9 +3253,9 @@ dependencies = [ [[package]] name = "swc_css_prefixer" -version = "0.117.0" +version = "0.121.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b89e03bf686929c74567627055f73525794de6002143f20540c6a2d7185634d6" +checksum = "774759d18cf8a0e2f5cab1d7fff457bb383f4b8e8c2fbe25a0a52e2a74c9a7be" dependencies = [ "once_cell", "preset_env_base", @@ -3223,9 +3270,9 @@ dependencies = [ [[package]] name = "swc_css_utils" -version = "0.104.0" +version = "0.107.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4123740701151259c69a4b7ba151efa630ae241111de7564f288059fa3768290" +checksum = "2b611f636a937f50361b8d18cfae08ae20fa1e3b659ab7d2e5ec7e774a6fbef4" dependencies = [ "once_cell", "serde", @@ -3238,9 +3285,9 @@ dependencies = [ [[package]] name = "swc_css_visit" -version = "0.106.0" +version = "0.109.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24688aa5b9533715d0f3443ff25b08eb16eddf045dd9a857dc6893fb409f3487" +checksum = "706be455229bd4c5c5761295fb02ef13f82c26daa0ef8f6efd1d769805462fe6" dependencies = [ "serde", "swc_atoms", @@ -3251,9 +3298,9 @@ dependencies = [ [[package]] name = "swc_ecma_ast" -version = "0.90.10" +version = "0.90.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4d9cb0825962e9f9baabec6270aeb6e7c21ade1a16d707916186ad5f13126d1" +checksum = "571989e199094be58d107e032c0b868f7b04a59a238e0a31bc9df8faf537dcd3" dependencies = [ "bitflags", "bytecheck", @@ -3270,9 +3317,9 @@ dependencies = [ [[package]] name = "swc_ecma_codegen" -version = "0.121.5" +version = "0.123.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b0bf7259fec5655df5163eafe0fabe4619f1d507b4c19a8b2be8a9ea2c806ff" +checksum = "616548c924bb4834b0570078c8edb85c07f5033d438316c482693d8968686dbb" dependencies = [ "memchr", "num-bigint", @@ -3302,9 +3349,9 @@ dependencies = [ [[package]] name = "swc_ecma_ext_transforms" -version = "0.85.5" +version = "0.87.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f19eb16fed54a740f92e9cb2d6ee79fc69b4a3b63d4a467c709693a413f6737" +checksum = "24cc13886dcab94205e82358abd59b49a6ca06f15ee66f28c082d0277c4f0a1f" dependencies = [ "phf", "swc_atoms", @@ -3316,9 +3363,9 @@ dependencies = [ [[package]] name = "swc_ecma_lints" -version = "0.58.5" +version = "0.61.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "931f3b19bad8a2d0e65eb2bf19771f92d6a0bf73a3b3f47f4a12c5c7259d9b85" +checksum = "3240efa29a4a5968134622766cd122ae2cbb81c3bb3f3fdd9e81814f15d28b47" dependencies = [ "ahash", "auto_impl", @@ -3359,9 +3406,9 @@ dependencies = [ [[package]] name = "swc_ecma_minifier" -version = "0.144.7" +version = "0.152.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "244bf8e9472a7fc50466d3ab3a288969f82ab7d2547e445305f745c8c52ba384" +checksum = "62550be2e2773991286ea412d5277b39c81f8a47b1fbcfe68af6bf8788c58722" dependencies = [ "ahash", "arrayvec", @@ -3370,6 +3417,7 @@ dependencies = [ "num_cpus", "once_cell", "parking_lot", + "rayon", "regex", "retain_mut", "rustc-hash", @@ -3388,14 +3436,13 @@ dependencies = [ "swc_ecma_visit", "swc_timer", "tracing", - "unicode-id", ] [[package]] name = "swc_ecma_parser" -version = "0.117.5" +version = "0.118.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6f6a817020e88bd7084e516f67f40ef33640c1fe336e66cd0dcdeabdaa16eb" +checksum = "da59bf24d3284fd5a93d0aee8f16d618ab43f032f7bdf9985553f4ba26584377" dependencies = [ "either", "enum_kind", @@ -3412,9 +3459,9 @@ dependencies = [ [[package]] name = "swc_ecma_preset_env" -version = "0.158.4" +version = "0.167.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef62b25660684da925c7b53b1a4724bdaf1a8520a419ad736263b101ca4c9e1d" +checksum = "f3d37f5aecc5e4e809946ea76021c00c80ca797471c1b1d36e9225643c999b36" dependencies = [ "ahash", "anyhow", @@ -3437,9 +3484,9 @@ dependencies = [ [[package]] name = "swc_ecma_testing" -version = "0.14.5" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "871addc48b001e559cf74493d465e050b0c6ef244cf7b7112cd756b271d1beac" +checksum = "3a333f88b7a6e373fe94911f145064044ab1ffb6f2dfd4bcd36ac7ea90026fa6" dependencies = [ "anyhow", "hex", @@ -3453,9 +3500,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms" -version = "0.183.4" +version = "0.191.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a8cbc090b992ae508db16c9ae38024195f5d5b39826f0a74d4091e410fbc045" +checksum = "7ca874b86485f26b882110bc711e718707a28aeb8528b1880e46923f619706bc" dependencies = [ "swc_atoms", "swc_common", @@ -3473,15 +3520,16 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_base" -version = "0.103.8" +version = "0.106.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c794bf556b57109e59ee694db25994b27dc5a632de745af40968b4f3e2622862" +checksum = "b1a5bd2f4633734c712b3539b60d5ee7151a93fa827f2b9b19ffb05accece2b0" dependencies = [ "better_scoped_tls", "bitflags", "num_cpus", "once_cell", "phf", + "rayon", "rustc-hash", "serde", "smallvec", @@ -3496,9 +3544,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_classes" -version = "0.91.5" +version = "0.95.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f37ac07ffe2fd6704763cf6fb1ccf92ab9496ecec0cb28084775fe35d7d21665" +checksum = "6bd6ef2fe490311bb13898a464f2a582374c50f81996fbcce7358674522f992a" dependencies = [ "swc_atoms", "swc_common", @@ -3510,9 +3558,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_compat" -version = "0.122.6" +version = "0.129.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6127cdb1a52d720a1559d1365ea1682de8189612b979be95b12ac17eb0f3c83" +checksum = "3dce692c9efbfebbc068253eb4d1f97f18809878e4a3d6a85a6900cc507bf08c" dependencies = [ "ahash", "arrayvec", @@ -3520,6 +3568,7 @@ dependencies = [ "is-macro", "num-bigint", "ordered-float", + "rayon", "serde", "smallvec", "swc_atoms", @@ -3550,9 +3599,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_module" -version = "0.139.4" +version = "0.146.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "930bf6a0f0ee0a5fff8da817ae5f1652408714c7198a5f50ef018facdbe9be6f" +checksum = "e39d8eca155d211e191d8b3a3ba44908d6aaa82e82152fca73524382e68d9fb3" dependencies = [ "Inflector", "ahash", @@ -3578,14 +3627,16 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_optimization" -version = "0.152.4" +version = "0.160.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3cd48bd97dd61b382bca4aa8b316b86364900e293e3e7bc19083e3e40551055" +checksum = "60929573686464dd117839acef42287205407865385eed448e5625dd4ff5214b" dependencies = [ "ahash", "dashmap", "indexmap", "once_cell", + "petgraph", + "rayon", "rustc-hash", "serde_json", "swc_atoms", @@ -3596,14 +3647,15 @@ dependencies = [ "swc_ecma_transforms_macros", "swc_ecma_utils", "swc_ecma_visit", + "swc_fast_graph", "tracing", ] [[package]] name = "swc_ecma_transforms_proposal" -version = "0.130.4" +version = "0.137.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5431eff966464e9eb14e31a548fea6a8fb066c0ca13ea3f334c43533ae1f6c7" +checksum = "fb2b44281820a732b88b26da3448846ac82e6338af133928b7a879b14ea40e59" dependencies = [ "either", "serde", @@ -3620,15 +3672,16 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_react" -version = "0.141.4" +version = "0.148.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e25a0fb253cc8f4c91f4f097aafb110baefda11bf3584bea1a034481cb929f22" +checksum = "b148e31430d71af020a9eaed963f55126a150036a8de708fcfd03e6a1b852159" dependencies = [ "ahash", "base64 0.13.0", "dashmap", "indexmap", "once_cell", + "rayon", "regex", "serde", "sha-1 0.10.0", @@ -3646,9 +3699,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_testing" -version = "0.105.5" +version = "0.108.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55a3f0a517e598284dff81299e07c0766b81c295a90f34fba60bb0e9b92bd385" +checksum = "780945cfbf7755795b5c5d2755c28c17a9cb87ce2549e3597eae66967d63053b" dependencies = [ "ansi_term", "anyhow", @@ -3670,9 +3723,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_typescript" -version = "0.145.4" +version = "0.152.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ece3fe114e22ed4a1711bb1f23d2991b744f89e44c061d84063335421b8f2f2" +checksum = "8acba735ad42b7658045c7bb43b8989dfe2681c97b627f264b760d4ca300e670" dependencies = [ "serde", "swc_atoms", @@ -3686,12 +3739,13 @@ dependencies = [ [[package]] name = "swc_ecma_utils" -version = "0.99.5" +version = "0.101.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30700fb85603ce56423770d77696c1b0c602733a57d3b5cdd93a47ba450b0cd9" +checksum = "64bf09a91b69dc0ffa57a7bde2a8131be8dbe09997e95b9a51b08ba76e7384fb" dependencies = [ "indexmap", "once_cell", + "rayon", "swc_atoms", "swc_common", "swc_ecma_ast", @@ -3714,21 +3768,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "swc_ecmascript" -version = "0.189.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b16deafbca757db8f8e26d0667f93e673a8bf51d99281fd09c83139c9d99818" -dependencies = [ - "swc_ecma_ast", - "swc_ecma_codegen", - "swc_ecma_minifier", - "swc_ecma_parser", - "swc_ecma_transforms", - "swc_ecma_utils", - "swc_ecma_visit", -] - [[package]] name = "swc_emotion" version = "0.17.0" @@ -3742,12 +3781,7 @@ dependencies = [ "serde", "serde_json", "sourcemap", - "swc_atoms", - "swc_common", - "swc_ecma_transforms_react", - "swc_ecma_transforms_testing", - "swc_ecmascript", - "swc_trace_macro", + "swc_core", "testing", "tracing", ] @@ -3779,9 +3813,9 @@ dependencies = [ [[package]] name = "swc_fast_graph" -version = "0.15.4" +version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7b0ff4fa987b8722801a7789563b8cbc71058027f2f2cc4e7e95876a0cc4960" +checksum = "056b5c705601d607480e67add408af73144712b445db5872ee2483d76acffb55" dependencies = [ "ahash", "indexmap", @@ -3853,9 +3887,9 @@ dependencies = [ [[package]] name = "swc_plugin_runner" -version = "0.71.15" +version = "0.73.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a116a790c682e2acfaa674a80320d21fb6d8c22b07b9f0a66160f44d7cc08a44" +checksum = "fabaa68c69344c1fdf7e802e7d059d7f5f08ee9afdbacb3470a4f6e115b7887e" dependencies = [ "anyhow", "once_cell", @@ -3917,13 +3951,13 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.92" +version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ff7c592601f11445996a06f8ad0c27f094a58857c2f89e97974ab9235b92c52" +checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13" dependencies = [ "proc-macro2", "quote", - "unicode-xid", + "unicode-ident", ] [[package]] @@ -4014,18 +4048,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.30" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" +checksum = "f5f6586b7f764adc0231f4c79be7b920e766bb2f3e51b3661cdb263828f19994" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.30" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" +checksum = "12bafc5b54507e0149cdf1b145a5d80ab80a90bcd9275df43d4fff68460f6c21" dependencies = [ "proc-macro2", "quote", @@ -4089,9 +4123,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.11" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72c91f41dcb2f096c05f0873d667dceec1087ce5bcf984ec8ffb19acddbb3217" +checksum = "db76ff9fa4b1458b3c7f077f3ff9887394058460d21e634355b273aaf11eea45" dependencies = [ "itoa", "libc", @@ -4323,6 +4357,12 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4285d92be83dfbc8950a2601178b89ed36f979ebf51bfcf7b272b17001184e6c" +[[package]] +name = "unicode-ident" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf" + [[package]] name = "unicode-linebreak" version = "0.1.2" @@ -4347,12 +4387,6 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" -[[package]] -name = "unicode-xid" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" - [[package]] name = "unreachable" version = "0.1.1" @@ -4403,6 +4437,21 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "vergen" +version = "7.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ffa80ed519f45995741e70664d4abcf147d2a47b8c7ea0a4aa495548ef9474f" +dependencies = [ + "anyhow", + "cfg-if 1.0.0", + "enum-iterator 1.2.0", + "getset", + "rustversion", + "thiserror", + "time 0.3.13", +] + [[package]] name = "version_check" version = "0.9.4" @@ -4462,15 +4511,10 @@ dependencies = [ "path-clean", "serde", "serde_json", - "swc", - "swc_common", - "swc_ecmascript", - "swc_plugin_runner", + "swc_core", "tracing", "wasm-bindgen", "wasm-bindgen-futures", - "wasmer", - "wasmer-wasi", ] [[package]] @@ -4502,9 +4546,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.22" +version = "0.4.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73157efb9af26fb564bb59a009afd1c7c334a44db171d280690d0c3faaec3468" +checksum = "fa76fb221a1f8acddf5b54ace85912606980ad661ac7a503b4570ffd3a624dad" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -4674,7 +4718,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad0358af9c154724587731175553805648d9acb8f6657880d165e378672b7e53" dependencies = [ "cfg-if 1.0.0", - "enum-iterator", + "enum-iterator 0.7.0", "enumset", "leb128", "libloading", @@ -4719,7 +4763,7 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68f1db3f54152657eb6e86c44b66525ff7801dad8328fe677da48dd06af9ad41" dependencies = [ - "enum-iterator", + "enum-iterator 0.7.0", "enumset", "loupe", "rkyv", @@ -4748,7 +4792,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39df01ea05dc0a9bab67e054c7cb01521e53b35a7bb90bd02eca564ed0b2667f" dependencies = [ "backtrace", - "enum-iterator", + "enum-iterator 0.7.0", "indexmap", "loupe", "more-asserts", @@ -4779,7 +4823,7 @@ dependencies = [ "cc", "cfg-if 1.0.0", "corosensei", - "enum-iterator", + "enum-iterator 0.7.0", "indexmap", "lazy_static", "libc", diff --git a/packages/next-swc/crates/core/Cargo.toml b/packages/next-swc/crates/core/Cargo.toml index 8f98805cf49b..49c55aae4f92 100644 --- a/packages/next-swc/crates/core/Cargo.toml +++ b/packages/next-swc/crates/core/Cargo.toml @@ -9,7 +9,7 @@ crate-type = ["cdylib", "rlib"] [features] plugin = [ - "swc/plugin" + "swc_core/plugin_transform_host_native" ] [dependencies] @@ -26,18 +26,27 @@ swc_emotion = {path="../emotion"} styled_components = {path="../styled_components"} styled_jsx = {path="../styled_jsx"} modularize_imports = {path="../modularize_imports"} -swc = "0.214.9" -swc_atoms = "0.4.8" -swc_common = { version = "0.27.11", features = ["concurrent", "sourcemap", "plugin_transform_schema_v1"] } -swc_ecma_loader = { version = "0.39.4", features = ["node", "lru"] } -swc_ecmascript = { version = "0.189.4", features = ["codegen", "minifier", "optimization", "parser", "react", "transforms", "typescript", "utils", "visit"] } -swc_plugin_runner = { version = "0.71.15", optional = true, default-features = false, features = ["plugin_transform_schema_v1"] } -swc_cached = "0.3.5" tracing = { version = "0.1.32", features = ["release_max_level_info"] } -wasmer = { version = "2.3.0", optional = true, default-features = false } -wasmer-wasi = { version = "2.3.0", optional = true, default-features = false } + +swc_core = { version = "0.20.4", features = [ + "common_concurrent", + "ecma_ast", + "ecma_visit", + "ecma_loader_node", + "ecma_loader_lru", + "ecma_utils", + "ecma_minifier", + "ecma_transforms", + "__ecma_transforms", + "ecma_transforms_react", + "ecma_transforms_typescript", + "ecma_parser", + "ecma_parser_typescript", + "cached", + "base" +] } [dev-dependencies] -swc_ecma_transforms_testing = "0.105.5" +swc_core = { version = "0.20.4", features = ["testing_transform"] } testing = "0.29.4" walkdir = "2.3.2" diff --git a/packages/next-swc/crates/core/src/amp_attributes.rs b/packages/next-swc/crates/core/src/amp_attributes.rs index a5935641edd9..386980d5e465 100644 --- a/packages/next-swc/crates/core/src/amp_attributes.rs +++ b/packages/next-swc/crates/core/src/amp_attributes.rs @@ -1,8 +1,8 @@ -use swc_atoms::JsWord; -use swc_ecmascript::ast::{ - Ident, JSXAttr, JSXAttrName, JSXAttrOrSpread, JSXElementName, JSXOpeningElement, +use swc_core::{ + ecma::ast::{Ident, JSXAttr, JSXAttrName, JSXAttrOrSpread, JSXElementName, JSXOpeningElement}, + ecma::atoms::JsWord, + ecma::visit::Fold, }; -use swc_ecmascript::visit::Fold; pub fn amp_attributes() -> impl Fold { AmpAttributePatcher::default() diff --git a/packages/next-swc/crates/core/src/auto_cjs/mod.rs b/packages/next-swc/crates/core/src/auto_cjs/mod.rs index 7e49265de7e5..0859f9ebe11e 100644 --- a/packages/next-swc/crates/core/src/auto_cjs/mod.rs +++ b/packages/next-swc/crates/core/src/auto_cjs/mod.rs @@ -1,6 +1,6 @@ -use swc_ecmascript::{ - ast::*, - visit::{Visit, VisitWith}, +use swc_core::{ + ecma::ast::*, + ecma::visit::{Visit, VisitWith}, }; pub(crate) fn contains_cjs(m: &Module) -> bool { diff --git a/packages/next-swc/crates/core/src/disallow_re_export_all_in_page.rs b/packages/next-swc/crates/core/src/disallow_re_export_all_in_page.rs index 2d0871952e1d..3636c4774fcf 100644 --- a/packages/next-swc/crates/core/src/disallow_re_export_all_in_page.rs +++ b/packages/next-swc/crates/core/src/disallow_re_export_all_in_page.rs @@ -1,7 +1,9 @@ -use swc_common::errors::HANDLER; -use swc_common::pass::Optional; -use swc_ecmascript::ast::ExportAll; -use swc_ecmascript::visit::{noop_fold_type, Fold}; +use swc_core::{ + common::errors::HANDLER, + ecma::ast::ExportAll, + ecma::transforms::base::pass::Optional, + ecma::visit::{noop_fold_type, Fold}, +}; pub fn disallow_re_export_all_in_page(is_page_file: bool) -> impl Fold { Optional::new(DisallowReExportAllInPage, is_page_file) diff --git a/packages/next-swc/crates/core/src/hook_optimizer.rs b/packages/next-swc/crates/core/src/hook_optimizer.rs index 6c95deb9740e..bf3acd39df64 100644 --- a/packages/next-swc/crates/core/src/hook_optimizer.rs +++ b/packages/next-swc/crates/core/src/hook_optimizer.rs @@ -1,10 +1,12 @@ -use swc_atoms::JsWord; -use swc_common::DUMMY_SP; -use swc_ecmascript::ast::{ - ArrayPat, Callee, Decl, Expr, Ident, ImportDecl, ImportSpecifier, KeyValuePatProp, Number, - ObjectPat, ObjectPatProp, Pat, PropName, VarDecl, VarDeclarator, +use swc_core::{ + common::DUMMY_SP, + ecma::ast::{ + ArrayPat, Callee, Decl, Expr, Ident, ImportDecl, ImportSpecifier, KeyValuePatProp, Number, + ObjectPat, ObjectPatProp, Pat, PropName, VarDecl, VarDeclarator, + }, + ecma::atoms::JsWord, + ecma::visit::{Fold, FoldWith}, }; -use swc_ecmascript::visit::{Fold, FoldWith}; pub fn hook_optimizer() -> impl Fold { HookOptimizer::default() @@ -72,7 +74,7 @@ impl HookOptimizer { } = &decl; let init_clone = init.clone(); if let Pat::Array(a) = name { - if let Expr::Call(c) = &*init.as_deref().unwrap() { + if let Expr::Call(c) = init.as_deref().unwrap() { if let Callee::Expr(i) = &c.callee { if let Expr::Ident(Ident { sym, .. }) = &**i { if self.hooks.contains(sym) { diff --git a/packages/next-swc/crates/core/src/lib.rs b/packages/next-swc/crates/core/src/lib.rs index 98190b487a62..68e1efe0d074 100644 --- a/packages/next-swc/crates/core/src/lib.rs +++ b/packages/next-swc/crates/core/src/lib.rs @@ -36,14 +36,15 @@ use serde::Deserialize; use std::cell::RefCell; use std::rc::Rc; use std::{path::PathBuf, sync::Arc}; -use swc::config::ModuleConfig; -use swc_common::comments::Comments; -use swc_common::{self, chain, pass::Optional}; -use swc_common::{FileName, SourceFile, SourceMap}; -use swc_ecmascript::ast::EsVersion; -use swc_ecmascript::parser::parse_file_as_module; -use swc_ecmascript::transforms::pass::noop; -use swc_ecmascript::visit::Fold; + +use swc_core::{ + base::config::ModuleConfig, + common::{chain, comments::Comments, pass::Optional, FileName, SourceFile, SourceMap}, + ecma::ast::EsVersion, + ecma::parser::parse_file_as_module, + ecma::transforms::base::pass::noop, + ecma::visit::Fold, +}; pub mod amp_attributes; mod auto_cjs; @@ -63,7 +64,7 @@ mod top_level_binding_collector; #[serde(rename_all = "camelCase")] pub struct TransformOptions { #[serde(flatten)] - pub swc: swc::config::Options, + pub swc: swc_core::base::config::Options, #[serde(default)] pub disable_next_ssg: bool, diff --git a/packages/next-swc/crates/core/src/next_dynamic.rs b/packages/next-swc/crates/core/src/next_dynamic.rs index 7b82bcaef2e3..0bd30a6682b0 100644 --- a/packages/next-swc/crates/core/src/next_dynamic.rs +++ b/packages/next-swc/crates/core/src/next_dynamic.rs @@ -1,16 +1,18 @@ use std::path::{Path, PathBuf}; use pathdiff::diff_paths; -use swc_atoms::js_word; -use swc_common::errors::HANDLER; -use swc_common::{FileName, DUMMY_SP}; -use swc_ecmascript::ast::{ - ArrayLit, ArrowExpr, BinExpr, BinaryOp, BlockStmtOrExpr, Bool, CallExpr, Callee, Expr, - ExprOrSpread, Id, Ident, ImportDecl, ImportSpecifier, KeyValueProp, Lit, MemberExpr, - MemberProp, Null, ObjectLit, Prop, PropName, PropOrSpread, Str, Tpl, + +use swc_core::{ + common::{errors::HANDLER, FileName, DUMMY_SP}, + ecma::ast::{ + ArrayLit, ArrowExpr, BinExpr, BinaryOp, BlockStmtOrExpr, Bool, CallExpr, Callee, Expr, + ExprOrSpread, Id, Ident, ImportDecl, ImportSpecifier, KeyValueProp, Lit, MemberExpr, + MemberProp, Null, ObjectLit, Prop, PropName, PropOrSpread, Str, Tpl, + }, + ecma::atoms::js_word, + ecma::utils::ExprFactory, + ecma::visit::{Fold, FoldWith}, }; -use swc_ecmascript::utils::ExprFactory; -use swc_ecmascript::visit::{Fold, FoldWith}; pub fn next_dynamic( is_development: bool, diff --git a/packages/next-swc/crates/core/src/next_ssg.rs b/packages/next-swc/crates/core/src/next_ssg.rs index 9ea18dcb7b84..022885da76a9 100644 --- a/packages/next-swc/crates/core/src/next_ssg.rs +++ b/packages/next-swc/crates/core/src/next_ssg.rs @@ -3,12 +3,16 @@ use fxhash::FxHashSet; use std::cell::RefCell; use std::mem::take; use std::rc::Rc; -use swc_common::errors::HANDLER; -use swc_common::pass::{Repeat, Repeated}; -use swc_common::DUMMY_SP; -use swc_ecmascript::ast::*; -use swc_ecmascript::visit::FoldWith; -use swc_ecmascript::visit::{noop_fold_type, Fold}; + +use swc_core::{ + common::{ + errors::HANDLER, + pass::{Repeat, Repeated}, + DUMMY_SP, + }, + ecma::ast::*, + ecma::visit::{noop_fold_type, Fold, FoldWith}, +}; static SSG_EXPORTS: &[&str; 3] = &["getStaticProps", "getStaticPaths", "getServerSideProps"]; diff --git a/packages/next-swc/crates/core/src/page_config.rs b/packages/next-swc/crates/core/src/page_config.rs index 1747358557f8..213995e5ca52 100644 --- a/packages/next-swc/crates/core/src/page_config.rs +++ b/packages/next-swc/crates/core/src/page_config.rs @@ -1,8 +1,10 @@ use chrono::Utc; -use swc_common::errors::HANDLER; -use swc_common::{Span, DUMMY_SP}; -use swc_ecmascript::ast::*; -use swc_ecmascript::visit::{Fold, FoldWith}; + +use swc_core::{ + common::{errors::HANDLER, Span, DUMMY_SP}, + ecma::ast::*, + ecma::visit::{Fold, FoldWith}, +}; pub fn page_config(is_development: bool, is_page_file: bool) -> impl Fold { PageConfig { diff --git a/packages/next-swc/crates/core/src/react_remove_properties.rs b/packages/next-swc/crates/core/src/react_remove_properties.rs index f2944795537d..5e4b03a6b754 100644 --- a/packages/next-swc/crates/core/src/react_remove_properties.rs +++ b/packages/next-swc/crates/core/src/react_remove_properties.rs @@ -1,7 +1,10 @@ use regex::Regex; use serde::Deserialize; -use swc_ecmascript::ast::*; -use swc_ecmascript::visit::{noop_fold_type, Fold, FoldWith}; + +use swc_core::{ + ecma::ast::*, + ecma::visit::{noop_fold_type, Fold, FoldWith}, +}; #[derive(Clone, Debug, Deserialize)] #[serde(untagged)] diff --git a/packages/next-swc/crates/core/src/relay.rs b/packages/next-swc/crates/core/src/relay.rs index 1f3f693e36d3..934d9207716d 100644 --- a/packages/next-swc/crates/core/src/relay.rs +++ b/packages/next-swc/crates/core/src/relay.rs @@ -2,12 +2,14 @@ use once_cell::sync::Lazy; use regex::Regex; use serde::Deserialize; use std::path::{Path, PathBuf}; -use swc_atoms::JsWord; -use swc_common::errors::HANDLER; -use swc_common::FileName; -use swc_ecmascript::ast::*; -use swc_ecmascript::utils::{quote_ident, ExprFactory}; -use swc_ecmascript::visit::{Fold, FoldWith}; + +use swc_core::{ + common::{errors::HANDLER, FileName}, + ecma::ast::*, + ecma::atoms::JsWord, + ecma::utils::{quote_ident, ExprFactory}, + ecma::visit::{Fold, FoldWith}, +}; #[derive(Copy, Clone, Debug, Deserialize)] #[serde(rename_all = "lowercase")] diff --git a/packages/next-swc/crates/core/src/remove_console.rs b/packages/next-swc/crates/core/src/remove_console.rs index 909cf5b5f322..0068cbe16034 100644 --- a/packages/next-swc/crates/core/src/remove_console.rs +++ b/packages/next-swc/crates/core/src/remove_console.rs @@ -1,9 +1,11 @@ use serde::Deserialize; -use swc_atoms::JsWord; -use swc_common::collections::AHashSet; -use swc_common::DUMMY_SP; -use swc_ecmascript::ast::*; -use swc_ecmascript::visit::{noop_fold_type, Fold, FoldWith}; + +use swc_core::{ + common::{collections::AHashSet, DUMMY_SP}, + ecma::ast::*, + ecma::atoms::JsWord, + ecma::visit::{noop_fold_type, Fold, FoldWith}, +}; use crate::top_level_binding_collector::collect_top_level_decls; diff --git a/packages/next-swc/crates/core/src/shake_exports.rs b/packages/next-swc/crates/core/src/shake_exports.rs index 23af7d12f937..c08a19ea28ef 100644 --- a/packages/next-swc/crates/core/src/shake_exports.rs +++ b/packages/next-swc/crates/core/src/shake_exports.rs @@ -1,10 +1,12 @@ use serde::Deserialize; -use swc_atoms::js_word; -use swc_atoms::JsWord; -use swc_common::Mark; -use swc_ecmascript::ast::*; -use swc_ecmascript::transforms::optimization::simplify::dce::{dce, Config as DCEConfig}; -use swc_ecmascript::visit::{Fold, FoldWith}; + +use swc_core::{ + common::Mark, + ecma::ast::*, + ecma::atoms::{js_word, JsWord}, + ecma::transforms::optimization::simplify::dce::{dce, Config as DCEConfig}, + ecma::visit::{Fold, FoldWith}, +}; #[derive(Clone, Debug, Deserialize)] pub struct Config { diff --git a/packages/next-swc/crates/core/src/top_level_binding_collector.rs b/packages/next-swc/crates/core/src/top_level_binding_collector.rs index b591a7f5e9c0..1eef9229528d 100644 --- a/packages/next-swc/crates/core/src/top_level_binding_collector.rs +++ b/packages/next-swc/crates/core/src/top_level_binding_collector.rs @@ -1,12 +1,13 @@ use std::hash::Hash; -use swc_common::{collections::AHashSet, SyntaxContext}; -use swc_ecmascript::{ - ast::{ + +use swc_core::{ + common::{collections::AHashSet, SyntaxContext}, + ecma::ast::{ ClassDecl, FnDecl, Ident, ImportDefaultSpecifier, ImportNamedSpecifier, ImportStarAsSpecifier, ModuleItem, ObjectPatProp, Param, Pat, Stmt, VarDeclarator, }, - utils::ident::IdentLike, - visit::{noop_visit_type, Visit, VisitWith}, + ecma::utils::ident::IdentLike, + ecma::visit::{noop_visit_type, Visit, VisitWith}, }; // Modified from swc_ecma_utils/src/lib.rs:BindingCollector. diff --git a/packages/next-swc/crates/core/tests/errors.rs b/packages/next-swc/crates/core/tests/errors.rs index bd73be935c66..6af191fe96da 100644 --- a/packages/next-swc/crates/core/tests/errors.rs +++ b/packages/next-swc/crates/core/tests/errors.rs @@ -3,9 +3,11 @@ use next_swc::{ next_ssg::next_ssg, }; use std::path::PathBuf; -use swc_common::FileName; -use swc_ecma_transforms_testing::test_fixture_allowing_error; -use swc_ecmascript::parser::{EsConfig, Syntax}; +use swc_core::{ + common::FileName, + ecma::parser::{EsConfig, Syntax}, + ecma::transforms::testing::test_fixture_allowing_error, +}; use testing::fixture; fn syntax() -> Syntax { diff --git a/packages/next-swc/crates/core/tests/fixture.rs b/packages/next-swc/crates/core/tests/fixture.rs index f6879aef8200..0bdcb527860f 100644 --- a/packages/next-swc/crates/core/tests/fixture.rs +++ b/packages/next-swc/crates/core/tests/fixture.rs @@ -9,11 +9,11 @@ use next_swc::{ shake_exports::{shake_exports, Config as ShakeExportsConfig}, }; use std::path::PathBuf; -use swc_common::{chain, comments::SingleThreadedComments, FileName, Mark}; -use swc_ecma_transforms_testing::{test, test_fixture}; -use swc_ecmascript::{ - parser::{EsConfig, Syntax}, - transforms::react::jsx, +use swc_core::{ + common::{chain, comments::SingleThreadedComments, FileName, Mark}, + ecma::parser::{EsConfig, Syntax}, + ecma::transforms::react::jsx, + ecma::transforms::testing::{test, test_fixture}, }; use testing::fixture; @@ -86,7 +86,7 @@ fn next_ssg_fixture(input: PathBuf) { let jsx = jsx::( tr.cm.clone(), None, - swc_ecmascript::transforms::react::Options { + swc_core::ecma::transforms::react::Options { next: false.into(), runtime: None, import_source: Some("".into()), diff --git a/packages/next-swc/crates/core/tests/full.rs b/packages/next-swc/crates/core/tests/full.rs index 8466972a49a0..6c9ad7c5c4b2 100644 --- a/packages/next-swc/crates/core/tests/full.rs +++ b/packages/next-swc/crates/core/tests/full.rs @@ -1,10 +1,10 @@ use next_swc::{custom_before_pass, TransformOptions}; use serde::de::DeserializeOwned; use std::path::{Path, PathBuf}; -use swc::Compiler; -use swc_ecmascript::{ - parser::{Syntax, TsConfig}, - transforms::pass::noop, +use swc_core::{ + base::Compiler, + ecma::parser::{Syntax, TsConfig}, + ecma::transforms::base::pass::noop, }; use testing::{NormalizedOutput, Tester}; @@ -28,14 +28,14 @@ fn test(input: &Path, minify: bool) { let fm = cm.load_file(input).expect("failed to load file"); let options = TransformOptions { - swc: swc::config::Options { + swc: swc_core::base::config::Options { swcrc: true, output_path: Some(output.clone()), - config: swc::config::Config { - is_module: swc::config::IsModule::Bool(true), + config: swc_core::base::config::Config { + is_module: swc_core::base::config::IsModule::Bool(true), - jsc: swc::config::JscConfig { + jsc: swc_core::base::config::JscConfig { minify: if minify { Some(assert_json("{ \"compress\": true, \"mangle\": true }")) } else { diff --git a/packages/next-swc/crates/core/tests/full/example/output.js b/packages/next-swc/crates/core/tests/full/example/output.js index 3f100a93d96b..0398540c5b35 100644 --- a/packages/next-swc/crates/core/tests/full/example/output.js +++ b/packages/next-swc/crates/core/tests/full/example/output.js @@ -1,47 +1,41 @@ -function n(n, t) { - (null == t || t > n.length) && (t = n.length); - for(var r = 0, e = new Array(t); r < t; r++)e[r] = n[r]; +function t(t, r) { + (null == r || r > t.length) && (r = t.length); + for(var n = 0, e = new Array(r); n < r; n++)e[n] = t[n]; return e; } -import t from "other"; -(function(t, r) { - return function(n) { - if (Array.isArray(n)) return n; - }(t) || function(n, t) { - var r, e, o = null == n ? null : "undefined" != typeof Symbol && n[Symbol.iterator] || n["@@iterator"]; +import r from "other"; +(function(r, n) { + return function(t) { + if (Array.isArray(t)) return t; + }(r) || function(t, r) { + var n, e, o = null == t ? null : "undefined" != typeof Symbol && t[Symbol.iterator] || t["@@iterator"]; if (null != o) { - var u = [], l = !0, f = !1; + var u = [], l = !0, i = !1; try { - for(o = o.call(n); !(l = (r = o.next()).done) && (u.push(r.value), !t || u.length !== t); l = !0); - } catch (i) { - f = !0, e = i; + for(o = o.call(t); !(l = (n = o.next()).done) && (u.push(n.value), !r || u.length !== r); l = !0); + } catch (a) { + i = !0, e = a; } finally{ try { l || null == o.return || o.return(); } finally{ - if (f) throw e; + if (i) throw e; } } return u; } - }(t, r) || function t(r, e) { + }(r, n) || function(r, n) { if (r) { - if ("string" == typeof r) return n(r, e); - var o = Object.prototype.toString.call(r).slice(8, -1); - if ("Object" === o && r.constructor && (o = r.constructor.name), "Map" === o || "Set" === o) return Array.from(o); - if ("Arguments" === o || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(o)) return n(r, e); + if ("string" == typeof r) return t(r, n); + var e = Object.prototype.toString.call(r).slice(8, -1); + if ("Object" === e && r.constructor && (e = r.constructor.name), "Map" === e || "Set" === e) return Array.from(e); + if ("Arguments" === e || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(e)) return t(r, n); } - }(t, r) || function() { + }(r, n) || function() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }(); -})(t, 1)[0]; -var r = function() { - "use strict"; - !function(n, t) { - if (!(n instanceof t)) throw new TypeError("Cannot call a class as a function"); - }(this, r); -}; +})(r, 1)[0]; export var __N_SSG = !0; -export default function e() { +export default function n() { return React.createElement("div", null); }; diff --git a/packages/next-swc/crates/core/tests/telemetry.rs b/packages/next-swc/crates/core/tests/telemetry.rs index 52c073d36644..85af75512f4f 100644 --- a/packages/next-swc/crates/core/tests/telemetry.rs +++ b/packages/next-swc/crates/core/tests/telemetry.rs @@ -5,9 +5,12 @@ use std::sync::Arc; use fxhash::FxHashSet; use next_swc::next_ssg::next_ssg; use once_cell::sync::Lazy; -use swc::{try_with_handler, Compiler}; -use swc_common::{FileName, FilePathMapping, SourceMap}; -use swc_ecmascript::transforms::pass::noop; + +use swc_core::{ + base::{try_with_handler, Compiler}, + common::{FileName, FilePathMapping, SourceMap}, + ecma::transforms::base::pass::noop, +}; static COMPILER: Lazy> = Lazy::new(|| { let cm = Arc::new(SourceMap::new(FilePathMapping::empty())); diff --git a/packages/next-swc/crates/emotion/Cargo.toml b/packages/next-swc/crates/emotion/Cargo.toml index 2b38b85d2f87..ecf9a8f784c6 100644 --- a/packages/next-swc/crates/emotion/Cargo.toml +++ b/packages/next-swc/crates/emotion/Cargo.toml @@ -18,14 +18,10 @@ radix_fmt = "1" regex = "1.5" serde = "1" sourcemap = "6.0.1" -swc_atoms = "0.4.8" -swc_common = { version = "0.27.11", features = ["concurrent", "sourcemap"] } -swc_ecmascript = { version = "0.189.4", features = ["codegen", "utils", "visit"] } -swc_trace_macro = "0.1.2" tracing = { version = "0.1.32", features = ["release_max_level_info"] } +swc_core = { version = "0.20.4", features = ["common_concurrent", "ecma_ast","ecma_codegen", "ecma_utils", "ecma_visit", "trace_macro"] } [dev-dependencies] -swc_ecma_transforms_testing = "0.105.5" +swc_core = { version = "0.20.4", features = ["testing_transform", "ecma_transforms_react"] } testing = "0.29.4" serde_json = "1" -swc_ecma_transforms_react = "0.141.4" diff --git a/packages/next-swc/crates/emotion/src/import_map.rs b/packages/next-swc/crates/emotion/src/import_map.rs index dc8cbdf0ab1d..4f832a1dcc3f 100644 --- a/packages/next-swc/crates/emotion/src/import_map.rs +++ b/packages/next-swc/crates/emotion/src/import_map.rs @@ -1,6 +1,6 @@ use serde::{Deserialize, Serialize}; -use swc_atoms::JsWord; -use swc_common::collections::AHashMap; + +use swc_core::{common::collections::AHashMap, ecma::atoms::JsWord}; use crate::{EmotionModuleConfig, ExportItem}; @@ -31,7 +31,7 @@ pub(crate) fn expand_import_map( .for_each(|(local_export_name, Config { canonical_import })| { let ImportItem(package_name, export_name) = canonical_import; - if &*package_name == "@emotion/react" && &*export_name == "jsx" { + if &**package_name == "@emotion/react" && &**export_name == "jsx" { return; } diff --git a/packages/next-swc/crates/emotion/src/lib.rs b/packages/next-swc/crates/emotion/src/lib.rs index 0059bf69cc33..7dd867559311 100644 --- a/packages/next-swc/crates/emotion/src/lib.rs +++ b/packages/next-swc/crates/emotion/src/lib.rs @@ -8,23 +8,21 @@ use once_cell::sync::Lazy; use regex::Regex; use serde::{Deserialize, Serialize}; use sourcemap::{RawToken, SourceMap as RawSourcemap}; -use swc_atoms::JsWord; -use swc_common::comments::Comments; -use swc_common::util::take::Take; -use swc_common::{BytePos, SourceMapperDyn, DUMMY_SP}; -use swc_ecmascript::ast::{ - ArrayLit, CallExpr, JSXAttr, JSXAttrName, JSXAttrOrSpread, JSXAttrValue, JSXElementName, - JSXExpr, JSXExprContainer, JSXObject, ModuleExportName, SourceMapperExt, -}; -use swc_ecmascript::utils::ExprFactory; -use swc_ecmascript::{ - ast::{ - Callee, Expr, ExprOrSpread, Id, Ident, ImportDecl, ImportSpecifier, JSXElement, - KeyValueProp, MemberProp, ObjectLit, Pat, Prop, PropName, PropOrSpread, Tpl, VarDeclarator, +use swc_core::{ + common::{comments::Comments, util::take::Take, BytePos, SourceMapperDyn, DUMMY_SP}, + ecma::utils::ExprFactory, + ecma::visit::{Fold, FoldWith}, + ecma::{ + ast::{ + ArrayLit, CallExpr, Callee, Expr, ExprOrSpread, Id, Ident, ImportDecl, ImportSpecifier, + JSXAttr, JSXAttrName, JSXAttrOrSpread, JSXAttrValue, JSXElement, JSXElementName, + JSXExpr, JSXExprContainer, JSXObject, KeyValueProp, MemberProp, ModuleExportName, + ObjectLit, Pat, Prop, PropName, PropOrSpread, SourceMapperExt, Tpl, VarDeclarator, + }, + atoms::JsWord, }, - visit::{Fold, FoldWith}, + trace_macro::swc_trace, }; -use swc_trace_macro::swc_trace; mod hash; mod import_map; diff --git a/packages/next-swc/crates/emotion/tests/fixture.rs b/packages/next-swc/crates/emotion/tests/fixture.rs index d9f878f7e69c..1068a3d8cd15 100644 --- a/packages/next-swc/crates/emotion/tests/fixture.rs +++ b/packages/next-swc/crates/emotion/tests/fixture.rs @@ -1,8 +1,11 @@ use std::path::PathBuf; -use swc_common::{chain, comments::SingleThreadedComments, Mark}; -use swc_ecma_transforms_testing::test_fixture; -use swc_ecmascript::parser::{Syntax, TsConfig}; +use swc_core::{ + common::{chain, comments::SingleThreadedComments, Mark}, + ecma::parser::{Syntax, TsConfig}, + ecma::transforms::react::{jsx, Runtime}, + ecma::transforms::testing::test_fixture, +}; use swc_emotion::EmotionOptions; use testing::fixture; @@ -12,7 +15,6 @@ fn ts_syntax() -> Syntax { ..Default::default() }) } -use swc_ecma_transforms_react::{jsx, Runtime}; #[fixture("tests/fixture/**/input.tsx")] fn next_emotion_fixture(input: PathBuf) { @@ -24,7 +26,7 @@ fn next_emotion_fixture(input: PathBuf) { let jsx = jsx::( tr.cm.clone(), Some(tr.comments.as_ref().clone()), - swc_ecmascript::transforms::react::Options { + swc_core::ecma::transforms::react::Options { next: false.into(), runtime: Some(Runtime::Automatic), throw_if_namespace: false.into(), diff --git a/packages/next-swc/crates/modularize_imports/Cargo.toml b/packages/next-swc/crates/modularize_imports/Cargo.toml index 82f19725e0b7..9cc850592acf 100644 --- a/packages/next-swc/crates/modularize_imports/Cargo.toml +++ b/packages/next-swc/crates/modularize_imports/Cargo.toml @@ -15,9 +15,8 @@ handlebars = "4.2.1" once_cell = "1.13.0" regex = "1.5" serde = "1" -swc_cached = "0.3.5" -swc_ecmascript = { version = "0.189.4", features = ["visit"] } +swc_core = { version = "0.20.4", features = ["cached", "ecma_ast", "ecma_visit"] } [dev-dependencies] -swc_ecma_transforms_testing = "0.105.5" +swc_core = { version = "0.20.4", features = ["testing_transform"] } testing = "0.29.4" diff --git a/packages/next-swc/crates/modularize_imports/src/lib.rs b/packages/next-swc/crates/modularize_imports/src/lib.rs index f76a78e2df62..d51779ede0d0 100644 --- a/packages/next-swc/crates/modularize_imports/src/lib.rs +++ b/packages/next-swc/crates/modularize_imports/src/lib.rs @@ -5,9 +5,12 @@ use handlebars::{Context, Handlebars, Helper, HelperResult, Output, RenderContex use once_cell::sync::Lazy; use regex::{Captures, Regex}; use serde::{Deserialize, Serialize}; -use swc_cached::regex::CachedRegex; -use swc_ecmascript::ast::*; -use swc_ecmascript::visit::{noop_fold_type, Fold}; + +use swc_core::{ + cached::regex::CachedRegex, + ecma::ast::*, + ecma::visit::{noop_fold_type, Fold}, +}; static DUP_SLASH_REGEX: Lazy = Lazy::new(|| Regex::new(r"//").unwrap()); diff --git a/packages/next-swc/crates/modularize_imports/tests/fixture.rs b/packages/next-swc/crates/modularize_imports/tests/fixture.rs index 7aeb9e20fef4..1f17c81978de 100644 --- a/packages/next-swc/crates/modularize_imports/tests/fixture.rs +++ b/packages/next-swc/crates/modularize_imports/tests/fixture.rs @@ -1,8 +1,10 @@ use std::path::PathBuf; use modularize_imports::{modularize_imports, PackageConfig}; -use swc_ecma_transforms_testing::test_fixture; -use swc_ecmascript::parser::{EsConfig, Syntax}; +use swc_core::{ + ecma::parser::{EsConfig, Syntax}, + ecma::transforms::testing::test_fixture, +}; use testing::fixture; fn syntax() -> Syntax { diff --git a/packages/next-swc/crates/napi/Cargo.toml b/packages/next-swc/crates/napi/Cargo.toml index e05340a4034f..83d8b862754a 100644 --- a/packages/next-swc/crates/napi/Cargo.toml +++ b/packages/next-swc/crates/napi/Cargo.toml @@ -14,10 +14,7 @@ default = [] # this is due to some of transitive dependencies have features cannot be enabled at the same time # (i.e wasmer/default vs wasmer/js-default) while cargo merges all the features at once. plugin = [ - "swc/plugin", - "swc_plugin_runner/default", - "wasmer/default", - "wasmer-wasi/default", + "swc_core/plugin_transform_host_native", "next-swc/plugin" ] sentry_native_tls = ["_sentry_native_tls"] @@ -33,20 +30,30 @@ next-swc = {version = "0.0.0", path = "../core"} once_cell = "1.13.0" serde = "1" serde_json = "1" -swc = "0.214.9" -swc_atoms = "0.4.8" -swc_bundler = { version = "0.177.4", features = ["concurrent"] } -swc_common = { version = "0.27.11", features = ["concurrent", "sourcemap"] } -swc_ecma_loader = { version = "0.39.4", features = ["node", "lru"] } -swc_ecmascript = { version = "0.189.4", features = ["codegen", "minifier", "optimization", "parser", "react", "transforms", "typescript", "utils", "visit"] } -swc_plugin_runner = { version = "0.71.15", optional = true } -swc_node_base = "0.5.5" +swc_core = { version = "0.20.4", features = [ + "allocator_node", + "base_concurrent", # concurrent? + "common_concurrent", + "ecma_ast", + "ecma_loader_node", + "ecma_loader_lru", + "bundler", + "bundler_concurrent", + "ecma_codegen", + "ecma_minifier", + "ecma_parser", + "ecma_parser_typescript", + "ecma_transforms", + "ecma_transforms_optimization", + "ecma_transforms_react", + "ecma_transforms_typescript", + "ecma_utils", + "ecma_visit" +] } tracing = { version = "0.1.32", features = ["release_max_level_info"] } tracing-futures = "0.2.5" tracing-subscriber = "0.3.9" tracing-chrome = "0.5.0" -wasmer = { version = "2.3.0", optional = true, default-features = false } -wasmer-wasi = { version = "2.3.0", optional = true, default-features = false } # There are few build targets we can't use native-tls which default features rely on, # allow to specify alternative (rustls) instead via features. # Note to opt in rustls default-features should be disabled diff --git a/packages/next-swc/crates/napi/src/bundle/mod.rs b/packages/next-swc/crates/napi/src/bundle/mod.rs index a573002efb04..a9e0a66121f2 100644 --- a/packages/next-swc/crates/napi/src/bundle/mod.rs +++ b/packages/next-swc/crates/napi/src/bundle/mod.rs @@ -7,22 +7,22 @@ use napi::{CallContext, JsObject, Task}; use once_cell::sync::Lazy; use serde::Deserialize; use std::{collections::HashMap, path::PathBuf, sync::Arc}; -use swc::{config::SourceMapsConfig, try_with_handler, TransformOutput}; -use swc_atoms::JsWord; -use swc_bundler::{Bundler, ModuleData, ModuleRecord}; -use swc_common::{ - collections::AHashMap, - errors::{ColorConfig, Handler}, - BytePos, FileName, SourceMap, Span, -}; -use swc_ecma_loader::{ - resolvers::{lru::CachingResolver, node::NodeModulesResolver}, - TargetEnv, NODE_BUILTINS, -}; -use swc_ecmascript::{ - ast::*, - parser::{lexer::Lexer, EsConfig, Parser, StringInput, Syntax}, - visit::{noop_visit_type, Visit, VisitWith}, +use swc_core::{ + base::{config::SourceMapsConfig, try_with_handler, TransformOutput}, + bundler::{Bundler, ModuleData, ModuleRecord}, + common::{ + collections::AHashMap, + errors::{ColorConfig, Handler}, + BytePos, FileName, SourceMap, Span, + }, + ecma::ast::*, + ecma::atoms::JsWord, + ecma::loader::{ + resolvers::{lru::CachingResolver, node::NodeModulesResolver}, + TargetEnv, NODE_BUILTINS, + }, + ecma::parser::{lexer::Lexer, EsConfig, Parser, StringInput, Syntax}, + ecma::visit::{noop_visit_type, Visit, VisitWith}, }; #[js_function(1)] @@ -44,7 +44,7 @@ struct BundleOption { } struct BundleTask { - c: Arc, + c: Arc, config: String, } @@ -58,7 +58,7 @@ impl Task for BundleTask { try_with_handler( self.c.cm.clone(), - swc::HandlerOpts { + swc_core::base::HandlerOpts { color: ColorConfig::Never, skip_filename: true, }, @@ -79,11 +79,11 @@ impl Task for BundleTask { handler, }, make_resolver(), - swc_bundler::Config { + swc_core::bundler::Config { require: true, disable_inliner: false, external_modules: builtins, - module: swc_bundler::ModuleType::Es, + module: swc_core::bundler::ModuleType::Es, ..Default::default() }, Box::new(CustomHook), @@ -156,7 +156,7 @@ struct CustomLoader<'a> { cm: Arc, } -impl swc_bundler::Load for CustomLoader<'_> { +impl swc_core::bundler::Load for CustomLoader<'_> { fn load(&self, f: &FileName) -> Result { let fm = match f { FileName::Real(path) => self.cm.load_file(path)?, @@ -188,7 +188,7 @@ impl swc_bundler::Load for CustomLoader<'_> { struct CustomHook; -impl swc_bundler::Hook for CustomHook { +impl swc_core::bundler::Hook for CustomHook { fn get_import_meta_props( &self, _span: Span, diff --git a/packages/next-swc/crates/napi/src/lib.rs b/packages/next-swc/crates/napi/src/lib.rs index e102cfbe7365..eda87bc78110 100644 --- a/packages/next-swc/crates/napi/src/lib.rs +++ b/packages/next-swc/crates/napi/src/lib.rs @@ -32,14 +32,16 @@ DEALINGS IN THE SOFTWARE. #[macro_use] extern crate napi_derive; /// Explicit extern crate to use allocator. -extern crate swc_node_base; +extern crate swc_core; use backtrace::Backtrace; use fxhash::FxHashSet; use napi::{CallContext, Env, JsObject, JsUndefined}; use std::{env, panic::set_hook, sync::Arc}; -use swc::{Compiler, TransformOutput}; -use swc_common::{self, sync::Lazy, FilePathMapping, SourceMap}; +use swc_core::{ + base::{Compiler, TransformOutput}, + common::{sync::Lazy, FilePathMapping, SourceMap}, +}; mod bundle; mod minify; diff --git a/packages/next-swc/crates/napi/src/minify.rs b/packages/next-swc/crates/napi/src/minify.rs index 042373c65389..349fee4c76e3 100644 --- a/packages/next-swc/crates/napi/src/minify.rs +++ b/packages/next-swc/crates/napi/src/minify.rs @@ -33,13 +33,15 @@ use fxhash::FxHashMap; use napi::{CallContext, JsObject, Task}; use serde::Deserialize; use std::sync::Arc; -use swc::{config::JsMinifyOptions, try_with_handler, TransformOutput}; -use swc_common::{errors::ColorConfig, sync::Lrc, FileName, SourceFile, SourceMap}; +use swc_core::{ + base::{config::JsMinifyOptions, try_with_handler, TransformOutput}, + common::{errors::ColorConfig, sync::Lrc, FileName, SourceFile, SourceMap}, +}; struct MinifyTask { - c: Arc, + c: Arc, code: MinifyTarget, - opts: swc::config::JsMinifyOptions, + opts: swc_core::base::config::JsMinifyOptions, } #[derive(Deserialize)] @@ -78,7 +80,7 @@ impl Task for MinifyTask { fn compute(&mut self) -> napi::Result { try_with_handler( self.c.cm.clone(), - swc::HandlerOpts { + swc_core::base::HandlerOpts { color: ColorConfig::Never, skip_filename: true, }, @@ -125,7 +127,7 @@ pub fn minify_sync(cx: CallContext) -> napi::Result { let output = try_with_handler( c.cm.clone(), - swc::HandlerOpts { + swc_core::base::HandlerOpts { color: ColorConfig::Never, skip_filename: true, }, diff --git a/packages/next-swc/crates/napi/src/parse.rs b/packages/next-swc/crates/napi/src/parse.rs index 3210443953e0..4119b3e3dc9b 100644 --- a/packages/next-swc/crates/napi/src/parse.rs +++ b/packages/next-swc/crates/napi/src/parse.rs @@ -2,8 +2,10 @@ use crate::util::{deserialize_json, CtxtExt, MapErr}; use anyhow::Context as _; use napi::{CallContext, Either, Env, JsObject, JsString, JsUndefined, Task}; use std::sync::Arc; -use swc::{config::ParseOptions, try_with_handler}; -use swc_common::{comments::Comments, errors::ColorConfig, FileName, FilePathMapping, SourceMap}; +use swc_core::{ + base::{config::ParseOptions, try_with_handler}, + common::{comments::Comments, errors::ColorConfig, FileName, FilePathMapping, SourceMap}, +}; pub struct ParseTask { pub filename: FileName, @@ -20,7 +22,7 @@ impl Task for ParseTask { type JsValue = JsString; fn compute(&mut self) -> napi::Result { - let c = swc::Compiler::new(Arc::new(SourceMap::new(FilePathMapping::empty()))); + let c = swc_core::base::Compiler::new(Arc::new(SourceMap::new(FilePathMapping::empty()))); let options: ParseOptions = deserialize_json(&self.options).convert_err()?; let comments = c.comments().clone(); @@ -33,7 +35,7 @@ impl Task for ParseTask { c.cm.new_source_file(self.filename.clone(), self.src.clone()); let program = try_with_handler( c.cm.clone(), - swc::HandlerOpts { + swc_core::base::HandlerOpts { color: ColorConfig::Never, skip_filename: false, }, diff --git a/packages/next-swc/crates/napi/src/transform.rs b/packages/next-swc/crates/napi/src/transform.rs index ad97c0ed1b57..25c4bfba747d 100644 --- a/packages/next-swc/crates/napi/src/transform.rs +++ b/packages/next-swc/crates/napi/src/transform.rs @@ -42,9 +42,11 @@ use std::{ rc::Rc, sync::Arc, }; -use swc::{try_with_handler, Compiler, TransformOutput}; -use swc_common::{errors::ColorConfig, FileName}; -use swc_ecmascript::transforms::pass::noop; +use swc_core::{ + base::{try_with_handler, Compiler, TransformOutput}, + common::{errors::ColorConfig, FileName}, + ecma::transforms::base::pass::noop, +}; /// Input to transform #[derive(Debug)] @@ -70,7 +72,7 @@ impl Task for TransformTask { let res = catch_unwind(AssertUnwindSafe(|| { try_with_handler( self.c.cm.clone(), - swc::HandlerOpts { + swc_core::base::HandlerOpts { color: ColorConfig::Never, skip_filename: true, }, diff --git a/packages/next-swc/crates/styled_components/Cargo.toml b/packages/next-swc/crates/styled_components/Cargo.toml index ca0943ff2778..a4ed8723a5b8 100644 --- a/packages/next-swc/crates/styled_components/Cargo.toml +++ b/packages/next-swc/crates/styled_components/Cargo.toml @@ -15,13 +15,19 @@ Inflector = "0.11.4" once_cell = "1.13.0" regex = {version = "1.5.4", features = ["std", "perf"], default-features = false} serde = {version = "1.0.130", features = ["derive"]} -swc_atoms = "0.4.8" -swc_common = { version = "0.27.11", features = ["concurrent"] } -swc_ecmascript = { version = "0.189.4", features = ["utils", "visit"] } tracing = "0.1.32" +swc_core = { version = "0.20.4", features = [ + "common_concurrent", + "ecma_ast", + "ecma_utils", + "ecma_visit" +] } [dev-dependencies] serde_json = "1" -swc_ecma_transforms_testing = "0.105.5" -swc_ecmascript = { version = "0.189.4", features = ["parser", "transforms"] } testing = "0.29.4" +swc_core = { version = "0.20.4", features = [ + "ecma_parser", + "ecma_transforms", + "testing_transform" +] } diff --git a/packages/next-swc/crates/styled_components/src/lib.rs b/packages/next-swc/crates/styled_components/src/lib.rs index 88a1fc6d20de..975841f84ec3 100644 --- a/packages/next-swc/crates/styled_components/src/lib.rs +++ b/packages/next-swc/crates/styled_components/src/lib.rs @@ -8,9 +8,11 @@ pub use crate::{ }; use serde::Deserialize; use std::{cell::RefCell, rc::Rc}; -use swc_atoms::JsWord; -use swc_common::{chain, pass::Optional, FileName}; -use swc_ecmascript::visit::{Fold, VisitMut}; +use swc_core::{ + common::{chain, pass::Optional, FileName}, + ecma::atoms::JsWord, + ecma::visit::{Fold, VisitMut}, +}; mod css; mod utils; diff --git a/packages/next-swc/crates/styled_components/src/utils/analyzer.rs b/packages/next-swc/crates/styled_components/src/utils/analyzer.rs index b6c4bca8d9e2..9336b6112aef 100644 --- a/packages/next-swc/crates/styled_components/src/utils/analyzer.rs +++ b/packages/next-swc/crates/styled_components/src/utils/analyzer.rs @@ -1,9 +1,11 @@ use super::State; use crate::Config; use std::{cell::RefCell, rc::Rc}; -use swc_ecmascript::{ - ast::*, - visit::{as_folder, noop_visit_mut_type, noop_visit_type, Fold, Visit, VisitMut, VisitWith}, +use swc_core::{ + ecma::ast::*, + ecma::visit::{ + as_folder, noop_visit_mut_type, noop_visit_type, Fold, Visit, VisitMut, VisitWith, + }, }; pub fn analyzer(config: Rc, state: Rc>) -> impl VisitMut + Fold { diff --git a/packages/next-swc/crates/styled_components/src/utils/mod.rs b/packages/next-swc/crates/styled_components/src/utils/mod.rs index 754b4cc33449..cdf498dbc88c 100644 --- a/packages/next-swc/crates/styled_components/src/utils/mod.rs +++ b/packages/next-swc/crates/styled_components/src/utils/mod.rs @@ -1,8 +1,10 @@ pub use self::analyzer::{analyze, analyzer}; use std::{borrow::Cow, cell::RefCell}; -use swc_atoms::js_word; -use swc_common::{collections::AHashMap, SyntaxContext}; -use swc_ecmascript::ast::*; +use swc_core::{ + common::{collections::AHashMap, SyntaxContext}, + ecma::ast::*, + ecma::atoms::js_word, +}; mod analyzer; @@ -310,7 +312,11 @@ impl State { } pub fn prefix_leading_digit(s: &str) -> Cow { - if s.chars().next().map(|c| c.is_digit(10)).unwrap_or(false) { + if s.chars() + .next() + .map(|c| c.is_ascii_digit()) + .unwrap_or(false) + { Cow::Owned(format!("sc-{}", s)) } else { Cow::Borrowed(s) diff --git a/packages/next-swc/crates/styled_components/src/visitors/display_name_and_id.rs b/packages/next-swc/crates/styled_components/src/visitors/display_name_and_id.rs index 0b761ec51f1b..1df685287885 100644 --- a/packages/next-swc/crates/styled_components/src/visitors/display_name_and_id.rs +++ b/packages/next-swc/crates/styled_components/src/visitors/display_name_and_id.rs @@ -5,12 +5,12 @@ use crate::{ use once_cell::sync::Lazy; use regex::Regex; use std::{cell::RefCell, convert::TryInto, path::Path, rc::Rc}; -use swc_atoms::{js_word, JsWord}; -use swc_common::{util::take::Take, FileName, DUMMY_SP}; -use swc_ecmascript::{ - ast::*, - utils::{quote_ident, ExprFactory}, - visit::{as_folder, noop_visit_mut_type, Fold, VisitMut, VisitMutWith}, +use swc_core::{ + common::{util::take::Take, FileName, DUMMY_SP}, + ecma::ast::*, + ecma::atoms::{js_word, JsWord}, + ecma::utils::{quote_ident, ExprFactory}, + ecma::visit::{as_folder, noop_visit_mut_type, Fold, VisitMut, VisitMutWith}, }; use tracing::{debug, span, trace, Level}; diff --git a/packages/next-swc/crates/styled_components/src/visitors/transpile_css_prop/top_level_binding_collector.rs b/packages/next-swc/crates/styled_components/src/visitors/transpile_css_prop/top_level_binding_collector.rs index 85848cb124a2..78cbf49996d9 100644 --- a/packages/next-swc/crates/styled_components/src/visitors/transpile_css_prop/top_level_binding_collector.rs +++ b/packages/next-swc/crates/styled_components/src/visitors/transpile_css_prop/top_level_binding_collector.rs @@ -1,10 +1,10 @@ -use swc_common::collections::AHashSet; -use swc_ecmascript::{ - ast::{ +use swc_core::{ + common::collections::AHashSet, + ecma::ast::{ ArrowExpr, ClassDecl, FnDecl, Function, Id, ImportDefaultSpecifier, ImportNamedSpecifier, ImportStarAsSpecifier, ObjectPatProp, Pat, VarDeclarator, }, - visit::{noop_visit_type, Visit, VisitWith}, + ecma::visit::{noop_visit_type, Visit, VisitWith}, }; // Modified from swc_ecma_utils/src/lib.rs:BindingCollector. diff --git a/packages/next-swc/crates/styled_components/src/visitors/transpile_css_prop/transpile.rs b/packages/next-swc/crates/styled_components/src/visitors/transpile_css_prop/transpile.rs index 1396c9fedaf4..26f621482c5c 100644 --- a/packages/next-swc/crates/styled_components/src/visitors/transpile_css_prop/transpile.rs +++ b/packages/next-swc/crates/styled_components/src/visitors/transpile_css_prop/transpile.rs @@ -8,16 +8,16 @@ use crate::State; use inflector::Inflector; use once_cell::sync::Lazy; use regex::Regex; -use swc_atoms::{js_word, JsWord}; -use swc_common::{ - collections::{AHashMap, AHashSet}, - util::take::Take, - Spanned, DUMMY_SP, -}; -use swc_ecmascript::{ - ast::*, - utils::{prepend_stmt, private_ident, quote_ident, ExprFactory}, - visit::{as_folder, noop_visit_mut_type, Fold, VisitMut, VisitMutWith}, +use swc_core::{ + common::{ + collections::{AHashMap, AHashSet}, + util::take::Take, + Spanned, DUMMY_SP, + }, + ecma::ast::*, + ecma::atoms::{js_word, JsWord}, + ecma::utils::{prepend_stmt, private_ident, quote_ident, ExprFactory}, + ecma::visit::{as_folder, noop_visit_mut_type, Fold, VisitMut, VisitMutWith}, }; use crate::utils::{get_prop_key_as_expr, get_prop_name, get_prop_name2}; diff --git a/packages/next-swc/crates/styled_components/tests/fixture.rs b/packages/next-swc/crates/styled_components/tests/fixture.rs index 17c3183878cb..509ac5bc6c21 100644 --- a/packages/next-swc/crates/styled_components/tests/fixture.rs +++ b/packages/next-swc/crates/styled_components/tests/fixture.rs @@ -2,11 +2,11 @@ use std::{fs::read_to_string, path::PathBuf}; use styled_components::{styled_components, Config}; -use swc_common::{chain, Mark}; -use swc_ecma_transforms_testing::test_fixture; -use swc_ecmascript::{ - parser::{EsConfig, Syntax}, - transforms::resolver, +use swc_core::{ + common::{chain, Mark}, + ecma::parser::{EsConfig, Syntax}, + ecma::transforms::base::resolver, + ecma::transforms::testing::test_fixture, }; #[testing::fixture("tests/fixtures/**/code.js")] diff --git a/packages/next-swc/crates/styled_jsx/Cargo.toml b/packages/next-swc/crates/styled_jsx/Cargo.toml index 271b2de1eaf6..953d3ed4768f 100644 --- a/packages/next-swc/crates/styled_jsx/Cargo.toml +++ b/packages/next-swc/crates/styled_jsx/Cargo.toml @@ -11,12 +11,23 @@ version = "0.15.0" [dependencies] easy-error = "1.0.0" -swc_common = { version = "0.27.11", features = ["concurrent", "sourcemap"] } -swc_css = "0.120.0" -swc_css_prefixer = "0.117.0" -swc_ecmascript = { version = "0.189.4", features = ["parser", "minifier", "utils", "visit"] } tracing = "0.1.32" +swc_core = { version = "0.20.4", features = [ + "common_concurrent", + "css_ast", + "css_codegen", + "css_parser", + "css_prefixer", + "css_visit", + "ecma_parser", + "ecma_minifier", + "ecma_utils", + "ecma_visit" +] } + [dev-dependencies] -swc_ecma_transforms_testing = "0.105.5" testing = "0.29.4" +swc_core = { version = "0.20.4", features = [ + "testing_transform" +] } diff --git a/packages/next-swc/crates/styled_jsx/src/lib.rs b/packages/next-swc/crates/styled_jsx/src/lib.rs index ef64527b9f68..3750aa61ef64 100644 --- a/packages/next-swc/crates/styled_jsx/src/lib.rs +++ b/packages/next-swc/crates/styled_jsx/src/lib.rs @@ -3,16 +3,17 @@ use std::collections::hash_map::DefaultHasher; use std::hash::{Hash, Hasher}; use std::mem::take; use std::sync::Arc; -use swc_common::errors::HANDLER; -use swc_common::{collections::AHashSet, FileName, SourceMap, Span, DUMMY_SP}; -use swc_ecmascript::ast::*; -use swc_ecmascript::minifier::{ - eval::{EvalResult, Evaluator}, - marks::Marks, + +use swc_core::{ + common::{collections::AHashSet, errors::HANDLER, FileName, SourceMap, Span, DUMMY_SP}, + ecma::ast::*, + ecma::minifier::{ + eval::{EvalResult, Evaluator}, + marks::Marks, + }, + ecma::utils::{collect_decls, drop_span, prepend_stmt, private_ident}, + ecma::visit::{Fold, FoldWith}, }; -use swc_ecmascript::utils::{collect_decls, prepend_stmt}; -use swc_ecmascript::utils::{drop_span, private_ident}; -use swc_ecmascript::visit::{Fold, FoldWith}; //use external::external_styles; use transform_css::transform_css; @@ -173,7 +174,7 @@ impl Fold for StyledJSXTransformer { if let JSXElementName::Ident(Ident { sym, span, .. }) = &el.name { if sym != "style" && sym != self.style_import_name.as_ref().unwrap() - && (!is_capitalized(&*sym) + && (!is_capitalized(&**sym) || self .nearest_scope_bindings .contains(&(sym.clone(), span.ctxt))) @@ -535,13 +536,13 @@ impl StyledJSXTransformer { } } - return JSXStyle::Local(LocalStyle { + JSXStyle::Local(LocalStyle { hash: format!("{:x}", hasher.finish()), css, css_span, is_dynamic, expressions, - }); + }) } fn replace_jsx_style(&mut self, el: &JSXElement) -> Result { diff --git a/packages/next-swc/crates/styled_jsx/src/transform_css.rs b/packages/next-swc/crates/styled_jsx/src/transform_css.rs index 8ebb1f32bf62..aae5378d0adf 100644 --- a/packages/next-swc/crates/styled_jsx/src/transform_css.rs +++ b/packages/next-swc/crates/styled_jsx/src/transform_css.rs @@ -1,22 +1,27 @@ use easy_error::{bail, Error}; use std::panic; use std::sync::Arc; -use swc_common::errors::HANDLER; -use swc_common::util::take::Take; -use swc_common::{source_map::Pos, BytePos, Span, SyntaxContext, DUMMY_SP}; -use swc_common::{SourceMap, Spanned}; -use swc_css::ast::*; -use swc_css::codegen::{ - writer::basic::{BasicCssWriter, BasicCssWriterConfig}, - CodeGenerator, CodegenConfig, Emit, -}; -use swc_css::parser::{parse_str, parse_tokens, parser::ParserConfig}; -use swc_css::visit::{VisitMut, VisitMutWith}; -use swc_css_prefixer::prefixer; -use swc_ecmascript::ast::{Expr, Tpl, TplElement}; -use swc_ecmascript::parser::StringInput; use tracing::{debug, trace}; +use swc_core::{ + common::{ + errors::HANDLER, source_map::Pos, util::take::Take, BytePos, SourceMap, Span, Spanned, + SyntaxContext, DUMMY_SP, + }, + css::prefixer::prefixer, + css::{ + ast::*, + codegen::{ + writer::basic::{BasicCssWriter, BasicCssWriterConfig}, + CodeGenerator, CodegenConfig, Emit, + }, + parser::{parse_str, parse_tokens, parser::ParserConfig}, + visit::{VisitMut, VisitMutWith}, + }, + ecma::ast::{Expr, Tpl, TplElement}, + ecma::parser::StringInput, +}; + use super::{hash_string, string_literal_expr, LocalStyle}; pub fn transform_css( @@ -110,7 +115,7 @@ pub fn transform_css( /// Returns `(length, value)` fn read_number(s: &str) -> (usize, usize) { for (idx, c) in s.char_indices() { - if c.is_digit(10) { + if c.is_ascii_digit() { continue; } @@ -219,6 +224,12 @@ impl Namespacer { to_tokens(v).tokens } PseudoClassSelectorChildren::CompoundSelector(v) => to_tokens(v).tokens, + PseudoClassSelectorChildren::ForgivingSelectorList(v) => { + to_tokens(v).tokens + } + PseudoClassSelectorChildren::ForgivingRelativeSelectorList(v) => { + to_tokens(v).tokens + } }) .collect::>(); @@ -501,7 +512,7 @@ where } let span = node.span(); - let lexer = swc_css::parser::lexer::Lexer::new( + let lexer = swc_core::css::parser::lexer::Lexer::new( StringInput::new(&s, span.lo, span.hi), ParserConfig { allow_wrong_line_comments: true, diff --git a/packages/next-swc/crates/styled_jsx/src/utils.rs b/packages/next-swc/crates/styled_jsx/src/utils.rs index bc720b16af38..ed2173533617 100644 --- a/packages/next-swc/crates/styled_jsx/src/utils.rs +++ b/packages/next-swc/crates/styled_jsx/src/utils.rs @@ -1,7 +1,6 @@ use std::collections::hash_map::DefaultHasher; use std::hash::Hasher; -use swc_common::DUMMY_SP; -use swc_ecmascript::ast::*; +use swc_core::{common::DUMMY_SP, ecma::ast::*}; use super::{ExternalStyle, JSXStyle, LocalStyle}; diff --git a/packages/next-swc/crates/styled_jsx/tests/fixture.rs b/packages/next-swc/crates/styled_jsx/tests/fixture.rs index 476f22ebf028..d851a562d0b6 100644 --- a/packages/next-swc/crates/styled_jsx/tests/fixture.rs +++ b/packages/next-swc/crates/styled_jsx/tests/fixture.rs @@ -1,11 +1,11 @@ use std::path::PathBuf; use styled_jsx::styled_jsx; -use swc_common::{chain, FileName, Mark, Span, DUMMY_SP}; -use swc_ecma_transforms_testing::{test_fixture, test_fixture_allowing_error}; -use swc_ecmascript::{ - parser::{EsConfig, Syntax}, - transforms::resolver, +use swc_core::{ + common::{chain, FileName, Mark, Span, DUMMY_SP}, + ecma::parser::{EsConfig, Syntax}, + ecma::transforms::base::resolver, + ecma::transforms::testing::{test_fixture, test_fixture_allowing_error}, }; use testing::fixture; @@ -60,7 +60,7 @@ fn styled_jsx_fixture(input: PathBuf) { } pub struct DropSpan; -impl swc_ecmascript::visit::VisitMut for DropSpan { +impl swc_core::ecma::visit::VisitMut for DropSpan { fn visit_mut_span(&mut self, span: &mut Span) { *span = DUMMY_SP } diff --git a/packages/next-swc/crates/styled_jsx/tests/fixture/issue-30570/output.js b/packages/next-swc/crates/styled_jsx/tests/fixture/issue-30570/output.js index c97fb8923815..97583682d358 100644 --- a/packages/next-swc/crates/styled_jsx/tests/fixture/issue-30570/output.js +++ b/packages/next-swc/crates/styled_jsx/tests/fixture/issue-30570/output.js @@ -6,7 +6,7 @@ export default function IndexPage() { - <_JSXStyle id={"bbdada4ef17d18ef"}>{"@supports(display:flex){h1{color:hotpink}}"} + <_JSXStyle id={"bbdada4ef17d18ef"}>{"@supports((display:flex)or (display:-webkit-box)or (display:-webkit-flex)or (display:-moz-box)or (display:-ms-flexbox)){h1{color:hotpink}}"} ; }; diff --git a/packages/next-swc/crates/wasm/Cargo.toml b/packages/next-swc/crates/wasm/Cargo.toml index 81c7acfcea83..56ef94e1e695 100644 --- a/packages/next-swc/crates/wasm/Cargo.toml +++ b/packages/next-swc/crates/wasm/Cargo.toml @@ -8,12 +8,12 @@ version = "0.0.0" crate-type = ["cdylib"] [features] +default = ["swc_v1"] +swc_v1 = [] + plugin = [ - "swc/plugin", - "swc_plugin_runner/memory_cache", - "wasmer/js-default", - "wasmer-wasi/js-default", - "getrandom/js" + "getrandom/js", + "swc_core/plugin_transform_host_js" ] [dependencies] @@ -25,14 +25,23 @@ parking_lot_core = "=0.8.0" path-clean = "0.1" serde = {version = "1", features = ["derive"]} serde_json = "1" -swc = "0.214.9" -swc_common = { version = "0.27.11", features = ["concurrent", "sourcemap"] } -swc_ecmascript = { version = "0.189.4", features = ["codegen", "minifier", "optimization", "parser", "react", "transforms", "typescript", "utils", "visit"] } -swc_plugin_runner = { version = "0.71.15", default-features = false, optional = true } tracing = { version = "0.1.32", features = ["release_max_level_off"] } wasm-bindgen = {version = "0.2", features = ["serde-serialize", "enable-interning"]} wasm-bindgen-futures = "0.4.8" -wasmer = { version = "2.3.0", optional = true, default-features = false } -wasmer-wasi = { version = "2.3.0", optional = true, default-features = false } getrandom = { version = "0.2.5", optional = true, default-features = false } js-sys = "0.3.59" + +swc_core = { version = "0.20.4", features = [ + "common_concurrent", + "binding_macro_wasm", + "ecma_codegen", + "ecma_minifier", + "ecma_transforms", + "ecma_transforms_typescript", + "ecma_transforms_optimization", + "ecma_transforms_react", + "ecma_parser", + "ecma_parser_typescript", + "ecma_utils", + "ecma_visit" +] } diff --git a/packages/next-swc/crates/wasm/src/lib.rs b/packages/next-swc/crates/wasm/src/lib.rs index e6b0c7331418..22b22d479ad8 100644 --- a/packages/next-swc/crates/wasm/src/lib.rs +++ b/packages/next-swc/crates/wasm/src/lib.rs @@ -3,12 +3,15 @@ use js_sys::JsString; use next_swc::{custom_before_pass, TransformOptions}; use once_cell::sync::Lazy; use std::sync::Arc; -use swc::{config::JsMinifyOptions, config::ParseOptions, try_with_handler, Compiler}; -use swc_common::{comments::Comments, errors::ColorConfig, FileName, FilePathMapping, SourceMap}; -use swc_ecmascript::transforms::pass::noop; use wasm_bindgen::{prelude::*, JsCast}; use wasm_bindgen_futures::future_to_promise; +use swc_core::{ + base::{config::JsMinifyOptions, config::ParseOptions, try_with_handler, Compiler}, + common::{comments::Comments, errors::ColorConfig, FileName, FilePathMapping, SourceMap}, + ecma::transforms::base::pass::noop, +}; + fn convert_err(err: Error) -> JsValue { format!("{:?}", err).into() } @@ -21,7 +24,7 @@ pub fn minify_sync(s: JsString, opts: JsValue) -> Result { try_with_handler( c.cm.clone(), - swc::HandlerOpts { + swc_core::base::HandlerOpts { color: ColorConfig::Never, skip_filename: false, }, @@ -54,7 +57,7 @@ pub fn transform_sync(s: JsValue, opts: JsValue) -> Result { try_with_handler( c.cm.clone(), - swc::HandlerOpts { + swc_core::base::HandlerOpts { color: ColorConfig::Never, skip_filename: false, }, @@ -112,11 +115,11 @@ pub fn transform(s: JsValue, opts: JsValue) -> js_sys::Promise { pub fn parse_sync(s: JsString, opts: JsValue) -> Result { console_error_panic_hook::set_once(); - let c = swc::Compiler::new(Arc::new(SourceMap::new(FilePathMapping::empty()))); + let c = swc_core::base::Compiler::new(Arc::new(SourceMap::new(FilePathMapping::empty()))); try_with_handler( c.cm.clone(), - swc::HandlerOpts { + swc_core::base::HandlerOpts { ..Default::default() }, |handler| { diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index 75beba2b8dbc..bb66664beaa6 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "12.2.6-canary.8", + "version": "12.2.6-canary.9", "private": true, "scripts": { "build-native": "napi build --platform -p next-swc-napi --cargo-name next_swc_napi native --features plugin", diff --git a/packages/next-swc/rust-toolchain b/packages/next-swc/rust-toolchain index 4e7e21b01962..928512b397cc 100644 --- a/packages/next-swc/rust-toolchain +++ b/packages/next-swc/rust-toolchain @@ -1 +1 @@ -nightly-2022-02-23 \ No newline at end of file +nightly-2022-06-12 \ No newline at end of file diff --git a/packages/next/README.md b/packages/next/README.md index dd075a57575b..a85ea7acb225 100644 --- a/packages/next/README.md +++ b/packages/next/README.md @@ -1,6 +1,6 @@

- +

Next.js

diff --git a/packages/next/build/entries.ts b/packages/next/build/entries.ts index 65b62563154e..aed59e8e069d 100644 --- a/packages/next/build/entries.ts +++ b/packages/next/build/entries.ts @@ -69,12 +69,14 @@ export function createPagesMapping({ pageExtensions, pagePaths, pagesType, + pagesDir, }: { hasServerComponents: boolean isDev: boolean pageExtensions: string[] pagePaths: string[] pagesType: 'pages' | 'root' | 'app' + pagesDir: string | undefined }): { [page: string]: string } { const previousPages: { [key: string]: string } = {} const pages = pagePaths.reduce<{ [key: string]: string }>( @@ -133,7 +135,7 @@ export function createPagesMapping({ // In development we always alias these to allow Webpack to fallback to // the correct source file so that HMR can work properly when a file is // added or removed. - const root = isDev ? PAGES_DIR_ALIAS : 'next/dist/pages' + const root = isDev && pagesDir ? PAGES_DIR_ALIAS : 'next/dist/pages' return { '/_app': `${root}/_app`, @@ -149,7 +151,7 @@ interface CreateEntrypointsParams { envFiles: LoadedEnvFiles isDev?: boolean pages: { [page: string]: string } - pagesDir: string + pagesDir?: string previewMode: __ApiPreviewProps rootDir: string rootPaths?: Record @@ -366,7 +368,7 @@ export async function createEntrypoints(params: CreateEntrypointsParams) { // Handle paths that have aliases const pageFilePath = (() => { - if (absolutePagePath.startsWith(PAGES_DIR_ALIAS)) { + if (absolutePagePath.startsWith(PAGES_DIR_ALIAS) && pagesDir) { return absolutePagePath.replace(PAGES_DIR_ALIAS, pagesDir) } @@ -444,12 +446,7 @@ export async function createEntrypoints(params: CreateEntrypointsParams) { }) } } else { - server[serverBundlePath] = isServerComponent - ? { - import: mappings[page], - layer: WEBPACK_LAYERS.server, - } - : [mappings[page]] + server[serverBundlePath] = [mappings[page]] } }, onEdgeServer: () => { @@ -490,7 +487,7 @@ export async function createEntrypoints(params: CreateEntrypointsParams) { await Promise.all(Object.keys(pages).map(getEntryHandler(pages, 'pages'))) if (nestedMiddleware.length > 0) { - throw new NestedMiddlewareError(nestedMiddleware, rootDir, pagesDir) + throw new NestedMiddlewareError(nestedMiddleware, rootDir, pagesDir!) } return { diff --git a/packages/next/build/index.ts b/packages/next/build/index.ts index f9097ff16470..5f107284eb66 100644 --- a/packages/next/build/index.ts +++ b/packages/next/build/index.ts @@ -314,7 +314,9 @@ export default async function build( eventCliSession(dir, config, { webpackVersion: 5, cliCommand: 'build', - isSrcDir: path.relative(dir, pagesDir!).startsWith('src'), + isSrcDir: + (!!pagesDir && path.relative(dir, pagesDir).startsWith('src')) || + (!!appDir && path.relative(dir, appDir).startsWith('src')), hasNowJson: !!(await findUp('now.json', { cwd: dir })), isCustomServer: null, }) @@ -395,7 +397,8 @@ export default async function build( config.eslint?.dirs, config.experimental.cpus, config.experimental.workerThreads, - telemetry + telemetry, + !!config.experimental.appDir ) }), ]) @@ -436,14 +439,16 @@ export default async function build( const isLikeServerless = isTargetLikeServerless(target) - const pagesPaths = await nextBuildSpan - .traceChild('collect-pages') - .traceAsyncFn(() => - recursiveReadDir( - pagesDir, - new RegExp(`\\.(?:${config.pageExtensions.join('|')})$`) - ) - ) + const pagesPaths = pagesDir + ? await nextBuildSpan + .traceChild('collect-pages') + .traceAsyncFn(() => + recursiveReadDir( + pagesDir, + new RegExp(`\\.(?:${config.pageExtensions.join('|')})$`) + ) + ) + : [] let appPaths: string[] | undefined @@ -462,9 +467,11 @@ export default async function build( `^${MIDDLEWARE_FILENAME}\\.(?:${config.pageExtensions.join('|')})$` ) - const rootPaths = ( - await flatReaddir(join(pagesDir, '..'), middlewareDetectionRegExp) - ).map((absoluteFile) => absoluteFile.replace(dir, '')) + const rootPaths = pagesDir + ? ( + await flatReaddir(join(pagesDir, '..'), middlewareDetectionRegExp) + ).map((absoluteFile) => absoluteFile.replace(dir, '')) + : [] // needed for static exporting since we want to replace with HTML // files @@ -487,6 +494,7 @@ export default async function build( pageExtensions: config.pageExtensions, pagesType: 'pages', pagePaths: pagesPaths, + pagesDir, }) ) @@ -502,6 +510,7 @@ export default async function build( isDev: false, pagesType: 'app', pageExtensions: config.pageExtensions, + pagesDir: pagesDir, }) ) } @@ -514,6 +523,7 @@ export default async function build( pageExtensions: config.pageExtensions, pagePaths: rootPaths, pagesType: 'root', + pagesDir: pagesDir, }) } @@ -1256,7 +1266,7 @@ export default async function build( : appPaths?.find((p) => p.startsWith(actualPage + '/page.')) const pageRuntime = - pageType === 'pages' && pagePath + pagesDir && pageType === 'pages' && pagePath ? ( await getPageStaticInfo({ pageFilePath: join(pagesDir, pagePath), @@ -1913,6 +1923,7 @@ export default async function build( await staticWorkers.end() } : undefined, + appPaths, } const exportConfig: any = { ...config, diff --git a/packages/next/build/utils.ts b/packages/next/build/utils.ts index e5cdc0f93929..fa114b46ef03 100644 --- a/packages/next/build/utils.ts +++ b/packages/next/build/utils.ts @@ -305,7 +305,7 @@ export async function printTreeView( }: { distPath: string buildId: string - pagesDir: string + pagesDir?: string pageExtensions: string[] buildManifest: BuildManifest appBuildManifest?: AppBuildManifest @@ -345,7 +345,8 @@ export async function printTreeView( .replace(/(?:^|[.-])([0-9a-z]{6})[0-9a-z]{14}(?=\.)/, '.$1') // Check if we have a custom app. - const hasCustomApp = await findPageFile(pagesDir, '/_app', pageExtensions) + const hasCustomApp = + pagesDir && (await findPageFile(pagesDir, '/_app', pageExtensions, false)) const filterAndSortList = (list: ReadonlyArray) => list @@ -1081,7 +1082,13 @@ export async function isPageStatic({ getStaticProps: mod.getStaticProps, } } else { - componentsResult = await loadComponents(distDir, page, serverless) + componentsResult = await loadComponents( + distDir, + page, + serverless, + false, + false + ) } const Comp = componentsResult.Component @@ -1207,7 +1214,13 @@ export async function hasCustomGetInitialProps( ): Promise { require('../shared/lib/runtime-config').setConfig(runtimeEnvConfig) - const components = await loadComponents(distDir, page, isLikeServerless) + const components = await loadComponents( + distDir, + page, + isLikeServerless, + false, + false + ) let mod = components.ComponentMod if (checkingApp) { @@ -1226,7 +1239,13 @@ export async function getNamedExports( runtimeEnvConfig: any ): Promise> { require('../shared/lib/runtime-config').setConfig(runtimeEnvConfig) - const components = await loadComponents(distDir, page, isLikeServerless) + const components = await loadComponents( + distDir, + page, + isLikeServerless, + false, + false + ) let mod = components.ComponentMod return Object.keys(mod) diff --git a/packages/next/build/webpack-config.ts b/packages/next/build/webpack-config.ts index d47806b40c23..02f1012f7497 100644 --- a/packages/next/build/webpack-config.ts +++ b/packages/next/build/webpack-config.ts @@ -518,7 +518,7 @@ export default async function getBaseWebpackConfig( entrypoints: webpack.EntryObject hasReactRoot: boolean isDevFallback?: boolean - pagesDir: string + pagesDir?: string reactProductionProfiling?: boolean rewrites: CustomRoutes['rewrites'] runWebpackSpan: Span @@ -794,24 +794,30 @@ export default async function getBaseWebpackConfig( if (dev) { customAppAliases[`${PAGES_DIR_ALIAS}/_app`] = [ - ...rawPageExtensions.reduce((prev, ext) => { - prev.push(path.join(pagesDir, `_app.${ext}`)) - return prev - }, [] as string[]), + ...(pagesDir + ? rawPageExtensions.reduce((prev, ext) => { + prev.push(path.join(pagesDir, `_app.${ext}`)) + return prev + }, [] as string[]) + : []), 'next/dist/pages/_app.js', ] customAppAliases[`${PAGES_DIR_ALIAS}/_error`] = [ - ...rawPageExtensions.reduce((prev, ext) => { - prev.push(path.join(pagesDir, `_error.${ext}`)) - return prev - }, [] as string[]), + ...(pagesDir + ? rawPageExtensions.reduce((prev, ext) => { + prev.push(path.join(pagesDir, `_error.${ext}`)) + return prev + }, [] as string[]) + : []), 'next/dist/pages/_error.js', ] customDocumentAliases[`${PAGES_DIR_ALIAS}/_document`] = [ - ...rawPageExtensions.reduce((prev, ext) => { - prev.push(path.join(pagesDir, `_document.${ext}`)) - return prev - }, [] as string[]), + ...(pagesDir + ? rawPageExtensions.reduce((prev, ext) => { + prev.push(path.join(pagesDir, `_document.${ext}`)) + return prev + }, [] as string[]) + : []), `next/dist/pages/_document.js`, ] } @@ -850,7 +856,7 @@ export default async function getBaseWebpackConfig( ...customDocumentAliases, ...customRootAliases, - [PAGES_DIR_ALIAS]: pagesDir, + ...(pagesDir ? { [PAGES_DIR_ALIAS]: pagesDir } : {}), ...(appDir ? { [APP_DIR_ALIAS]: appDir, @@ -2051,7 +2057,9 @@ export default async function getBaseWebpackConfig( webpackConfig = await buildConfiguration(webpackConfig, { supportedBrowsers, rootDirectory: dir, - customAppFile: new RegExp(escapeStringRegexp(path.join(pagesDir, `_app`))), + customAppFile: pagesDir + ? new RegExp(escapeStringRegexp(path.join(pagesDir, `_app`))) + : undefined, isDevelopment: dev, isServer: isNodeServer || isEdgeServer, isEdgeRuntime: isEdgeServer, diff --git a/packages/next/build/webpack/config/index.ts b/packages/next/build/webpack/config/index.ts index 8da928de6009..201403bae8c2 100644 --- a/packages/next/build/webpack/config/index.ts +++ b/packages/next/build/webpack/config/index.ts @@ -25,7 +25,7 @@ export async function build( }: { supportedBrowsers: string[] | undefined rootDirectory: string - customAppFile: RegExp + customAppFile: RegExp | undefined isDevelopment: boolean isServer: boolean isEdgeRuntime: boolean diff --git a/packages/next/build/webpack/config/utils.ts b/packages/next/build/webpack/config/utils.ts index d2cdbb1277aa..b8355ad52ef5 100644 --- a/packages/next/build/webpack/config/utils.ts +++ b/packages/next/build/webpack/config/utils.ts @@ -4,7 +4,7 @@ import type { NextConfigComplete } from '../../../server/config-shared' export type ConfigurationContext = { supportedBrowsers: string[] | undefined rootDirectory: string - customAppFile: RegExp + customAppFile: RegExp | undefined isDevelopment: boolean isProduction: boolean diff --git a/packages/next/build/webpack/plugins/react-loadable-plugin.ts b/packages/next/build/webpack/plugins/react-loadable-plugin.ts index aacb383b5dd0..2677a6c94658 100644 --- a/packages/next/build/webpack/plugins/react-loadable-plugin.ts +++ b/packages/next/build/webpack/plugins/react-loadable-plugin.ts @@ -53,9 +53,14 @@ function getChunkGroupFromBlock( function buildManifest( _compiler: webpack.Compiler, compilation: webpack.Compilation, - pagesDir: string, + pagesDir: string | undefined, dev: boolean ) { + // If there's no pagesDir, output an empty manifest + if (!pagesDir) { + return {} + } + let manifest: { [k: string]: { id: string | number; files: string[] } } = {} // This is allowed: @@ -145,13 +150,13 @@ function buildManifest( export class ReactLoadablePlugin { private filename: string - private pagesDir: string + private pagesDir?: string private runtimeAsset?: string private dev: boolean constructor(opts: { filename: string - pagesDir: string + pagesDir?: string runtimeAsset?: string dev: boolean }) { diff --git a/packages/next/cli/next-lint.ts b/packages/next/cli/next-lint.ts index c25b340e238d..ca0d1e5246a0 100755 --- a/packages/next/cli/next-lint.ts +++ b/packages/next/cli/next-lint.ts @@ -92,11 +92,11 @@ const nextLint: cliCommand = async (argv) => { printAndExit( ` Description - Run ESLint on every file in specified directories. + Run ESLint on every file in specified directories. If not configured, ESLint will be set up for the first time. Usage - $ next lint [options] + $ next lint [options] represents the directory of the Next.js application. If no directory is provided, the current directory will be used. @@ -127,7 +127,7 @@ const nextLint: cliCommand = async (argv) => { Handling warnings: --quiet Report errors only - default: false --max-warnings Int Number of warnings to trigger nonzero exit code - default: -1 - + Output: -o, --output-file path::String Specify file to write report to -f, --format String Use a specific output format - default: Next.js custom formatter @@ -140,7 +140,7 @@ const nextLint: cliCommand = async (argv) => { --no-cache Disable caching --cache-location path::String Path to the cache file or directory - default: .eslintcache --cache-strategy String Strategy to use for detecting changed files in the cache, either metadata or content - default: metadata - + Miscellaneous: --error-on-unmatched-pattern Show errors when any file patterns are unmatched - default: false `, @@ -179,17 +179,16 @@ const nextLint: cliCommand = async (argv) => { const distDir = join(baseDir, nextConfig.distDir) const defaultCacheLocation = join(distDir, 'cache', 'eslint/') - runLintCheck( - baseDir, - pathsToLint, - false, - eslintOptions(args, defaultCacheLocation), - reportErrorsOnly, + runLintCheck(baseDir, pathsToLint, { + lintDuringBuild: false, + eslintOptions: eslintOptions(args, defaultCacheLocation), + reportErrorsOnly: reportErrorsOnly, maxWarnings, formatter, outputFile, - strict - ) + strict, + hasAppDir: !!nextConfig.experimental.appDir, + }) .then(async (lintResults) => { const lintOutput = typeof lintResults === 'string' ? lintResults : lintResults?.output diff --git a/packages/next/client/script.tsx b/packages/next/client/script.tsx index c1adef2378bd..e9ebd6a022c0 100644 --- a/packages/next/client/script.tsx +++ b/packages/next/client/script.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useContext } from 'react' +import React, { useEffect, useContext, useRef } from 'react' import { ScriptHTMLAttributes } from 'react' import { HeadManagerContext } from '../shared/lib/head-manager-context' import { DOMAttributeNames } from './head-manager' @@ -57,21 +57,25 @@ const loadScript = (props: ScriptProps): void => { return } + /** Execute after the script first loaded */ + const afterLoad = () => { + // Run onReady for the first time after load event + if (onReady) { + onReady() + } + // add cacheKey to LoadCache when load successfully + LoadCache.add(cacheKey) + } + const el = document.createElement('script') const loadPromise = new Promise((resolve, reject) => { el.addEventListener('load', function (e) { - // add cacheKey to LoadCache when load successfully - LoadCache.add(cacheKey) - resolve() if (onLoad) { onLoad.call(this, e) } - // Run onReady for the first time after load event - if (onReady) { - onReady() - } + afterLoad() }) el.addEventListener('error', function (e) { reject(e) @@ -85,8 +89,7 @@ const loadScript = (props: ScriptProps): void => { if (dangerouslySetInnerHTML) { el.innerHTML = dangerouslySetInnerHTML.__html || '' - // add cacheKey to LoadCache for inline script - LoadCache.add(cacheKey) + afterLoad() } else if (children) { el.textContent = typeof children === 'string' @@ -95,8 +98,7 @@ const loadScript = (props: ScriptProps): void => { ? children.join('') : '' - // add cacheKey to LoadCache for inline script - LoadCache.add(cacheKey) + afterLoad() } else if (src) { el.src = src // do not add cacheKey into LoadCache for remote script here @@ -174,12 +176,42 @@ function Script(props: ScriptProps): JSX.Element | null { // Context is available only during SSR const { updateScripts, scripts, getIsSsr } = useContext(HeadManagerContext) + /** + * - First mount: + * 1. The useEffect for onReady executes + * 2. hasOnReadyEffectCalled.current is false, but the script hasn't loaded yet (not in LoadCache) + * onReady is skipped, set hasOnReadyEffectCalled.current to true + * 3. The useEffect for loadScript executes + * Once the script is loaded, the onReady will be called by then + * [If strict mode is enabled / is wrapped in component] + * 5. The useEffect for onReady executes again + * 6. hasOnReadyEffectCalled.current is true, so entire effect is skipped + * 7. The useEffect for loadScript executes again + * 8. The script is already loaded/loading, loadScript bails out + * + * - Second mount: + * 1. The useEffect for onReady executes + * 2. hasOnReadyEffectCalled.current is false, but the script has already loaded (found in LoadCache) + * onReady is called, set hasOnReadyEffectCalled.current to true + * 3. The useEffect for loadScript executes + * 4. The script is already loaded, loadScript bails out + * [If strict mode is enabled / is wrapped in component] + * 5. The useEffect for onReady executes again + * 6. hasOnReadyEffectCalled.current is true, so entire effect is skipped + * 7. The useEffect for loadScript executes again + * 8. The script is already loaded, loadScript will bail out + */ + const hasOnReadyEffectCalled = useRef(false) + useEffect(() => { const cacheKey = id || src + if (!hasOnReadyEffectCalled.current) { + // Run onReady if script has loaded before but component is re-mounted + if (onReady && cacheKey && LoadCache.has(cacheKey)) { + onReady() + } - // Run onReady if script has loaded before but component is re-mounted - if (onReady && cacheKey && LoadCache.has(cacheKey)) { - onReady() + hasOnReadyEffectCalled.current = true } }, [onReady, id, src]) diff --git a/packages/next/export/index.ts b/packages/next/export/index.ts index da2854199513..e5c56a41e6ae 100644 --- a/packages/next/export/index.ts +++ b/packages/next/export/index.ts @@ -133,6 +133,7 @@ interface ExportOptions { statusMessage?: string exportPageWorker?: typeof import('./worker').default endWorker?: () => Promise + appPaths?: string[] } export default async function exportApp( @@ -582,7 +583,6 @@ export default async function exportApp( outDir, pagesDataDir, renderOpts, - appDir: nextConfig.experimental.appDir, serverRuntimeConfig, subFolders, buildExport: options.buildExport, @@ -594,6 +594,7 @@ export default async function exportApp( parentSpanId: pageExportSpan.id, httpAgentOptions: nextConfig.httpAgentOptions, serverComponents: nextConfig.experimental.serverComponents, + appPaths: options.appPaths || [], }) for (const validation of result.ampValidations || []) { diff --git a/packages/next/export/worker.ts b/packages/next/export/worker.ts index 298b87cb5fc6..51655364d667 100644 --- a/packages/next/export/worker.ts +++ b/packages/next/export/worker.ts @@ -65,7 +65,7 @@ interface ExportPageInput { parentSpanId: any httpAgentOptions: NextConfigComplete['httpAgentOptions'] serverComponents?: boolean - appDir?: boolean + appPaths: string[] } interface ExportPageResults { @@ -91,7 +91,6 @@ interface RenderOpts { defaultLocale?: string domainLocales?: DomainLocale[] trailingSlash?: boolean - appDir?: boolean } type ComponentModule = ComponentType<{}> & { @@ -105,7 +104,7 @@ export default async function exportPage({ pathMap, distDir, outDir, - appDir, + appPaths, pagesDataDir, renderOpts, buildExport, @@ -273,6 +272,9 @@ export default async function exportPage({ return !buildExport && getStaticProps && !isDynamicRoute(path) } + const isAppPath = appPaths.some((appPath: string) => + appPath.startsWith(page + '.page') + ) if (serverless) { const curUrl = url.parse(req.url!, true) req.url = url.format({ @@ -292,8 +294,8 @@ export default async function exportPage({ distDir, page, serverless, - serverComponents, - appDir + !!serverComponents, + isAppPath ) const ampState = { ampFirst: pageConfig?.amp === true, @@ -359,7 +361,8 @@ export default async function exportPage({ distDir, page, serverless, - serverComponents + !!serverComponents, + isAppPath ) const ampState = { ampFirst: components.pageConfig?.amp === true, diff --git a/packages/next/lib/eslint/runLintCheck.ts b/packages/next/lib/eslint/runLintCheck.ts index 8f349ac2ed55..9799f6733074 100644 --- a/packages/next/lib/eslint/runLintCheck.ts +++ b/packages/next/lib/eslint/runLintCheck.ts @@ -83,12 +83,22 @@ async function lint( lintDirs: string[], eslintrcFile: string | null, pkgJsonPath: string | null, - lintDuringBuild: boolean = false, - eslintOptions: any = null, - reportErrorsOnly: boolean = false, - maxWarnings: number = -1, - formatter: string | null = null, - outputFile: string | null = null + hasAppDir: boolean, + { + lintDuringBuild = false, + eslintOptions = null, + reportErrorsOnly = false, + maxWarnings = -1, + formatter = null, + outputFile = null, + }: { + lintDuringBuild: boolean + eslintOptions: any + reportErrorsOnly: boolean + maxWarnings: number + formatter: string | null + outputFile: string | null + } ): Promise< | string | null @@ -176,8 +186,7 @@ async function lint( } } - // TODO: should we apply these rules to "root" dir as well? - const pagesDir = findPagesDir(baseDir).pages + const pagesDir = findPagesDir(baseDir, hasAppDir).pages if (nextEslintPluginIsEnabled) { let updatedPagesDir = false @@ -268,14 +277,27 @@ async function lint( export async function runLintCheck( baseDir: string, lintDirs: string[], - lintDuringBuild: boolean = false, - eslintOptions: any = null, - reportErrorsOnly: boolean = false, - maxWarnings: number = -1, - formatter: string | null = null, - outputFile: string | null = null, - strict: boolean = false + opts: { + lintDuringBuild?: boolean + eslintOptions?: any + reportErrorsOnly?: boolean + maxWarnings?: number + formatter?: string | null + outputFile?: string | null + strict?: boolean + hasAppDir: boolean + } ): ReturnType { + const { + lintDuringBuild = false, + eslintOptions = null, + reportErrorsOnly = false, + maxWarnings = -1, + formatter = null, + outputFile = null, + strict = false, + hasAppDir, + } = opts try { // Find user's .eslintrc file // See: https://eslint.org/docs/user-guide/configuring/configuration-files#configuration-file-formats @@ -313,12 +335,15 @@ export async function runLintCheck( lintDirs, eslintrcFile, pkgJsonPath, - lintDuringBuild, - eslintOptions, - reportErrorsOnly, - maxWarnings, - formatter, - outputFile + hasAppDir, + { + lintDuringBuild, + eslintOptions, + reportErrorsOnly, + maxWarnings, + formatter, + outputFile, + } ) } else { // Display warning if no ESLint configuration is present inside diff --git a/packages/next/lib/find-pages-dir.ts b/packages/next/lib/find-pages-dir.ts index 61592f9e4f9d..2edec19c3f99 100644 --- a/packages/next/lib/find-pages-dir.ts +++ b/packages/next/lib/find-pages-dir.ts @@ -24,19 +24,25 @@ function findDir(dir: string, name: 'pages' | 'app'): string | null { export function findPagesDir( dir: string, appDirEnabled?: boolean -): { pages: string; appDir?: string } { - const pagesDir = findDir(dir, 'pages') +): { pages: string | undefined; appDir: string | undefined } { + const pagesDir = findDir(dir, 'pages') || undefined let appDir: undefined | string if (appDirEnabled) { appDir = findDir(dir, 'app') || undefined + if (appDirEnabled == null && pagesDir == null) { + throw new Error( + "> Couldn't find any `pages` or `app` directory. Please create one under the project root" + ) + } } - // TODO: allow "root" dir without pages dir - if (pagesDir === null) { - throw new Error( - "> Couldn't find a `pages` directory. Please create one under the project root" - ) + if (!appDirEnabled) { + if (pagesDir == null) { + throw new Error( + "> Couldn't find a `pages` directory. Please create one under the project root" + ) + } } return { diff --git a/packages/next/lib/verifyAndLint.ts b/packages/next/lib/verifyAndLint.ts index 76f384db10de..b5e47d423f82 100644 --- a/packages/next/lib/verifyAndLint.ts +++ b/packages/next/lib/verifyAndLint.ts @@ -14,7 +14,8 @@ export async function verifyAndLint( configLintDirs: string[] | undefined, numWorkers: number | undefined, enableWorkerThreads: boolean | undefined, - telemetry: Telemetry + telemetry: Telemetry, + hasAppDir: boolean ): Promise { try { const lintWorkers = new Worker(require.resolve('./eslint/runLintCheck'), { @@ -38,8 +39,12 @@ export async function verifyAndLint( [] ) - const lintResults = await lintWorkers.runLintCheck(dir, lintDirs, true, { - cacheLocation, + const lintResults = await lintWorkers.runLintCheck(dir, lintDirs, { + hasAppDir, + lintDuringBuild: true, + eslintOptions: { + cacheLocation, + }, }) const lintOutput = typeof lintResults === 'string' ? lintResults : lintResults?.output diff --git a/packages/next/package.json b/packages/next/package.json index bb1a3a4beef3..a9afd24424fb 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "12.2.6-canary.8", + "version": "12.2.6-canary.9", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -70,8 +70,8 @@ ] }, "dependencies": { - "@next/env": "12.2.6-canary.8", - "@swc/helpers": "0.4.3", + "@next/env": "12.2.6-canary.9", + "@swc/helpers": "0.4.11", "caniuse-lite": "^1.0.30001332", "postcss": "8.4.14", "styled-jsx": "5.0.5", @@ -121,11 +121,11 @@ "@hapi/accept": "5.0.2", "@napi-rs/cli": "2.7.0", "@napi-rs/triples": "1.1.0", - "@next/polyfill-module": "12.2.6-canary.8", - "@next/polyfill-nomodule": "12.2.6-canary.8", - "@next/react-dev-overlay": "12.2.6-canary.8", - "@next/react-refresh-utils": "12.2.6-canary.8", - "@next/swc": "12.2.6-canary.8", + "@next/polyfill-module": "12.2.6-canary.9", + "@next/polyfill-nomodule": "12.2.6-canary.9", + "@next/react-dev-overlay": "12.2.6-canary.9", + "@next/react-refresh-utils": "12.2.6-canary.9", + "@next/swc": "12.2.6-canary.9", "@segment/ajv-human-errors": "2.1.2", "@taskr/clear": "1.1.0", "@taskr/esnext": "1.1.0", diff --git a/packages/next/server/base-server.ts b/packages/next/server/base-server.ts index c162054dc1eb..29b732fcd3a1 100644 --- a/packages/next/server/base-server.ts +++ b/packages/next/server/base-server.ts @@ -241,9 +241,9 @@ export default abstract class Server { protected abstract getFilesystemPaths(): Set protected abstract findPageComponents( pathname: string, - query?: NextParsedUrlQuery, - params?: Params, - isAppDir?: boolean + query: NextParsedUrlQuery, + params: Params, + isAppPath: boolean ): Promise protected abstract getFontManifest(): FontManifest | undefined protected abstract getPrerenderManifest(): PrerenderManifest @@ -1522,9 +1522,9 @@ export default abstract class Server { bubbleNoFallback: boolean ) { const { query, pathname } = ctx - const appPath = this.getOriginalAppPath(pathname) let page = pathname + const appPath = this.getOriginalAppPath(pathname) if (typeof appPath === 'string') { page = appPath } @@ -1532,7 +1532,7 @@ export default abstract class Server { const result = await this.findPageComponents( page, query, - ctx.renderOpts.params, + ctx.renderOpts.params || {}, typeof appPath === 'string' ) if (result) { @@ -1737,7 +1737,7 @@ export default abstract class Server { // use static 404 page if available and is 404 response if (is404 && (await this.hasPage('/404'))) { - result = await this.findPageComponents('/404', query) + result = await this.findPageComponents('/404', query, {}, false) using404Page = result !== null } let statusPage = `/${res.statusCode}` @@ -1750,12 +1750,12 @@ export default abstract class Server { // skip ensuring /500 in dev mode as it isn't used and the // dev overlay is used instead if (statusPage !== '/500' || !this.renderOpts.dev) { - result = await this.findPageComponents(statusPage, query) + result = await this.findPageComponents(statusPage, query, {}, false) } } if (!result) { - result = await this.findPageComponents('/_error', query) + result = await this.findPageComponents('/_error', query, {}, false) statusPage = '/_error' } diff --git a/packages/next/server/dev/hot-reloader.ts b/packages/next/server/dev/hot-reloader.ts index 76aa45105996..921706767ce1 100644 --- a/packages/next/server/dev/hot-reloader.ts +++ b/packages/next/server/dev/hot-reloader.ts @@ -159,7 +159,7 @@ export default class HotReloader { private dir: string private buildId: string private interceptors: any[] - private pagesDir: string + private pagesDir?: string private distDir: string private webpackHotMiddleware?: WebpackHotMiddleware private config: NextConfigComplete @@ -197,7 +197,7 @@ export default class HotReloader { appDir, }: { config: NextConfigComplete - pagesDir: string + pagesDir?: string distDir: string buildId: string previewProps: __ApiPreviewProps @@ -405,14 +405,21 @@ export default class HotReloader { : this.config.pageExtensions return webpackConfigSpan.traceAsyncFn(async () => { - const pagePaths = await webpackConfigSpan - .traceChild('get-page-paths') - .traceAsyncFn(() => - Promise.all([ - findPageFile(this.pagesDir, '/_app', rawPageExtensions), - findPageFile(this.pagesDir, '/_document', rawPageExtensions), - ]) - ) + const pagePaths = !this.pagesDir + ? ([] as (string | null)[]) + : await webpackConfigSpan + .traceChild('get-page-paths') + .traceAsyncFn(() => + Promise.all([ + findPageFile(this.pagesDir!, '/_app', rawPageExtensions, false), + findPageFile( + this.pagesDir!, + '/_document', + rawPageExtensions, + false + ), + ]) + ) this.pagesMapping = webpackConfigSpan .traceChild('create-pages-mapping') @@ -423,8 +430,9 @@ export default class HotReloader { pageExtensions: this.config.pageExtensions, pagesType: 'pages', pagePaths: pagePaths.filter( - (i): i is string => typeof i === 'string' + (i: string | null): i is string => typeof i === 'string' ), + pagesDir: this.pagesDir, }) ) @@ -848,6 +856,10 @@ export default class HotReloader { this.serverError = null this.serverStats = stats + if (!this.pagesDir) { + return + } + const { compilation } = stats // We only watch `_document` for changes on the server compilation @@ -1060,10 +1072,7 @@ export default class HotReloader { ) } - public async ensurePage( - page: string, - clientOnly: boolean = false - ): Promise { + public async ensurePage(page: string, clientOnly: boolean): Promise { // Make sure we don't re-build or dispose prebuilt pages if (page !== '/_error' && BLOCKED_PAGES.indexOf(page) !== -1) { return diff --git a/packages/next/server/dev/next-dev-server.ts b/packages/next/server/dev/next-dev-server.ts index 0452eea5b6a2..78f4656d8532 100644 --- a/packages/next/server/dev/next-dev-server.ts +++ b/packages/next/server/dev/next-dev-server.ts @@ -102,7 +102,7 @@ export default class DevServer extends Server { private isCustomServer: boolean protected sortedRoutes?: string[] private addedUpgradeListener = false - private pagesDir: string + private pagesDir?: string private appDir?: string private actualMiddlewareFile?: string private middleware?: MiddlewareRoutingItem @@ -259,28 +259,32 @@ export default class DevServer extends Server { let resolved = false return new Promise(async (resolve, reject) => { - // Watchpack doesn't emit an event for an empty directory - fs.readdir(this.pagesDir, (_, files) => { - if (files?.length) { - return - } + if (this.pagesDir) { + // Watchpack doesn't emit an event for an empty directory + fs.readdir(this.pagesDir, (_, files) => { + if (files?.length) { + return + } - if (!resolved) { - resolve() - resolved = true - } - }) + if (!resolved) { + resolve() + resolved = true + } + }) + } const wp = (this.webpackWatcher = new Watchpack({ ignored: /([/\\]node_modules[/\\]|[/\\]\.next[/\\]|[/\\]\.git[/\\])/, })) - const pages = [this.pagesDir] + const pages = this.pagesDir ? [this.pagesDir] : [] const app = this.appDir ? [this.appDir] : [] const directories = [...pages, ...app] - const files = getPossibleMiddlewareFilenames( - pathJoin(this.pagesDir, '..'), - this.nextConfig.pageExtensions - ) + const files = this.pagesDir + ? getPossibleMiddlewareFilenames( + pathJoin(this.pagesDir, '..'), + this.nextConfig.pageExtensions + ) + : [] let nestedMiddleware: string[] = [] const envFiles = [ @@ -380,7 +384,7 @@ export default class DevServer extends Server { } let pageName = absolutePathToPage(fileName, { - pagesDir: isAppPath ? this.appDir! : this.pagesDir, + pagesDir: isAppPath ? this.appDir! : this.pagesDir!, extensions: this.nextConfig.pageExtensions, keepIndex: isAppPath, }) @@ -529,8 +533,11 @@ export default class DevServer extends Server { if (nestedMiddleware.length > 0) { Log.error( - new NestedMiddlewareError(nestedMiddleware, this.dir, this.pagesDir) - .message + new NestedMiddlewareError( + nestedMiddleware, + this.dir, + this.pagesDir! + ).message ) nestedMiddleware = [] } @@ -618,7 +625,7 @@ export default class DevServer extends Server { this.verifyingTypeScript = true const verifyResult = await verifyTypeScriptSetup({ dir: this.dir, - intentDirs: [this.pagesDir!, this.appDir].filter(Boolean) as string[], + intentDirs: [this.pagesDir, this.appDir].filter(Boolean) as string[], typeCheckPreflight: false, tsconfigPath: this.nextConfig.typescript.tsconfigPath, disableStaticImages: this.nextConfig.images.disableStaticImages, @@ -679,7 +686,10 @@ export default class DevServer extends Server { eventCliSession(this.distDir, this.nextConfig, { webpackVersion: 5, cliCommand: 'dev', - isSrcDir: relative(this.dir, this.pagesDir).startsWith('src'), + isSrcDir: + (!!this.pagesDir && + relative(this.dir, this.pagesDir).startsWith('src')) || + (!!this.appDir && relative(this.dir, this.appDir).startsWith('src')), hasNowJson: !!(await findUp('now.json', { cwd: this.dir })), isCustomServer: this.isCustomServer, }) @@ -721,7 +731,8 @@ export default class DevServer extends Server { return findPageFile( this.dir, normalizedPath, - this.nextConfig.pageExtensions + this.nextConfig.pageExtensions, + false ).then(Boolean) } @@ -730,17 +741,22 @@ export default class DevServer extends Server { const pageFile = await findPageFile( this.appDir, normalizedPath, - this.nextConfig.pageExtensions + this.nextConfig.pageExtensions, + true ) if (pageFile) return true } - const pageFile = await findPageFile( - this.pagesDir, - normalizedPath, - this.nextConfig.pageExtensions - ) - return !!pageFile + if (this.pagesDir) { + const pageFile = await findPageFile( + this.pagesDir, + normalizedPath, + this.nextConfig.pageExtensions, + false + ) + return !!pageFile + } + return false } protected async _beforeCatchAllRender( @@ -886,6 +902,7 @@ export default class DevServer extends Server { query: ParsedUrlQuery params: Params | undefined page: string + isAppPath: boolean }) { try { return super.runEdgeFunction({ @@ -1101,11 +1118,11 @@ export default class DevServer extends Server { } protected async ensureMiddleware() { - return this.hotReloader!.ensurePage(this.actualMiddlewareFile!) + return this.hotReloader!.ensurePage(this.actualMiddlewareFile!, false) } protected async ensureEdgeFunction(pathname: string) { - return this.hotReloader!.ensurePage(pathname) + return this.hotReloader!.ensurePage(pathname, false) } generateRoutes() { @@ -1271,14 +1288,14 @@ export default class DevServer extends Server { } protected async ensureApiPage(pathname: string): Promise { - return this.hotReloader!.ensurePage(pathname) + return this.hotReloader!.ensurePage(pathname, false) } protected async findPageComponents( pathname: string, - query: ParsedUrlQuery = {}, - params: Params | null = null, - isAppDir: boolean = false + query: ParsedUrlQuery, + params: Params, + isAppPath: boolean ): Promise { await this.devReady const compilationErr = await this.getCompilationError(pathname) @@ -1287,7 +1304,7 @@ export default class DevServer extends Server { throw new WrappedBuildError(compilationErr) } try { - await this.hotReloader!.ensurePage(pathname) + await this.hotReloader!.ensurePage(pathname, false) const serverComponents = this.nextConfig.experimental.serverComponents @@ -1298,7 +1315,7 @@ export default class DevServer extends Server { this.serverCSSManifest = super.getServerCSSManifest() } - return super.findPageComponents(pathname, query, params, isAppDir) + return super.findPageComponents(pathname, query, params, isAppPath) } catch (err) { if ((err as any).code !== 'ENOENT') { throw err @@ -1311,7 +1328,7 @@ export default class DevServer extends Server { await this.hotReloader!.buildFallbackError() // Build the error page to ensure the fallback is built too. // TODO: See if this can be moved into hotReloader or removed. - await this.hotReloader!.ensurePage('/_error') + await this.hotReloader!.ensurePage('/_error', false) return await loadDefaultErrorComponents(this.distDir) } diff --git a/packages/next/server/dev/on-demand-entry-handler.ts b/packages/next/server/dev/on-demand-entry-handler.ts index 09570760812f..c3ce13b67ac6 100644 --- a/packages/next/server/dev/on-demand-entry-handler.ts +++ b/packages/next/server/dev/on-demand-entry-handler.ts @@ -255,6 +255,7 @@ function disposeInactiveEntries(maxInactiveAge: number) { }) } +// Normalize both app paths and page paths function tryToNormalizePagePath(page: string) { try { return normalizePagePath(page) @@ -276,16 +277,21 @@ function tryToNormalizePagePath(page: string) { */ async function findPagePathData( rootDir: string, - pagesDir: string, page: string, extensions: string[], + pagesDir?: string, appDir?: string ) { const normalizedPagePath = tryToNormalizePagePath(page) let pagePath: string | null = null if (isMiddlewareFile(normalizedPagePath)) { - pagePath = await findPageFile(rootDir, normalizedPagePath, extensions) + pagePath = await findPageFile( + rootDir, + normalizedPagePath, + extensions, + false + ) if (!pagePath) { throw new PageNotFoundError(normalizedPagePath) @@ -306,7 +312,7 @@ async function findPagePathData( // Check appDir first falling back to pagesDir if (appDir) { - pagePath = await findPageFile(appDir, normalizedPagePath, extensions) + pagePath = await findPageFile(appDir, normalizedPagePath, extensions, true) if (pagePath) { const pageUrl = ensureLeadingSlash( removePagePathTail(normalizePathSep(pagePath), { @@ -323,11 +329,16 @@ async function findPagePathData( } } - if (!pagePath) { - pagePath = await findPageFile(pagesDir, normalizedPagePath, extensions) + if (!pagePath && pagesDir) { + pagePath = await findPageFile( + pagesDir, + normalizedPagePath, + extensions, + false + ) } - if (pagePath !== null) { + if (pagePath !== null && pagesDir) { const pageUrl = ensureLeadingSlash( removePagePathTail(normalizePathSep(pagePath), { extensions, @@ -365,7 +376,7 @@ export function onDemandEntryHandler({ multiCompiler: webpack.MultiCompiler nextConfig: NextConfigComplete pagesBufferLength: number - pagesDir: string + pagesDir?: string rootDir: string appDir?: string }) { @@ -545,9 +556,9 @@ export function onDemandEntryHandler({ try { const pagePathData = await findPagePathData( rootDir, - pagesDir, page, nextConfig.pageExtensions, + pagesDir, appDir ) diff --git a/packages/next/server/dev/static-paths-worker.ts b/packages/next/server/dev/static-paths-worker.ts index 240178e25968..185948d7f2d1 100644 --- a/packages/next/server/dev/static-paths-worker.ts +++ b/packages/next/server/dev/static-paths-worker.ts @@ -38,7 +38,13 @@ export async function loadStaticPaths( require('../../shared/lib/runtime-config').setConfig(config) setHttpAgentOptions(httpAgentOptions) - const components = await loadComponents(distDir, pathname, serverless) + const components = await loadComponents( + distDir, + pathname, + serverless, + false, + false + ) if (!components.getStaticPaths) { // we shouldn't get to this point since the worker should diff --git a/packages/next/server/lib/find-page-file.ts b/packages/next/server/lib/find-page-file.ts index eab4d18f72cc..53d2a86dd35e 100644 --- a/packages/next/server/lib/find-page-file.ts +++ b/packages/next/server/lib/find-page-file.ts @@ -29,14 +29,16 @@ async function isTrueCasePagePath(pagePath: string, pagesDir: string) { export async function findPageFile( pagesDir: string, normalizedPagePath: string, - pageExtensions: string[] + pageExtensions: string[], + isAppDir: boolean ): Promise { - const pagePaths = getPagePaths(normalizedPagePath, pageExtensions) + const pagePaths = getPagePaths(normalizedPagePath, pageExtensions, isAppDir) const [existingPath, ...others] = ( await Promise.all( - pagePaths.map(async (path) => - (await fileExists(join(pagesDir, path))) ? path : null - ) + pagePaths.map(async (path) => { + const filePath = join(pagesDir, path) + return (await fileExists(filePath)) ? path : null + }) ) ).filter(nonNullable) diff --git a/packages/next/server/load-components.ts b/packages/next/server/load-components.ts index e54139ce0519..5cbf543ccc40 100644 --- a/packages/next/server/load-components.ts +++ b/packages/next/server/load-components.ts @@ -15,7 +15,7 @@ import { FLIGHT_MANIFEST, } from '../shared/lib/constants' import { join } from 'path' -import { requirePage, getPagePath } from './require' +import { requirePage } from './require' import { BuildManifest } from './get-page-files' import { interopDefault } from '../lib/interop-default' @@ -63,8 +63,8 @@ export async function loadComponents( distDir: string, pathname: string, serverless: boolean, - hasServerComponents?: boolean, - appDirEnabled?: boolean + hasServerComponents: boolean, + isAppPath: boolean ): Promise { if (serverless) { const ComponentMod = await requirePage(pathname, distDir, serverless) @@ -99,17 +99,21 @@ export async function loadComponents( } as LoadComponentsReturnType } - const [DocumentMod, AppMod, ComponentMod] = await Promise.all([ - Promise.resolve().then(() => - requirePage('/_document', distDir, serverless, appDirEnabled) - ), - Promise.resolve().then(() => - requirePage('/_app', distDir, serverless, appDirEnabled) - ), - Promise.resolve().then(() => - requirePage(pathname, distDir, serverless, appDirEnabled) - ), - ]) + let DocumentMod = {} + let AppMod = {} + if (!isAppPath) { + ;[DocumentMod, AppMod] = await Promise.all([ + Promise.resolve().then(() => + requirePage('/_document', distDir, serverless, false) + ), + Promise.resolve().then(() => + requirePage('/_app', distDir, serverless, false) + ), + ]) + } + const ComponentMod = await Promise.resolve().then(() => + requirePage(pathname, distDir, serverless, isAppPath) + ) const [buildManifest, reactLoadableManifest, serverComponentManifest] = await Promise.all([ @@ -126,20 +130,6 @@ export async function loadComponents( const { getServerSideProps, getStaticProps, getStaticPaths } = ComponentMod - let isAppPath = false - - if (appDirEnabled) { - const pagePath = getPagePath( - pathname, - distDir, - serverless, - false, - undefined, - appDirEnabled - ) - isAppPath = !!pagePath?.match(/server[/\\]app[/\\]/) - } - return { App, Document, diff --git a/packages/next/server/next-server.ts b/packages/next/server/next-server.ts index 48f19bf2e474..5e39ac360fc7 100644 --- a/packages/next/server/next-server.ts +++ b/packages/next/server/next-server.ts @@ -101,6 +101,7 @@ import ResponseCache from './response-cache' import { IncrementalCache } from './lib/incremental-cache' import { interpolateDynamicPath } from '../build/webpack/loaders/next-serverless-loader/utils' import { getNamedRouteRegex } from '../shared/lib/router/utils/route-regex' +import { normalizeAppPath } from '../shared/lib/router/utils/app-paths' if (shouldUseReactRoot) { ;(process.env as any).__NEXT_REACT_ROOT = 'true' @@ -247,12 +248,20 @@ export default class NextNodeServer extends BaseServer { if (!options.dev) { // pre-warm _document and _app as these will be // needed for most requests - loadComponents(this.distDir, '/_document', this._isLikeServerless).catch( - () => {} - ) - loadComponents(this.distDir, '/_app', this._isLikeServerless).catch( - () => {} - ) + loadComponents( + this.distDir, + '/_document', + this._isLikeServerless, + false, + false + ).catch(() => {}) + loadComponents( + this.distDir, + '/_app', + this._isLikeServerless, + false, + false + ).catch(() => {}) } } @@ -750,6 +759,7 @@ export default class NextNodeServer extends BaseServer { query, params, page, + isAppPath: false, }) if (handledAsEdgeFunction) { @@ -879,10 +889,11 @@ export default class NextNodeServer extends BaseServer { ctx: RequestContext, bubbleNoFallback: boolean ) { - const appPath = this.getOriginalAppPath(ctx.pathname) + const appPath = this.getOriginalAppPath(ctx.pathname) || undefined let page = ctx.pathname - if (typeof appPath === 'string') { + const isAppPath = typeof appPath === 'string' + if (isAppPath) { page = appPath } @@ -895,7 +906,9 @@ export default class NextNodeServer extends BaseServer { res: ctx.res, query: ctx.query, params: ctx.renderOpts.params, - page, + page: ctx.pathname, + appPath, + isAppPath: isAppPath, }) return null } @@ -906,13 +919,17 @@ export default class NextNodeServer extends BaseServer { protected async findPageComponents( pathname: string, - query: NextParsedUrlQuery = {}, - params: Params | null = null, - isAppDir: boolean = false + query: NextParsedUrlQuery, + params: Params, + isAppPath: boolean ): Promise { let paths = [ // try serving a static AMP version first - query.amp ? normalizePagePath(pathname) + '.amp' : null, + query.amp + ? (isAppPath + ? normalizeAppPath(pathname) + : normalizePagePath(pathname)) + '.amp' + : null, pathname, ].filter(Boolean) @@ -931,8 +948,8 @@ export default class NextNodeServer extends BaseServer { this.distDir, pagePath!, !this.renderOpts.dev && this._isLikeServerless, - this.renderOpts.serverComponents, - this.nextConfig.experimental.appDir + !!this.renderOpts.serverComponents, + isAppPath ) if ( @@ -958,7 +975,7 @@ export default class NextNodeServer extends BaseServer { } as NextParsedUrlQuery) : query), // For appDir params is excluded. - ...((isAppDir ? {} : params) || {}), + ...((isAppPath ? {} : params) || {}), }, } } catch (err) { @@ -1999,18 +2016,17 @@ export default class NextNodeServer extends BaseServer { query: ParsedUrlQuery params: Params | undefined page: string + isAppPath: boolean + appPath?: string onWarning?: (warning: Error) => void }): Promise { let middlewareInfo: ReturnType | undefined - let appPath = this.getOriginalAppPath(params.page) - - if (typeof appPath === 'string') { - params.page = appPath - } - await this.ensureEdgeFunction(params.page) + // If it's edge app route, use appPath to find the edge SSR page + const page = params.isAppPath ? params.appPath! : params.page + await this.ensureEdgeFunction(page) middlewareInfo = this.getEdgeFunctionInfo({ - page: params.page, + page: page, middleware: false, }) @@ -2024,6 +2040,7 @@ export default class NextNodeServer extends BaseServer { Object.assign({}, getRequestMeta(params.req, '__NEXT_INIT_QUERY') || {}) ).toString() const locale = params.query.__nextLocale + // Use original pathname (without `/page`) instead of appPath for url let normalizedPathname = params.page if (isDataReq) { diff --git a/packages/next/server/web-server.ts b/packages/next/server/web-server.ts index 7afff576aea2..0b966acb9b8e 100644 --- a/packages/next/server/web-server.ts +++ b/packages/next/server/web-server.ts @@ -406,8 +406,9 @@ export default class NextWebServer extends BaseServer { } protected async findPageComponents( pathname: string, - query?: NextParsedUrlQuery, - params?: Params | null + query: NextParsedUrlQuery, + params: Params | null, + _isAppPath: boolean ) { const result = await this.serverOptions.webServerConfig.loadComponent( pathname diff --git a/packages/next/shared/lib/page-path/get-page-paths.ts b/packages/next/shared/lib/page-path/get-page-paths.ts index 4d4906e3d868..3ea3d9bd8e72 100644 --- a/packages/next/shared/lib/page-path/get-page-paths.ts +++ b/packages/next/shared/lib/page-path/get-page-paths.ts @@ -7,17 +7,28 @@ import { join } from '../isomorphic/path' * allowed extensions. This can be used to check which one of the files exists * and to debug inspected locations. * + * For pages, map `/route` to [`/route.[ext]`, `/route/index.[ext]`] + * For app paths, map `/route/page` to [`/route/page.[ext]`] + * * @param normalizedPagePath Normalized page path (it will denormalize). * @param extensions Allowed extensions. */ -export function getPagePaths(normalizedPagePath: string, extensions: string[]) { +export function getPagePaths( + normalizedPagePath: string, + extensions: string[], + isAppDir: boolean +) { const page = denormalizePagePath(normalizedPagePath) return flatten( extensions.map((extension) => { - return !normalizedPagePath.endsWith('/index') - ? [`${page}.${extension}`, join(page, `index.${extension}`)] - : [join(page, `index.${extension}`)] + const appPage = `${page}.${extension}` + const folderIndexPage = join(page, `index.${extension}`) + + if (!normalizedPagePath.endsWith('/index')) { + return isAppDir ? [appPage] : [`${page}.${extension}`, folderIndexPage] + } + return [isAppDir ? appPage : folderIndexPage] }) ) } diff --git a/packages/react-dev-overlay/package.json b/packages/react-dev-overlay/package.json index 4955d77cb12a..eea59b23423c 100644 --- a/packages/react-dev-overlay/package.json +++ b/packages/react-dev-overlay/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-dev-overlay", - "version": "12.2.6-canary.8", + "version": "12.2.6-canary.9", "description": "A development-only overlay for developing React applications.", "repository": { "url": "vercel/next.js", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index 7147d242b639..8b57702884a6 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "12.2.6-canary.8", + "version": "12.2.6-canary.9", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c61b382d35ee..0a5bafd0ed59 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -32,7 +32,7 @@ importers: '@svgr/webpack': 5.5.0 '@swc/cli': 0.1.55 '@swc/core': 1.2.203 - '@swc/helpers': 0.4.2 + '@swc/helpers': 0.4.11 '@testing-library/react': 13.0.0 '@types/cheerio': 0.22.16 '@types/fs-extra': 8.1.0 @@ -186,7 +186,7 @@ importers: '@svgr/webpack': 5.5.0 '@swc/cli': 0.1.55_@swc+core@1.2.203 '@swc/core': 1.2.203 - '@swc/helpers': 0.4.2 + '@swc/helpers': 0.4.11 '@testing-library/react': 13.0.0_biqbaboplfbrettd7655fr4n2y '@types/cheerio': 0.22.16 '@types/fs-extra': 8.1.0 @@ -203,7 +203,7 @@ importers: '@types/trusted-types': 2.0.2 '@typescript-eslint/eslint-plugin': 4.29.1_qxyn66xcaddhgaahwkbomftvi4 '@typescript-eslint/parser': 4.29.1_6x3mpmmsttbpxxsctsorxedanu - '@vercel/fetch': 6.1.1_fii5qhbaymjqmfm7e2spxc5z4m + '@vercel/fetch': 6.1.1_wbqoqouw2iimn65bqgaw3lwmza '@webassemblyjs/ast': 1.11.1 '@webassemblyjs/floating-point-hex-parser': 1.11.1 '@webassemblyjs/helper-api-error': 1.11.1 @@ -312,7 +312,7 @@ importers: tailwindcss: 1.1.3 taskr: 1.1.0 tree-kill: 1.2.2 - tsec: 0.2.1_5lteecu6rkec2muzvz255n4mrq + tsec: 0.2.1_sbe2uaqno6akssxfwbhgeg7v2q turbo: 1.3.2-canary.1 typescript: 4.8.2 wait-port: 0.2.2 @@ -363,7 +363,7 @@ importers: packages/eslint-config-next: specifiers: - '@next/eslint-plugin-next': 12.2.6-canary.8 + '@next/eslint-plugin-next': 12.2.6-canary.9 '@rushstack/eslint-patch': ^1.1.3 '@typescript-eslint/parser': ^5.21.0 eslint-import-resolver-node: ^0.3.6 @@ -419,14 +419,14 @@ importers: '@hapi/accept': 5.0.2 '@napi-rs/cli': 2.7.0 '@napi-rs/triples': 1.1.0 - '@next/env': 12.2.6-canary.8 - '@next/polyfill-module': 12.2.6-canary.8 - '@next/polyfill-nomodule': 12.2.6-canary.8 - '@next/react-dev-overlay': 12.2.6-canary.8 - '@next/react-refresh-utils': 12.2.6-canary.8 - '@next/swc': 12.2.6-canary.8 + '@next/env': 12.2.6-canary.9 + '@next/polyfill-module': 12.2.6-canary.9 + '@next/polyfill-nomodule': 12.2.6-canary.9 + '@next/react-dev-overlay': 12.2.6-canary.9 + '@next/react-refresh-utils': 12.2.6-canary.9 + '@next/swc': 12.2.6-canary.9 '@segment/ajv-human-errors': 2.1.2 - '@swc/helpers': 0.4.3 + '@swc/helpers': 0.4.11 '@taskr/clear': 1.1.0 '@taskr/esnext': 1.1.0 '@taskr/watch': 1.1.0 @@ -581,7 +581,7 @@ importers: ws: 8.2.3 dependencies: '@next/env': link:../next-env - '@swc/helpers': 0.4.3 + '@swc/helpers': 0.4.11 caniuse-lite: 1.0.30001332 postcss: 8.4.14 styled-jsx: 5.0.5_@babel+core@7.18.0 @@ -3672,10 +3672,10 @@ packages: '@babel/helper-validator-identifier': 7.16.7 to-fast-properties: 2.0.0 - /@bazel/bazelisk/1.12.0: + /@bazel/bazelisk/1.12.1: resolution: { - integrity: sha512-7oQusq1e4AIyFgotxVV7Pc40Et0QyvoVjujL+7/qV5Vrbfh0Nj3CfqSgl63weEyI4r0+K6RlGVsjfRuBi05p5w==, + integrity: sha512-TGCwVeIiVeQUP6yLpxAg8yluFOC+tBQnWw5l8lqwMxKhRtOA+WaH1CJKAXeCBAaS2MxohhkXq44zj/7AM+t2jg==, } hasBin: true dev: true @@ -4545,7 +4545,7 @@ packages: collect-v8-coverage: 1.0.1 exit: 0.1.2 glob: 7.2.0 - graceful-fs: 4.2.9 + graceful-fs: 4.2.10 istanbul-lib-coverage: 3.0.0 istanbul-lib-instrument: 4.0.3 istanbul-lib-report: 3.0.0 @@ -4583,7 +4583,7 @@ packages: engines: { node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0 } dependencies: callsites: 3.1.0 - graceful-fs: 4.2.9 + graceful-fs: 4.2.10 source-map: 0.6.1 dev: true @@ -4608,7 +4608,7 @@ packages: engines: { node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0 } dependencies: '@jest/test-result': 27.0.6 - graceful-fs: 4.2.9 + graceful-fs: 4.2.10 jest-haste-map: 27.0.6 jest-runtime: 27.0.6 transitivePeerDependencies: @@ -4628,7 +4628,7 @@ packages: chalk: 4.1.2 convert-source-map: 1.7.0 fast-json-stable-stringify: 2.1.0 - graceful-fs: 4.2.9 + graceful-fs: 4.2.10 jest-haste-map: 27.0.6 jest-regex-util: 27.0.6 jest-util: 27.0.6 @@ -6626,23 +6626,13 @@ packages: '@swc/core-win32-x64-msvc': 1.2.203 dev: true - /@swc/helpers/0.4.2: - resolution: - { - integrity: sha512-556Az0VX7WR6UdoTn4htt/l3zPQ7bsQWK+HqdG4swV7beUCxo/BqmvbOpUkTIm/9ih86LIf1qsUnywNL3obGHw==, - } - dependencies: - tslib: 2.4.0 - dev: true - - /@swc/helpers/0.4.3: + /@swc/helpers/0.4.11: resolution: { - integrity: sha512-6JrF+fdUK2zbGpJIlN7G3v966PQjyx/dPt1T9km2wj+EUBqgrxCk3uX4Kct16MIm9gGxfKRcfax2hVf5jvlTzA==, + integrity: sha512-rEUrBSGIoSFuYxwBYtlUFMlE2CwGhmW+w9355/5oduSw8e5h2+Tj4UrAGNNgP9915++wj5vkQo0UuOBqOAq4nw==, } dependencies: tslib: 2.4.0 - dev: false /@szmarczak/http-timer/1.1.2: resolution: @@ -7285,6 +7275,16 @@ packages: form-data: 3.0.1 dev: true + /@types/node-fetch/2.6.2: + resolution: + { + integrity: sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A==, + } + dependencies: + '@types/node': 17.0.21 + form-data: 3.0.1 + dev: true + /@types/node/10.12.18: resolution: { @@ -7890,7 +7890,7 @@ packages: - supports-color dev: true - /@vercel/fetch/6.1.1_fii5qhbaymjqmfm7e2spxc5z4m: + /@vercel/fetch/6.1.1_wbqoqouw2iimn65bqgaw3lwmza: resolution: { integrity: sha512-nddCkgpA0aVIqOlzh+qVlzDNcQq0cSnqefM+x6SciGI4GCvVZeaZ7WEowgX8I/HwBAq8Uj5Bdnd+r0+sYsJsig==, @@ -7900,7 +7900,7 @@ packages: node-fetch: '2' dependencies: '@types/async-retry': 1.2.1 - '@types/node-fetch': 2.6.1 + '@types/node-fetch': 2.6.2 '@vercel/fetch-cached-dns': 2.0.2_node-fetch@2.6.7 '@vercel/fetch-retry': 5.0.3_node-fetch@2.6.7 agentkeepalive: 3.4.1 @@ -9142,7 +9142,7 @@ packages: babel-plugin-istanbul: 6.0.0 babel-preset-jest: 27.0.6_@babel+core@7.18.0 chalk: 4.1.2 - graceful-fs: 4.2.9 + graceful-fs: 4.2.10 slash: 3.0.0 transitivePeerDependencies: - supports-color @@ -11035,7 +11035,7 @@ packages: engines: { node: '>=4' } dependencies: dot-prop: 4.2.0 - graceful-fs: 4.2.9 + graceful-fs: 4.2.10 make-dir: 1.3.0 unique-string: 1.0.0 write-file-atomic: 2.4.3 @@ -11050,7 +11050,7 @@ packages: engines: { node: '>=8' } dependencies: dot-prop: 5.3.0 - graceful-fs: 4.2.9 + graceful-fs: 4.2.10 make-dir: 3.1.0 unique-string: 2.0.0 write-file-atomic: 3.0.3 @@ -12400,7 +12400,7 @@ packages: engines: { node: '>=10' } dependencies: globby: 11.1.0 - graceful-fs: 4.2.9 + graceful-fs: 4.2.10 is-glob: 4.0.3 is-path-cwd: 2.2.0 is-path-inside: 3.0.3 @@ -14775,7 +14775,7 @@ packages: integrity: sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==, } dependencies: - graceful-fs: 4.2.9 + graceful-fs: 4.2.10 jsonfile: 4.0.0 universalify: 0.1.2 dev: true @@ -14787,7 +14787,7 @@ packages: } engines: { node: '>=6 <7 || >=8' } dependencies: - graceful-fs: 4.2.9 + graceful-fs: 4.2.10 jsonfile: 4.0.0 universalify: 0.1.2 dev: true @@ -14813,7 +14813,7 @@ packages: engines: { node: '>=10' } dependencies: at-least-node: 1.0.0 - graceful-fs: 4.2.9 + graceful-fs: 4.2.10 jsonfile: 6.0.1 universalify: 2.0.0 dev: true @@ -15531,6 +15531,13 @@ packages: url-parse-lax: 3.0.0 dev: true + /graceful-fs/4.2.10: + resolution: + { + integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==, + } + dev: true + /graceful-fs/4.2.9: resolution: { @@ -15599,7 +15606,7 @@ packages: source-map: 0.6.1 wordwrap: 1.0.0 optionalDependencies: - uglify-js: 3.7.3 + uglify-js: 3.17.0 dev: true /har-schema/2.0.0: @@ -17760,7 +17767,7 @@ packages: chalk: 4.1.2 deepmerge: 4.2.2 glob: 7.2.0 - graceful-fs: 4.2.9 + graceful-fs: 4.2.10 is-ci: 3.0.0 jest-circus: 27.0.6 jest-environment-jsdom: 27.0.6 @@ -17929,7 +17936,7 @@ packages: '@types/node': 17.0.21 anymatch: 3.1.1 fb-watchman: 2.0.1 - graceful-fs: 4.2.9 + graceful-fs: 4.2.10 jest-regex-util: 27.0.6 jest-serializer: 27.0.6 jest-util: 27.0.6 @@ -18030,7 +18037,7 @@ packages: '@jest/types': 26.6.2 '@types/stack-utils': 2.0.0 chalk: 4.1.2 - graceful-fs: 4.2.9 + graceful-fs: 4.2.10 micromatch: 4.0.4 pretty-format: 26.6.2 slash: 3.0.0 @@ -18048,7 +18055,7 @@ packages: '@jest/types': 27.0.6 '@types/stack-utils': 2.0.0 chalk: 4.1.2 - graceful-fs: 4.2.9 + graceful-fs: 4.2.10 micromatch: 4.0.4 pretty-format: 27.5.1 slash: 3.0.0 @@ -18066,7 +18073,7 @@ packages: '@jest/types': 28.1.3 '@types/stack-utils': 2.0.0 chalk: 4.1.2 - graceful-fs: 4.2.9 + graceful-fs: 4.2.10 micromatch: 4.0.4 pretty-format: 28.1.3 slash: 3.0.0 @@ -18150,7 +18157,7 @@ packages: '@jest/types': 27.0.6 chalk: 4.1.2 escalade: 3.1.1 - graceful-fs: 4.2.9 + graceful-fs: 4.2.10 jest-pnp-resolver: 1.2.2_jest-resolve@27.0.6 jest-util: 27.0.6 jest-validate: 27.0.6 @@ -18174,7 +18181,7 @@ packages: chalk: 4.1.2 emittery: 0.8.1 exit: 0.1.2 - graceful-fs: 4.2.9 + graceful-fs: 4.2.10 jest-docblock: 27.0.6 jest-environment-jsdom: 27.0.6 jest-environment-node: 27.0.6 @@ -18215,7 +18222,7 @@ packages: collect-v8-coverage: 1.0.1 exit: 0.1.2 glob: 7.2.0 - graceful-fs: 4.2.9 + graceful-fs: 4.2.10 jest-haste-map: 27.0.6 jest-message-util: 27.0.6 jest-mock: 27.0.6 @@ -18239,7 +18246,7 @@ packages: engines: { node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0 } dependencies: '@types/node': 17.0.21 - graceful-fs: 4.2.9 + graceful-fs: 4.2.10 dev: true /jest-snapshot/27.0.6: @@ -18262,7 +18269,7 @@ packages: babel-preset-current-node-syntax: 1.0.1_@babel+core@7.18.0 chalk: 4.1.2 expect: 27.0.6 - graceful-fs: 4.2.9 + graceful-fs: 4.2.10 jest-diff: 27.0.6 jest-get-type: 27.0.6 jest-haste-map: 27.0.6 @@ -18287,7 +18294,7 @@ packages: '@jest/types': 27.0.6 '@types/node': 17.0.21 chalk: 4.1.2 - graceful-fs: 4.2.9 + graceful-fs: 4.2.10 is-ci: 3.0.0 picomatch: 2.2.3 dev: true @@ -18628,7 +18635,7 @@ packages: integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==, } optionalDependencies: - graceful-fs: 4.2.9 + graceful-fs: 4.2.10 dev: true /jsonfile/6.0.1: @@ -18639,7 +18646,7 @@ packages: dependencies: universalify: 1.0.0 optionalDependencies: - graceful-fs: 4.2.9 + graceful-fs: 4.2.10 dev: true /jsonparse/1.3.1: @@ -19116,7 +19123,7 @@ packages: resolution: { integrity: sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= } engines: { node: '>=0.10.0' } dependencies: - graceful-fs: 4.2.9 + graceful-fs: 4.2.10 parse-json: 2.2.0 pify: 2.3.0 pinkie-promise: 2.0.1 @@ -19127,7 +19134,7 @@ packages: resolution: { integrity: sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg= } engines: { node: '>=4' } dependencies: - graceful-fs: 4.2.9 + graceful-fs: 4.2.10 parse-json: 2.2.0 pify: 2.3.0 strip-bom: 3.0.0 @@ -19137,7 +19144,7 @@ packages: resolution: { integrity: sha1-L19Fq5HjMhYjT9U62rZo607AmTs= } engines: { node: '>=4' } dependencies: - graceful-fs: 4.2.9 + graceful-fs: 4.2.10 parse-json: 4.0.0 pify: 3.0.0 strip-bom: 3.0.0 @@ -19150,7 +19157,7 @@ packages: } engines: { node: '>=8' } dependencies: - graceful-fs: 4.2.9 + graceful-fs: 4.2.10 parse-json: 5.0.0 strip-bom: 4.0.0 type-fest: 0.6.0 @@ -20842,7 +20849,7 @@ packages: dependencies: env-paths: 2.2.0 glob: 7.2.0 - graceful-fs: 4.2.9 + graceful-fs: 4.2.10 mkdirp: 0.5.5 nopt: 4.0.3 npmlog: 4.1.2 @@ -20863,7 +20870,7 @@ packages: dependencies: env-paths: 2.2.0 glob: 7.2.0 - graceful-fs: 4.2.9 + graceful-fs: 4.2.10 nopt: 5.0.0 npmlog: 4.1.2 request: 2.88.2 @@ -21071,7 +21078,7 @@ packages: } dependencies: byline: 5.0.0 - graceful-fs: 4.2.9 + graceful-fs: 4.2.10 node-gyp: 5.1.1 resolve-from: 4.0.0 slide: 1.1.6 @@ -22262,7 +22269,7 @@ packages: resolution: { integrity: sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= } engines: { node: '>=0.10.0' } dependencies: - graceful-fs: 4.2.9 + graceful-fs: 4.2.10 pify: 2.3.0 pinkie-promise: 2.0.1 dev: true @@ -24383,7 +24390,7 @@ packages: normalize-package-data: 2.5.0 npm-normalize-package-bin: 1.0.1 optionalDependencies: - graceful-fs: 4.2.9 + graceful-fs: 4.2.10 dev: true /read-package-json/3.0.0: @@ -24562,7 +24569,7 @@ packages: dependencies: debuglog: 1.0.1 dezalgo: 1.0.3 - graceful-fs: 4.2.9 + graceful-fs: 4.2.10 once: 1.4.0 dev: true @@ -27192,7 +27199,7 @@ packages: } engines: { node: '>=8' } dependencies: - graceful-fs: 4.2.9 + graceful-fs: 4.2.10 is-stream: 2.0.0 make-dir: 3.1.0 temp-dir: 1.0.0 @@ -27702,7 +27709,7 @@ packages: minimist: 1.2.6 strip-bom: 3.0.0 - /tsec/0.2.1_5lteecu6rkec2muzvz255n4mrq: + /tsec/0.2.1_sbe2uaqno6akssxfwbhgeg7v2q: resolution: { integrity: sha512-RP9vhbRbRI9VH4CfOlQvo5W9HdfiPKq0gdiUOWI5oKmLaZKNFN8CsPwBfT5ySmhnKNwmmAS/BtY3WoTfABwwig==, @@ -27712,7 +27719,7 @@ packages: '@bazel/bazelisk': '>=1.7.5' typescript: '>=3.9.2' dependencies: - '@bazel/bazelisk': 1.12.0 + '@bazel/bazelisk': 1.12.1 glob: 7.2.0 minimatch: 3.1.2 typescript: 4.8.2 @@ -28112,17 +28119,14 @@ packages: } dev: true - /uglify-js/3.7.3: + /uglify-js/3.17.0: resolution: { - integrity: sha512-7tINm46/3puUA4hCkKYo4Xdts+JDaVC9ZPRcG8Xw9R4nhO/gZgUM3TENq8IF4Vatk8qCig4MzP/c8G4u2BkVQg==, + integrity: sha512-aTeNPVmgIMPpm1cxXr2Q/nEbvkmV8yq66F3om7X3P/cvOXQ0TMQ64Wk63iyT1gPlmdmGzjGpyLh1f3y8MZWXGg==, } engines: { node: '>=0.8.0' } hasBin: true requiresBuild: true - dependencies: - commander: 2.20.3 - source-map: 0.6.1 dev: true optional: true @@ -29445,7 +29449,7 @@ packages: engines: { node: '>=6' } dependencies: detect-indent: 5.0.0 - graceful-fs: 4.2.9 + graceful-fs: 4.2.10 make-dir: 2.1.0 pify: 4.0.1 sort-keys: 2.0.0 @@ -29460,7 +29464,7 @@ packages: engines: { node: '>=8.3' } dependencies: detect-indent: 6.0.0 - graceful-fs: 4.2.9 + graceful-fs: 4.2.10 is-plain-obj: 2.1.0 make-dir: 3.1.0 sort-keys: 4.2.0 diff --git a/scripts/trace-dd.mjs b/scripts/trace-dd.mjs index 3b8336b70a36..a08c09c0fd75 100644 --- a/scripts/trace-dd.mjs +++ b/scripts/trace-dd.mjs @@ -99,7 +99,7 @@ const collectTraces = async (filePath, metadata) => { const traces = new Map() const rootTraces = [] - // Input trace file contains newline-seperated sets of traces, where each line is valid JSON + // Input trace file contains newline-separated sets of traces, where each line is valid JSON // type of Array. Read it line-by-line to manually reconstruct trace trees. // // We have to read through end of the trace - diff --git a/scripts/trace-to-event-format.mjs b/scripts/trace-to-event-format.mjs index 2361ed71129c..11652ebeaf3a 100644 --- a/scripts/trace-to-event-format.mjs +++ b/scripts/trace-to-event-format.mjs @@ -12,7 +12,7 @@ const createEvent = (trace, ph, cat) => ({ ph, // process id. We don't collect this for now, putting arbitrary numbers. pid: 1, - // thread id. We don't collect this for now, putting arbitrary numebers. + // thread id. We don't collect this for now, putting arbitrary numbers. tid: 10, args: trace.tags, }) @@ -112,7 +112,7 @@ const collectTraces = async (filePath, outFilePath, metadata) => { const traces = new Map() const rootTraces = [] - // Input trace file contains newline-seperated sets of traces, where each line is valid JSON + // Input trace file contains newline-separated sets of traces, where each line is valid JSON // type of Array. Read it line-by-line to manually reconstruct trace trees. // // We have to read through end of the trace - diff --git a/test/e2e/app-dir/app-rendering/pages/.gitkeep b/test/e2e/app-dir/app-rendering/pages/.gitkeep deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/test/e2e/app-dir/rendering.test.ts b/test/e2e/app-dir/rendering.test.ts index 10ec1b72df4f..69f1f0dd3859 100644 --- a/test/e2e/app-dir/rendering.test.ts +++ b/test/e2e/app-dir/rendering.test.ts @@ -22,7 +22,6 @@ describe('app dir rendering', () => { next = await createNext({ files: { app: new FileRef(path.join(__dirname, 'app-rendering/app')), - pages: new FileRef(path.join(__dirname, 'app-rendering/pages')), 'next.config.js': new FileRef( path.join(__dirname, 'app-rendering/next.config.js') ), diff --git a/test/e2e/app-dir/rsc-basic.test.ts b/test/e2e/app-dir/rsc-basic.test.ts index 09dd011d5229..4b9b3471992a 100644 --- a/test/e2e/app-dir/rsc-basic.test.ts +++ b/test/e2e/app-dir/rsc-basic.test.ts @@ -39,7 +39,6 @@ describe('app dir - react server components', () => { next = await createNext({ files: { node_modules_bak: new FileRef(path.join(appDir, 'node_modules_bak')), - pages: new FileRef(path.join(appDir, 'pages')), public: new FileRef(path.join(appDir, 'public')), components: new FileRef(path.join(appDir, 'components')), app: new FileRef(path.join(appDir, 'app')), @@ -58,6 +57,7 @@ describe('app dir - react server components', () => { start: 'next start', }, }, + installCommand: 'yarn', startCommand: (global as any).isNextDev ? 'yarn dev' : 'yarn start', buildCommand: 'yarn build', }) @@ -167,7 +167,7 @@ describe('app dir - react server components', () => { // expect(modFromClient[1]).not.toBe(modFromServer[1]) }) - it('should be able to navigate between rsc pages', async () => { + it('should be able to navigate between rsc routes', async () => { const browser = await webdriver(next.url, '/root') await browser.waitForElementByCss('#goto-next-link').click() @@ -262,6 +262,14 @@ describe('app dir - react server components', () => { expect(manipulated).toBe(undefined) }) + it('should render built-in 404 page for missing route if pagesDir is not presented', async () => { + const res = await fetchViaHTTP(next.url, '/does-not-exist') + + expect(res.status).toBe(404) + const html = await res.text() + expect(html).toContain('This page could not be found') + }) + it('should suspense next/image in server components', async () => { const imageHTML = await renderViaHTTP(next.url, '/next-api/image') const imageTag = getNodeBySelector(imageHTML, '#myimg') diff --git a/test/e2e/app-dir/rsc-basic/pages/.gitkeep b/test/e2e/app-dir/rsc-basic/pages/.gitkeep deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/test/integration/script-loader/strictmode/next.config.js b/test/integration/script-loader/base/next.config.js similarity index 100% rename from test/integration/script-loader/strictmode/next.config.js rename to test/integration/script-loader/base/next.config.js diff --git a/test/integration/script-loader/base/pages/page10.js b/test/integration/script-loader/base/pages/page10.js index dd10c2f6a1d1..e2fdde0e776f 100644 --- a/test/integration/script-loader/base/pages/page10.js +++ b/test/integration/script-loader/base/pages/page10.js @@ -1,11 +1,6 @@ import Script from 'next/script' import Link from 'next/link' -if (typeof window !== 'undefined') { - window.remoteScriptsOnReadyCalls ??= 0 - window.inlineScriptsOnReadyCalls ??= 0 -} - const Page = () => { return (
@@ -14,6 +9,7 @@ const Page = () => {