Skip to content

Commit

Permalink
Merge branch 'canary' of https://github.com/vercel/next.js into font-…
Browse files Browse the repository at this point in the history
…defaults
  • Loading branch information
prateekbh committed Dec 2, 2020
2 parents cfac345 + 8c2cb46 commit a06a04f
Show file tree
Hide file tree
Showing 49 changed files with 851 additions and 144 deletions.
8 changes: 4 additions & 4 deletions docs/basic-features/data-fetching.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@ The `context` parameter is an object containing the following keys:
> This includes reading from the filesystem or a database.
> **Note**: You should not use [`fetch()`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) to
> call an API route in your application.
> Instead, directly import the API route and call its function yourself.
> call an API route in `getStaticProps`.
> Instead, directly import the logic used inside your API route.
> You may need to slightly refactor your code for this approach.
>
> Fetching from an external API is fine!
Expand Down Expand Up @@ -661,8 +661,8 @@ The `context` parameter is an object containing the following keys:
> This includes reading from the filesystem or a database.
> **Note**: You should not use [`fetch()`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) to
> call an API route in your application.
> Instead, directly import the API route and call its function yourself.
> call an API route in `getServerSideProps`.
> Instead, directly import the logic used inside your API route.
> You may need to slightly refactor your code for this approach.
>
> Fetching from an external API is fine!
Expand Down
8 changes: 6 additions & 2 deletions docs/basic-features/environment-variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,12 @@ export async function getStaticProps() {
> ```bash
> # .env
> A=abc
> WRONG=pre$A # becomes "preabc"
> CORRECT=pre\$A # becomes "pre$A"
>
> # becomes "preabc"
> WRONG=pre$A
>
> # becomes "pre$A"
> CORRECT=pre\$A
> ```
## Exposing Environment Variables to the Browser
Expand Down
28 changes: 28 additions & 0 deletions errors/undefined-webpack-config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Missing webpack config

#### Why This Error Occurred

The value returned from the custom `webpack` function in your `next.config.js` was undefined. This can occur from the initial config value not being returned.

#### Possible Ways to Fix It

Make sure to return the `webpack` config from your custom `webpack` function in your `next.config.js`

```js
// next.config.js

module.exports = {
webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
// Note: we provide webpack above so you should not `require` it
// Perform customizations to webpack config
config.plugins.push(new webpack.IgnorePlugin(/\/__tests__\//))

// Important: return the modified config
return config
},
}
```

### Useful Links

- [Custom webpack config Documentation](https://nextjs.org/docs/api-reference/next.config.js/custom-webpack-config)
2 changes: 1 addition & 1 deletion examples/custom-server-typescript/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
/out/

# production
/build
/dist

# misc
.DS_Store
Expand Down
2 changes: 1 addition & 1 deletion examples/with-zones/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ To get started, push the example to GitHub/GitLab/Bitbucket and [import your rep

![Import flow for blog app](docs/import-blog.jpg)

Click continue and finish the import process. After that's done copy the domain URL that was assigned to your project and paste it on `home/.env`:
Click continue and finish the import process. After that's done copy the domain URL that was assigned to your project, paste it on `home/.env`, and push the change to your repo:

```bash
# Replace this URL with the URL of your blog app
Expand Down
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@
"registry": "https://registry.npmjs.org/"
}
},
"version": "10.0.3"
"version": "10.0.4-canary.1"
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
"cookie": "0.4.1",
"cors": "2.8.5",
"coveralls": "3.0.3",
"critters": "0.0.6",
"cross-env": "6.0.3",
"cross-spawn": "6.0.5",
"escape-string-regexp": "2.0.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/create-next-app/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "create-next-app",
"version": "10.0.3",
"version": "10.0.4-canary.1",
"keywords": [
"react",
"next",
Expand Down
2 changes: 1 addition & 1 deletion packages/eslint-plugin-next/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/eslint-plugin-next",
"version": "10.0.3",
"version": "10.0.4-canary.1",
"description": "ESLint plugin for NextJS.",
"main": "lib/index.js",
"license": "MIT",
Expand Down
2 changes: 1 addition & 1 deletion packages/next-bundle-analyzer/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/bundle-analyzer",
"version": "10.0.3",
"version": "10.0.4-canary.1",
"main": "index.js",
"license": "MIT",
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion packages/next-codemod/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/codemod",
"version": "10.0.3",
"version": "10.0.4-canary.1",
"license": "MIT",
"dependencies": {
"chalk": "4.1.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/next-env/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/env",
"version": "10.0.3",
"version": "10.0.4-canary.1",
"keywords": [
"react",
"next",
Expand Down
2 changes: 1 addition & 1 deletion packages/next-mdx/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/mdx",
"version": "10.0.3",
"version": "10.0.4-canary.1",
"main": "index.js",
"license": "MIT",
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion packages/next-plugin-google-analytics/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/plugin-google-analytics",
"version": "10.0.3",
"version": "10.0.4-canary.1",
"repository": {
"url": "vercel/next.js",
"directory": "packages/next-plugin-google-analytics"
Expand Down
2 changes: 1 addition & 1 deletion packages/next-plugin-sentry/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/plugin-sentry",
"version": "10.0.3",
"version": "10.0.4-canary.1",
"repository": {
"url": "vercel/next.js",
"directory": "packages/next-plugin-sentry"
Expand Down
2 changes: 1 addition & 1 deletion packages/next-plugin-storybook/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/plugin-storybook",
"version": "10.0.3",
"version": "10.0.4-canary.1",
"repository": {
"url": "vercel/next.js",
"directory": "packages/next-plugin-storybook"
Expand Down
2 changes: 1 addition & 1 deletion packages/next-polyfill-module/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/polyfill-module",
"version": "10.0.3",
"version": "10.0.4-canary.1",
"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",
Expand Down
2 changes: 1 addition & 1 deletion packages/next-polyfill-nomodule/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/polyfill-nomodule",
"version": "10.0.3",
"version": "10.0.4-canary.1",
"description": "A polyfill for non-dead, nomodule browsers.",
"main": "dist/polyfill-nomodule.js",
"license": "MIT",
Expand Down
17 changes: 17 additions & 0 deletions packages/next/build/webpack-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,9 @@ export default async function getBaseWebpackConfig(
// Which makes bundles slightly smaller, but also skips parsing a module that we know will result in this alias
'next/head': 'next/dist/next-server/lib/head.js',
'next/router': 'next/dist/client/router.js',
'next/experimental-script': config.experimental.scriptLoader
? 'next/dist/client/experimental-script.js'
: '',
'next/config': 'next/dist/next-server/lib/runtime-config.js',
'next/dynamic': 'next/dist/next-server/lib/dynamic.js',
next: NEXT_PROJECT_ROOT,
Expand Down Expand Up @@ -728,6 +731,10 @@ export default async function getBaseWebpackConfig(
// When the 'serverless' target is used all node_modules will be compiled into the output bundles
// So that the 'serverless' bundles have 0 runtime dependencies
'@ampproject/toolbox-optimizer', // except this one

// Mark this as external if not enabled so it doesn't cause a
// webpack error from being missing
...(config.experimental.optimizeCss ? [] : ['critters']),
],
optimization: {
// Webpack 5 uses a new property for the same functionality
Expand Down Expand Up @@ -966,6 +973,9 @@ export default async function getBaseWebpackConfig(
'process.env.__NEXT_OPTIMIZE_IMAGES': JSON.stringify(
config.experimental.optimizeImages
),
'process.env.__NEXT_OPTIMIZE_CSS': JSON.stringify(
!!config.experimental.optimizeCss && !dev
),
'process.env.__NEXT_SCROLL_RESTORATION': JSON.stringify(
config.experimental.scrollRestoration
),
Expand Down Expand Up @@ -1209,6 +1219,13 @@ export default async function getBaseWebpackConfig(
webpack,
})

if (!webpackConfig) {
throw new Error(
'Webpack config is undefined. You may have forgot to return properly from within the "webpack" method of your next.config.js.\n' +
'See more info here https://err.sh/next.js/undefined-webpack-config'
)
}

if (dev && originalDevtool !== webpackConfig.devtool) {
webpackConfig.devtool = originalDevtool
devtoolRevertWarning(originalDevtool)
Expand Down
159 changes: 159 additions & 0 deletions packages/next/client/experimental-script.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
import React, { useEffect, useContext } from 'react'
import { ScriptHTMLAttributes } from 'react'
import { HeadManagerContext } from '../next-server/lib/head-manager-context'
import { DOMAttributeNames } from './head-manager'
import requestIdleCallback from './request-idle-callback'

const ScriptCache = new Map()
const LoadCache = new Set()

interface Props extends ScriptHTMLAttributes<HTMLScriptElement> {
strategy?: 'defer' | 'lazy' | 'dangerouslyBlockRendering' | 'eager'
id?: string
onLoad?: () => void
onError?: () => void
children?: React.ReactNode
preload?: boolean
}

const loadScript = (props: Props) => {
const {
src = '',
onLoad = () => {},
dangerouslySetInnerHTML,
children = '',
id,
onError,
} = props

const cacheKey = id || src
if (ScriptCache.has(src)) {
if (!LoadCache.has(cacheKey)) {
LoadCache.add(cacheKey)
// Execute onLoad since the script loading has begun
ScriptCache.get(src).then(onLoad, onError)
}
return
}

const el = document.createElement('script')

const loadPromise = new Promise((resolve, reject) => {
el.addEventListener('load', function () {
resolve()
if (onLoad) {
onLoad.call(this)
}
})
el.addEventListener('error', function () {
reject()
if (onError) {
onError()
}
})
})

if (src) {
ScriptCache.set(src, loadPromise)
LoadCache.add(cacheKey)
}

if (dangerouslySetInnerHTML) {
el.innerHTML = dangerouslySetInnerHTML.__html || ''
} else if (children) {
el.textContent =
typeof children === 'string'
? children
: Array.isArray(children)
? children.join('')
: ''
} else if (src) {
el.src = src
}

for (const [k, value] of Object.entries(props)) {
if (value === undefined) {
continue
}

const attr = DOMAttributeNames[k] || k.toLowerCase()
el.setAttribute(attr, value)
}

document.body.appendChild(el)
}

export default function Script(props: Props) {
const {
src = '',
onLoad = () => {},
dangerouslySetInnerHTML,
children = '',
strategy = 'defer',
onError,
preload = false,
...restProps
} = props

// Context is available only during SSR
const { updateScripts, scripts } = useContext(HeadManagerContext)

useEffect(() => {
if (strategy === 'defer') {
loadScript(props)
} else if (strategy === 'lazy') {
window.addEventListener('load', () => {
requestIdleCallback(() => loadScript(props))
})
}
}, [strategy, props])

if (strategy === 'dangerouslyBlockRendering') {
const syncProps: Props = { ...restProps }

for (const [k, value] of Object.entries({
src,
onLoad,
onError,
dangerouslySetInnerHTML,
children,
})) {
if (!value) {
continue
}
if (k === 'children') {
syncProps.dangerouslySetInnerHTML = {
__html:
typeof value === 'string'
? value
: Array.isArray(value)
? value.join('')
: '',
}
} else {
;(syncProps as any)[k] = value
}
}

return <script {...syncProps} />
} else if (strategy === 'defer') {
if (updateScripts && preload) {
scripts.defer = (scripts.defer || []).concat([src])
updateScripts(scripts)
}
} else if (strategy === 'eager') {
if (updateScripts) {
scripts.eager = (scripts.eager || []).concat([
{
src,
onLoad,
onError,
...restProps,
},
])
updateScripts(scripts)
}
}

return null
}
2 changes: 1 addition & 1 deletion packages/next/client/head-manager.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const DOMAttributeNames: Record<string, string> = {
export const DOMAttributeNames: Record<string, string> = {
acceptCharset: 'accept-charset',
className: 'class',
htmlFor: 'for',
Expand Down
Loading

0 comments on commit a06a04f

Please sign in to comment.