addEntries.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. 'use strict';
  2. const webpack = require('webpack');
  3. const createDomain = require('./createDomain');
  4. function addEntries(config, options, server) {
  5. if (options.inline !== false) {
  6. // we're stubbing the app in this method as it's static and doesn't require
  7. // a server to be supplied. createDomain requires an app with the
  8. // address() signature.
  9. const app = server || {
  10. address() {
  11. return { port: options.port };
  12. },
  13. };
  14. const domain = createDomain(options, app);
  15. const sockHost = options.sockHost ? `&sockHost=${options.sockHost}` : '';
  16. const sockPath = options.sockPath ? `&sockPath=${options.sockPath}` : '';
  17. const sockPort = options.sockPort ? `&sockPort=${options.sockPort}` : '';
  18. const clientEntry = `${require.resolve(
  19. '../../client/'
  20. )}?${domain}${sockHost}${sockPath}${sockPort}`;
  21. let hotEntry;
  22. if (options.hotOnly) {
  23. hotEntry = require.resolve('webpack/hot/only-dev-server');
  24. } else if (options.hot) {
  25. hotEntry = require.resolve('webpack/hot/dev-server');
  26. }
  27. const prependEntry = (originalEntry, additionalEntries) => {
  28. if (typeof originalEntry === 'function') {
  29. return () =>
  30. Promise.resolve(originalEntry()).then((entry) =>
  31. prependEntry(entry, additionalEntries)
  32. );
  33. }
  34. if (typeof originalEntry === 'object' && !Array.isArray(originalEntry)) {
  35. const clone = {};
  36. Object.keys(originalEntry).forEach((key) => {
  37. // entry[key] should be a string here
  38. clone[key] = prependEntry(originalEntry[key], additionalEntries);
  39. });
  40. return clone;
  41. }
  42. // in this case, entry is a string or an array.
  43. // make sure that we do not add duplicates.
  44. const entriesClone = additionalEntries.slice(0);
  45. [].concat(originalEntry).forEach((newEntry) => {
  46. if (!entriesClone.includes(newEntry)) {
  47. entriesClone.push(newEntry);
  48. }
  49. });
  50. return entriesClone;
  51. };
  52. // eslint-disable-next-line no-shadow
  53. const checkInject = (option, config, defaultValue) => {
  54. if (typeof option === 'boolean') return option;
  55. if (typeof option === 'function') return option(config);
  56. return defaultValue;
  57. };
  58. // eslint-disable-next-line no-shadow
  59. [].concat(config).forEach((config) => {
  60. const webTarget =
  61. config.target === 'web' ||
  62. config.target === 'webworker' ||
  63. config.target === 'electron-renderer' ||
  64. config.target === 'node-webkit' ||
  65. config.target == null;
  66. const additionalEntries = checkInject(
  67. options.injectClient,
  68. config,
  69. webTarget
  70. )
  71. ? [clientEntry]
  72. : [];
  73. if (hotEntry && checkInject(options.injectHot, config, true)) {
  74. additionalEntries.push(hotEntry);
  75. }
  76. config.entry = prependEntry(config.entry || './src', additionalEntries);
  77. if (options.hot || options.hotOnly) {
  78. config.plugins = config.plugins || [];
  79. if (
  80. !config.plugins.find(
  81. (plugin) =>
  82. plugin.constructor === webpack.HotModuleReplacementPlugin
  83. )
  84. ) {
  85. config.plugins.push(new webpack.HotModuleReplacementPlugin());
  86. }
  87. }
  88. });
  89. }
  90. }
  91. module.exports = addEntries;