UNPKG

st-bundle

Version:

CLI for watching and bundling SpringType projects.

156 lines (155 loc) 5.99 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const express = require("express"); const Bundle_1 = require("../bundle/Bundle"); const resolver_1 = require("../resolver/resolver"); const devServerProps_1 = require("./devServerProps"); const hmrServer_1 = require("./hmrServer"); const open = require("open"); const proxyMiddleware = require("http-proxy-middleware"); const FasterThanLightReload_1 = require("../FTL/FasterThanLightReload"); function createExpressApp(ctx, props, extra) { const app = express(); app.all('/__ftl', (req, res) => { const ftlModules = ctx.assembleContext.getFTLModules(); const js = FasterThanLightReload_1.generateFTLJavaScript(ftlModules); res.set('Content-Type', 'application/javascript; charset=UTF-8'); res.send(js); }); if (props.express) props.express(app, express); function logProvider(p) { return { log: msg => { ctx.log.info('proxy', msg); }, debug: msg => { ctx.log.info('proxy', msg); }, info: msg => { ctx.log.info('proxy', msg); }, warn: msg => ctx.log.warn(msg), error: msg => ctx.log.error(msg), }; } if (extra && extra.proxyProps) { for (const item of extra.proxyProps) { item.options.logProvider = logProvider; app.use(item.path, proxyMiddleware(item.options)); } } app.use('/', express.static(props.root)); app.use('*', (req, res) => { res.sendFile(props.fallback); }); const server = app.listen(props.port, () => { if (extra && extra.openProps) { extra.openProps.target = extra.openProps.target || `http://localhost:${props.port}`; open(extra.openProps.target, extra.openProps); } ctx.log.info('development', `Development server is running at <bold>http://localhost:$port</bold>`, { port: props.port, }); }); if (server) { server.on('error', err => { ctx.fatal('An error occurred while trying to start the devServer.', [err.message]); }); } return server; } exports.createExpressApp = createExpressApp; function createDevServer(ctx) { const ict = ctx.ict; const props = devServerProps_1.createDevServerConfig(ctx); if (!props.enabled) { return; } const httpServerProps = props.httpServer; const hmrServerProps = props.hmrServer; const isProduction = !!ctx.config.production; let openProps; if (props.open) { if (typeof props.open === 'boolean') { openProps = {}; } if (typeof props.open === 'object') { openProps = props.open; } } let proxyProps; if (props.proxy) { proxyProps = props.proxy; } // injecting some settings into the dev bundle if (hmrServerProps.enabled) { // injecting hmr dependency if (!isProduction) { ict.on('assemble_fast_analysis', props => { const module = props.module; const pkg = module.pkg; if (pkg.isDefaultPackage && pkg.entry === module) { module.fastAnalysis.imports.push({ type: resolver_1.ImportType.REQUIRE, statement: 'fuse-box-hot-reload' }); } return props; }); ict.on('before_bundle_write', props => { const bundle = props.bundle; if (bundle.props.type === Bundle_1.BundleType.PROJECT_JS) { const clientProps = {}; if (hmrServerProps.connectionURL) { clientProps.connectionURL = hmrServerProps.connectionURL; } else { if (hmrServerProps.useCurrentURL || httpServerProps.port === hmrServerProps.port) { clientProps.useCurrentURL = true; } else if (hmrServerProps.port) { clientProps.port = hmrServerProps.port; } } bundle.addContent(`FuseBox.import("fuse-box-hot-reload").connect(${JSON.stringify(clientProps)})`); } return props; }); } } let hmrServerMethods; let onMessageCallbacks = []; ict.on('complete', props => { if (httpServerProps.enabled) { const internalServer = createExpressApp(ctx, httpServerProps, { openProps, proxyProps }); // if the ports are the same, we mount HMR on the same server if (hmrServerProps.enabled && hmrServerProps.port === httpServerProps.port && !isProduction) { hmrServerMethods = hmrServer_1.createHMRServer({ internalServer, ctx, opts: hmrServerProps }); } } if (hmrServerProps.enabled && !hmrServerMethods && !isProduction) { // which means that we require a separate HMR server on a different port hmrServerMethods = hmrServer_1.createHMRServer({ ctx, opts: hmrServerProps }); } if (onMessageCallbacks.length && hmrServerMethods) { onMessageCallbacks.map(cb => hmrServerMethods.onMessage(cb)); onMessageCallbacks = []; } return props; }); return { onClientMessage: (fn) => { if (hmrServerMethods) { hmrServerMethods.onMessage(fn); } else { // if the server isn't ready store it here onMessageCallbacks.push(fn); } }, clientSend: (name, payload, ws_instance) => { if (hmrServerMethods) { hmrServerMethods.sendEvent(name, payload, ws_instance); } }, }; } exports.createDevServer = createDevServer;