From b74d537cbada7b52b91be7d36a815b81c4805676 Mon Sep 17 00:00:00 2001 From: Alexander Lichter Date: Sat, 8 Sep 2018 21:18:14 +0100 Subject: [PATCH] feat(renderer): make compression middleware customizable (#3863) --- lib/common/nuxt.config.js | 2 +- lib/common/options.js | 8 +++++++- lib/core/renderer.js | 16 ++++++++++++---- test/fixtures/with-config/nuxt.config.js | 2 ++ test/fixtures/with-config/with-config.test.js | 11 ++++++++++- test/utils/build.js | 3 ++- 6 files changed, 34 insertions(+), 8 deletions(-) diff --git a/lib/common/nuxt.config.js b/lib/common/nuxt.config.js index bf25274f3b..22e03328ec 100644 --- a/lib/common/nuxt.config.js +++ b/lib/common/nuxt.config.js @@ -207,7 +207,7 @@ export default { static: { prefix: true }, - gzip: { + compressor: { threshold: 0 }, etag: { diff --git a/lib/common/options.js b/lib/common/options.js index d60d1b9b24..9cf2b1bc45 100644 --- a/lib/common/options.js +++ b/lib/common/options.js @@ -3,7 +3,6 @@ import fs from 'fs' import _ from 'lodash' import consola from 'consola' - import { isPureObject, isUrl } from '../common/utils' import modes from './modes' @@ -169,6 +168,13 @@ Options.from = function (_options) { options.ignore.push(`**/${options.ignorePrefix}*.*`) } + // Compression middleware legacy + if (options.render.gzip) { + consola.warn('render.gzip is deprecated and will be removed in a future version! Please switch to build.render.compressor') + options.render.compressor = options.render.gzip + delete options.render.gzip + } + // Apply mode preset const modePreset = modes[options.mode || 'universal'] || modes.universal _.defaultsDeep(options, modePreset) diff --git a/lib/core/renderer.js b/lib/core/renderer.js index 6e4827ce0c..fbca2308a6 100644 --- a/lib/core/renderer.js +++ b/lib/core/renderer.js @@ -3,7 +3,6 @@ import crypto from 'crypto' import serialize from 'serialize-javascript' import serveStatic from 'serve-static' -import compression from 'compression' import _ from 'lodash' import fs from 'fs-extra' import { createBundleRenderer } from 'vue-server-renderer' @@ -201,9 +200,18 @@ export default class Renderer { // Apply setupMiddleware from modules first await this.nuxt.callHook('render:setupMiddleware', this.app) - // Gzip middleware for production - if (!this.options.dev && this.options.render.gzip) { - this.useMiddleware(compression(this.options.render.gzip)) + // Compression middleware for production + if (!this.options.dev) { + const compressor = this.options.render.compressor + if (typeof compressor === 'object') { + // If only setting for `compression` are provided, require the module and insert + // Prefer require instead of requireModule to keep dependency in nuxt-start + const compression = require('compression') + this.useMiddleware(compression(compressor)) + } else { + // Else, require own compression middleware + this.useMiddleware(compressor) + } } // Add webpack middleware only for development diff --git a/test/fixtures/with-config/nuxt.config.js b/test/fixtures/with-config/nuxt.config.js index 31d2f9c413..225158dea9 100644 --- a/test/fixtures/with-config/nuxt.config.js +++ b/test/fixtures/with-config/nuxt.config.js @@ -1,4 +1,5 @@ import path from 'path' +import compression from 'compression' export default { srcDir: __dirname, @@ -86,6 +87,7 @@ export default { return ['script', 'style', 'font'].includes(type) } }, + compressor: function damn(...args) { return compression({ threshold: 9 })(...args) }, static: { maxAge: '1y' } diff --git a/test/fixtures/with-config/with-config.test.js b/test/fixtures/with-config/with-config.test.js index b9b0ebe953..484bb11f72 100644 --- a/test/fixtures/with-config/with-config.test.js +++ b/test/fixtures/with-config/with-config.test.js @@ -1,13 +1,22 @@ import consola from 'consola' import { buildFixture } from '../../utils/build' +let customCompressionMiddlewareFunctionName +const hooks = [ + ['render:errorMiddleware', (app) => { + customCompressionMiddlewareFunctionName = app.stack[0].handle.name + }] +] + describe('with-config', () => { buildFixture('with-config', () => { expect(consola.warn).toHaveBeenCalledTimes(1) + expect(consola.fatal).toHaveBeenCalledTimes(0) expect(consola.warn.mock.calls[0]).toMatchObject([{ message: 'Found 2 plugins that match the configuration, suggest to specify extension:', additional: expect.stringContaining('plugins/test.json'), badge: true }]) - }) + expect(customCompressionMiddlewareFunctionName).toBe('damn') + }, hooks) }) diff --git a/test/utils/build.js b/test/utils/build.js index a95c4954fd..3052e4938f 100644 --- a/test/utils/build.js +++ b/test/utils/build.js @@ -1,10 +1,11 @@ import { loadFixture, Nuxt, Builder } from './index' -export const buildFixture = function (fixture, callback) { +export const buildFixture = function (fixture, callback, hooks = []) { test(`Build ${fixture}`, async () => { const config = await loadFixture(fixture) const nuxt = new Nuxt(config) const buildDone = jest.fn() + hooks.forEach(([hook, fn]) => nuxt.hook(hook, fn)) nuxt.hook('build:done', buildDone) const builder = await new Builder(nuxt).build() // 2: BUILD_DONE