* Add support for custom App and Component enhancers
* Add ctx.renderPage test
* Add tests for single enhancer function
* Cleanup renderPage options check
* Cleanup
* Add comment about backwards compatibility for renderPage
* Add more test cases
This PR fixes#4615
From the issue :
> One thing we might consider is merging and showing a warning for keys not defined in exportPathMap
The behaviour after this PR is the following :
```js
// next.config.js
module.exports = {
exportPathMap: () => ({
'/': { page: '/', query: { a: 'blue' } }
})
}
```
| url called | `ctx.query` | warning ? |
|-|-|-|
| `/` | `{ a: 'blue' }` | |
| `/?a=red` | `{ a: 'blue' }` | |
| `/?b=green` | `{ a: 'blue', b: 'green' }` | `... parameter 'b' missing in exportPathMap` |
Is that the expected behaviour ? If not, I'll update the PR to shape the expected behavior.
I can't use a functional component with `_document.js`.
[is-react](https://www.npmjs.com/package/is-react) can be used for another potential implementation of the warning logic, but maybe relying on `React.createElement()` internal checks is enough.
A follow-up to #4604: the dot in the regexp was not escaped as intended. By default `*` matches greedily, so the results are the same, but the new regexp should be more clear. Sorry for the mistake.
The prepares for next-server.
I also took this as an opportunity to get all build directory paths from a single location, as they were previously scattered across webpack/babel plugins and loaders.
Fixes#4603.
Tests explain it the best:
```js
describe('development mode (no chunkhash)', () => {
it('should strip the extension from the filename', () => {
const filename = 'foo_bar_0123456789abcdef.js'
expect(getChunkNameFromFilename(filename, true)).toBe('foo_bar_0123456789abcdef')
})
it('should only strip the extension even if there\'s a hyphen in the name', () => {
const filename = 'foo-bar-0123456789abcdef.js'
expect(getChunkNameFromFilename(filename, true)).toBe('foo-bar-0123456789abcdef')
})
})
describe('production mode (with chunkhash)', () => {
it('should strip the hash from the filename', () => {
const filename = 'foo_bar_0123456789abcdef-0123456789abcdef.js'
expect(getChunkNameFromFilename(filename, false)).toBe('foo_bar_0123456789abcdef')
})
it('should only strip the part after the last hyphen in the filename', () => {
const filename = 'foo-bar-0123456789abcdef-0123456789abcdef.js'
expect(getChunkNameFromFilename(filename, false)).toBe('foo-bar-0123456789abcdef')
})
})
```
This fixes a missed bug introduced in #4510.
Because the regexp was `/-[^-]*/` and not `/-[^-]*$/`, a wrong part of the filename was being removed:
```
bad:
'foo-bar-0123456789abcdef-0123456789abcdef.js' -> 'foo-0123456789abcdef-0123456789abcdef.js'
good:
'foo-bar-0123456789abcdef-0123456789abcdef.js' -> 'foo-bar-0123456789abcdef'
```
By a stroke of luck this didn't affect the existing dynamically generated chunks. To prevent regression I've added unit tests for the function that generates the name.
Btw. in the original issue (#4433) I used the right regexp, I just used the wrong regexp in #4510.
cc @timneutkens
Fixes one of the problems described in #4433.
The old regexp was removing everything after a hyphen, so with a chunk name like so:
```
chunks/path-to-a-file-[hash].js
```
the saved chunk name was
```
chunks/path
```
This caused problems, because webpack by default changes `/` to `-` in chunk names generated e.g. by ``import(`foo/${bar}`)``.
After this change the chunk name will be
```
chunks/path-to-a-file
```
Since `_app.js` is used on every page it makes sense to move it's dependencies to the `commons.js` so that if you require a dependency in `_app.js` and in one of your pages it is not included twice in your bundles.
This PR modifies the `CommonsChunkPlugin` to move every module that is used in `_app.js` and at least in one other bundle.
Previously we called this directory holding the pages/chunks for server rendering `.next/dist` instead of `.next/server` which is confusing both when looking at it and in the codebase, since there's also `distDir` as a configuration option.
Also made this a constant in `next/constants` so functionality using this can be easily found.
This fixes the generated page chunk created by the webpack `pages-plugin` which adds a new line in the beginning of the template, when using `output.libraryTarget` set to be [`umd`](https://webpack.js.org/configuration/output/#module-definition-systems) it returns the module.
Consider the following example, which is the output with the previous implementation:
```js
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else if(typeof exports === 'object')
exports["MyLibrary"] = factory();
else
root["MyLibrary"] = factory();
})(typeof self !== 'undefined' ? self : this, function() {
return
__NEXT_REGISTER_PAGE(...)
});
```
`__NEXT_REGISTER_PAGE()` won't be executed since a `return` statement followed by a new line is the same as having a semicolon inserted right after the `return`. By removing the new line in the beginning of the source concatenation (which I suppose was added for stylistic reasons) this works as expected.
* Don’t use chunkhash in development
* Add test for dynamic imports styling
* Remove pre-load of dynamic page
* Make sure the browser gets closed only once
When running some tests, I noticed that Akamai was still caching the
response for render errors for some reason. Honestly, I would've
thought that `no-store, must-revalidate` would be enough to prevent
the CDN from caching it.
That being said, MDN's documentation on [Cache-Control] has a section
called ["Preventing Caching"] and recommends also using the `no-cache`
directive.
Given the definitions provided for `no-cache` and `no-store`, I can't
tell much of a difference between these two. But I _do_ know that,
for whatever reason, Akamai seems to respect the `no-cache` value for
this header.
[Cache-Control]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control
["Preventing Caching"]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#Preventing_caching
* Handle production errors correctly
* Improved source map support
* Make react-hot-loader hold state again
* Remove console.log
* Load modules on demand
* Catch errors in rewriteErrorTrace
* Update comment
* Update comment
* Remove source-map-support
* Load modules in next-dev
* Make sure error logged has sourcemaps too
* Add tests for production runtime errors
* Add tests for development runtime errors. Fix issue with client side errors in development
* Move functionality back to renderError now that error handling is consistent
* Rename to applySourcemaps
* Expose pages/_app.js
* Add tests for _app and _document
* Uncomment deprecation warnings
* Add documentation for _app, improve documentation of _document
* Update docs / test for _document
* Add _document to client compiler in development
* Add missing app.js to comment
* Only warn once
* Add url-deprecated error page
* Combine tests
* Yse same message for all methods of ‘props.url’
* Update docs around _app
* Update documentation
* Quotes
* Update table of contents
* Add build manifest
* Split out css since they don’t have exact name
* Remove pages map
* Fix locations test
* Re-run tests
* Get consistent open ports
* Fix static tests
* Add comment about Cache-Control header
* Allow BUILD_ID to be set in the environment
This makes multi server deploys with Capistrano possible.
* next.config.js generateBuildId support
enable customising the build id via config
* Provide default for generateBuildId
* This is not used