All files index.js

50% Statements 17/34
12.5% Branches 2/16
30% Functions 3/10
51.52% Lines 17/33
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118    1x 1x 1x 1x 1x   1x                                                                                                             8x     8x 8x   8x   8x 10x 10x                                                                                 1x 1x 1x 1x
"use strict";
 
var fs = require('fs');
var path = require('path');
var express = require('express');
var createMemoryHistory = require("react-router").createMemoryHistory;
var utils = require('./utils');
 
var skippedExtensions = [
    '.coffee',
    '.css',
    '.eot',
    '.gif',
    '.jpg',
    '.jpeg',
    '.less',
    '.png',
    '.sass',
    '.scss',
    '.svg',
    '.ts',
    '.ttf',
    '.woff',
    '.woff2'
];
 
function skipRequireExtensions(additional) {
 
    skippedExtensions
        .concat(additional || [])
        .forEach(function(ext) {
            require.extensions[ext] = function() {};
        });
 
}
 
function createWebpackMiddleware(compiler, config) {
 
    if (!compiler.outputFileSystem) {
        throw new Error('Compiler has no file system yet, use inside config.devServer.setup(cb) callback');
    }
 
    return function(options) {
        options.fs = compiler.outputFileSystem;
        return createExpressMiddleware(options);
    };
 
}
 
/**
 * @param {function} options.createRoutes function must return routes or routes config for React Router
 * @param {function} [options.createStore] if set function must return an instance of Redux Store with initial state
 * @param {function} [options.template] main [template function](#template-function), performs injection of rendered HTML to the template, default = replaces `<div id="root"></div>` with `<div id="root">%HTML%</div>`
 * @param {string} [options.outputPath] path with static files, usually equals to Webpack's `output.path`
 * @param {string} [options.templatePath] path to `index.html`, default = `%outputPath%/index.html`
 * @param {boolean} [options.debug] emits to console some extra information about request handling, default = `false`
 * @param {object} [options.fs] internal option used to pass an instance of file system object
 * @param {string} [options.initialStateKey] key in `window` object that will be used to pass initial props, default = `__INITIAL_PROPS__`
 * @param {string} [options.initialPropsKey] key in `window` object that will be used to pass initial state, default = `__INITIAL_STATE__`
 * @return {Function}
 */
function createExpressMiddleware(options) {
 
    options = options || {};
 
    //TODO Create every time?
    var history = createMemoryHistory();
    var routes = options.createRoutes();
 
    options.fs = options.fs || fs;
 
    return function(req, res, next) {
        utils.waitForTemplate(options).then(function(template){
            utils.middleware(options, routes, history, template, req, res, next);
        });
    }
 
}
 
/**
 * @param {string} options.outputPath path with static files, usually equals to Webpack's `output.path`
 * @param {function} options.createRoutes function must return routes or routes config React Router
 * @param {function} [options.createStore] if set function must return an instance of Redux Store with initial state
 * @param {function} [options.template] main [template function](#template-function), performs injection of rendered HTML to the template, default = replaces `<div id="root"></div>` with `<div id="root">%HTML%</div>`
 * @param {string} [options.templatePath] path to `index.html`, default = `%outputPath%/index.html`
 * @param {boolean} [options.debug] emits to console some extra information about request handling, default = `false`
 * @param {object} [options.fs] internal option used to pass an instance of file system object
 * @param {string} [options.initialStateKey] key in `window` object that will be used to pass initial props, default = `__INITIAL_PROPS__`
 * @param {string} [options.initialPropsKey] key in `window` object that will be used to pass initial state, default = `__INITIAL_STATE__`
 * @param {string[]} [options.skipExtensions] array of strings that represent most commonly imported non-JS extensions that has to be skipped during server build, default = `['css', 'jpg', 'gif', ...]`
 * @param {number} [options.port] listening port, default = `3000`
 * @param {function} [options.listen] Express's listen function
 * @return {Function}
 */
function createExpressServer(options) {
 
    skipRequireExtensions(options.skipExtensions || null);
 
    var app = express();
    var port = options.port || 3000;
 
    app.use(createExpressMiddleware(options));
 
    app.use(express.static(options.outputPath));
 
    app.listen(port, options.listen || function(err) {
            if (err) throw err;
            console.log('Listening', port);
        });
 
    return app;
 
}
 
exports.skipRequireExtensions = skipRequireExtensions;
exports.createWebpackMiddleware = createWebpackMiddleware;
exports.createExpressMiddleware = createExpressMiddleware;
exports.createExpressServer = createExpressServer;