diff --git a/docs/basic-features/environment-variables.md b/docs/basic-features/environment-variables.md
index 8d378f91d7ac6..a68cb4e7d0e8b 100644
--- a/docs/basic-features/environment-variables.md
+++ b/docs/basic-features/environment-variables.md
@@ -46,6 +46,11 @@ export async function getStaticProps() {
}
```
+> **Note**: In order to keep server-only secrets safe, Next.js replaces `process.env.*` with the correct values
+> at build time. This means that `process.env` is not a standard JavaScript object, so you’re not able to
+> use [object destructuring](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment).
+> Environment variables must be referenced as e.g. `process.env.NEXT_PUBLIC_PUBLISHABLE_KEY`, _not_ `const { NEXT_PUBLIC_PUBLISHABLE_KEY } = process.env`.
+
> **Note**: Next.js will automatically expand variables (`$VAR`) inside of your `.env*` files.
> This allows you to reference other secrets, like so:
>
diff --git a/errors/can-not-output-to-static.md b/errors/can-not-output-to-static.md
new file mode 100644
index 0000000000000..b949bc06ffb7a
--- /dev/null
+++ b/errors/can-not-output-to-static.md
@@ -0,0 +1,15 @@
+# Cannot output to /static
+
+#### Why This Error Occurred
+
+Either you set `distDir` to `static` in your `next.config.js` or during `next export` you tried to export to the `static` directory.
+
+This is not allowed due to `static` being a special folder in Next.js used to serve static assets.
+
+#### Possible Ways to Fix It
+
+Use a different `distDir` or export to a different folder.
+
+### Useful Links
+
+- [Static file serving docs](https://nextjs.org/docs/basic-features/static-file-serving)
diff --git a/examples/blog-starter-typescript/package.json b/examples/blog-starter-typescript/package.json
index 561fd67d33286..9b8cd0f86c8a7 100644
--- a/examples/blog-starter-typescript/package.json
+++ b/examples/blog-starter-typescript/package.json
@@ -24,6 +24,8 @@
"@types/node": "^14.0.1",
"@types/react": "^16.9.35",
"@types/react-dom": "^16.9.8",
+ "autoprefixer": "^10.2.1",
+ "postcss": "^8.2.4",
"postcss-preset-env": "^6.7.0",
"tailwindcss": "^2.0.2"
},
diff --git a/examples/blog-starter/package.json b/examples/blog-starter/package.json
index 134d656d9364f..a49f724f21bfd 100644
--- a/examples/blog-starter/package.json
+++ b/examples/blog-starter/package.json
@@ -17,10 +17,10 @@
"remark-html": "13.0.1"
},
"devDependencies": {
- "autoprefixer": "10.0.4",
- "postcss": "8.1.10",
+ "autoprefixer": "^10.2.1",
+ "postcss": "^8.2.4",
"postcss-preset-env": "^6.7.0",
- "tailwindcss": "2.0.1"
+ "tailwindcss": "^2.0.2"
},
"license": "MIT"
}
diff --git a/examples/cms-graphcms/components/avatar.js b/examples/cms-graphcms/components/avatar.js
index 2dcc7eee10693..6777f50313593 100644
--- a/examples/cms-graphcms/components/avatar.js
+++ b/examples/cms-graphcms/components/avatar.js
@@ -1,7 +1,16 @@
+import Image from 'next/image'
+
export default function Avatar({ name, picture }) {
return (
-
+
+
+
{name}
)
diff --git a/examples/cms-graphcms/components/cover-image.js b/examples/cms-graphcms/components/cover-image.js
index 560c40d4c711b..a4cda9cc8ba75 100644
--- a/examples/cms-graphcms/components/cover-image.js
+++ b/examples/cms-graphcms/components/cover-image.js
@@ -1,9 +1,10 @@
-import cn from 'classnames'
+import Image from 'next/image'
import Link from 'next/link'
+import cn from 'classnames'
export default function CoverImage({ title, url, slug }) {
const image = (
-
More Stories
-
+
{posts.map((post) => (
{
- const server = express()
-
- server.get('/service-worker.js', (req, res) => {
- app.serveStatic(req, res, './.next/service-worker.js')
- })
-
- const serviceWorkers = [
- {
- filename: 'service-worker.js',
- path: './.next/service-worker.js',
- },
- {
- filename: 'firebase-messaging-sw.js',
- path: './static/firebase-messaging-sw.js',
- },
- ]
-
- serviceWorkers.forEach(({ filename, path }) => {
- server.get(`/${filename}`, (req, res) => {
- app.serveStatic(req, res, path)
- })
- })
-
- server.get('*', (req, res) => {
- return handle(req, res)
- })
-
- server.listen(port, (err) => {
- if (err) throw err
- console.log(`> Ready on http://localhost:${port}`)
- })
-})
diff --git a/examples/with-graphql-hooks/components/app.js b/examples/with-graphql-hooks/components/app.js
index 97c5647a6f01a..5a0ce7dee5c9b 100644
--- a/examples/with-graphql-hooks/components/app.js
+++ b/examples/with-graphql-hooks/components/app.js
@@ -1,44 +1,3 @@
export default function App({ children }) {
- return (
-
- {children}
-
-
- )
+ return {children}
}
diff --git a/examples/with-graphql-hooks/components/post-list.js b/examples/with-graphql-hooks/components/post-list.js
index 45707ece6fec2..3cf8a132433b1 100644
--- a/examples/with-graphql-hooks/components/post-list.js
+++ b/examples/with-graphql-hooks/components/post-list.js
@@ -4,9 +4,9 @@ import ErrorMessage from './error-message'
import PostUpvoter from './post-upvoter'
import Submit from './submit'
-export const allPostsQuery = `
+export const ALL_POSTS_QUERY = `
query allPosts($first: Int!, $skip: Int!) {
- allPosts(orderBy: createdAt_DESC, first: $first, skip: $skip) {
+ allPosts(orderBy: { createdAt: desc }, first: $first, skip: $skip) {
id
title
votes
@@ -32,7 +32,7 @@ export const allPostsQueryOptions = (skip = 0) => ({
export default function PostList() {
const [skip, setSkip] = useState(0)
const { loading, error, data, refetch } = useQuery(
- allPostsQuery,
+ ALL_POSTS_QUERY,
allPostsQueryOptions(skip)
)
@@ -40,8 +40,8 @@ export default function PostList() {
if (!data) return Loading
const { allPosts, _allPostsMeta } = data
-
const areMorePosts = allPosts.length < _allPostsMeta.count
+
return (
<>
{areMorePosts ? (
- setSkip(skip + 10)}>
+ setSkip(skip + 10)}>
{' '}
{loading && !data ? 'Loading...' : 'Show More'}{' '}
) : (
''
)}
-
>
)
diff --git a/examples/with-graphql-hooks/components/post-upvoter.js b/examples/with-graphql-hooks/components/post-upvoter.js
index 98ea3ddf9656f..d2266c40a9fef 100644
--- a/examples/with-graphql-hooks/components/post-upvoter.js
+++ b/examples/with-graphql-hooks/components/post-upvoter.js
@@ -2,11 +2,11 @@ import React from 'react'
import { useMutation } from 'graphql-hooks'
const UPDATE_POST = `
- mutation updatePost($id: ID!, $votes: Int) {
- updatePost(id: $id, votes: $votes) {
+ mutation votePost($id: String!) {
+ votePost(id: $id) {
id
- __typename
votes
+ __typename
}
}
`
@@ -16,12 +16,12 @@ export default function PostUpvoter({ votes, id, onUpdate }) {
return (
{
try {
const result = await updatePost({
variables: {
id,
- votes: votes + 1,
},
})
@@ -32,26 +32,6 @@ export default function PostUpvoter({ votes, id, onUpdate }) {
}}
>
{votes}
-
)
}
diff --git a/examples/with-graphql-hooks/lib/graphql-client.js b/examples/with-graphql-hooks/lib/graphql-client.js
index e7d8ad8258495..50750d6afaada 100644
--- a/examples/with-graphql-hooks/lib/graphql-client.js
+++ b/examples/with-graphql-hooks/lib/graphql-client.js
@@ -7,7 +7,7 @@ let graphQLClient
function createClient(initialState) {
return new GraphQLClient({
ssrMode: typeof window === 'undefined',
- url: 'https://api.graph.cool/simple/v1/cixmkt2ul01q00122mksg82pn', // Server URL (must be absolute)
+ url: 'https://nextjs-graphql-with-prisma-simple.vercel.app/api', // Server URL (must be absolute)
cache: memCache({ initialState }),
})
}
diff --git a/examples/with-graphql-hooks/package.json b/examples/with-graphql-hooks/package.json
index 2bc97a22cd0dc..8960f769307c4 100644
--- a/examples/with-graphql-hooks/package.json
+++ b/examples/with-graphql-hooks/package.json
@@ -8,11 +8,11 @@
},
"license": "MIT",
"dependencies": {
- "graphql-hooks": "^4.5.0",
- "graphql-hooks-memcache": "^1.3.3",
+ "graphql-hooks": "^5.1.0",
+ "graphql-hooks-memcache": "^2.1.0",
"next": "latest",
"prop-types": "^15.7.2",
- "react": "^16.8.2",
- "react-dom": "^16.8.2"
+ "react": "^17.0.1",
+ "react-dom": "^17.0.1"
}
}
diff --git a/examples/with-graphql-hooks/pages/_app.js b/examples/with-graphql-hooks/pages/_app.js
index 9420b692f11ee..c72524f1a03ac 100644
--- a/examples/with-graphql-hooks/pages/_app.js
+++ b/examples/with-graphql-hooks/pages/_app.js
@@ -1,3 +1,4 @@
+import '../styles.css'
import { ClientContext } from 'graphql-hooks'
import { useGraphQLClient } from '../lib/graphql-client'
diff --git a/examples/with-graphql-hooks/pages/index.js b/examples/with-graphql-hooks/pages/index.js
index 85aa71d251cb4..dc9ec59025d1b 100644
--- a/examples/with-graphql-hooks/pages/index.js
+++ b/examples/with-graphql-hooks/pages/index.js
@@ -3,7 +3,7 @@ import graphQLRequest from '../lib/graphql-request'
import App from '../components/app'
import Header from '../components/header'
import PostList, {
- allPostsQuery,
+ ALL_POSTS_QUERY,
allPostsQueryOptions,
} from '../components/post-list'
@@ -19,7 +19,7 @@ export default function Home() {
export async function getStaticProps() {
const client = initializeGraphQL()
- await graphQLRequest(client, allPostsQuery, allPostsQueryOptions())
+ await graphQLRequest(client, ALL_POSTS_QUERY, allPostsQueryOptions())
return {
props: {
diff --git a/examples/with-graphql-hooks/styles.css b/examples/with-graphql-hooks/styles.css
new file mode 100644
index 0000000000000..dd28550255ba9
--- /dev/null
+++ b/examples/with-graphql-hooks/styles.css
@@ -0,0 +1,104 @@
+* {
+ font-family: Menlo, Monaco, 'Lucida Console', 'Liberation Mono',
+ 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace,
+ serif;
+}
+body {
+ margin: 0;
+ padding: 25px 50px;
+}
+a {
+ color: #22bad9;
+}
+p {
+ font-size: 14px;
+ line-height: 24px;
+}
+article {
+ margin: 0 auto;
+ max-width: 650px;
+}
+form {
+ border-bottom: 1px solid #ececec;
+ padding-bottom: 20px;
+ margin-bottom: 20px;
+}
+h1 {
+ font-size: 20px;
+}
+input {
+ display: block;
+ margin-bottom: 10px;
+}
+section {
+ padding-bottom: 20px;
+}
+li {
+ display: block;
+ margin-bottom: 10px;
+}
+div {
+ align-items: center;
+ display: flex;
+}
+a {
+ font-size: 14px;
+ margin-right: 10px;
+ text-decoration: none;
+ padding-bottom: 0;
+ border: 0;
+}
+span {
+ font-size: 14px;
+ margin-right: 5px;
+}
+ul {
+ margin: 0;
+ padding: 0;
+}
+
+button:before {
+ align-self: center;
+ border-style: solid;
+ content: '';
+ height: 0;
+ margin-right: 5px;
+ width: 0;
+}
+
+button {
+ align-items: center;
+ background-color: #22bad9;
+ border: 0;
+ color: white;
+ display: flex;
+ padding: 5px 7px;
+}
+button:active {
+ background-color: #1b9db7;
+ transition: background-color 0.3s;
+}
+
+button:focus {
+ outline: none;
+}
+
+button:active {
+ background-color: transparent;
+}
+
+.upvote {
+ background-color: transparent;
+ border: 1px solid #e4e4e4;
+ color: #000;
+}
+
+.upvote:before {
+ border-width: 0 4px 6px 4px;
+ border-color: transparent transparent #000000 transparent;
+}
+
+.more:before {
+ border-width: 6px 4px 0 4px;
+ border-color: #ffffff transparent transparent transparent;
+}
diff --git a/examples/with-supabase-auth-realtime-db/README.md b/examples/with-supabase-auth-realtime-db/README.md
index a84917ffb2ea9..537029ce5f8d5 100644
--- a/examples/with-supabase-auth-realtime-db/README.md
+++ b/examples/with-supabase-auth-realtime-db/README.md
@@ -38,7 +38,7 @@ Sign up to Supabase - [https://app.supabase.io](https://app.supabase.io) and cre
Once your database has started, run the "Slack Clone" quickstart.
-![Slack Clone Quick Start](https://user-images.githubusercontent.com/10214025/88916135-1b1d7a00-d298-11ea-82e7-e2c18314e805.png)
+![Slack Clone Quick Start](./docs/quickstart.png)
### Step 3. Set up environment variables
diff --git a/examples/with-supabase-auth-realtime-db/docs/quickstart.png b/examples/with-supabase-auth-realtime-db/docs/quickstart.png
new file mode 100644
index 0000000000000..e406fc9c0826f
Binary files /dev/null and b/examples/with-supabase-auth-realtime-db/docs/quickstart.png differ
diff --git a/examples/with-supabase-auth-realtime-db/package.json b/examples/with-supabase-auth-realtime-db/package.json
index 38ba2ea0b6623..cd117d52fadca 100644
--- a/examples/with-supabase-auth-realtime-db/package.json
+++ b/examples/with-supabase-auth-realtime-db/package.json
@@ -12,7 +12,11 @@
"next": "latest",
"react": "^16.13.1",
"react-dom": "^16.13.1",
- "sass": "^1.26.2",
- "tailwindcss": "^1.1.4"
+ "sass": "^1.26.2"
+ },
+ "devDependencies": {
+ "autoprefixer": "10.1.0",
+ "postcss": "8.2.2",
+ "tailwindcss": "2.0.2"
}
}
diff --git a/examples/with-supabase-auth-realtime-db/postcss.config.js b/examples/with-supabase-auth-realtime-db/postcss.config.js
new file mode 100644
index 0000000000000..33ad091d26d8a
--- /dev/null
+++ b/examples/with-supabase-auth-realtime-db/postcss.config.js
@@ -0,0 +1,6 @@
+module.exports = {
+ plugins: {
+ tailwindcss: {},
+ autoprefixer: {},
+ },
+}
diff --git a/examples/with-supabase-auth-realtime-db/tailwind.config.js b/examples/with-supabase-auth-realtime-db/tailwind.config.js
new file mode 100644
index 0000000000000..c00fe06cdbeb2
--- /dev/null
+++ b/examples/with-supabase-auth-realtime-db/tailwind.config.js
@@ -0,0 +1,11 @@
+module.exports = {
+ purge: ['./pages/**/*.js', './components/**/*.js'],
+ darkMode: false, // or 'media' or 'class'
+ theme: {
+ extend: {},
+ },
+ variants: {
+ extend: {},
+ },
+ plugins: [],
+}
diff --git a/examples/with-tailwindcss/README.md b/examples/with-tailwindcss/README.md
index e185165506a38..06c729ea5bbee 100644
--- a/examples/with-tailwindcss/README.md
+++ b/examples/with-tailwindcss/README.md
@@ -1,6 +1,6 @@
# Tailwind CSS example
-This is an example of using [Tailwind CSS](https://tailwindcss.com) in a Next.js project.
+This example is a basic starting point for using [Tailwind CSS](https://tailwindcss.com) with Next.js.
## Deploy your own
@@ -22,8 +22,9 @@ Deploy it to the cloud with [Vercel](https://vercel.com/new?utm_source=github&ut
## Notes
-This example is a basic starting point for using [Tailwind CSS](https://tailwindcss.com) with Next.js. It includes the following [PostCSS](https://github.com/postcss/postcss) plugins:
+This example includes the following [PostCSS](https://github.com/postcss/postcss) plugins:
-- [postcss-preset-env](https://preset-env.cssdb.org/) - Adds stage 2+ features and autoprefixes
+- [tailwindcss](https://tailwindcss.com) - utility-first CSS framework
+- [autoprefixer](https://github.com/postcss/autoprefixer) - plugin to parse CSS and add vendor prefixes to CSS rules using values from [Can I Use](https://caniuse.com).
To control the generated stylesheet's filesize, this example uses Tailwind CSS' [`purge` option](https://tailwindcss.com/docs/controlling-file-size/#removing-unused-css) to remove unused CSS.
diff --git a/examples/with-three-js/components/Bird.js b/examples/with-three-js/components/Bird.js
index e2e71022ece83..024dcd5f06b9d 100644
--- a/examples/with-three-js/components/Bird.js
+++ b/examples/with-three-js/components/Bird.js
@@ -25,14 +25,14 @@ const Bird = ({ speed, factor, url, ...props }) => {
-
+
diff --git a/examples/with-three-js/next.config.js b/examples/with-three-js/next.config.js
index e87bd46b091ae..588b99c9e65bd 100644
--- a/examples/with-three-js/next.config.js
+++ b/examples/with-three-js/next.config.js
@@ -1,7 +1,3 @@
-const withTM = require('next-transpile-modules')([
- 'drei',
- 'three',
- 'postprocessing',
-])
+const withTM = require('next-transpile-modules')(['drei', 'three'])
module.exports = withTM()
diff --git a/examples/with-three-js/package.json b/examples/with-three-js/package.json
index 5d4dac6aba916..8ed25de54441e 100644
--- a/examples/with-three-js/package.json
+++ b/examples/with-three-js/package.json
@@ -8,15 +8,15 @@
"start": "next start"
},
"dependencies": {
- "drei": "0.0.60",
- "next": "9.4.4",
- "react": "16.13.1",
- "react-dom": "16.13.1",
- "react-three-fiber": "4.2.12",
- "three": "0.118.3"
+ "drei": "2.2.13",
+ "next": "10.0.5",
+ "react": "17.0.1",
+ "react-dom": "17.0.1",
+ "react-three-fiber": "5.3.11",
+ "three": "0.124.0"
},
"devDependencies": {
- "next-transpile-modules": "4.0.2"
+ "next-transpile-modules": "6.0.0"
},
"license": "MIT"
}
diff --git a/examples/with-three-js/pages/birds.js b/examples/with-three-js/pages/birds.js
index 1e95d62b3e5bd..0f7f2717c7c13 100644
--- a/examples/with-three-js/pages/birds.js
+++ b/examples/with-three-js/pages/birds.js
@@ -1,7 +1,7 @@
import dynamic from 'next/dynamic'
import { Suspense } from 'react'
import { Canvas } from 'react-three-fiber'
-import { OrbitControls, StandardEffects } from 'drei'
+import { OrbitControls } from 'drei'
const Bird = dynamic(() => import('../components/Bird'), { ssr: false })
@@ -41,7 +41,6 @@ const BirdsPage = (props) => {
-
>
diff --git a/examples/with-three-js/pages/boxes.js b/examples/with-three-js/pages/boxes.js
index 03b8ae138b479..f2cc839f4993e 100644
--- a/examples/with-three-js/pages/boxes.js
+++ b/examples/with-three-js/pages/boxes.js
@@ -1,6 +1,6 @@
-import { useRef, useState, Suspense } from 'react'
+import { useRef, useState } from 'react'
import { Canvas, useFrame } from 'react-three-fiber'
-import { OrbitControls, StandardEffects, Box } from 'drei'
+import { OrbitControls, Box } from 'drei'
const MyBox = (props) => {
const mesh = useRef()
@@ -39,9 +39,6 @@ const BoxesPage = () => {
-
-
-
,
]
}
diff --git a/license.md b/license.md
index fa5d39b6213f8..b708f872cb51e 100644
--- a/license.md
+++ b/license.md
@@ -1,6 +1,6 @@
The MIT License (MIT)
-Copyright (c) 2020 Vercel, Inc.
+Copyright (c) 2021 Vercel, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/package.json b/package.json
index 2be79259ff215..a2f6710414e1b 100644
--- a/package.json
+++ b/package.json
@@ -100,7 +100,7 @@
"npm-run-all": "4.1.5",
"nprogress": "0.2.0",
"pixrem": "5.0.0",
- "pnpm": "5.8.0",
+ "pnpm": "5.14.3",
"postcss-nested": "4.2.1",
"postcss-pseudoelements": "5.0.0",
"postcss-short-size": "4.0.0",
diff --git a/packages/next-codemod/license.md b/packages/next-codemod/license.md
index fa5d39b6213f8..b708f872cb51e 100644
--- a/packages/next-codemod/license.md
+++ b/packages/next-codemod/license.md
@@ -1,6 +1,6 @@
The MIT License (MIT)
-Copyright (c) 2020 Vercel, Inc.
+Copyright (c) 2021 Vercel, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/packages/next-mdx/license.md b/packages/next-mdx/license.md
index fa5d39b6213f8..b708f872cb51e 100644
--- a/packages/next-mdx/license.md
+++ b/packages/next-mdx/license.md
@@ -1,6 +1,6 @@
The MIT License (MIT)
-Copyright (c) 2020 Vercel, Inc.
+Copyright (c) 2021 Vercel, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/packages/next/build/babel/preset.ts b/packages/next/build/babel/preset.ts
index be7415e6b1c10..5215020169879 100644
--- a/packages/next/build/babel/preset.ts
+++ b/packages/next/build/babel/preset.ts
@@ -77,6 +77,10 @@ module.exports = (
// Default to production mode if not `test` nor `development`:
const isProduction = !(isTest || isDevelopment)
+ const isBabelLoader = api.caller(
+ (caller: any) => !!caller && caller.name === 'babel-loader'
+ )
+
const useJsxRuntime =
options['preset-react']?.runtime === 'automatic' ||
(Boolean(api.caller((caller: any) => !!caller && caller.hasJsxRuntime)) &&
@@ -180,7 +184,7 @@ module.exports = (
helpers: true,
regenerator: true,
useESModules: supportsESM && presetEnvConfig.modules !== 'commonjs',
- absoluteRuntime: process.versions.pnp
+ absoluteRuntime: isBabelLoader
? dirname(require.resolve('@babel/runtime/package.json'))
: undefined,
...options['transform-runtime'],
diff --git a/packages/next/build/plugins/collect-plugins.ts b/packages/next/build/plugins/collect-plugins.ts
index c23e876359c0e..bb5c5e33c96a7 100644
--- a/packages/next/build/plugins/collect-plugins.ts
+++ b/packages/next/build/plugins/collect-plugins.ts
@@ -1,7 +1,6 @@
import findUp from 'next/dist/compiled/find-up'
import { promises } from 'fs'
import path from 'path'
-import resolve from 'next/dist/compiled/resolve/index.js'
import { execOnce } from '../../next-server/lib/utils'
const { version } = require('next/package.json')
@@ -213,10 +212,7 @@ async function _collectPlugins(
nextPluginNames.map((name) =>
collectPluginMeta(
env,
- resolve.sync(path.join(name, 'package.json'), {
- basedir: dir,
- preserveSymlinks: true,
- }),
+ require.resolve(path.join(name, 'package.json'), { paths: [dir] }),
name,
version
)
diff --git a/packages/next/build/webpack-config.ts b/packages/next/build/webpack-config.ts
index a40321b4f75f4..1b2e33c7c6e53 100644
--- a/packages/next/build/webpack-config.ts
+++ b/packages/next/build/webpack-config.ts
@@ -18,7 +18,6 @@ import {
import { fileExists } from '../lib/file-exists'
import { getPackageVersion } from '../lib/get-package-version'
import { Rewrite } from '../lib/load-custom-routes'
-import { resolveRequest } from '../lib/resolve-request'
import { getTypeScriptConfiguration } from '../lib/typescript/getTypeScriptConfiguration'
import {
CLIENT_STATIC_FILES_RUNTIME_MAIN,
@@ -306,7 +305,7 @@ export default async function getBaseWebpackConfig(
let typeScriptPath: string | undefined
try {
- typeScriptPath = resolveRequest('typescript', `${dir}/`)
+ typeScriptPath = require.resolve('typescript', { paths: [dir] })
} catch (_) {}
const tsConfigPath = path.join(dir, 'tsconfig.json')
const useTypeScript = Boolean(
@@ -607,7 +606,7 @@ export default async function getBaseWebpackConfig(
// exist.
let res: string
try {
- res = resolveRequest(request, `${context}/`)
+ res = require.resolve(request, { paths: [context] })
} catch (err) {
// If the request cannot be resolved, we need to tell webpack to
// "bundle" it so that webpack shows an error (that it cannot be
@@ -645,7 +644,7 @@ export default async function getBaseWebpackConfig(
// we need to bundle the code (even if it _should_ be external).
let baseRes: string | null
try {
- baseRes = resolveRequest(request, `${dir}/`)
+ baseRes = require.resolve(request, { paths: [dir] })
} catch (err) {
baseRes = null
}
@@ -911,14 +910,13 @@ export default async function getBaseWebpackConfig(
},
plugins: [
hasReactRefresh && new ReactRefreshWebpackPlugin(),
- // Makes sure `Buffer` is polyfilled in client-side bundles (same behavior as webpack 4)
+ // Makes sure `Buffer` and `process` are polyfilled in client-side bundles (same behavior as webpack 4)
isWebpack5 &&
!isServer &&
- new webpack.ProvidePlugin({ Buffer: ['buffer', 'Buffer'] }),
- // Makes sure `process` is polyfilled in client-side bundles (same behavior as webpack 4)
- isWebpack5 &&
- !isServer &&
- new webpack.ProvidePlugin({ process: ['process'] }),
+ new webpack.ProvidePlugin({
+ Buffer: [require.resolve('buffer'), 'Buffer'],
+ process: [require.resolve('process')],
+ }),
// This plugin makes sure `output.filename` is used for entry chunks
!isWebpack5 && new ChunkNamesPlugin(),
new webpack.DefinePlugin({
@@ -1422,29 +1420,32 @@ export default async function getBaseWebpackConfig(
try {
// Resolve the version of `@zeit/next-css` as depended on by the Sass,
// Less or Stylus plugin.
- const correctNextCss = resolveRequest(
- '@zeit/next-css',
- isCss
- ? // Resolve `@zeit/next-css` from the base directory
- `${dir}/`
- : // Else, resolve it from the specific plugins
- require.resolve(
- isSass
- ? '@zeit/next-sass'
- : isLess
- ? '@zeit/next-less'
- : isStylus
- ? '@zeit/next-stylus'
- : 'next'
- )
- )
+ const correctNextCss = require.resolve('@zeit/next-css', {
+ paths: [
+ isCss
+ ? // Resolve `@zeit/next-css` from the base directory
+ dir
+ : // Else, resolve it from the specific plugins
+ require.resolve(
+ isSass
+ ? '@zeit/next-sass'
+ : isLess
+ ? '@zeit/next-less'
+ : isStylus
+ ? '@zeit/next-stylus'
+ : 'next'
+ ),
+ ],
+ })
// If we found `@zeit/next-css` ...
if (correctNextCss) {
// ... resolve the version of `css-loader` shipped with that
// package instead of whichever was hoisted highest in your
// `node_modules` tree.
- const correctCssLoader = resolveRequest(use.loader, correctNextCss)
+ const correctCssLoader = require.resolve(use.loader, {
+ paths: [correctNextCss],
+ })
if (correctCssLoader) {
// We saved the user from a failed build!
use.loader = correctCssLoader
diff --git a/packages/next/build/webpack/config/blocks/css/plugins.ts b/packages/next/build/webpack/config/blocks/css/plugins.ts
index c1fd7aba2dc78..7aa6d22e41d95 100644
--- a/packages/next/build/webpack/config/blocks/css/plugins.ts
+++ b/packages/next/build/webpack/config/blocks/css/plugins.ts
@@ -1,6 +1,5 @@
import chalk from 'chalk'
import { findConfig } from '../../../../../lib/find-config'
-import { resolveRequest } from '../../../../../lib/resolve-request'
import browserslist from 'browserslist'
type CssPluginCollection_Array = (string | [string, boolean | object])[]
@@ -57,7 +56,7 @@ async function loadPlugin(
throw new Error(genericErrorText)
}
- const pluginPath = resolveRequest(pluginName, `${dir}/`)
+ const pluginPath = require.resolve(pluginName, { paths: [dir] })
if (isIgnoredPlugin(pluginPath)) {
return false
} else if (options === true) {
diff --git a/packages/next/compiled/resolve/LICENSE b/packages/next/compiled/resolve/LICENSE
deleted file mode 100644
index ee27ba4b4412b..0000000000000
--- a/packages/next/compiled/resolve/LICENSE
+++ /dev/null
@@ -1,18 +0,0 @@
-This software is released under the MIT license:
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/packages/next/compiled/resolve/index.js b/packages/next/compiled/resolve/index.js
deleted file mode 100644
index e0e41629c41a2..0000000000000
--- a/packages/next/compiled/resolve/index.js
+++ /dev/null
@@ -1 +0,0 @@
-module.exports=(()=>{var e={731:e=>{"use strict";var r=process.platform==="win32";var n=/^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/;var t=/^([\s\S]*?)((?:\.{1,2}|[^\\\/]+?|)(\.[^.\/\\]*|))(?:[\\\/]*)$/;var i={};function win32SplitPath(e){var r=n.exec(e),i=(r[1]||"")+(r[2]||""),a=r[3]||"";var o=t.exec(a),s=o[1],l=o[2],u=o[3];return[i,s,l,u]}i.parse=function(e){if(typeof e!=="string"){throw new TypeError("Parameter 'pathString' must be a string, not "+typeof e)}var r=win32SplitPath(e);if(!r||r.length!==4){throw new TypeError("Invalid path '"+e+"'")}return{root:r[0],dir:r[0]+r[1].slice(0,-1),base:r[2],ext:r[3],name:r[2].slice(0,r[2].length-r[3].length)}};var a=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;var o={};function posixSplitPath(e){return a.exec(e).slice(1)}o.parse=function(e){if(typeof e!=="string"){throw new TypeError("Parameter 'pathString' must be a string, not "+typeof e)}var r=posixSplitPath(e);if(!r||r.length!==4){throw new TypeError("Invalid path '"+e+"'")}r[1]=r[1]||"";r[2]=r[2]||"";r[3]=r[3]||"";return{root:r[0],dir:r[0]+r[1].slice(0,-1),base:r[2],ext:r[3],name:r[2].slice(0,r[2].length-r[3].length)}};if(r)e.exports=i.parse;else e.exports=o.parse;e.exports.posix=o.parse;e.exports.win32=i.parse},283:(e,r,n)=>{var t=n(226);var i=n(125);i.core=t;i.isCore=function isCore(e){return t[e]};i.sync=n(284);r=i;e.exports=i},125:(e,r,n)=>{var t=n(226);var i=n(747);var a=n(622);var o=n(155);var s=n(433);var l=n(990);var u=function isFile(e,r){i.stat(e,function(e,n){if(!e){return r(null,n.isFile()||n.isFIFO())}if(e.code==="ENOENT"||e.code==="ENOTDIR")return r(null,false);return r(e)})};var f=function isDirectory(e,r){i.stat(e,function(e,n){if(!e){return r(null,n.isDirectory())}if(e.code==="ENOENT"||e.code==="ENOTDIR")return r(null,false);return r(e)})};e.exports=function resolve(e,r,n){var c=n;var p=r;if(typeof r==="function"){c=p;p={}}if(typeof e!=="string"){var v=new TypeError("Path must be a string.");return process.nextTick(function(){c(v)})}p=l(e,p);var d=p.isFile||u;var y=p.isDirectory||f;var _=p.readFile||i.readFile;var g=p.extensions||[".js"];var m=p.basedir||a.dirname(o());var h=p.filename||m;p.paths=p.paths||[];var F=a.resolve(m);if(p.preserveSymlinks===false){i.realpath(F,function(e,r){if(e&&e.code!=="ENOENT")c(v);else init(e?F:r)})}else{init(F)}var w;function init(r){if(/^(?:\.\.?(?:\/|$)|\/|([A-Za-z]:)?[/\\])/.test(e)){w=a.resolve(r,e);if(e===".."||e.slice(-1)==="/")w+="/";if(/\/$/.test(e)&&w===r){loadAsDirectory(w,p.package,onfile)}else loadAsFile(w,p.package,onfile)}else loadNodeModules(e,r,function(r,n,i){if(r)c(r);else if(n)c(null,n,i);else if(t[e])return c(null,e);else{var a=new Error("Cannot find module '"+e+"' from '"+h+"'");a.code="MODULE_NOT_FOUND";c(a)}})}function onfile(r,n,t){if(r)c(r);else if(n)c(null,n,t);else loadAsDirectory(w,function(r,n,t){if(r)c(r);else if(n)c(null,n,t);else{var i=new Error("Cannot find module '"+e+"' from '"+h+"'");i.code="MODULE_NOT_FOUND";c(i)}})}function loadAsFile(e,r,n){var t=r;var i=n;if(typeof t==="function"){i=t;t=undefined}var o=[""].concat(g);load(o,e,t);function load(e,r,n){if(e.length===0)return i(null,undefined,n);var t=r+e[0];var o=n;if(o)onpkg(null,o);else loadpkg(a.dirname(t),onpkg);function onpkg(n,s,l){o=s;if(n)return i(n);if(l&&o&&p.pathFilter){var u=a.relative(l,t);var f=u.slice(0,u.length-e[0].length);var c=p.pathFilter(o,r,f);if(c)return load([""].concat(g.slice()),a.resolve(l,c),o)}d(t,onex)}function onex(n,a){if(n)return i(n);if(a)return i(null,t,o);load(e.slice(1),r,o)}}}function loadpkg(e,r){if(e===""||e==="/")return r(null);if(process.platform==="win32"&&/^\w:[/\\]*$/.test(e)){return r(null)}if(/[/\\]node_modules[/\\]*$/.test(e))return r(null);var n=a.join(e,"package.json");d(n,function(t,i){if(!i)return loadpkg(a.dirname(e),r);_(n,function(t,i){if(t)r(t);try{var a=JSON.parse(i)}catch(e){}if(a&&p.packageFilter){a=p.packageFilter(a,n)}r(null,a,e)})})}function loadAsDirectory(e,r,n){var t=n;var i=r;if(typeof i==="function"){t=i;i=p.package}var o=a.join(e,"package.json");d(o,function(r,n){if(r)return t(r);if(!n)return loadAsFile(a.join(e,"index"),i,t);_(o,function(r,n){if(r)return t(r);try{var i=JSON.parse(n)}catch(e){}if(p.packageFilter){i=p.packageFilter(i,o)}if(i.main){if(typeof i.main!=="string"){var s=new TypeError("package “"+i.name+"” `main` must be a string");s.code="INVALID_PACKAGE_MAIN";return t(s)}if(i.main==="."||i.main==="./"){i.main="index"}loadAsFile(a.resolve(e,i.main),i,function(r,n,i){if(r)return t(r);if(n)return t(null,n,i);if(!i)return loadAsFile(a.join(e,"index"),i,t);var o=a.resolve(e,i.main);loadAsDirectory(o,i,function(r,n,i){if(r)return t(r);if(n)return t(null,n,i);loadAsFile(a.join(e,"index"),i,t)})});return}loadAsFile(a.join(e,"/index"),i,t)})})}function processDirs(r,n){if(n.length===0)return r(null,undefined);var t=n[0];y(t,isdir);function isdir(i,o){if(i)return r(i);if(!o)return processDirs(r,n.slice(1));var s=a.join(t,e);loadAsFile(s,p.package,onfile)}function onfile(n,i,o){if(n)return r(n);if(i)return r(null,i,o);loadAsDirectory(a.join(t,e),p.package,ondir)}function ondir(e,t,i){if(e)return r(e);if(t)return r(null,t,i);processDirs(r,n.slice(1))}}function loadNodeModules(e,r,n){processDirs(n,s(r,p,e))}}},155:e=>{e.exports=function(){var e=Error.prepareStackTrace;Error.prepareStackTrace=function(e,r){return r};var r=(new Error).stack;Error.prepareStackTrace=e;return r[2].getFileName()}},226:(e,r,n)=>{var t=process.versions&&process.versions.node&&process.versions.node.split(".")||[];function specifierIncluded(e){var r=e.split(" ");var n=r.length>1?r[0]:"=";var i=(r.length>1?r[1]:r[0]).split(".");for(var a=0;a<3;++a){var o=Number(t[a]||0);var s=Number(i[a]||0);if(o===s){continue}if(n==="<"){return o="){return o>=s}else{return false}}return n===">="}function matchesRange(e){var r=e.split(/ ?&& ?/);if(r.length===0){return false}for(var n=0;n{var t=n(622);var i=t.parse||n(731);var a=function getNodeModulesDirs(e,r){var n="/";if(/^([A-Za-z]:)/.test(e)){n=""}else if(/^\\\\/.test(e)){n="\\\\"}var a=[e];var o=i(e);while(o.dir!==a[a.length-1]){a.push(o.dir);o=i(o.dir)}return a.reduce(function(e,i){return e.concat(r.map(function(e){return t.join(n,i,e)}))},[])};e.exports=function nodeModulesPaths(e,r,n){var t=r&&r.moduleDirectory?[].concat(r.moduleDirectory):["node_modules"];if(r&&typeof r.paths==="function"){return r.paths(n,e,function(){return a(e,t)},r)}var i=a(e,t);return r&&r.paths?i.concat(r.paths):i}},990:e=>{e.exports=function(e,r){return r||{}}},284:(e,r,n)=>{var t=n(226);var i=n(747);var a=n(622);var o=n(155);var s=n(433);var l=n(990);var u=function isFile(e){try{var r=i.statSync(e)}catch(e){if(e&&(e.code==="ENOENT"||e.code==="ENOTDIR"))return false;throw e}return r.isFile()||r.isFIFO()};var f=function isDirectory(e){try{var r=i.statSync(e)}catch(e){if(e&&(e.code==="ENOENT"||e.code==="ENOTDIR"))return false;throw e}return r.isDirectory()};e.exports=function(e,r){if(typeof e!=="string"){throw new TypeError("Path must be a string.")}var n=l(e,r);var c=n.isFile||u;var p=n.readFileSync||i.readFileSync;var v=n.isDirectory||f;var d=n.extensions||[".js"];var y=n.basedir||a.dirname(o());var _=n.filename||y;n.paths=n.paths||[];var g=a.resolve(y);if(n.preserveSymlinks===false){try{g=i.realpathSync(g)}catch(e){if(e.code!=="ENOENT"){throw e}}}if(/^(?:\.\.?(?:\/|$)|\/|([A-Za-z]:)?[/\\])/.test(e)){var m=a.resolve(g,e);if(e===".."||e.slice(-1)==="/")m+="/";var h=loadAsFileSync(m)||loadAsDirectorySync(m);if(h)return h}else{var F=loadNodeModulesSync(e,g);if(F)return F}if(t[e])return e;var w=new Error("Cannot find module '"+e+"' from '"+_+"'");w.code="MODULE_NOT_FOUND";throw w;function loadAsFileSync(e){var r=loadpkg(a.dirname(e));if(r&&r.dir&&r.pkg&&n.pathFilter){var t=a.relative(r.dir,e);var i=n.pathFilter(r.pkg,e,t);if(i){e=a.resolve(r.dir,i)}}if(c(e)){return e}for(var o=0;o{"use strict";e.exports=JSON.parse('{"assert":true,"async_hooks":">= 8","buffer_ieee754":"< 0.9.7","buffer":true,"child_process":true,"cluster":true,"console":true,"constants":true,"crypto":true,"_debugger":"< 8","dgram":true,"dns":true,"domain":true,"events":true,"freelist":"< 6","fs":true,"fs/promises":">= 10 && < 10.1","_http_agent":">= 0.11.1","_http_client":">= 0.11.1","_http_common":">= 0.11.1","_http_incoming":">= 0.11.1","_http_outgoing":">= 0.11.1","_http_server":">= 0.11.1","http":true,"http2":">= 8.8","https":true,"inspector":">= 8.0.0","_linklist":"< 8","module":true,"net":true,"node-inspect/lib/_inspect":">= 7.6.0 && < 12","node-inspect/lib/internal/inspect_client":">= 7.6.0 && < 12","node-inspect/lib/internal/inspect_repl":">= 7.6.0 && < 12","os":true,"path":true,"perf_hooks":">= 8.5","process":">= 1","punycode":true,"querystring":true,"readline":true,"repl":true,"smalloc":">= 0.11.5 && < 3","_stream_duplex":">= 0.9.4","_stream_transform":">= 0.9.4","_stream_wrap":">= 1.4.1","_stream_passthrough":">= 0.9.4","_stream_readable":">= 0.9.4","_stream_writable":">= 0.9.4","stream":true,"string_decoder":true,"sys":true,"timers":true,"_tls_common":">= 0.11.13","_tls_legacy":">= 0.11.3 && < 10","_tls_wrap":">= 0.11.3","tls":true,"trace_events":">= 10","tty":true,"url":true,"util":true,"v8/tools/arguments":">= 10 && < 12","v8/tools/codemap":[">= 4.4.0 && < 5",">= 5.2.0 && < 12"],"v8/tools/consarray":[">= 4.4.0 && < 5",">= 5.2.0 && < 12"],"v8/tools/csvparser":[">= 4.4.0 && < 5",">= 5.2.0 && < 12"],"v8/tools/logreader":[">= 4.4.0 && < 5",">= 5.2.0 && < 12"],"v8/tools/profile_view":[">= 4.4.0 && < 5",">= 5.2.0 && < 12"],"v8/tools/splaytree":[">= 4.4.0 && < 5",">= 5.2.0 && < 12"],"v8":">= 1","vm":true,"worker_threads":">= 11.7","zlib":true}')},747:e=>{"use strict";e.exports=require("fs")},622:e=>{"use strict";e.exports=require("path")}};var r={};function __webpack_require__(n){if(r[n]){return r[n].exports}var t=r[n]={exports:{}};var i=true;try{e[n](t,t.exports,__webpack_require__);i=false}finally{if(i)delete r[n]}return t.exports}__webpack_require__.ab=__dirname+"/";return __webpack_require__(283)})();
\ No newline at end of file
diff --git a/packages/next/compiled/resolve/package.json b/packages/next/compiled/resolve/package.json
deleted file mode 100644
index 7b090b9743e5e..0000000000000
--- a/packages/next/compiled/resolve/package.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":"resolve","main":"index.js","author":{"name":"James Halliday","email":"mail@substack.net","url":"http://substack.net"},"license":"MIT"}
diff --git a/packages/next/export/index.ts b/packages/next/export/index.ts
index fc611fccb91a5..c820e25c8904d 100644
--- a/packages/next/export/index.ts
+++ b/packages/next/export/index.ts
@@ -252,6 +252,12 @@ export default async function exportApp(
)
}
+ if (outDir === join(dir, 'static')) {
+ throw new Error(
+ `The 'static' directory is reserved in Next.js and can not be used as the export out directory. https://err.sh/vercel/next.js/can-not-output-to-static`
+ )
+ }
+
await recursiveDelete(join(outDir))
await promises.mkdir(join(outDir, '_next', buildId), { recursive: true })
diff --git a/packages/next/lib/get-package-version.ts b/packages/next/lib/get-package-version.ts
index 9e2fcbebf8969..2b516a59dcf7a 100644
--- a/packages/next/lib/get-package-version.ts
+++ b/packages/next/lib/get-package-version.ts
@@ -2,7 +2,6 @@ import { promises as fs } from 'fs'
import findUp from 'next/dist/compiled/find-up'
import JSON5 from 'next/dist/compiled/json5'
import * as path from 'path'
-import { resolveRequest } from './resolve-request'
type PackageJsonDependencies = {
dependencies: Record
@@ -52,7 +51,9 @@ export async function getPackageVersion({
: `${cwd}/`
try {
- const targetPath = resolveRequest(`${name}/package.json`, cwd2)
+ const targetPath = require.resolve(`${name}/package.json`, {
+ paths: [cwd2],
+ })
const targetContent = await fs.readFile(targetPath, 'utf-8')
return JSON5.parse(targetContent).version ?? null
} catch {
diff --git a/packages/next/lib/resolve-request.ts b/packages/next/lib/resolve-request.ts
deleted file mode 100644
index e15f3d737bde0..0000000000000
--- a/packages/next/lib/resolve-request.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import resolve from 'next/dist/compiled/resolve/index.js'
-import path from 'path'
-
-export function resolveRequest(req: string, issuer: string): string {
- // The `resolve` package is prebuilt through ncc, which prevents
- // PnP from being able to inject itself into it. To circumvent
- // this, we simply use PnP directly when available.
- if (process.versions.pnp) {
- const { resolveRequest: pnpResolveRequest } = require(`pnpapi`)
- return pnpResolveRequest(req, issuer, { considerBuiltins: false })
- } else {
- const basedir =
- issuer.endsWith(path.posix.sep) || issuer.endsWith(path.win32.sep)
- ? issuer
- : path.dirname(issuer)
- return resolve.sync(req, { basedir })
- }
-}
diff --git a/packages/next/lib/typescript/diagnosticFormatter.ts b/packages/next/lib/typescript/diagnosticFormatter.ts
index 7b50c9ada0efc..6d183431415e7 100644
--- a/packages/next/lib/typescript/diagnosticFormatter.ts
+++ b/packages/next/lib/typescript/diagnosticFormatter.ts
@@ -45,7 +45,7 @@ export async function getFormattedDiagnostic(
const character = pos.character + 1
let fileName = path.posix.normalize(
- path.relative(baseDir, diagnostic.file.fileName).replace(/\\/, '/')
+ path.relative(baseDir, diagnostic.file.fileName).replace(/\\/g, '/')
)
if (!fileName.startsWith('.')) {
fileName = './' + fileName
diff --git a/packages/next/lib/typescript/hasNecessaryDependencies.ts b/packages/next/lib/typescript/hasNecessaryDependencies.ts
index 6dac0650c0744..5e49969784701 100644
--- a/packages/next/lib/typescript/hasNecessaryDependencies.ts
+++ b/packages/next/lib/typescript/hasNecessaryDependencies.ts
@@ -2,7 +2,6 @@ import chalk from 'chalk'
import path from 'path'
import { fileExists } from '../file-exists'
import { getOxfordCommaList } from '../oxford-comma-list'
-import { resolveRequest } from '../resolve-request'
import { FatalTypeScriptError } from './FatalTypeScriptError'
const requiredPackages = [
@@ -22,7 +21,7 @@ export async function hasNecessaryDependencies(
const missingPackages = requiredPackages.filter((p) => {
try {
- resolutions.set(p.pkg, resolveRequest(p.file, path.join(baseDir, '/')))
+ resolutions.set(p.pkg, require.resolve(p.file, { paths: [baseDir] }))
return false
} catch (_) {
return true
diff --git a/packages/next/license.md b/packages/next/license.md
index fa5d39b6213f8..b708f872cb51e 100644
--- a/packages/next/license.md
+++ b/packages/next/license.md
@@ -1,6 +1,6 @@
The MIT License (MIT)
-Copyright (c) 2020 Vercel, Inc.
+Copyright (c) 2021 Vercel, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/packages/next/package.json b/packages/next/package.json
index 761abd06dbffa..c5d79017f16f9 100644
--- a/packages/next/package.json
+++ b/packages/next/package.json
@@ -172,7 +172,6 @@
"@types/react": "16.9.17",
"@types/react-dom": "16.9.4",
"@types/react-is": "16.7.1",
- "@types/resolve": "0.0.8",
"@types/semver": "7.3.1",
"@types/send": "0.14.4",
"@types/sharp": "0.26.0",
@@ -220,7 +219,6 @@
"postcss-preset-env": "6.7.0",
"postcss-scss": "3.0.4",
"recast": "0.18.5",
- "resolve": "1.11.0",
"semver": "7.3.2",
"send": "0.17.1",
"source-map": "0.6.1",
diff --git a/packages/next/taskfile.js b/packages/next/taskfile.js
index 0712a9be2211d..89b8d525ffb75 100644
--- a/packages/next/taskfile.js
+++ b/packages/next/taskfile.js
@@ -404,16 +404,6 @@ export async function ncc_recast(task, opts) {
.target('compiled/recast')
}
// eslint-disable-next-line camelcase
-// NB: Used by other dependencies, but Vercel version is a duplicate
-// version so can be inlined anyway (although may change in future)
-externals['resolve'] = 'next/dist/compiled/resolve'
-export async function ncc_resolve(task, opts) {
- await task
- .source(opts.src || relative(__dirname, require.resolve('resolve')))
- .ncc({ packageName: 'resolve', externals })
- .target('compiled/resolve')
-}
-// eslint-disable-next-line camelcase
externals['schema-utils'] = 'next/dist/compiled/schema-utils'
export async function ncc_schema_utils(task, opts) {
await task
@@ -576,7 +566,6 @@ export async function ncc(task) {
'ncc_postcss_preset_env',
'ncc_postcss_scss',
'ncc_recast',
- 'ncc_resolve',
'ncc_schema_utils',
'ncc_send',
'ncc_source_map',
diff --git a/packages/next/types/misc.d.ts b/packages/next/types/misc.d.ts
index aa1832b69dadf..afb31154d8125 100644
--- a/packages/next/types/misc.d.ts
+++ b/packages/next/types/misc.d.ts
@@ -145,10 +145,6 @@ declare module 'next/dist/compiled/recast' {
import m from 'recast'
export = m
}
-declare module 'next/dist/compiled/resolve/index.js' {
- import m from 'resolve'
- export = m
-}
declare module 'next/dist/compiled/send' {
import m from 'send'
export = m
diff --git a/test-pnp.sh b/test-pnp.sh
index 6ea70845a22b8..43564baf466a2 100644
--- a/test-pnp.sh
+++ b/test-pnp.sh
@@ -1,7 +1,10 @@
declare -a testCases=(
"with-typescript"
"with-next-sass"
+ # Tests @next/mdx
"with-mdx"
+ # Tests babel config
+ "with-styled-components"
)
set -e
@@ -25,6 +28,7 @@ do
touch yarn.lock
yarn set version berry
yarn config set pnpFallbackMode none
+ yarn config set enableGlobalCache true
yarn link --all --private -r ../..
yarn build
diff --git a/test/integration/errors-on-output-to-public/test/index.test.js b/test/integration/errors-on-output-to-public/test/index.test.js
index b094b29a74fda..be7e9b9bcd1f4 100644
--- a/test/integration/errors-on-output-to-public/test/index.test.js
+++ b/test/integration/errors-on-output-to-public/test/index.test.js
@@ -13,7 +13,7 @@ describe('Errors on output to public', () => {
await fs.writeFile(nextConfig, `module.exports = { distDir: 'public' }`)
const results = await nextBuild(appDir, [], { stdout: true, stderr: true })
expect(results.stdout + results.stderr).toMatch(
- /The 'public' directory is reserved in Next.js and can not be set as/
+ /The 'public' directory is reserved in Next\.js and can not be set as/
)
await fs.remove(nextConfig)
})
@@ -31,7 +31,7 @@ describe('Errors on output to public', () => {
}
)
expect(results.stdout + results.stderr).toMatch(
- /The 'public' directory is reserved in Next.js and can not be used as/
+ /The 'public' directory is reserved in Next\.js and can not be used as/
)
})
})
diff --git a/test/integration/errors-on-output-to-static/pages/index.js b/test/integration/errors-on-output-to-static/pages/index.js
new file mode 100644
index 0000000000000..0957a987fc2f2
--- /dev/null
+++ b/test/integration/errors-on-output-to-static/pages/index.js
@@ -0,0 +1 @@
+export default () => 'hi'
diff --git a/test/integration/errors-on-output-to-static/test/index.test.js b/test/integration/errors-on-output-to-static/test/index.test.js
new file mode 100644
index 0000000000000..9ee69eba8d410
--- /dev/null
+++ b/test/integration/errors-on-output-to-static/test/index.test.js
@@ -0,0 +1,28 @@
+/* eslint-env jest */
+
+import path from 'path'
+import fs from 'fs-extra'
+import { nextBuild, nextExport } from 'next-test-utils'
+
+jest.setTimeout(1000 * 60 * 1)
+const appDir = path.join(__dirname, '..')
+const nextConfig = path.join(appDir, 'next.config.js')
+
+describe('Errors on output to static', () => {
+ it('Throws error when export out dir is static', async () => {
+ await fs.remove(nextConfig)
+ await nextBuild(appDir)
+ const outdir = path.join(appDir, 'static')
+ const results = await nextExport(
+ appDir,
+ { outdir },
+ {
+ stdout: true,
+ stderr: true,
+ }
+ )
+ expect(results.stdout + results.stderr).toMatch(
+ /The 'static' directory is reserved in Next\.js and can not be used as/
+ )
+ })
+})
diff --git a/test/package-managers-tests/basic-pnpm/pages/about.js b/test/package-managers-tests/basic-pnpm/pages/about.js
deleted file mode 100644
index 46817af02a5c1..0000000000000
--- a/test/package-managers-tests/basic-pnpm/pages/about.js
+++ /dev/null
@@ -1,3 +0,0 @@
-export default function About() {
- return About us
-}
diff --git a/test/package-managers-tests/basic-pnpm/pages/about2.js b/test/package-managers-tests/basic-pnpm/pages/about2.js
deleted file mode 100644
index 2b8fe3f38cba6..0000000000000
--- a/test/package-managers-tests/basic-pnpm/pages/about2.js
+++ /dev/null
@@ -1,3 +0,0 @@
-export default function About2() {
- return About 2
-}
diff --git a/test/package-managers-tests/basic-pnpm/pages/day/index.js b/test/package-managers-tests/basic-pnpm/pages/day/index.js
deleted file mode 100644
index a3cd64f29174d..0000000000000
--- a/test/package-managers-tests/basic-pnpm/pages/day/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-export default function Day() {
- return Hello Day
-}
diff --git a/test/package-managers-tests/basic-pnpm/pages/index.js b/test/package-managers-tests/basic-pnpm/pages/index.js
deleted file mode 100644
index 7bb25eccba89e..0000000000000
--- a/test/package-managers-tests/basic-pnpm/pages/index.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import Link from 'next/link'
-export default function Home() {
- return (
-
- Hello World.{' '}
-
-
About
-
-
- )
-}
diff --git a/test/package-managers-tests/basic-pnpm/test/index.test.js b/test/package-managers-tests/basic-pnpm/test/index.test.js
deleted file mode 100644
index f1340f8e06dff..0000000000000
--- a/test/package-managers-tests/basic-pnpm/test/index.test.js
+++ /dev/null
@@ -1,74 +0,0 @@
-/* eslint-env jest */
-import { execSync } from 'child_process'
-import fs from 'fs-extra'
-import path from 'path'
-
-jest.setTimeout(100 * 1000)
-
-beforeAll(async () => {
- await clean()
-})
-
-afterAll(async () => {
- await clean()
-})
-
-test('pnpm installs', async () => {
- const pnpm = getStdout('yarn bin pnpm')
- exec(pnpm + ' init -y')
- exec(pnpm + ' add next react react-dom')
- await useLocalNextjs()
- // exec('pnpm install')
-})
-
-test('nextjs builds with pnpm', () => {
- const pnpx = getStdout(`yarn bin pnpx`)
- exec(pnpx + ' next build')
-})
-
-const exec = (cmd) => {
- return execSync(cmd, {
- env: process.env,
- shell: true,
- stdio: 'inherit',
- cwd: path.resolve(__dirname, '..'),
- })
-}
-
-const getStdout = (cmd) => {
- return execSync(cmd, {
- env: process.env,
- shell: true,
- stdio: 'pipe',
- })
- .toString()
- .trim()
-}
-
-async function useLocalNextjs() {
- // installed nextjs
- const nextPath = path.dirname(require.resolve('next/package.json'))
-
- // repository root
- const root = path.dirname(
- require.resolve(path.resolve(process.cwd(), 'package.json'))
- )
-
- // local nextjs
- const currentNextPath = path.resolve(root, 'packages/next')
-
- // copy local nextjs to node_modules
- await fs.copy(
- path.resolve(currentNextPath, 'dist'),
- path.resolve(nextPath, 'dist')
- )
-
- console.log('copied local nextjs to node_modules')
-}
-
-async function clean() {
- // jest test cannot be found if a package.json exists in test directory
- await fs.remove(path.resolve(__dirname, '../package.json'))
- await fs.remove(path.resolve(__dirname, '../node_modules'))
- await fs.remove(path.resolve(__dirname, '../pnpm-lock.yaml'))
-}
diff --git a/test/package-managers/pnpm/app/package.json b/test/package-managers/pnpm/app/package.json
new file mode 100644
index 0000000000000..3cc6af9e7f671
--- /dev/null
+++ b/test/package-managers/pnpm/app/package.json
@@ -0,0 +1,14 @@
+{
+ "name": "pnpm-app",
+ "version": "1.0.0",
+ "private": true,
+ "scripts": {
+ "dev": "next dev",
+ "build": "next build",
+ "start": "next start"
+ },
+ "dependencies": {
+ "react": "^16.7.0",
+ "react-dom": "^16.7.0"
+ }
+}
diff --git a/test/package-managers/pnpm/app/pages/index.js b/test/package-managers/pnpm/app/pages/index.js
new file mode 100644
index 0000000000000..69192c68a0ce5
--- /dev/null
+++ b/test/package-managers/pnpm/app/pages/index.js
@@ -0,0 +1 @@
+export default () => Hello World
diff --git a/test/package-managers/pnpm/test/index.test.js b/test/package-managers/pnpm/test/index.test.js
new file mode 100644
index 0000000000000..2a34123a3804b
--- /dev/null
+++ b/test/package-managers/pnpm/test/index.test.js
@@ -0,0 +1,127 @@
+/* eslint-env jest */
+import execa from 'execa'
+import fs from 'fs-extra'
+import os from 'os'
+import path from 'path'
+
+const pnpmExecutable = path.join(
+ __dirname,
+ '..',
+ '..',
+ '..',
+ '..',
+ 'node_modules',
+ '.bin',
+ 'pnpm'
+)
+const packagesDir = path.join(__dirname, '..', '..', '..', '..', 'packages')
+const appDir = path.join(__dirname, '..', 'app')
+
+jest.setTimeout(1000 * 60 * 5)
+
+const runNpm = (cwd, ...args) => execa('npm', [...args], { cwd })
+const runPnpm = (cwd, ...args) => execa(pnpmExecutable, [...args], { cwd })
+
+async function usingTempDir(fn) {
+ const folder = path.join(os.tmpdir(), Math.random().toString(36).substring(2))
+ await fs.mkdirp(folder)
+ try {
+ return await fn(folder)
+ } finally {
+ await fs.remove(folder)
+ }
+}
+
+/**
+ * Using 'npm pack', create a tarball of the given package in
+ * directory `pkg` and write it to `cwd`.
+ *
+ * `pkg` is relative to the monorepo 'packages/' directory.
+ *
+ * Return the absolute path to the tarball.
+ */
+async function pack(cwd, pkg) {
+ const pkgDir = path.join(packagesDir, pkg)
+ const { stdout } = await runNpm(
+ cwd,
+ 'pack',
+ '--ignore-scripts', // Skip the prepublish script
+ path.join(packagesDir, pkg)
+ )
+ const tarballFilename = stdout.match(/.*\.tgz/)[0]
+
+ if (!tarballFilename) {
+ throw new Error(
+ `pnpm failed to pack "next" package tarball in directory ${pkgDir}.`
+ )
+ }
+
+ return path.join(cwd, tarballFilename)
+}
+
+describe('pnpm support', () => {
+ it('should build with dependencies installed via pnpm', async () => {
+ // Create a Next.js app in a temporary directory, and install dependencies with pnpm.
+ //
+ // "next" and its monorepo dependencies are installed by `npm pack`-ing tarballs from
+ // 'next.js/packages/*', because installing "next" directly via
+ // `pnpm add path/to/next.js/packages/next` results in a symlink:
+ // 'app/node_modules/next' -> 'path/to/next.js/packages/next'.
+ // This is undesired since modules inside "next" would be resolved to the
+ // next.js monorepo 'node_modules' and lead to false test results;
+ // installing from a tarball avoids this issue.
+ //
+ // The "next" package's monorepo dependencies (e.g. "@next/env", "@next/polyfill-module")
+ // are not bundled with `npm pack next.js/packages/next`,
+ // so they need to be packed individually.
+ // To ensure that they are installed upon installing "next", a package.json "pnpm.overrides"
+ // field is used to override these dependency paths at install time.
+ await usingTempDir(async (tempDir) => {
+ const nextTarballPath = await pack(tempDir, 'next')
+ const dependencyTarballPaths = {
+ '@next/env': await pack(tempDir, 'next-env'),
+ '@next/polyfill-module': await pack(tempDir, 'next-polyfill-module'),
+ '@next/react-dev-overlay': await pack(tempDir, 'react-dev-overlay'),
+ '@next/react-refresh-utils': await pack(tempDir, 'react-refresh-utils'),
+ }
+
+ const tempAppDir = path.join(tempDir, 'app')
+ await fs.copy(appDir, tempAppDir)
+
+ // Inject dependency tarball paths into a "pnpm.overrides" field in package.json,
+ // so that they are installed from packed tarballs rather than from the npm registry.
+ const packageJsonPath = path.join(tempAppDir, 'package.json')
+ const overrides = {}
+ for (const [dependency, tarballPath] of Object.entries(
+ dependencyTarballPaths
+ )) {
+ overrides[dependency] = `file:${tarballPath}`
+ }
+ const packageJsonWithOverrides = {
+ ...(await fs.readJson(packageJsonPath)),
+ pnpm: { overrides },
+ }
+ await fs.writeFile(
+ packageJsonPath,
+ JSON.stringify(packageJsonWithOverrides, null, 2)
+ )
+
+ await runPnpm(tempAppDir, 'install')
+ await runPnpm(tempAppDir, 'add', nextTarballPath)
+
+ expect(
+ await fs.pathExists(path.join(tempAppDir, 'pnpm-lock.yaml'))
+ ).toBeTruthy()
+
+ const packageJson = await fs.readJson(packageJsonPath)
+ expect(packageJson.dependencies['next']).toMatch(/^file:/)
+ for (const dependency of Object.keys(dependencyTarballPaths)) {
+ expect(packageJson.pnpm.overrides[dependency]).toMatch(/^file:/)
+ }
+
+ const { stdout, stderr } = await runPnpm(tempAppDir, 'run', 'build')
+ console.log(stdout, stderr)
+ expect(stdout).toMatch(/Compiled successfully/)
+ })
+ })
+})
diff --git a/yarn.lock b/yarn.lock
index 41600effcdf6d..dda54689a2d5a 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2944,12 +2944,6 @@
"@types/prop-types" "*"
csstype "^2.2.0"
-"@types/resolve@0.0.8":
- version "0.0.8"
- resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-0.0.8.tgz#f26074d238e02659e323ce1a13d041eee280e194"
- dependencies:
- "@types/node" "*"
-
"@types/resolve@1.17.1":
version "1.17.1"
resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.17.1.tgz#3afd6ad8967c77e4376c598a82ddd58f46ec45d6"
@@ -11951,10 +11945,10 @@ pnp-webpack-plugin@1.6.4:
dependencies:
ts-pnp "^1.1.6"
-pnpm@5.8.0:
- version "5.8.0"
- resolved "https://registry.yarnpkg.com/pnpm/-/pnpm-5.8.0.tgz#a933d6c756efe8795b12004bbff1b82c622e771b"
- integrity sha512-J2rAxEXnohwcDkR4KNI6UsYhDs9hJ/tje/BahHpXawi406pmxd6caJUXfRxZPbKvKdyVqfBRKhlX1vyhYbM8lQ==
+pnpm@5.14.3:
+ version "5.14.3"
+ resolved "https://registry.yarnpkg.com/pnpm/-/pnpm-5.14.3.tgz#88e53906652c85ba2e6f69294042d95aad018cbe"
+ integrity sha512-PFjHFWCsHgaNCpOwOAgN6H71PA8td8PnwSE1ArXz//OyfdfIwws1s23XLmokhHcnE3JsBSiIR3NOW8JZ5QcxlQ==
posix-character-classes@^0.1.0:
version "0.1.1"
@@ -13655,13 +13649,6 @@ resolve@1.1.7:
version "1.1.7"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b"
-resolve@1.11.0:
- version "1.11.0"
- resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.11.0.tgz#4014870ba296176b86343d50b60f3b50609ce232"
- integrity sha512-WL2pBDjqT6pGUNSUzMw00o4T7If+z4H2x3Gz893WoUQ5KW8Vr9txp00ykiP16VBaZF5+j/OcXJHZ9+PCvdiDKw==
- dependencies:
- path-parse "^1.0.6"
-
resolve@1.17.0:
version "1.17.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444"