diff --git a/lib/util/addDevServerEntrypoints.js b/lib/util/addDevServerEntrypoints.js index 8007049008..f9fbeeac06 100644 --- a/lib/util/addDevServerEntrypoints.js +++ b/lib/util/addDevServerEntrypoints.js @@ -19,16 +19,22 @@ module.exports = function addDevServerEntrypoints(webpackOptions, devServerOptio if (devServerOptions.hotOnly) { devClient.push('webpack/hot/only-dev-server'); } else if (devServerOptions.hot) { devClient.push('webpack/hot/dev-server'); } - [].concat(webpackOptions).forEach((wpOpt) => { - if (typeof wpOpt.entry === 'object' && !Array.isArray(wpOpt.entry)) { - Object.keys(wpOpt.entry).forEach((key) => { - wpOpt.entry[key] = devClient.concat(wpOpt.entry[key]); + const prependDevClient = (entry) => { + if (typeof entry === 'function') { + return () => Promise.resolve(entry()).then(prependDevClient); + } + if (typeof entry === 'object' && !Array.isArray(entry)) { + const entryClone = {}; + Object.keys(entry).forEach((key) => { + entryClone[key] = devClient.concat(entry[key]); }); - } else if (typeof wpOpt.entry === 'function') { - wpOpt.entry = wpOpt.entry(devClient); - } else { - wpOpt.entry = devClient.concat(wpOpt.entry || './src'); + return entryClone; } + return devClient.concat(entry); + }; + + [].concat(webpackOptions).forEach((wpOpt) => { + wpOpt.entry = prependDevClient(wpOpt.entry || './src'); }); } }; diff --git a/test/Entry.test.js b/test/Entry.test.js index 1ccb2ae6e9..8516125156 100644 --- a/test/Entry.test.js +++ b/test/Entry.test.js @@ -2,17 +2,112 @@ const assert = require('assert'); const addDevServerEntrypoints = require('../lib/util/addDevServerEntrypoints'); +const config = require('./fixtures/simple-config/webpack.config'); describe('Entry', () => { - it('default to src if no entry point is given', (done) => { + it('adds devServer entry points to a single entry point', () => { + const webpackOptions = Object.assign({}, config); + const devServerOptions = {}; + + addDevServerEntrypoints(webpackOptions, devServerOptions); + + assert.equal(webpackOptions.entry.length, 2); + assert(webpackOptions.entry[0].indexOf('client/index.js?') !== -1); + assert.equal(webpackOptions.entry[1], './foo.js'); + }); + + it('adds devServer entry points to a multi-module entry point', () => { + const webpackOptions = Object.assign({}, config, { + entry: ['./foo.js', './bar.js'] + }); + const devServerOptions = {}; + + addDevServerEntrypoints(webpackOptions, devServerOptions); + + assert.equal(webpackOptions.entry.length, 3); + assert(webpackOptions.entry[0].indexOf('client/index.js?') !== -1); + assert.equal(webpackOptions.entry[1], './foo.js'); + assert.equal(webpackOptions.entry[2], './bar.js'); + }); + + it('adds devServer entry points to a multi entry point object', () => { + const webpackOptions = Object.assign({}, config, { + entry: { + foo: './foo.js', + bar: './bar.js' + } + }); + const devServerOptions = {}; + + addDevServerEntrypoints(webpackOptions, devServerOptions); + + assert.equal(webpackOptions.entry.foo.length, 2); + assert(webpackOptions.entry.foo[0].indexOf('client/index.js?') !== -1); + assert.equal(webpackOptions.entry.foo[1], './foo.js'); + assert.equal(webpackOptions.entry.bar[1], './bar.js'); + }); + + it('defaults to src if no entry point is given', () => { const webpackOptions = {}; const devServerOptions = {}; addDevServerEntrypoints(webpackOptions, devServerOptions); - assert(webpackOptions.entry.length, 2); - assert(webpackOptions.entry[1], './src'); + assert.equal(webpackOptions.entry.length, 2); + assert.equal(webpackOptions.entry[1], './src'); + }); + + it('preserves dynamic entry points', (done) => { + let i = 0; + const webpackOptions = { + // simulate dynamic entry + entry: () => { + i += 1; + return `./src-${i}.js`; + } + }; + const devServerOptions = {}; + + addDevServerEntrypoints(webpackOptions, devServerOptions); + + assert(typeof webpackOptions.entry, 'function'); + + webpackOptions.entry().then(entryFirstRun => ( + webpackOptions.entry().then((entrySecondRun) => { + assert.equal(entryFirstRun.length, 2); + assert.equal(entryFirstRun[1], './src-1.js'); + + assert.equal(entrySecondRun.length, 2); + assert.equal(entrySecondRun[1], './src-2.js'); + done(); + }) + )).catch(done); + }); + + it('preserves asynchronous dynamic entry points', (done) => { + let i = 0; + const webpackOptions = { + // simulate async dynamic entry + entry: () => new Promise((resolve) => { + i += 1; + resolve(`./src-${i}.js`); + }) + }; + const devServerOptions = {}; + + addDevServerEntrypoints(webpackOptions, devServerOptions); + + assert(typeof webpackOptions.entry, 'function'); + + webpackOptions.entry().then(entryFirstRun => ( + webpackOptions.entry().then((entrySecondRun) => { + assert.equal(entryFirstRun.length, 2); + assert.equal(entryFirstRun[1], './src-1.js'); - done(); + assert.equal(entrySecondRun.length, 2); + assert.equal(entrySecondRun[1], './src-2.js'); + done(); + }) + )).catch(done); }); });