This commit is contained in:
2022-07-18 02:50:52 +00:00
parent befd344ab0
commit 06181b34d6
8569 changed files with 818704 additions and 352705 deletions
+142 -81
View File
@@ -1,21 +1,42 @@
/*!
* @nuxt/server v2.13.3 (c) 2016-2020
* - All the amazing contributors
* Released under the MIT License.
* @nuxt/server v2.15.8 (c) 2016-2021
* Released under the MIT License
* Repository: https://github.com/nuxt/nuxt.js
* Website: https://nuxtjs.org
*/
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
const path = require('path');
const consola = require('consola');
const launchMiddleware = require('launch-editor-middleware');
const serveStatic = require('serve-static');
const servePlaceholder = require('serve-placeholder');
const connect = require('connect');
const compression = require('compression');
const utils = require('@nuxt/utils');
const vueRenderer = require('@nuxt/vue-renderer');
const generateETag = require('etag');
const fresh = require('fresh');
const ufo = require('ufo');
const fs = require('fs-extra');
const Youch = require('@nuxtjs/youch');
const http = require('http');
const https = require('https');
const enableDestroy = require('server-destroy');
const ip = require('ip');
const pify = require('pify');
const onHeaders = require('on-headers');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
function _interopNamespace(e) {
if (e && e.__esModule) { return e; } else {
var n = {};
if (e) {
Object.keys(e).forEach(function (k) {
if (e && e.__esModule) return e;
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
@@ -23,30 +44,30 @@ function _interopNamespace(e) {
return e[k];
}
});
});
}
n['default'] = e;
return n;
}
});
}
n['default'] = e;
return Object.freeze(n);
}
const path = _interopDefault(require('path'));
const consola = _interopDefault(require('consola'));
const launchMiddleware = _interopDefault(require('launch-editor-middleware'));
const serveStatic = _interopDefault(require('serve-static'));
const servePlaceholder = _interopDefault(require('serve-placeholder'));
const connect = _interopDefault(require('connect'));
const utils = require('@nuxt/utils');
const generateETag = _interopDefault(require('etag'));
const fresh = _interopDefault(require('fresh'));
const fs = _interopDefault(require('fs-extra'));
const Youch = _interopDefault(require('@nuxtjs/youch'));
const http = _interopDefault(require('http'));
const https = _interopDefault(require('https'));
const enableDestroy = _interopDefault(require('server-destroy'));
const ip = _interopDefault(require('ip'));
const pify = _interopDefault(require('pify'));
const onHeaders = _interopDefault(require('on-headers'));
const path__default = /*#__PURE__*/_interopDefaultLegacy(path);
const consola__default = /*#__PURE__*/_interopDefaultLegacy(consola);
const launchMiddleware__default = /*#__PURE__*/_interopDefaultLegacy(launchMiddleware);
const serveStatic__default = /*#__PURE__*/_interopDefaultLegacy(serveStatic);
const servePlaceholder__default = /*#__PURE__*/_interopDefaultLegacy(servePlaceholder);
const connect__default = /*#__PURE__*/_interopDefaultLegacy(connect);
const compression__default = /*#__PURE__*/_interopDefaultLegacy(compression);
const generateETag__default = /*#__PURE__*/_interopDefaultLegacy(generateETag);
const fresh__default = /*#__PURE__*/_interopDefaultLegacy(fresh);
const fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
const Youch__default = /*#__PURE__*/_interopDefaultLegacy(Youch);
const http__default = /*#__PURE__*/_interopDefaultLegacy(http);
const https__default = /*#__PURE__*/_interopDefaultLegacy(https);
const enableDestroy__default = /*#__PURE__*/_interopDefaultLegacy(enableDestroy);
const ip__default = /*#__PURE__*/_interopDefaultLegacy(ip);
const pify__default = /*#__PURE__*/_interopDefaultLegacy(pify);
const onHeaders__default = /*#__PURE__*/_interopDefaultLegacy(onHeaders);
class ServerContext {
constructor (server) {
@@ -66,10 +87,10 @@ async function renderAndGetWindow (
globals
} = {}
) {
const jsdom = await Promise.resolve().then(function () { return _interopNamespace(require('jsdom')); })
const jsdom = await Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespace(require('jsdom')); })
.then(m => m.default || m)
.catch((e) => {
consola.error(`
consola__default['default'].error(`
jsdom is not installed. Please install jsdom with:
$ yarn add --dev jsdom
OR
@@ -95,10 +116,13 @@ async function renderAndGetWindow (
if (options.virtualConsole) {
if (options.virtualConsole === true) {
options.virtualConsole = new jsdom.VirtualConsole().sendTo(consola);
options.virtualConsole = new jsdom.VirtualConsole().sendTo(consola__default['default']);
}
// Throw error when window creation failed
options.virtualConsole.on('jsdomError', jsdomErrHandler);
} else {
// If we get the virtualConsole option as `false` we should delete for don't pass it to `jsdom.JSDOM.fromURL`
delete options.virtualConsole;
}
const { window } = await jsdom.JSDOM.fromURL(url, options);
@@ -113,7 +137,7 @@ async function renderAndGetWindow (
throw error
}
// Used by Nuxt.js to say when the components are loaded and the app ready
// Used by Nuxt to say when the components are loaded and the app ready
await utils.timeout(new Promise((resolve) => {
window[loadedCallback] = () => resolve(window);
}), loadingTimeout, `Components loading in renderAndGetWindow was not completed in ${loadingTimeout / 1000}s`);
@@ -132,7 +156,7 @@ const nuxtMiddleware = ({ options, nuxt, renderRoute, resources }) => async func
const context = utils.getContext(req, res);
try {
const url = decodeURI(req.url);
const url = ufo.normalizeURL(req.url);
res.statusCode = 200;
const result = await renderRoute(url, context);
@@ -159,11 +183,19 @@ const nuxtMiddleware = ({ options, nuxt, renderRoute, resources }) => async func
res.statusCode = context.nuxt.error.statusCode || 500;
}
if (options.render.csp && cspScriptSrcHashes) {
const { allowedSources, policies } = options.render.csp;
const isReportOnly = !!options.render.csp.reportOnly;
const cspHeader = isReportOnly ? 'Content-Security-Policy-Report-Only' : 'Content-Security-Policy';
res.setHeader(cspHeader, getCspString({ cspScriptSrcHashes, allowedSources, policies, isReportOnly }));
}
// Add ETag header
if (!error && options.render.etag) {
const { hash } = options.render.etag;
const etag = hash ? hash(html, options.render.etag) : generateETag(html, options.render.etag);
if (fresh(req.headers, { etag })) {
const etag = hash ? hash(html, options.render.etag) : generateETag__default['default'](html, options.render.etag);
if (fresh__default['default'](req.headers, { etag })) {
res.statusCode = 304;
await nuxt.callHook('render:beforeResponse', url, result, context);
res.end();
@@ -192,14 +224,6 @@ const nuxtMiddleware = ({ options, nuxt, renderRoute, resources }) => async func
}
}
if (options.render.csp && cspScriptSrcHashes) {
const { allowedSources, policies } = options.render.csp;
const isReportOnly = !!options.render.csp.reportOnly;
const cspHeader = isReportOnly ? 'Content-Security-Policy-Report-Only' : 'Content-Security-Policy';
res.setHeader(cspHeader, getCspString({ cspScriptSrcHashes, allowedSources, policies, isReportOnly }));
}
// Send response
res.setHeader('Content-Type', 'text/html; charset=utf-8');
res.setHeader('Accept-Ranges', 'none'); // #3870
@@ -210,7 +234,7 @@ const nuxtMiddleware = ({ options, nuxt, renderRoute, resources }) => async func
return html
} catch (err) {
if (context && context.redirected) {
consola.error(err);
consola__default['default'].error(err);
return err
}
@@ -223,7 +247,7 @@ const nuxtMiddleware = ({ options, nuxt, renderRoute, resources }) => async func
const defaultPushAssets = (preloadFiles, shouldPush, publicPath, options) => {
if (shouldPush && options.dev) {
consola.warn('http2.shouldPush is deprecated. Use http2.pushAssets function');
consola__default['default'].warn('http2.shouldPush is deprecated. Use http2.pushAssets function');
}
const links = [];
@@ -311,7 +335,7 @@ const errorMiddleware = ({ resources, options }) => async function errorMiddlewa
if (!options.debug) {
// We hide actual errors from end users, so show them on server logs
if (error.statusCode !== 404) {
consola.error(error);
consola__default['default'].error(error);
}
// Json format is compatible with Youch json responses
@@ -330,7 +354,7 @@ const errorMiddleware = ({ resources, options }) => async function errorMiddlewa
}
// Show stack trace
const youch = new Youch(
const youch = new Youch__default['default'](
error,
req,
readSource,
@@ -356,8 +380,7 @@ const normalizeError = (_error, { srcDir, rootDir, buildDir }) => {
_error = { message: '<empty>' };
}
const error = new Error();
error.message = _error.message;
const error = new Error(_error.message);
error.name = _error.name;
error.statusCode = _error.statusCode || 500;
error.headers = _error.headers;
@@ -365,15 +388,15 @@ const normalizeError = (_error, { srcDir, rootDir, buildDir }) => {
const searchPath = [
srcDir,
rootDir,
path.join(buildDir, 'dist', 'server'),
path__default['default'].join(buildDir, 'dist', 'server'),
buildDir,
process.cwd()
];
const findInPaths = (fileName) => {
for (const dir of searchPath) {
const fullPath = path.resolve(dir, fileName);
if (fs.existsSync(fullPath)) {
const fullPath = path__default['default'].resolve(dir, fileName);
if (fs__default['default'].existsSync(fullPath)) {
return fullPath
}
}
@@ -396,9 +419,9 @@ const normalizeError = (_error, { srcDir, rootDir, buildDir }) => {
};
async function readSource (frame) {
if (fs.existsSync(frame.fileName)) {
if (fs__default['default'].existsSync(frame.fileName)) {
frame.fullPath = frame.fileName; // Youch BW compat
frame.contents = await fs.readFile(frame.fileName, 'utf-8');
frame.contents = await fs__default['default'].readFile(frame.fileName, 'utf-8');
}
}
@@ -427,7 +450,7 @@ class Listener {
// Destroy server by forcing every connection to be closed
if (this.server && this.server.listening) {
await this.server.destroy();
consola.debug('server closed');
consola__default['default'].debug('server closed');
}
// Delete references
@@ -443,10 +466,11 @@ class Listener {
if (!this.socket) {
switch (address.address) {
case '127.0.0.1': this.host = 'localhost'; break
case '0.0.0.0': this.host = ip.address(); break
case '0.0.0.0': this.host = ip__default['default'].address(); break
}
this.port = address.port;
this.url = `http${this.https ? 's' : ''}://${this.host}:${this.port}${this.baseURL}`;
this.url = decodeURI(this.url);
return
}
this.url = `unix+http://${address}`;
@@ -459,7 +483,7 @@ class Listener {
}
// Initialize underlying http(s) server
const protocol = this.https ? https : http;
const protocol = this.https ? https__default['default'] : http__default['default'];
const protocolOpts = this.https ? [this.https] : [];
this._server = protocol.createServer.apply(protocol, protocolOpts.concat(this.app));
@@ -479,8 +503,8 @@ class Listener {
}
// Enable destroy support
enableDestroy(this.server);
pify(this.server.destroy);
enableDestroy__default['default'](this.server);
pify__default['default'](this.server.destroy);
// Compute listen URL
this.computeURL();
@@ -500,8 +524,8 @@ class Listener {
// Listen to a random port on dev as a fallback
if (this.dev && !this.socket && this.port !== RANDOM_PORT) {
consola.warn(error.message);
consola.info('Trying a random port...');
consola__default['default'].warn(error.message);
consola__default['default'].info('Trying a random port...');
this.port = RANDOM_PORT;
await this.close();
await this.listen();
@@ -517,7 +541,7 @@ class Listener {
const createTimingMiddleware = options => (req, res, next) => {
if (res.timing) {
consola.warn('server-timing is already registered.');
consola__default['default'].warn('server-timing is already registered.');
}
res.timing = new ServerTiming();
@@ -525,7 +549,7 @@ const createTimingMiddleware = options => (req, res, next) => {
res.timing.start('total', 'Nuxt Server Time');
}
onHeaders(res, () => {
onHeaders__default['default'](res, () => {
res.timing.end('total');
if (res.timing.headers.length > 0) {
@@ -577,7 +601,7 @@ class Server {
this.publicPath = utils.isUrl(this.options.build.publicPath)
? this.options.build._publicPath
: this.options.build.publicPath;
: this.options.build.publicPath.replace(/^\.+\//, '/');
// Runtime shared resources
this.resources = {};
@@ -586,7 +610,7 @@ class Server {
this.listeners = [];
// Create new connect instance
this.app = connect();
this.app = connect__default['default']();
// Close hook
this.nuxt.hook('close', () => this.close());
@@ -608,10 +632,8 @@ class Server {
await this.nuxt.callHook('render:before', this, this.options.render);
// Initialize vue-renderer
const { VueRenderer } = await Promise.resolve().then(function () { return _interopNamespace(require('@nuxt/vue-renderer')); });
this.serverContext = new ServerContext(this);
this.renderer = new VueRenderer(this.serverContext);
this.renderer = new vueRenderer.VueRenderer(this.serverContext);
await this.renderer.ready();
// Setup nuxt middleware
@@ -632,8 +654,7 @@ class Server {
const { compressor } = this.options.render;
if (typeof compressor === 'object') {
// If only setting for `compression` are provided, require the module and insert
const compression = this.nuxt.resolver.requireModule('compression');
this.useMiddleware(compression(compressor));
this.useMiddleware(compression__default['default'](compressor));
} else if (compressor) {
// Else, require own compression middleware if compressor is actually truthy
this.useMiddleware(compressor);
@@ -645,8 +666,8 @@ class Server {
}
// For serving static/ files to /
const staticMiddleware = serveStatic(
path.resolve(this.options.srcDir, this.options.dir.static),
const staticMiddleware = serveStatic__default['default'](
path__default['default'].resolve(this.options.srcDir, this.options.dir.static),
this.options.render.static
);
staticMiddleware.prefix = this.options.render.static.prefix;
@@ -655,10 +676,10 @@ class Server {
// Serve .nuxt/dist/client files only for production
// For dev they will be served with devMiddleware
if (!this.options.dev) {
const distDir = path.resolve(this.options.buildDir, 'dist', 'client');
const distDir = path__default['default'].resolve(this.options.buildDir, 'dist', 'client');
this.useMiddleware({
path: this.publicPath,
handler: serveStatic(
handler: serveStatic__default['default'](
distDir,
this.options.render.dist
)
@@ -671,6 +692,12 @@ class Server {
if (!this.devMiddleware) {
return next()
}
// Safari over-caches JS (breaking HMR) and the seemingly only way to turn
// this off in dev mode is to set Vary: * header
// #3828, #9034
if (req.url.startsWith(this.publicPath) && req.url.endsWith('.js')) {
res.setHeader('Vary', '*');
}
this.devMiddleware(req, res, next);
});
@@ -678,7 +705,7 @@ class Server {
if (this.options.debug) {
this.useMiddleware({
path: '__open-in-editor',
handler: launchMiddleware(this.options.editor)
handler: launchMiddleware__default['default'](this.options.editor)
});
}
}
@@ -695,7 +722,7 @@ class Server {
if (fallback.dist) {
this.useMiddleware({
path: this.publicPath,
handler: servePlaceholder(fallback.dist)
handler: servePlaceholder__default['default'](fallback.dist)
});
}
@@ -703,7 +730,7 @@ class Server {
if (fallback.static) {
this.useMiddleware({
path: '/',
handler: servePlaceholder(fallback.static)
handler: servePlaceholder__default['default'](fallback.static)
});
}
}
@@ -716,6 +743,25 @@ class Server {
resources: this.resources
}));
// DX: redirect if router.base in development
const routerBase = this.nuxt.options.router.base;
if (this.options.dev && routerBase !== '/') {
this.useMiddleware({
prefix: false,
handler: (req, res, next) => {
if (decodeURI(req.url).startsWith(decodeURI(routerBase))) {
return next()
}
const to = utils.urlJoin(routerBase, req.url);
consola__default['default'].info(`[Development] Redirecting from \`${decodeURI(req.url)}\` to \`${decodeURI(to)}\` (router.base specified)`);
res.writeHead(302, {
Location: to
});
res.end();
}
});
}
// Apply errorMiddleware from modules first
await this.nuxt.callHook('render:errorMiddleware', this.app);
@@ -737,6 +783,11 @@ class Server {
middleware = this._requireMiddleware(middleware);
}
// #8584
// shallow clone the middleware before any change is made,
// in case any following mutation breaks when applied repeatedly.
middleware = Object.assign({}, middleware);
// Normalize handler to handle (backward compatibility)
if (middleware.handler && !middleware.handle) {
middleware.handle = middleware.handler;
@@ -785,7 +836,7 @@ class Server {
middleware = this.nuxt.resolver.requireModule(entry);
} catch (error) {
// Show full error
consola.error('ServerMiddleware Error:', error);
consola__default['default'].error('ServerMiddleware Error:', error);
// Placeholder for error
middleware = (req, res, next) => { next(error); };
@@ -809,6 +860,10 @@ class Server {
middleware.route = fallbackRoute;
}
// #8584
// save the original route before applying defaults
middleware._originalRoute = middleware.route;
// Resolve final route
middleware.route = (
(middleware.prefix !== false ? this.options.router.base : '') +
@@ -851,7 +906,13 @@ class Server {
this.unloadMiddleware(serverStackItem);
// Resolve middleware
const { route, handle } = this.resolveMiddleware(middleware, serverStackItem.route);
const { route, handle } = this.resolveMiddleware(
middleware,
// #8584 pass the original route as fallback
serverStackItem.handle._middleware
? serverStackItem.handle._middleware._originalRoute
: serverStackItem.route
);
// Update serverStackItem
serverStackItem.handle = handle;