getAdditionalEntries.js 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. const querystring = require('querystring');
  2. /**
  3. * @typedef {Object} AdditionalEntries
  4. * @property {string[]} prependEntries
  5. * @property {string[]} overlayEntries
  6. */
  7. /**
  8. * Creates an object that contains two entry arrays: the prependEntries and overlayEntries
  9. * @param {Object} optionsContainer This is the container for the options to this function
  10. * @param {import('../types').NormalizedPluginOptions} optionsContainer.options Configuration options for this plugin.
  11. * @param {import('webpack').Compiler["options"]["devServer"]} [optionsContainer.devServer] The webpack devServer config
  12. * @returns {AdditionalEntries} An object that contains the Webpack entries for prepending and the overlay feature
  13. */
  14. function getAdditionalEntries({ devServer, options }) {
  15. /** @type {Record<string, string | number>} */
  16. let resourceQuery = {};
  17. if (devServer) {
  18. const { client, https, http2, sockHost, sockPath, sockPort } = devServer;
  19. let { host, path, port } = devServer;
  20. let protocol = https || http2 ? 'https' : 'http';
  21. if (sockHost) host = sockHost;
  22. if (sockPath) path = sockPath;
  23. if (sockPort) port = sockPort;
  24. if (client && client.webSocketURL != null) {
  25. let parsedUrl = client.webSocketURL;
  26. if (typeof parsedUrl === 'string') parsedUrl = new URL(parsedUrl);
  27. let auth;
  28. if (parsedUrl.username) {
  29. auth = parsedUrl.username;
  30. if (parsedUrl.password) {
  31. auth += ':' + parsedUrl.password;
  32. }
  33. }
  34. if (parsedUrl.hostname != null) {
  35. host = [auth != null && auth, parsedUrl.hostname].filter(Boolean).join('@');
  36. }
  37. if (parsedUrl.pathname != null) {
  38. path = parsedUrl.pathname;
  39. }
  40. if (parsedUrl.port != null) {
  41. port = !['0', 'auto'].includes(String(parsedUrl.port)) ? parsedUrl.port : undefined;
  42. }
  43. if (parsedUrl.protocol != null) {
  44. protocol = parsedUrl.protocol !== 'auto' ? parsedUrl.protocol.replace(':', '') : 'ws';
  45. }
  46. }
  47. if (host) resourceQuery.sockHost = host;
  48. if (path) resourceQuery.sockPath = path;
  49. if (port) resourceQuery.sockPort = port;
  50. resourceQuery.sockProtocol = protocol;
  51. }
  52. if (options.overlay) {
  53. const { sockHost, sockPath, sockPort, sockProtocol } = options.overlay;
  54. if (sockHost) resourceQuery.sockHost = sockHost;
  55. if (sockPath) resourceQuery.sockPath = sockPath;
  56. if (sockPort) resourceQuery.sockPort = sockPort;
  57. if (sockProtocol) resourceQuery.sockProtocol = sockProtocol;
  58. }
  59. // We don't need to URI encode the resourceQuery as it will be parsed by Webpack
  60. const queryString = querystring.stringify(resourceQuery, undefined, undefined, {
  61. /**
  62. * @param {string} string
  63. * @returns {string}
  64. */
  65. encodeURIComponent(string) {
  66. return string;
  67. },
  68. });
  69. const prependEntries = [
  70. // React-refresh runtime
  71. require.resolve('../../client/ReactRefreshEntry'),
  72. ];
  73. const overlayEntries = [
  74. // Error overlay runtime
  75. options.overlay &&
  76. options.overlay.entry &&
  77. `${require.resolve(options.overlay.entry)}${queryString ? `?${queryString}` : ''}`,
  78. ].filter(Boolean);
  79. return { prependEntries, overlayEntries };
  80. }
  81. module.exports = getAdditionalEntries;