@module-federation/vite 1.1.2 → 1.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.cjs CHANGED
@@ -33,11 +33,15 @@ var MagicString__default = /*#__PURE__*/_interopDefaultLegacy(MagicString);
33
33
  var addEntry = function addEntry(_ref) {
34
34
  var entryName = _ref.entryName,
35
35
  entryPath = _ref.entryPath,
36
- fileName = _ref.fileName;
37
- var devEntryPath = entryPath.startsWith('virtual:mf') ? '/@id/' + entryPath : entryPath;
36
+ fileName = _ref.fileName,
37
+ _ref$inject = _ref.inject,
38
+ inject = _ref$inject === void 0 ? 'entry' : _ref$inject;
39
+ var devEntryPath = entryPath.startsWith('virtual:mf') ? '@id/' + entryPath : entryPath;
38
40
  var entryFiles = [];
39
41
  var htmlFilePath;
40
42
  var _command;
43
+ var emitFileId;
44
+ var viteConfig;
41
45
  return [{
42
46
  name: 'add-entry',
43
47
  apply: 'serve',
@@ -45,18 +49,22 @@ var addEntry = function addEntry(_ref) {
45
49
  var command = _ref2.command;
46
50
  _command = command;
47
51
  },
52
+ configResolved: function configResolved(config) {
53
+ viteConfig = config;
54
+ devEntryPath = config.base + devEntryPath.replace(/^\//, '');
55
+ },
48
56
  configureServer: function configureServer(server) {
49
57
  var _server$httpServer;
50
58
  (_server$httpServer = server.httpServer) == null || _server$httpServer.once == null || _server$httpServer.once('listening', function () {
51
59
  var port = server.config.server.port;
52
- fetch(path__namespace.join("http://localhost:" + port, "" + devEntryPath))["catch"](function (e) {});
60
+ fetch("http://localhost:" + port + devEntryPath)["catch"](function (e) {});
53
61
  });
54
62
  server.middlewares.use(function (req, res, next) {
55
63
  if (!fileName) {
56
64
  next();
57
65
  return;
58
66
  }
59
- if (req.url && req.url.startsWith(fileName.replace(/^\/?/, '/'))) {
67
+ if (req.url && req.url.startsWith((viteConfig.base + fileName).replace(/^\/?/, '/'))) {
60
68
  req.url = devEntryPath;
61
69
  }
62
70
  next();
@@ -69,6 +77,7 @@ var addEntry = function addEntry(_ref) {
69
77
  name: 'add-entry',
70
78
  enforce: 'post',
71
79
  configResolved: function configResolved(config) {
80
+ viteConfig = config;
72
81
  var inputOptions = config.build.rollupOptions.input;
73
82
  if (!inputOptions) {
74
83
  htmlFilePath = path__namespace.resolve(config.root, 'index.html');
@@ -95,7 +104,7 @@ var addEntry = function addEntry(_ref) {
95
104
  if (!hasHash) {
96
105
  emitFileOptions.fileName = fileName;
97
106
  }
98
- this.emitFile(emitFileOptions);
107
+ emitFileId = this.emitFile(emitFileOptions);
99
108
  if (htmlFilePath) {
100
109
  var htmlContent = fs__namespace.readFileSync(htmlFilePath, 'utf-8');
101
110
  var scriptRegex = /<script\s+[^>]*src=["']([^"']+)["'][^>]*>/gi;
@@ -105,8 +114,22 @@ var addEntry = function addEntry(_ref) {
105
114
  }
106
115
  }
107
116
  },
117
+ generateBundle: function generateBundle(options, bundle) {
118
+ if (inject !== 'html') return;
119
+ var file = this.getFileName(emitFileId);
120
+ var scriptContent = "\n <script type=\"module\" src=\"" + (viteConfig.base + file) + "\"></script>\n ";
121
+ for (var _fileName in bundle) {
122
+ if (_fileName.endsWith('.html')) {
123
+ var htmlAsset = bundle[_fileName];
124
+ if (htmlAsset.type === 'chunk') return;
125
+ var htmlContent = htmlAsset.source.toString() || '';
126
+ htmlContent = htmlContent.replace('<head>', "<head>" + scriptContent);
127
+ htmlAsset.source = htmlContent;
128
+ }
129
+ }
130
+ },
108
131
  transform: function transform(code, id) {
109
- if (entryFiles.some(function (file) {
132
+ if (inject === 'entry' && entryFiles.some(function (file) {
110
133
  return id.endsWith(file);
111
134
  })) {
112
135
  var injection = "\n import " + JSON.stringify(entryPath) + ";\n ";
@@ -383,7 +406,7 @@ function normalizeModuleFederationOptions(options) {
383
406
  dev: options.dev,
384
407
  dts: options.dts,
385
408
  getPublicPath: options.getPublicPath,
386
- shareStrategy: options.shareStrategy
409
+ shareStrategy: options.shareStrategy || 'version-first'
387
410
  };
388
411
  }
389
412
 
@@ -621,13 +644,14 @@ function generateRemoteEntry(options) {
621
644
  return item[1];
622
645
  }).join('\n') + "\n import exposesMap from \"" + VIRTUAL_EXPOSES + "\"\n import {usedShared, usedRemotes} from \"" + getLocalSharedImportMapPath() + "\"\n import {\n initResolve\n } from \"" + virtualRuntimeInitStatus.getImportId() + "\"\n async function init(shared = {}) {\n const initRes = runtimeInit({\n name: " + JSON.stringify(options.name) + ",\n remotes: usedRemotes,\n shared: usedShared,\n plugins: [" + pluginImportNames.map(function (item) {
623
646
  return item[0] + "()";
624
- }).join(', ') + "],\n " + (options.shareStrategy ? "shareStrategy: " + options.shareStrategy : '') + "\n });\n initRes.initShareScopeMap('" + options.shareScope + "', shared);\n initResolve(initRes)\n return initRes\n }\n\n function getExposes(moduleName) {\n if (!(moduleName in exposesMap)) throw new Error(`Module ${moduleName} does not exist in container.`)\n return (exposesMap[moduleName])().then(res => () => res)\n }\n export {\n init,\n getExposes as get\n }\n ";
647
+ }).join(', ') + "],\n " + (options.shareStrategy ? "shareStrategy: '" + options.shareStrategy + "'" : '') + "\n });\n initRes.initShareScopeMap('" + options.shareScope + "', shared);\n try {\n await Promise.all(await initRes.initializeSharing('" + options.shareScope + "', {strategy: '" + options.shareStrategy + "'}));\n } catch (e) {\n console.error(e)\n }\n initResolve(initRes)\n return initRes\n }\n\n function getExposes(moduleName) {\n if (!(moduleName in exposesMap)) throw new Error(`Module ${moduleName} does not exist in container.`)\n return (exposesMap[moduleName])().then(res => () => res)\n }\n export {\n init,\n getExposes as get\n }\n ";
625
648
  }
626
649
  /**
627
650
  * Inject entry file, automatically init when used as host,
628
651
  * and will not inject remoteEntry
629
652
  */
630
- var hostAutoInitModule = new VirtualModule('hostAutoInit');
653
+ var HOST_AUTO_INIT_TAG = '__H_A_I__';
654
+ var hostAutoInitModule = new VirtualModule('hostAutoInit', HOST_AUTO_INIT_TAG);
631
655
  function writeHostAutoInit() {
632
656
  hostAutoInitModule.writeSync("\n import {init} from \"" + REMOTE_ENTRY_ID + "\"\n init()\n ");
633
657
  }
@@ -662,16 +686,20 @@ var Manifest = function Manifest() {
662
686
  var remoteEntryFile;
663
687
  var publicPath;
664
688
  var _command;
689
+ var viteConfig;
665
690
  return [{
666
691
  name: 'module-federation-manifest',
667
692
  apply: 'serve',
693
+ configResolved: function configResolved(config) {
694
+ viteConfig = config;
695
+ },
668
696
  configureServer: function configureServer(server) {
669
697
  server.middlewares.use(function (req, res, next) {
670
698
  if (!mfManifestName) {
671
699
  next();
672
700
  return;
673
701
  }
674
- if (req.url === mfManifestName.replace(/^\/?/, '/')) {
702
+ if (req.url === (viteConfig.base + mfManifestName).replace(/^\/?/, '/')) {
675
703
  res.setHeader('Content-Type', 'application/json');
676
704
  res.setHeader('Access-Control-Allow-Origin', '*');
677
705
  res.end(JSON.stringify(_extends({}, generateMFManifest({}), {
@@ -720,11 +748,11 @@ var Manifest = function Manifest() {
720
748
  configResolved: function configResolved(config) {
721
749
  root = config.root;
722
750
  extensions = config.resolve.extensions || ['.mjs', '.js', '.mts', '.ts', '.jsx', '.tsx', '.json'];
723
- publicPath = config.base ? config.base.replace(/\/?$/, '/') : 'auto';
751
+ var base = config.base;
724
752
  if (_command === 'serve') {
725
- var origin = config.server.origin;
726
- publicPath = origin ? origin.replace(/\/?$/, '/') : 'auto';
753
+ base = (config.server.origin || '') + config.base;
727
754
  }
755
+ publicPath = base ? base.replace(/\/?$/, '/') : 'auto';
728
756
  },
729
757
  generateBundle: function generateBundle(options, bundle) {
730
758
  try {
@@ -1245,7 +1273,8 @@ function federation(mfUserOptions) {
1245
1273
  fileName: filename
1246
1274
  }), addEntry({
1247
1275
  entryName: 'hostInit',
1248
- entryPath: getHostAutoInitPath()
1276
+ entryPath: getHostAutoInitPath(),
1277
+ inject: 'html'
1249
1278
  }), addEntry({
1250
1279
  entryName: 'virtualExposes',
1251
1280
  entryPath: VIRTUAL_EXPOSES
package/lib/index.esm.js CHANGED
@@ -10,11 +10,15 @@ import { defu } from 'defu';
10
10
  var addEntry = function addEntry(_ref) {
11
11
  var entryName = _ref.entryName,
12
12
  entryPath = _ref.entryPath,
13
- fileName = _ref.fileName;
14
- var devEntryPath = entryPath.startsWith('virtual:mf') ? '/@id/' + entryPath : entryPath;
13
+ fileName = _ref.fileName,
14
+ _ref$inject = _ref.inject,
15
+ inject = _ref$inject === void 0 ? 'entry' : _ref$inject;
16
+ var devEntryPath = entryPath.startsWith('virtual:mf') ? '@id/' + entryPath : entryPath;
15
17
  var entryFiles = [];
16
18
  var htmlFilePath;
17
19
  var _command;
20
+ var emitFileId;
21
+ var viteConfig;
18
22
  return [{
19
23
  name: 'add-entry',
20
24
  apply: 'serve',
@@ -22,18 +26,22 @@ var addEntry = function addEntry(_ref) {
22
26
  var command = _ref2.command;
23
27
  _command = command;
24
28
  },
29
+ configResolved: function configResolved(config) {
30
+ viteConfig = config;
31
+ devEntryPath = config.base + devEntryPath.replace(/^\//, '');
32
+ },
25
33
  configureServer: function configureServer(server) {
26
34
  var _server$httpServer;
27
35
  (_server$httpServer = server.httpServer) == null || _server$httpServer.once == null || _server$httpServer.once('listening', function () {
28
36
  var port = server.config.server.port;
29
- fetch(path.join("http://localhost:" + port, "" + devEntryPath))["catch"](function (e) {});
37
+ fetch("http://localhost:" + port + devEntryPath)["catch"](function (e) {});
30
38
  });
31
39
  server.middlewares.use(function (req, res, next) {
32
40
  if (!fileName) {
33
41
  next();
34
42
  return;
35
43
  }
36
- if (req.url && req.url.startsWith(fileName.replace(/^\/?/, '/'))) {
44
+ if (req.url && req.url.startsWith((viteConfig.base + fileName).replace(/^\/?/, '/'))) {
37
45
  req.url = devEntryPath;
38
46
  }
39
47
  next();
@@ -46,6 +54,7 @@ var addEntry = function addEntry(_ref) {
46
54
  name: 'add-entry',
47
55
  enforce: 'post',
48
56
  configResolved: function configResolved(config) {
57
+ viteConfig = config;
49
58
  var inputOptions = config.build.rollupOptions.input;
50
59
  if (!inputOptions) {
51
60
  htmlFilePath = path.resolve(config.root, 'index.html');
@@ -72,7 +81,7 @@ var addEntry = function addEntry(_ref) {
72
81
  if (!hasHash) {
73
82
  emitFileOptions.fileName = fileName;
74
83
  }
75
- this.emitFile(emitFileOptions);
84
+ emitFileId = this.emitFile(emitFileOptions);
76
85
  if (htmlFilePath) {
77
86
  var htmlContent = fs.readFileSync(htmlFilePath, 'utf-8');
78
87
  var scriptRegex = /<script\s+[^>]*src=["']([^"']+)["'][^>]*>/gi;
@@ -82,8 +91,22 @@ var addEntry = function addEntry(_ref) {
82
91
  }
83
92
  }
84
93
  },
94
+ generateBundle: function generateBundle(options, bundle) {
95
+ if (inject !== 'html') return;
96
+ var file = this.getFileName(emitFileId);
97
+ var scriptContent = "\n <script type=\"module\" src=\"" + (viteConfig.base + file) + "\"></script>\n ";
98
+ for (var _fileName in bundle) {
99
+ if (_fileName.endsWith('.html')) {
100
+ var htmlAsset = bundle[_fileName];
101
+ if (htmlAsset.type === 'chunk') return;
102
+ var htmlContent = htmlAsset.source.toString() || '';
103
+ htmlContent = htmlContent.replace('<head>', "<head>" + scriptContent);
104
+ htmlAsset.source = htmlContent;
105
+ }
106
+ }
107
+ },
85
108
  transform: function transform(code, id) {
86
- if (entryFiles.some(function (file) {
109
+ if (inject === 'entry' && entryFiles.some(function (file) {
87
110
  return id.endsWith(file);
88
111
  })) {
89
112
  var injection = "\n import " + JSON.stringify(entryPath) + ";\n ";
@@ -360,7 +383,7 @@ function normalizeModuleFederationOptions(options) {
360
383
  dev: options.dev,
361
384
  dts: options.dts,
362
385
  getPublicPath: options.getPublicPath,
363
- shareStrategy: options.shareStrategy
386
+ shareStrategy: options.shareStrategy || 'version-first'
364
387
  };
365
388
  }
366
389
 
@@ -598,13 +621,14 @@ function generateRemoteEntry(options) {
598
621
  return item[1];
599
622
  }).join('\n') + "\n import exposesMap from \"" + VIRTUAL_EXPOSES + "\"\n import {usedShared, usedRemotes} from \"" + getLocalSharedImportMapPath() + "\"\n import {\n initResolve\n } from \"" + virtualRuntimeInitStatus.getImportId() + "\"\n async function init(shared = {}) {\n const initRes = runtimeInit({\n name: " + JSON.stringify(options.name) + ",\n remotes: usedRemotes,\n shared: usedShared,\n plugins: [" + pluginImportNames.map(function (item) {
600
623
  return item[0] + "()";
601
- }).join(', ') + "],\n " + (options.shareStrategy ? "shareStrategy: " + options.shareStrategy : '') + "\n });\n initRes.initShareScopeMap('" + options.shareScope + "', shared);\n initResolve(initRes)\n return initRes\n }\n\n function getExposes(moduleName) {\n if (!(moduleName in exposesMap)) throw new Error(`Module ${moduleName} does not exist in container.`)\n return (exposesMap[moduleName])().then(res => () => res)\n }\n export {\n init,\n getExposes as get\n }\n ";
624
+ }).join(', ') + "],\n " + (options.shareStrategy ? "shareStrategy: '" + options.shareStrategy + "'" : '') + "\n });\n initRes.initShareScopeMap('" + options.shareScope + "', shared);\n try {\n await Promise.all(await initRes.initializeSharing('" + options.shareScope + "', {strategy: '" + options.shareStrategy + "'}));\n } catch (e) {\n console.error(e)\n }\n initResolve(initRes)\n return initRes\n }\n\n function getExposes(moduleName) {\n if (!(moduleName in exposesMap)) throw new Error(`Module ${moduleName} does not exist in container.`)\n return (exposesMap[moduleName])().then(res => () => res)\n }\n export {\n init,\n getExposes as get\n }\n ";
602
625
  }
603
626
  /**
604
627
  * Inject entry file, automatically init when used as host,
605
628
  * and will not inject remoteEntry
606
629
  */
607
- var hostAutoInitModule = new VirtualModule('hostAutoInit');
630
+ var HOST_AUTO_INIT_TAG = '__H_A_I__';
631
+ var hostAutoInitModule = new VirtualModule('hostAutoInit', HOST_AUTO_INIT_TAG);
608
632
  function writeHostAutoInit() {
609
633
  hostAutoInitModule.writeSync("\n import {init} from \"" + REMOTE_ENTRY_ID + "\"\n init()\n ");
610
634
  }
@@ -639,16 +663,20 @@ var Manifest = function Manifest() {
639
663
  var remoteEntryFile;
640
664
  var publicPath;
641
665
  var _command;
666
+ var viteConfig;
642
667
  return [{
643
668
  name: 'module-federation-manifest',
644
669
  apply: 'serve',
670
+ configResolved: function configResolved(config) {
671
+ viteConfig = config;
672
+ },
645
673
  configureServer: function configureServer(server) {
646
674
  server.middlewares.use(function (req, res, next) {
647
675
  if (!mfManifestName) {
648
676
  next();
649
677
  return;
650
678
  }
651
- if (req.url === mfManifestName.replace(/^\/?/, '/')) {
679
+ if (req.url === (viteConfig.base + mfManifestName).replace(/^\/?/, '/')) {
652
680
  res.setHeader('Content-Type', 'application/json');
653
681
  res.setHeader('Access-Control-Allow-Origin', '*');
654
682
  res.end(JSON.stringify(_extends({}, generateMFManifest({}), {
@@ -697,11 +725,11 @@ var Manifest = function Manifest() {
697
725
  configResolved: function configResolved(config) {
698
726
  root = config.root;
699
727
  extensions = config.resolve.extensions || ['.mjs', '.js', '.mts', '.ts', '.jsx', '.tsx', '.json'];
700
- publicPath = config.base ? config.base.replace(/\/?$/, '/') : 'auto';
728
+ var base = config.base;
701
729
  if (_command === 'serve') {
702
- var origin = config.server.origin;
703
- publicPath = origin ? origin.replace(/\/?$/, '/') : 'auto';
730
+ base = (config.server.origin || '') + config.base;
704
731
  }
732
+ publicPath = base ? base.replace(/\/?$/, '/') : 'auto';
705
733
  },
706
734
  generateBundle: function generateBundle(options, bundle) {
707
735
  try {
@@ -1222,7 +1250,8 @@ function federation(mfUserOptions) {
1222
1250
  fileName: filename
1223
1251
  }), addEntry({
1224
1252
  entryName: 'hostInit',
1225
- entryPath: getHostAutoInitPath()
1253
+ entryPath: getHostAutoInitPath(),
1254
+ inject: 'html'
1226
1255
  }), addEntry({
1227
1256
  entryName: 'virtualExposes',
1228
1257
  entryPath: VIRTUAL_EXPOSES
@@ -10,12 +10,15 @@ import { defu } from 'defu';
10
10
  const addEntry = ({
11
11
  entryName,
12
12
  entryPath,
13
- fileName
13
+ fileName,
14
+ inject: _inject = 'entry'
14
15
  }) => {
15
- const devEntryPath = entryPath.startsWith('virtual:mf') ? '/@id/' + entryPath : entryPath;
16
+ let devEntryPath = entryPath.startsWith('virtual:mf') ? '@id/' + entryPath : entryPath;
16
17
  let entryFiles = [];
17
18
  let htmlFilePath;
18
19
  let _command;
20
+ let emitFileId;
21
+ let viteConfig;
19
22
  return [{
20
23
  name: 'add-entry',
21
24
  apply: 'serve',
@@ -24,20 +27,24 @@ const addEntry = ({
24
27
  }) {
25
28
  _command = command;
26
29
  },
30
+ configResolved(config) {
31
+ viteConfig = config;
32
+ devEntryPath = config.base + devEntryPath.replace(/^\//, '');
33
+ },
27
34
  configureServer(server) {
28
35
  var _server$httpServer;
29
36
  (_server$httpServer = server.httpServer) == null || _server$httpServer.once == null || _server$httpServer.once('listening', () => {
30
37
  const {
31
38
  port
32
39
  } = server.config.server;
33
- fetch(path.join(`http://localhost:${port}`, `${devEntryPath}`)).catch(e => {});
40
+ fetch(`http://localhost:${port}${devEntryPath}`).catch(e => {});
34
41
  });
35
42
  server.middlewares.use((req, res, next) => {
36
43
  if (!fileName) {
37
44
  next();
38
45
  return;
39
46
  }
40
- if (req.url && req.url.startsWith(fileName.replace(/^\/?/, '/'))) {
47
+ if (req.url && req.url.startsWith((viteConfig.base + fileName).replace(/^\/?/, '/'))) {
41
48
  req.url = devEntryPath;
42
49
  }
43
50
  next();
@@ -50,6 +57,7 @@ const addEntry = ({
50
57
  name: 'add-entry',
51
58
  enforce: 'post',
52
59
  configResolved(config) {
60
+ viteConfig = config;
53
61
  const inputOptions = config.build.rollupOptions.input;
54
62
  if (!inputOptions) {
55
63
  htmlFilePath = path.resolve(config.root, 'index.html');
@@ -76,7 +84,7 @@ const addEntry = ({
76
84
  if (!hasHash) {
77
85
  emitFileOptions.fileName = fileName;
78
86
  }
79
- this.emitFile(emitFileOptions);
87
+ emitFileId = this.emitFile(emitFileOptions);
80
88
  if (htmlFilePath) {
81
89
  const htmlContent = fs.readFileSync(htmlFilePath, 'utf-8');
82
90
  const scriptRegex = /<script\s+[^>]*src=["']([^"']+)["'][^>]*>/gi;
@@ -86,8 +94,24 @@ const addEntry = ({
86
94
  }
87
95
  }
88
96
  },
97
+ generateBundle(options, bundle) {
98
+ if (_inject !== 'html') return;
99
+ const file = this.getFileName(emitFileId);
100
+ const scriptContent = `
101
+ <script type="module" src="${viteConfig.base + file}"></script>
102
+ `;
103
+ for (const fileName in bundle) {
104
+ if (fileName.endsWith('.html')) {
105
+ let htmlAsset = bundle[fileName];
106
+ if (htmlAsset.type === 'chunk') return;
107
+ let htmlContent = htmlAsset.source.toString() || '';
108
+ htmlContent = htmlContent.replace('<head>', `<head>${scriptContent}`);
109
+ htmlAsset.source = htmlContent;
110
+ }
111
+ }
112
+ },
89
113
  transform(code, id) {
90
- if (entryFiles.some(file => id.endsWith(file))) {
114
+ if (_inject === 'entry' && entryFiles.some(file => id.endsWith(file))) {
91
115
  const injection = `
92
116
  import ${JSON.stringify(entryPath)};
93
117
  `;
@@ -333,7 +357,7 @@ function normalizeModuleFederationOptions(options) {
333
357
  dev: options.dev,
334
358
  dts: options.dts,
335
359
  getPublicPath: options.getPublicPath,
336
- shareStrategy: options.shareStrategy
360
+ shareStrategy: options.shareStrategy || 'version-first'
337
361
  };
338
362
  }
339
363
 
@@ -663,9 +687,14 @@ function generateRemoteEntry(options) {
663
687
  remotes: usedRemotes,
664
688
  shared: usedShared,
665
689
  plugins: [${pluginImportNames.map(item => `${item[0]}()`).join(', ')}],
666
- ${options.shareStrategy ? `shareStrategy: ${options.shareStrategy}` : ''}
690
+ ${options.shareStrategy ? `shareStrategy: '${options.shareStrategy}'` : ''}
667
691
  });
668
692
  initRes.initShareScopeMap('${options.shareScope}', shared);
693
+ try {
694
+ await Promise.all(await initRes.initializeSharing('${options.shareScope}', {strategy: '${options.shareStrategy}'}));
695
+ } catch (e) {
696
+ console.error(e)
697
+ }
669
698
  initResolve(initRes)
670
699
  return initRes
671
700
  }
@@ -684,7 +713,8 @@ function generateRemoteEntry(options) {
684
713
  * Inject entry file, automatically init when used as host,
685
714
  * and will not inject remoteEntry
686
715
  */
687
- const hostAutoInitModule = new VirtualModule('hostAutoInit');
716
+ const HOST_AUTO_INIT_TAG = '__H_A_I__';
717
+ const hostAutoInitModule = new VirtualModule('hostAutoInit', HOST_AUTO_INIT_TAG);
688
718
  function writeHostAutoInit() {
689
719
  hostAutoInitModule.writeSync(`
690
720
  import {init} from "${REMOTE_ENTRY_ID}"
@@ -724,16 +754,20 @@ const Manifest = () => {
724
754
  let remoteEntryFile;
725
755
  let publicPath;
726
756
  let _command;
757
+ let viteConfig;
727
758
  return [{
728
759
  name: 'module-federation-manifest',
729
760
  apply: 'serve',
761
+ configResolved(config) {
762
+ viteConfig = config;
763
+ },
730
764
  configureServer(server) {
731
765
  server.middlewares.use((req, res, next) => {
732
766
  if (!mfManifestName) {
733
767
  next();
734
768
  return;
735
769
  }
736
- if (req.url === mfManifestName.replace(/^\/?/, '/')) {
770
+ if (req.url === (viteConfig.base + mfManifestName).replace(/^\/?/, '/')) {
737
771
  res.setHeader('Content-Type', 'application/json');
738
772
  res.setHeader('Access-Control-Allow-Origin', '*');
739
773
  res.end(JSON.stringify(_extends({}, generateMFManifest({}), {
@@ -783,11 +817,11 @@ const Manifest = () => {
783
817
  configResolved(config) {
784
818
  root = config.root;
785
819
  extensions = config.resolve.extensions || ['.mjs', '.js', '.mts', '.ts', '.jsx', '.tsx', '.json'];
786
- publicPath = config.base ? config.base.replace(/\/?$/, '/') : 'auto';
820
+ let base = config.base;
787
821
  if (_command === 'serve') {
788
- const origin = config.server.origin;
789
- publicPath = origin ? origin.replace(/\/?$/, '/') : 'auto';
822
+ base = (config.server.origin || '') + config.base;
790
823
  }
824
+ publicPath = base ? base.replace(/\/?$/, '/') : 'auto';
791
825
  },
792
826
  async generateBundle(options, bundle) {
793
827
  if (!mfManifestName) return;
@@ -1266,7 +1300,8 @@ function federation(mfUserOptions) {
1266
1300
  fileName: filename
1267
1301
  }), ...addEntry({
1268
1302
  entryName: 'hostInit',
1269
- entryPath: getHostAutoInitPath()
1303
+ entryPath: getHostAutoInitPath(),
1304
+ inject: 'html'
1270
1305
  }), ...addEntry({
1271
1306
  entryName: 'virtualExposes',
1272
1307
  entryPath: VIRTUAL_EXPOSES
package/lib/index.umd.js CHANGED
@@ -31,11 +31,15 @@
31
31
  var addEntry = function addEntry(_ref) {
32
32
  var entryName = _ref.entryName,
33
33
  entryPath = _ref.entryPath,
34
- fileName = _ref.fileName;
35
- var devEntryPath = entryPath.startsWith('virtual:mf') ? '/@id/' + entryPath : entryPath;
34
+ fileName = _ref.fileName,
35
+ _ref$inject = _ref.inject,
36
+ inject = _ref$inject === void 0 ? 'entry' : _ref$inject;
37
+ var devEntryPath = entryPath.startsWith('virtual:mf') ? '@id/' + entryPath : entryPath;
36
38
  var entryFiles = [];
37
39
  var htmlFilePath;
38
40
  var _command;
41
+ var emitFileId;
42
+ var viteConfig;
39
43
  return [{
40
44
  name: 'add-entry',
41
45
  apply: 'serve',
@@ -43,18 +47,22 @@
43
47
  var command = _ref2.command;
44
48
  _command = command;
45
49
  },
50
+ configResolved: function configResolved(config) {
51
+ viteConfig = config;
52
+ devEntryPath = config.base + devEntryPath.replace(/^\//, '');
53
+ },
46
54
  configureServer: function configureServer(server) {
47
55
  var _server$httpServer;
48
56
  (_server$httpServer = server.httpServer) == null || _server$httpServer.once == null || _server$httpServer.once('listening', function () {
49
57
  var port = server.config.server.port;
50
- fetch(path__namespace.join("http://localhost:" + port, "" + devEntryPath))["catch"](function (e) {});
58
+ fetch("http://localhost:" + port + devEntryPath)["catch"](function (e) {});
51
59
  });
52
60
  server.middlewares.use(function (req, res, next) {
53
61
  if (!fileName) {
54
62
  next();
55
63
  return;
56
64
  }
57
- if (req.url && req.url.startsWith(fileName.replace(/^\/?/, '/'))) {
65
+ if (req.url && req.url.startsWith((viteConfig.base + fileName).replace(/^\/?/, '/'))) {
58
66
  req.url = devEntryPath;
59
67
  }
60
68
  next();
@@ -67,6 +75,7 @@
67
75
  name: 'add-entry',
68
76
  enforce: 'post',
69
77
  configResolved: function configResolved(config) {
78
+ viteConfig = config;
70
79
  var inputOptions = config.build.rollupOptions.input;
71
80
  if (!inputOptions) {
72
81
  htmlFilePath = path__namespace.resolve(config.root, 'index.html');
@@ -93,7 +102,7 @@
93
102
  if (!hasHash) {
94
103
  emitFileOptions.fileName = fileName;
95
104
  }
96
- this.emitFile(emitFileOptions);
105
+ emitFileId = this.emitFile(emitFileOptions);
97
106
  if (htmlFilePath) {
98
107
  var htmlContent = fs__namespace.readFileSync(htmlFilePath, 'utf-8');
99
108
  var scriptRegex = /<script\s+[^>]*src=["']([^"']+)["'][^>]*>/gi;
@@ -103,8 +112,22 @@
103
112
  }
104
113
  }
105
114
  },
115
+ generateBundle: function generateBundle(options, bundle) {
116
+ if (inject !== 'html') return;
117
+ var file = this.getFileName(emitFileId);
118
+ var scriptContent = "\n <script type=\"module\" src=\"" + (viteConfig.base + file) + "\"></script>\n ";
119
+ for (var _fileName in bundle) {
120
+ if (_fileName.endsWith('.html')) {
121
+ var htmlAsset = bundle[_fileName];
122
+ if (htmlAsset.type === 'chunk') return;
123
+ var htmlContent = htmlAsset.source.toString() || '';
124
+ htmlContent = htmlContent.replace('<head>', "<head>" + scriptContent);
125
+ htmlAsset.source = htmlContent;
126
+ }
127
+ }
128
+ },
106
129
  transform: function transform(code, id) {
107
- if (entryFiles.some(function (file) {
130
+ if (inject === 'entry' && entryFiles.some(function (file) {
108
131
  return id.endsWith(file);
109
132
  })) {
110
133
  var injection = "\n import " + JSON.stringify(entryPath) + ";\n ";
@@ -381,7 +404,7 @@
381
404
  dev: options.dev,
382
405
  dts: options.dts,
383
406
  getPublicPath: options.getPublicPath,
384
- shareStrategy: options.shareStrategy
407
+ shareStrategy: options.shareStrategy || 'version-first'
385
408
  };
386
409
  }
387
410
 
@@ -619,13 +642,14 @@
619
642
  return item[1];
620
643
  }).join('\n') + "\n import exposesMap from \"" + VIRTUAL_EXPOSES + "\"\n import {usedShared, usedRemotes} from \"" + getLocalSharedImportMapPath() + "\"\n import {\n initResolve\n } from \"" + virtualRuntimeInitStatus.getImportId() + "\"\n async function init(shared = {}) {\n const initRes = runtimeInit({\n name: " + JSON.stringify(options.name) + ",\n remotes: usedRemotes,\n shared: usedShared,\n plugins: [" + pluginImportNames.map(function (item) {
621
644
  return item[0] + "()";
622
- }).join(', ') + "],\n " + (options.shareStrategy ? "shareStrategy: " + options.shareStrategy : '') + "\n });\n initRes.initShareScopeMap('" + options.shareScope + "', shared);\n initResolve(initRes)\n return initRes\n }\n\n function getExposes(moduleName) {\n if (!(moduleName in exposesMap)) throw new Error(`Module ${moduleName} does not exist in container.`)\n return (exposesMap[moduleName])().then(res => () => res)\n }\n export {\n init,\n getExposes as get\n }\n ";
645
+ }).join(', ') + "],\n " + (options.shareStrategy ? "shareStrategy: '" + options.shareStrategy + "'" : '') + "\n });\n initRes.initShareScopeMap('" + options.shareScope + "', shared);\n try {\n await Promise.all(await initRes.initializeSharing('" + options.shareScope + "', {strategy: '" + options.shareStrategy + "'}));\n } catch (e) {\n console.error(e)\n }\n initResolve(initRes)\n return initRes\n }\n\n function getExposes(moduleName) {\n if (!(moduleName in exposesMap)) throw new Error(`Module ${moduleName} does not exist in container.`)\n return (exposesMap[moduleName])().then(res => () => res)\n }\n export {\n init,\n getExposes as get\n }\n ";
623
646
  }
624
647
  /**
625
648
  * Inject entry file, automatically init when used as host,
626
649
  * and will not inject remoteEntry
627
650
  */
628
- var hostAutoInitModule = new VirtualModule('hostAutoInit');
651
+ var HOST_AUTO_INIT_TAG = '__H_A_I__';
652
+ var hostAutoInitModule = new VirtualModule('hostAutoInit', HOST_AUTO_INIT_TAG);
629
653
  function writeHostAutoInit() {
630
654
  hostAutoInitModule.writeSync("\n import {init} from \"" + REMOTE_ENTRY_ID + "\"\n init()\n ");
631
655
  }
@@ -660,16 +684,20 @@
660
684
  var remoteEntryFile;
661
685
  var publicPath;
662
686
  var _command;
687
+ var viteConfig;
663
688
  return [{
664
689
  name: 'module-federation-manifest',
665
690
  apply: 'serve',
691
+ configResolved: function configResolved(config) {
692
+ viteConfig = config;
693
+ },
666
694
  configureServer: function configureServer(server) {
667
695
  server.middlewares.use(function (req, res, next) {
668
696
  if (!mfManifestName) {
669
697
  next();
670
698
  return;
671
699
  }
672
- if (req.url === mfManifestName.replace(/^\/?/, '/')) {
700
+ if (req.url === (viteConfig.base + mfManifestName).replace(/^\/?/, '/')) {
673
701
  res.setHeader('Content-Type', 'application/json');
674
702
  res.setHeader('Access-Control-Allow-Origin', '*');
675
703
  res.end(JSON.stringify(_extends({}, generateMFManifest({}), {
@@ -718,11 +746,11 @@
718
746
  configResolved: function configResolved(config) {
719
747
  root = config.root;
720
748
  extensions = config.resolve.extensions || ['.mjs', '.js', '.mts', '.ts', '.jsx', '.tsx', '.json'];
721
- publicPath = config.base ? config.base.replace(/\/?$/, '/') : 'auto';
749
+ var base = config.base;
722
750
  if (_command === 'serve') {
723
- var origin = config.server.origin;
724
- publicPath = origin ? origin.replace(/\/?$/, '/') : 'auto';
751
+ base = (config.server.origin || '') + config.base;
725
752
  }
753
+ publicPath = base ? base.replace(/\/?$/, '/') : 'auto';
726
754
  },
727
755
  generateBundle: function generateBundle(options, bundle) {
728
756
  try {
@@ -1243,7 +1271,8 @@
1243
1271
  fileName: filename
1244
1272
  }), addEntry({
1245
1273
  entryName: 'hostInit',
1246
- entryPath: getHostAutoInitPath()
1274
+ entryPath: getHostAutoInitPath(),
1275
+ inject: 'html'
1247
1276
  }), addEntry({
1248
1277
  entryName: 'virtualExposes',
1249
1278
  entryPath: VIRTUAL_EXPOSES
@@ -3,6 +3,7 @@ interface AddEntryOptions {
3
3
  entryName: string;
4
4
  entryPath: string;
5
5
  fileName?: string;
6
+ inject?: 'entry' | 'html';
6
7
  }
7
- declare const addEntry: ({ entryName, entryPath, fileName }: AddEntryOptions) => Plugin[];
8
+ declare const addEntry: ({ entryName, entryPath, fileName, inject, }: AddEntryOptions) => Plugin[];
8
9
  export default addEntry;
@@ -66,7 +66,7 @@ export interface NormalizedModuleFederationOptions {
66
66
  manifest: ManifestOptions | boolean;
67
67
  dev?: boolean | PluginDevOptions;
68
68
  dts?: boolean | PluginDtsOptions;
69
- shareStrategy?: ShareStrategy;
69
+ shareStrategy: ShareStrategy;
70
70
  getPublicPath?: string;
71
71
  }
72
72
  interface PluginDevOptions {
@@ -6,6 +6,11 @@ export declare function writeLocalSharedImportMap(): void;
6
6
  export declare function generateLocalSharedImportMap(): string;
7
7
  export declare const REMOTE_ENTRY_ID = "virtual:mf-REMOTE_ENTRY_ID";
8
8
  export declare function generateRemoteEntry(options: NormalizedModuleFederationOptions): string;
9
+ /**
10
+ * Inject entry file, automatically init when used as host,
11
+ * and will not inject remoteEntry
12
+ */
13
+ export declare const HOST_AUTO_INIT_TAG = "__H_A_I__";
9
14
  export declare function writeHostAutoInit(): void;
10
15
  export declare function getHostAutoInitImportId(): string;
11
16
  export declare function getHostAutoInitPath(): string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@module-federation/vite",
3
- "version": "1.1.2",
3
+ "version": "1.1.4",
4
4
  "description": "Vite plugin for Module Federation",
5
5
  "type": "module",
6
6
  "source": "src/index.ts",