st-bundle
Version:
CLI for watching and bundling SpringType projects.
156 lines (155 loc) • 5.99 kB
JavaScript
;
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;