es-dev-server
Version:
Development server for modern web apps
162 lines • 7.61 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.createMiddlewares = void 0;
const tslib_1 = require("tslib");
const chokidar_1 = tslib_1.__importDefault(require("chokidar"));
const koa_compress_1 = tslib_1.__importDefault(require("koa-compress"));
const koa_etag_1 = tslib_1.__importDefault(require("koa-etag"));
const koa_static_1 = tslib_1.__importDefault(require("koa-static"));
const cors_1 = tslib_1.__importDefault(require("@koa/cors"));
const constants_1 = require("./constants");
const base_path_1 = require("./middleware/base-path");
const etag_cache_1 = require("./middleware/etag-cache");
const history_api_fallback_1 = require("./middleware/history-api-fallback");
const message_channel_1 = require("./middleware/message-channel");
const plugin_mime_type_1 = require("./middleware/plugin-mime-type");
const plugin_serve_1 = require("./middleware/plugin-serve");
const plugin_transform_1 = require("./middleware/plugin-transform");
const response_transform_1 = require("./middleware/response-transform");
const watch_served_files_1 = require("./middleware/watch-served-files");
const babelTransformPlugin_1 = require("./plugins/babelTransformPlugin");
const fileExtensionsPlugin_1 = require("./plugins/fileExtensionsPlugin");
const nodeResolvePlugin_1 = require("./plugins/nodeResolvePlugin");
const polyfillsLoaderPlugin_1 = require("./plugins/polyfillsLoaderPlugin");
const resolveModuleImportsPlugin_1 = require("./plugins/resolveModuleImportsPlugin");
const utils_1 = require("./utils/utils");
const MessageChannel_1 = require("./utils/MessageChannel");
const browserReloadPlugin_1 = require("./plugins/browserReloadPlugin");
const defaultCompressOptions = {
filter(contentType) {
// event stream doesn't like compression
return contentType !== 'text/event-stream';
},
};
function hasHook(plugins, hook) {
return plugins.some(plugin => hook in plugin);
}
/**
* Creates middlewares based on the given configuration. The middlewares can be
* used by a koa server using `app.use()`:
*/
function createMiddlewares(config, fileWatcher = chokidar_1.default.watch([])) {
const { appIndex, appIndexDir, basePath, compatibilityMode, compress, customBabelConfig, customMiddlewares, responseTransformers, fileExtensions, nodeResolve, eventStream, polyfillsLoader, polyfillsLoaderConfig, readUserBabelConfig, plugins, rootDir, watch, logErrorsToBrowser, watchDebounce, babelExclude, babelModernExclude, babelModuleExclude, customBabelInclude, customBabelExclude, cors, } = config;
const middlewares = [];
middlewares.push((ctx, next) => {
utils_1.logDebug(`Receiving request: ${ctx.url}`);
return next();
});
if (compress) {
const options = typeof compress === 'object' ? compress : defaultCompressOptions;
middlewares.push(koa_compress_1.default(options));
}
if (!Object.values(constants_1.compatibilityModes).includes(compatibilityMode)) {
throw new Error(`Unknown compatibility mode: ${compatibilityMode}. Must be one of: ${Object.values(constants_1.compatibilityModes)}`);
}
const setupCompatibility = compatibilityMode !== constants_1.compatibilityModes.NONE;
const setupBabel = customBabelConfig || readUserBabelConfig;
const setupHistoryFallback = appIndex;
const setupMessageChannel = eventStream && (watch || (logErrorsToBrowser && (setupCompatibility || nodeResolve)));
const messageChannel = setupMessageChannel ? new MessageChannel_1.MessageChannel() : undefined;
if (fileExtensions.length > 0) {
plugins.unshift(fileExtensionsPlugin_1.fileExtensionsPlugin({ fileExtensions }));
}
if (nodeResolve || hasHook(plugins, 'resolveImport')) {
if (nodeResolve) {
plugins.push(nodeResolvePlugin_1.nodeResolvePlugin({ rootDir, fileExtensions, nodeResolve }));
}
plugins.push(resolveModuleImportsPlugin_1.resolveModuleImportsPlugin({ rootDir, plugins }));
}
if (setupCompatibility || setupBabel) {
plugins.push(babelTransformPlugin_1.babelTransformPlugin({
rootDir,
readUserBabelConfig,
nodeResolve,
compatibilityMode,
customBabelConfig,
fileExtensions,
babelExclude,
babelModernExclude,
babelModuleExclude,
customBabelInclude,
customBabelExclude,
}));
}
if (polyfillsLoader && setupCompatibility) {
plugins.push(polyfillsLoaderPlugin_1.polyfillsLoaderPlugin({
rootDir,
compatibilityMode,
polyfillsLoaderConfig,
}));
}
if (watch) {
plugins.push(browserReloadPlugin_1.browserReloadPlugin({ watchDebounce }));
}
// strips a base path from requests
if (basePath) {
middlewares.push(base_path_1.createBasePathMiddleware({ basePath }));
}
// adds custom user's middlewares
if (customMiddlewares && customMiddlewares.length > 0) {
customMiddlewares.forEach(customMiddleware => {
middlewares.push(customMiddleware);
});
}
middlewares.push(async (ctx, next) => {
await next();
utils_1.logDebug(`Serving request: ${ctx.url} with status: ${ctx.status}`);
});
// serves 304 responses if resource hasn't changed
middlewares.push(etag_cache_1.createEtagCacheMiddleware());
// adds etag headers for caching
middlewares.push(koa_etag_1.default());
// communicates with browser for reload or logging
if (setupMessageChannel && messageChannel) {
middlewares.push(message_channel_1.createMessageChannelMiddleware({ messageChannel }));
}
// watches served files
middlewares.push(watch_served_files_1.createWatchServedFilesMiddleware({
rootDir,
fileWatcher,
}));
// serves index.html for non-file requests for SPA routing
if (setupHistoryFallback && typeof appIndex === 'string' && typeof appIndexDir === 'string') {
middlewares.push(history_api_fallback_1.createHistoryAPIFallbackMiddleware({ appIndex, appIndexDir }));
}
middlewares.push(plugin_transform_1.createPluginTransformMiddlware({
plugins,
fileWatcher,
rootDir,
fileExtensions,
messageChannel,
logErrorsToBrowser,
}));
// DEPRECATED: Response transformers (now split up in serve and transform in plugins)
if (responseTransformers) {
middlewares.push(response_transform_1.createResponseTransformMiddleware({ responseTransformers }));
}
middlewares.push(plugin_mime_type_1.createPluginMimeTypeMiddleware({ plugins }));
if (cors) {
middlewares.push(cors_1.default());
}
middlewares.push(plugin_serve_1.createPluginServeMiddlware({ plugins }));
// serve static files
middlewares.push(koa_static_1.default(rootDir, {
hidden: true,
setHeaders(res) {
res.setHeader('cache-control', 'no-cache');
},
}));
return {
middlewares,
// callback called by start-server
async onServerStarted(app, server) {
// call server start plugin hooks in parallel
const startHooks = plugins
.filter(pl => !!pl.serverStart)
.map(pl => { var _a; return (_a = pl.serverStart) === null || _a === void 0 ? void 0 : _a.call(pl, { config, app, server, fileWatcher, messageChannel }); });
await Promise.all(startHooks);
},
};
}
exports.createMiddlewares = createMiddlewares;
//# sourceMappingURL=create-middlewares.js.map