@module-federation/native-federation-tests 0.1.0

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/README.md ADDED
@@ -0,0 +1,157 @@
1
+ # native-federation-tests
2
+
3
+ Bundler agnostic plugins to share federated components for testing purposes.
4
+
5
+ It aims to work for both [`vitest`](https://vitest.dev/) and [`jest`](https://jestjs.io/).
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm i -D @module-federation/native-federation-tests
11
+ ```
12
+
13
+ This module provides two plugins:
14
+
15
+ ### NativeFederationTestsRemote
16
+ This plugin is used to concat the components that will be used in tests.
17
+
18
+ #### Configuration
19
+ ```typescript
20
+ {
21
+ moduleFederationConfig: any; // the same configuration provided to the module federation plugin, it is MANDATORY
22
+ additionalBundlerConfig?: TsupOptions; // additional `tsup` build options that will be merged with the one generated by the plugin, default is {}
23
+ distFolder?: string; // folder used to store the dist, default is './dist'
24
+ testsFolder?: string; // folder where all the files will be stored, default is '@mf-tests'
25
+ deleteTestsFolder?: boolean; // indicate if the concatenated components folder will be deleted when the job completes, default is 'true'
26
+ }
27
+ ```
28
+
29
+ #### Additional configuration
30
+ Note that, for Webpack, the plugin automatically inject the `devServer.static.directory` configuration.
31
+ For the other bundlers, you should configure it by yourself.
32
+
33
+ ### NativeFederationTestsHost
34
+ This plugin is used to download the concatenated components mock that will be used for tests.
35
+
36
+ ### Configuration
37
+
38
+ ```typescript
39
+ {
40
+ moduleFederationConfig: any; // the configuration same configuration provided to the module federation plugin, it is MANDATORY
41
+ testsFolder?: string; // folder where all the files have been stored, default is '@mf-tests',
42
+ mocksFolder?: string; // folder where the concatenated files will be stored, default is './__mocks__',
43
+ deleteTestsFolder?: boolean; // indicate if the tests mock folder will be deleted before the job starts, default is 'true'
44
+ }
45
+ ```
46
+
47
+ ## Bundler configuration
48
+
49
+ <details>
50
+ <summary>Vite</summary><br>
51
+
52
+ ```ts
53
+ // vite.config.ts
54
+ import {NativeFederationTestsHost, NativeFederationTestsRemote} from '@module-federation/native-federation-tests/vite'
55
+
56
+ export default defineConfig({
57
+ plugins: [
58
+ NativeFederationTestsRemote({ /* options */ }),
59
+ NativeFederationTestsHost({ /* options */ }),
60
+ ],
61
+ /* ... */
62
+ server: { // This is needed to emulate the devServer.static.directory of WebPack and correctly serve the zip file
63
+ /* ... */
64
+ proxy: {
65
+ '/@mf-types.zip': {
66
+ target: 'http://localhost:3000',
67
+ changeOrigin: true,
68
+ rewrite: () => `/@fs/${process.cwd()}/dist/@mf-types.zip`
69
+ }
70
+ },
71
+ fs: {
72
+ /* ... */
73
+ allow: ['./dist']
74
+ /* ... */
75
+ }
76
+ }
77
+ })
78
+ ```
79
+
80
+ <br>
81
+ </details>
82
+ <details>
83
+ <summary>Rollup</summary><br>
84
+
85
+ ```ts
86
+ // rollup.config.js
87
+ import {NativeFederationTestsHost, NativeFederationTestsRemote} from '@module-federation/native-federation-tests/rollup'
88
+
89
+ export default {
90
+ plugins: [
91
+ NativeFederationTestsRemote({ /* options */ }),
92
+ NativeFederationTestsHost({ /* options */ }),
93
+ ],
94
+ }
95
+ ```
96
+
97
+ <br>
98
+ </details>
99
+ <details>
100
+ <summary>Webpack</summary><br>
101
+
102
+ ```ts
103
+ // webpack.config.js
104
+ const {NativeFederationTestsHost, NativeFederationTestsRemote} = require('@module-federation/native-federation-tests/webpack')
105
+ module.exports = {
106
+ /* ... */
107
+ plugins: [
108
+ NativeFederationTestsRemote({ /* options */ }),
109
+ NativeFederationTestsHost({ /* options */ })
110
+ ]
111
+ }
112
+ ```
113
+
114
+ <br>
115
+ </details>
116
+ <details>
117
+ <summary>esbuild</summary><br>
118
+
119
+ ```ts
120
+ // esbuild.config.js
121
+ import { build } from 'esbuild'
122
+ import {NativeFederationTestsHost, NativeFederationTestsRemote} from '@module-federation/native-federation-tests/esbuild'
123
+
124
+ build({
125
+ plugins: [
126
+ NativeFederationTestsRemote({ /* options */ }),
127
+ NativeFederationTestsHost({ /* options */ })
128
+ ],
129
+ })
130
+ ```
131
+
132
+ <br>
133
+ </details>
134
+
135
+ <details>
136
+ <summary>Rspack</summary><br>
137
+
138
+ ```ts
139
+ // rspack.config.js
140
+ const {NativeFederationTestsHost, NativeFederationTestsRemote} = require('@module-federation/native-federation-tests/rspack')
141
+
142
+ module.exports = {
143
+ /* ... */
144
+ plugins: [
145
+ NativeFederationTestsRemote({ /* options */ }),
146
+ NativeFederationTestsHost({ /* options */ })
147
+ ]
148
+ }
149
+ ```
150
+
151
+ <br>
152
+ </details>
153
+
154
+ ## Examples
155
+
156
+ To use it in a `host` module, refer to [this example](https://github.com/ilteoood/module-federation-typescript/tree/host).
157
+ To use it in a `remote` module, refer to [this example](https://github.com/ilteoood/module-federation-typescript/tree/remote).
@@ -0,0 +1,18 @@
1
+ import { Options } from 'tsup';
2
+
3
+ interface HostOptions {
4
+ moduleFederationConfig: any;
5
+ testsFolder?: string;
6
+ mocksFolder?: string;
7
+ deleteTestsFolder?: boolean;
8
+ }
9
+
10
+ interface RemoteOptions {
11
+ moduleFederationConfig: any;
12
+ additionalBundlerConfig?: Options;
13
+ distFolder?: string;
14
+ testsFolder?: string;
15
+ deleteTestsFolder?: boolean;
16
+ }
17
+
18
+ export { HostOptions as H, RemoteOptions as R };
@@ -0,0 +1 @@
1
+ import m from"ansi-colors";import{rm as q}from"fs/promises";import{resolve as S}from"path";import{mergeDeepRight as $,mergeRight as D}from"rambda";import{build as U}from"tsup";import{createUnplugin as O}from"unplugin";var R={testsFolder:"@mf-tests",mocksFolder:"./__mocks__",deleteTestsFolder:!0},w=(o,e)=>{let t=e.split("@").at(-1),r=new URL(t);return r.pathname=`${o.testsFolder}.zip`,r.href},x=o=>Object.entries(o.moduleFederationConfig.remotes).reduce((e,[t,r])=>(e[t]=w(o,r),e),{}),c=o=>{if(!o.moduleFederationConfig)throw new Error("moduleFederationConfig is required");let e={...R,...o},t=x(e);return{hostOptions:e,mapRemotesToDownload:t}};import{existsSync as v}from"fs";import{join as d}from"path";var y={testsFolder:"@mf-tests",distFolder:"./dist",deleteTestsFolder:!0,additionalBundlerConfig:{}},h=["ts","tsx","js","jsx","mjs"],p=o=>{let e=process.cwd();for(let t of h){let r=d(e,`${o}.${t}`);if(v(r))return r}},C=o=>Object.entries(o.moduleFederationConfig.exposes).reduce((e,[t,r])=>(e[t]=p(r)||p(d(r,"index"))||r,e),{}),a=o=>{if(!o.moduleFederationConfig)throw new Error("moduleFederationConfig is required");let e={...y,...o},t=C(e),r=Object.keys(o.moduleFederationConfig.shared||{}).concat(Object.keys(o.moduleFederationConfig.remotes||{})),s=d(e.distFolder,e.testsFolder);return{remoteOptions:e,externalDeps:r,compiledFilesFolder:s,mapComponentsToExpose:t}};import l from"adm-zip";import T from"ansi-colors";import b from"axios";import{join as f}from"path";var k=o=>f(o.distFolder,`${o.testsFolder}.zip`),u=async(o,e)=>{let t=new l;return t.addLocalFolder(e),t.writeZipPromise(k(o))},H=(o,e)=>t=>{throw console.error(T.red(`Unable to download federated mocks for '${o}' from '${e}' because '${t.message}', skipping...`)),t},g=o=>async([e,t])=>{let r=await b.get(t,{responseType:"arraybuffer"}).catch(H(e,t)),s=f(o.mocksFolder,e);new l(Buffer.from(r.data)).extractAllTo(s,!0)};import{rm as j}from"fs/promises";import{join as E}from"path";var F=async(o,e)=>{let t=e.map(r=>{let s=E(o.mocksFolder,r);return j(s,{recursive:!0,force:!0})});return Promise.allSettled(t)};var se=O(o=>{let{remoteOptions:e,compiledFilesFolder:t,externalDeps:r,mapComponentsToExpose:s}=a(o);return{name:"native-federation-tests/remote",async writeBundle(){let n=D(e.additionalBundlerConfig,{external:r.map(i=>new RegExp(i)),entry:s,outDir:t,silent:!0});try{await U(n),await u(e,t),e.deleteTestsFolder&&await q(t,{recursive:!0,force:!0}),console.log(m.green("Federated mocks created correctly"))}catch(i){console.error(m.red(`Unable to build federated mocks: ${i}`))}},webpack:n=>{n.options.devServer=$(n.options.devServer||{},{static:{directory:S(e.distFolder)}})}}}),ne=O(o=>{let{hostOptions:e,mapRemotesToDownload:t}=c(o);return{name:"native-federation-tests/host",async writeBundle(){e.deleteTestsFolder&&await F(e,Object.keys(t));let r=g(e),s=Object.entries(t).map(r);await Promise.allSettled(s),console.log(m.green("Federated mocks extraction completed"))}}});export{se as a,ne as b};
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }var _ansicolors = require('ansi-colors'); var _ansicolors2 = _interopRequireDefault(_ansicolors);var _promises = require('fs/promises');var _path = require('path');var _rambda = require('rambda');var _tsup = require('tsup');var _unplugin = require('unplugin');var R={testsFolder:"@mf-tests",mocksFolder:"./__mocks__",deleteTestsFolder:!0},w=(o,e)=>{let t=e.split("@").at(-1),r=new URL(t);return r.pathname=`${o.testsFolder}.zip`,r.href},x=o=>Object.entries(o.moduleFederationConfig.remotes).reduce((e,[t,r])=>(e[t]=w(o,r),e),{}),c=o=>{if(!o.moduleFederationConfig)throw new Error("moduleFederationConfig is required");let e={...R,...o},t=x(e);return{hostOptions:e,mapRemotesToDownload:t}};var _fs = require('fs');var y={testsFolder:"@mf-tests",distFolder:"./dist",deleteTestsFolder:!0,additionalBundlerConfig:{}},h=["ts","tsx","js","jsx","mjs"],p=o=>{let e=process.cwd();for(let t of h){let r=_path.join.call(void 0, e,`${o}.${t}`);if(_fs.existsSync.call(void 0, r))return r}},C=o=>Object.entries(o.moduleFederationConfig.exposes).reduce((e,[t,r])=>(e[t]=p(r)||p(_path.join.call(void 0, r,"index"))||r,e),{}),a=o=>{if(!o.moduleFederationConfig)throw new Error("moduleFederationConfig is required");let e={...y,...o},t=C(e),r=Object.keys(o.moduleFederationConfig.shared||{}).concat(Object.keys(o.moduleFederationConfig.remotes||{})),s=_path.join.call(void 0, e.distFolder,e.testsFolder);return{remoteOptions:e,externalDeps:r,compiledFilesFolder:s,mapComponentsToExpose:t}};var _admzip = require('adm-zip'); var _admzip2 = _interopRequireDefault(_admzip);var _axios = require('axios'); var _axios2 = _interopRequireDefault(_axios);var k=o=>_path.join.call(void 0, o.distFolder,`${o.testsFolder}.zip`),u=async(o,e)=>{let t=new _admzip2.default;return t.addLocalFolder(e),t.writeZipPromise(k(o))},H=(o,e)=>t=>{throw console.error(_ansicolors2.default.red(`Unable to download federated mocks for '${o}' from '${e}' because '${t.message}', skipping...`)),t},g=o=>async([e,t])=>{let r=await _axios2.default.get(t,{responseType:"arraybuffer"}).catch(H(e,t)),s=_path.join.call(void 0, o.mocksFolder,e);new (0, _admzip2.default)(Buffer.from(r.data)).extractAllTo(s,!0)};var F=async(o,e)=>{let t=e.map(r=>{let s=_path.join.call(void 0, o.mocksFolder,r);return _promises.rm.call(void 0, s,{recursive:!0,force:!0})});return Promise.allSettled(t)};var se=_unplugin.createUnplugin.call(void 0, o=>{let{remoteOptions:e,compiledFilesFolder:t,externalDeps:r,mapComponentsToExpose:s}=a(o);return{name:"native-federation-tests/remote",async writeBundle(){let n=_rambda.mergeRight.call(void 0, e.additionalBundlerConfig,{external:r.map(i=>new RegExp(i)),entry:s,outDir:t,silent:!0});try{await _tsup.build.call(void 0, n),await u(e,t),e.deleteTestsFolder&&await _promises.rm.call(void 0, t,{recursive:!0,force:!0}),console.log(_ansicolors2.default.green("Federated mocks created correctly"))}catch(i){console.error(_ansicolors2.default.red(`Unable to build federated mocks: ${i}`))}},webpack:n=>{n.options.devServer=_rambda.mergeDeepRight.call(void 0, n.options.devServer||{},{static:{directory:_path.resolve.call(void 0, e.distFolder)}})}}}),ne= exports.b =_unplugin.createUnplugin.call(void 0, o=>{let{hostOptions:e,mapRemotesToDownload:t}=c(o);return{name:"native-federation-tests/host",async writeBundle(){e.deleteTestsFolder&&await F(e,Object.keys(t));let r=g(e),s=Object.entries(t).map(r);await Promise.allSettled(s),console.log(_ansicolors2.default.green("Federated mocks extraction completed"))}}});exports.a = se; exports.b = ne;
@@ -0,0 +1,7 @@
1
+ import { R as RemoteOptions, H as HostOptions } from './RemoteOptions-ae724cfa.js';
2
+ import 'tsup';
3
+
4
+ declare const NativeFederationTestsRemote: (options: RemoteOptions) => undefined;
5
+ declare const NativeFederationTestsHost: (options: HostOptions) => undefined;
6
+
7
+ export { NativeFederationTestsHost, NativeFederationTestsRemote };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});var _chunkZ276SNUUjs = require('./chunk-Z276SNUU.js');var o=_chunkZ276SNUUjs.a.esbuild,a= exports.NativeFederationTestsHost =_chunkZ276SNUUjs.b.esbuild;exports.NativeFederationTestsHost = a; exports.NativeFederationTestsRemote = o;
@@ -0,0 +1 @@
1
+ import{a as e,b as t}from"./chunk-NLBUZNVY.mjs";var o=e.esbuild,a=t.esbuild;export{a as NativeFederationTestsHost,o as NativeFederationTestsRemote};
@@ -0,0 +1,8 @@
1
+ import * as unplugin from 'unplugin';
2
+ import { R as RemoteOptions, H as HostOptions } from './RemoteOptions-ae724cfa.js';
3
+ import 'tsup';
4
+
5
+ declare const NativeFederationTestsRemote: unplugin.UnpluginInstance<RemoteOptions, boolean>;
6
+ declare const NativeFederationTestsHost: unplugin.UnpluginInstance<HostOptions, boolean>;
7
+
8
+ export { NativeFederationTestsHost, NativeFederationTestsRemote };
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});var _chunkZ276SNUUjs = require('./chunk-Z276SNUU.js');exports.NativeFederationTestsHost = _chunkZ276SNUUjs.b; exports.NativeFederationTestsRemote = _chunkZ276SNUUjs.a;
package/dist/index.mjs ADDED
@@ -0,0 +1 @@
1
+ import{a,b}from"./chunk-NLBUZNVY.mjs";export{b as NativeFederationTestsHost,a as NativeFederationTestsRemote};
@@ -0,0 +1,7 @@
1
+ import { R as RemoteOptions, H as HostOptions } from './RemoteOptions-ae724cfa.js';
2
+ import 'tsup';
3
+
4
+ declare const NativeFederationTestsRemote: (options: RemoteOptions) => undefined | undefined[];
5
+ declare const NativeFederationTestsHost: (options: HostOptions) => undefined | undefined[];
6
+
7
+ export { NativeFederationTestsHost, NativeFederationTestsRemote };
package/dist/rollup.js ADDED
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});var _chunkZ276SNUUjs = require('./chunk-Z276SNUU.js');var s=_chunkZ276SNUUjs.a.rollup,a= exports.NativeFederationTestsHost =_chunkZ276SNUUjs.b.rollup;exports.NativeFederationTestsHost = a; exports.NativeFederationTestsRemote = s;
@@ -0,0 +1 @@
1
+ import{a as e,b as t}from"./chunk-NLBUZNVY.mjs";var s=e.rollup,a=t.rollup;export{a as NativeFederationTestsHost,s as NativeFederationTestsRemote};
@@ -0,0 +1,7 @@
1
+ import { R as RemoteOptions, H as HostOptions } from './RemoteOptions-ae724cfa.js';
2
+ import 'tsup';
3
+
4
+ declare const NativeFederationTestsRemote: (options: RemoteOptions) => RspackPluginInstance;
5
+ declare const NativeFederationTestsHost: (options: HostOptions) => RspackPluginInstance;
6
+
7
+ export { NativeFederationTestsHost, NativeFederationTestsRemote };
package/dist/rspack.js ADDED
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});var _chunkZ276SNUUjs = require('./chunk-Z276SNUU.js');var o=_chunkZ276SNUUjs.a.rspack,a= exports.NativeFederationTestsHost =_chunkZ276SNUUjs.b.rspack;exports.NativeFederationTestsHost = a; exports.NativeFederationTestsRemote = o;
@@ -0,0 +1 @@
1
+ import{a as e,b as t}from"./chunk-NLBUZNVY.mjs";var o=e.rspack,a=t.rspack;export{a as NativeFederationTestsHost,o as NativeFederationTestsRemote};
package/dist/vite.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ import { R as RemoteOptions, H as HostOptions } from './RemoteOptions-ae724cfa.js';
2
+ import 'tsup';
3
+
4
+ declare const NativeFederationTestsRemote: (options: RemoteOptions) => any;
5
+ declare const NativeFederationTestsHost: (options: HostOptions) => any;
6
+
7
+ export { NativeFederationTestsHost, NativeFederationTestsRemote };
package/dist/vite.js ADDED
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});var _chunkZ276SNUUjs = require('./chunk-Z276SNUU.js');var s=_chunkZ276SNUUjs.a.vite,i= exports.NativeFederationTestsHost =_chunkZ276SNUUjs.b.vite;exports.NativeFederationTestsHost = i; exports.NativeFederationTestsRemote = s;
package/dist/vite.mjs ADDED
@@ -0,0 +1 @@
1
+ import{a as t,b as e}from"./chunk-NLBUZNVY.mjs";var s=t.vite,i=e.vite;export{i as NativeFederationTestsHost,s as NativeFederationTestsRemote};
@@ -0,0 +1,7 @@
1
+ import { R as RemoteOptions, H as HostOptions } from './RemoteOptions-ae724cfa.js';
2
+ import 'tsup';
3
+
4
+ declare const NativeFederationTestsRemote: (options: RemoteOptions) => undefined;
5
+ declare const NativeFederationTestsHost: (options: HostOptions) => undefined;
6
+
7
+ export { NativeFederationTestsHost, NativeFederationTestsRemote };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});var _chunkZ276SNUUjs = require('./chunk-Z276SNUU.js');var s=_chunkZ276SNUUjs.a.webpack,a= exports.NativeFederationTestsHost =_chunkZ276SNUUjs.b.webpack;exports.NativeFederationTestsHost = a; exports.NativeFederationTestsRemote = s;
@@ -0,0 +1 @@
1
+ import{a as e,b as t}from"./chunk-NLBUZNVY.mjs";var s=e.webpack,a=t.webpack;export{a as NativeFederationTestsHost,s as NativeFederationTestsRemote};
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "@module-federation/native-federation-tests",
3
+ "version": "0.1.0",
4
+ "description": "Bundler agnostic unplugin to share federated tests",
5
+ "exports": {
6
+ ".": {
7
+ "import": "./dist/index.mjs",
8
+ "require": "./dist/index.js",
9
+ "types": "./dist/index.d.ts"
10
+ },
11
+ "./rollup": {
12
+ "types": "./dist/rollup.d.ts",
13
+ "require": "./dist/rollup.js",
14
+ "import": "./dist/rollup.mjs"
15
+ },
16
+ "./vite": {
17
+ "types": "./dist/vite.d.ts",
18
+ "require": "./dist/vite.js",
19
+ "import": "./dist/vite.mjs"
20
+ },
21
+ "./webpack": {
22
+ "types": "./dist/webpack.d.ts",
23
+ "require": "./dist/webpack.js",
24
+ "import": "./dist/webpack.mjs"
25
+ },
26
+ "./esbuild": {
27
+ "types": "./dist/esbuild.d.ts",
28
+ "require": "./dist/esbuild.js",
29
+ "import": "./dist/esbuild.mjs"
30
+ },
31
+ "./rspack": {
32
+ "types": "./dist/rspack.d.ts",
33
+ "require": "./dist/rspack.js",
34
+ "import": "./dist/rspack.mjs"
35
+ }
36
+ },
37
+ "main": "./dist/index.js",
38
+ "types": "./dist/index.d.ts",
39
+ "keywords": [
40
+ "module federation",
41
+ "tests",
42
+ "remote tests",
43
+ "federated tests"
44
+ ],
45
+ "author": "Matteo Pietro Dazzi <matteopietro.dazzi@gmail.com> (https://github.com/ilteoood)",
46
+ "license": "MIT",
47
+ "dependencies": {
48
+ "adm-zip": "^0.5.10",
49
+ "ansi-colors": "^4.1.3",
50
+ "axios": "^1.3.4",
51
+ "rambda": "^7.5.0",
52
+ "tsup": "^6.7.0",
53
+ "unplugin": "^1.3.1"
54
+ }
55
+ }