mirror of
https://github.com/terribleplan/next.js.git
synced 2024-01-19 02:48:18 +00:00
Allow etags to be disabled with config option (#3915)
* Allow etags to be disabled with config option - CR Change: Rename option to generateEtags - CR Change: Add tests for etag generation - CR Change: Refactor to use next.config.js - Update documentation * Use renderOpts instead of passing nextConfig
This commit is contained in:
parent
c5bd36e373
commit
eff27bdcfb
11
readme.md
11
readme.md
|
@ -1047,6 +1047,17 @@ module.exports = {
|
|||
}
|
||||
```
|
||||
|
||||
#### Disabling etag generation
|
||||
|
||||
You can disable etag generation for HTML pages depending on your cache strategy. If no configuration is specified then Next will generate etags for every page.
|
||||
|
||||
```js
|
||||
// next.config.js
|
||||
module.exports = {
|
||||
generateEtags: false
|
||||
}
|
||||
```
|
||||
|
||||
#### Configuring the onDemandEntries
|
||||
|
||||
Next exposes some options that give you some control over how the server will dispose or keep in memories pages built:
|
||||
|
|
|
@ -10,6 +10,7 @@ const defaultConfig = {
|
|||
assetPrefix: '',
|
||||
configOrigin: 'default',
|
||||
useFileSystemPublicRoutes: true,
|
||||
generateEtags: true,
|
||||
pageExtensions: ['jsx', 'js'] // jsx before js because otherwise regex matching will match js first
|
||||
}
|
||||
|
||||
|
|
|
@ -45,6 +45,10 @@ export default class Server {
|
|||
updateNotifier(pkg, 'next')
|
||||
}
|
||||
|
||||
// Only serverRuntimeConfig needs the default
|
||||
// publicRuntimeConfig gets it's default in client/index.js
|
||||
const {serverRuntimeConfig = {}, publicRuntimeConfig, assetPrefix, generateEtags} = this.nextConfig
|
||||
|
||||
if (!dev && !fs.existsSync(resolve(dir, this.dist, 'BUILD_ID'))) {
|
||||
console.error(`> Could not find a valid build in the '${this.dist}' directory! Try building your app with 'next build' before starting the server.`)
|
||||
process.exit(1)
|
||||
|
@ -57,13 +61,10 @@ export default class Server {
|
|||
dist: this.dist,
|
||||
hotReloader: this.hotReloader,
|
||||
buildId: this.buildId,
|
||||
availableChunks: dev ? {} : getAvailableChunks(this.dir, this.dist)
|
||||
availableChunks: dev ? {} : getAvailableChunks(this.dir, this.dist),
|
||||
generateEtags
|
||||
}
|
||||
|
||||
// Only serverRuntimeConfig needs the default
|
||||
// publicRuntimeConfig gets it's default in client/index.js
|
||||
const {serverRuntimeConfig = {}, publicRuntimeConfig, assetPrefix} = this.nextConfig
|
||||
|
||||
// Only the `publicRuntimeConfig` key is exposed to the client side
|
||||
// It'll be rendered as part of __NEXT_DATA__ on the client side
|
||||
if (publicRuntimeConfig) {
|
||||
|
|
|
@ -138,9 +138,9 @@ export async function renderScriptError (req, res, page, error) {
|
|||
res.end('500 - Internal Error')
|
||||
}
|
||||
|
||||
export function sendHTML (req, res, html, method, { dev }) {
|
||||
export function sendHTML (req, res, html, method, { dev, generateEtags }) {
|
||||
if (isResSent(res)) return
|
||||
const etag = generateETag(html)
|
||||
const etag = generateEtags && generateETag(html)
|
||||
|
||||
if (fresh(req.headers, { etag })) {
|
||||
res.statusCode = 304
|
||||
|
@ -154,7 +154,10 @@ export function sendHTML (req, res, html, method, { dev }) {
|
|||
res.setHeader('Cache-Control', 'no-store, must-revalidate')
|
||||
}
|
||||
|
||||
if (etag) {
|
||||
res.setHeader('ETag', etag)
|
||||
}
|
||||
|
||||
if (!res.getHeader('Content-Type')) {
|
||||
res.setHeader('Content-Type', 'text/html; charset=utf-8')
|
||||
}
|
||||
|
|
|
@ -2,5 +2,6 @@ module.exports = {
|
|||
onDemandEntries: {
|
||||
// Make sure entries are not getting disposed.
|
||||
maxInactiveAge: 1000 * 60 * 60
|
||||
}
|
||||
},
|
||||
generateEtags: process.env.GENERATE_ETAGS === 'true'
|
||||
}
|
||||
|
|
|
@ -7,7 +7,8 @@ import cheerio from 'cheerio'
|
|||
import {
|
||||
initNextServerScript,
|
||||
killApp,
|
||||
renderViaHTTP
|
||||
renderViaHTTP,
|
||||
fetchViaHTTP
|
||||
} from 'next-test-utils'
|
||||
import webdriver from 'next-webdriver'
|
||||
|
||||
|
@ -18,18 +19,24 @@ jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000 * 60 * 2
|
|||
|
||||
const context = {}
|
||||
|
||||
describe('Custom Server', () => {
|
||||
beforeAll(async () => {
|
||||
const startServer = async (optEnv = {}) => {
|
||||
const scriptPath = join(appDir, 'server.js')
|
||||
context.appPort = appPort = await getPort()
|
||||
const env = clone(process.env)
|
||||
env.PORT = `${appPort}`
|
||||
const env = Object.assign(
|
||||
{},
|
||||
clone(process.env),
|
||||
{ PORT: `${appPort}` },
|
||||
optEnv
|
||||
)
|
||||
|
||||
server = await initNextServerScript(scriptPath, /Ready on/, env)
|
||||
})
|
||||
}
|
||||
|
||||
describe('Custom Server', () => {
|
||||
describe('with dynamic assetPrefix', () => {
|
||||
beforeAll(() => startServer())
|
||||
afterAll(() => killApp(server))
|
||||
|
||||
describe('with dynamic assetPrefix', () => {
|
||||
it('should set the assetPrefix dynamically', async () => {
|
||||
const normalUsage = await renderViaHTTP(appPort, '/asset')
|
||||
expect(normalUsage).not.toMatch(/127\.0\.0\.1/)
|
||||
|
@ -83,4 +90,24 @@ describe('Custom Server', () => {
|
|||
browser2.close()
|
||||
})
|
||||
})
|
||||
|
||||
describe('with generateEtags enabled', () => {
|
||||
beforeAll(() => startServer({ GENERATE_ETAGS: 'true' }))
|
||||
afterAll(() => killApp(server))
|
||||
|
||||
it('response includes etag header', async () => {
|
||||
const response = await fetchViaHTTP(appPort, '/')
|
||||
expect(response.headers.get('etag')).toBeTruthy()
|
||||
})
|
||||
})
|
||||
|
||||
describe('with generateEtags disabled', () => {
|
||||
beforeAll(() => startServer({ GENERATE_ETAGS: 'false' }))
|
||||
afterAll(() => killApp(server))
|
||||
|
||||
it('response does not include etag header', async () => {
|
||||
const response = await fetchViaHTTP(appPort, '/')
|
||||
expect(response.headers.get('etag')).toBeNull()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
Loading…
Reference in a new issue