@touk/federated-types 1.2.2-beta.1 → 1.3.0-beta.1

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.
Files changed (3) hide show
  1. package/README.md +41 -4
  2. package/cli.js +69 -14
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -30,7 +30,6 @@ It's recommended that you spread these properties into your ModuleFederationPlug
30
30
  ```javascript
31
31
  //webpack.config.js
32
32
 
33
- const deps = require('../package.json').dependencies;
34
33
  const federationConfig = require('./federation.config.json');
35
34
 
36
35
  module.exports = {
@@ -40,9 +39,7 @@ module.exports = {
40
39
  new ModuleFederationPlugin({
41
40
  ...federationConfig,
42
41
  filename: "remoteEntry.js",
43
- shared: {
44
- ...deps,
45
- },
42
+ shared: { ... },
46
43
  }),
47
44
  ],
48
45
 
@@ -84,3 +81,43 @@ scripts: {
84
81
  "make-types": "make-federated-types --config ./path/to/my/config.json --outputDir ../../my_types/"
85
82
  }
86
83
  ```
84
+
85
+ ## Inline configuration (without config file)
86
+
87
+ If you prefer not to maintain a separate `federation.config.json` file, you can provide the configuration directly via CLI arguments using `--name` and `--exposes`:
88
+
89
+ ```bash
90
+ make-federated-types \
91
+ --name myApp \
92
+ --exposes App ./src/App.tsx \
93
+ --exposes Button ./src/components/Button.tsx \
94
+ --outputDir ./types
95
+ ```
96
+
97
+ ### Inline config features:
98
+
99
+ - **Multiple exposures**: Use `--exposes` multiple times, each followed by a key and file path
100
+ - **Auto-prefix**: Keys without `./` prefix are automatically normalized (e.g., `App` becomes `./App`)
101
+ - **Shell-friendly**: Works with tab completion for file paths
102
+ - **Priority**: Inline config takes precedence over `--config` and auto-discovery
103
+
104
+ ### Examples:
105
+
106
+ ```bash
107
+ # Simple inline config
108
+ make-federated-types --name app2 --exposes Button ./src/Button.tsx
109
+
110
+ # Multiple exposures
111
+ make-federated-types \
112
+ --name app2 \
113
+ --exposes ./Button ./src/Button.tsx \
114
+ --exposes ./Header ./src/Header.tsx
115
+
116
+ # Nested keys (auto-prefixed with ./)
117
+ make-federated-types \
118
+ --name app2 \
119
+ --exposes components/Button ./src/components/Button.tsx \
120
+ --exposes utils/helpers ./src/utils/helpers.ts
121
+ ```
122
+
123
+ **Note**: When using inline config, both `--name` and at least one `--exposes` are required.
package/cli.js CHANGED
@@ -29,6 +29,26 @@ const getArg = (argName) => {
29
29
  const argIndex = process.argv.indexOf(argName);
30
30
  return argIndex !== -1 ? process.argv[argIndex + 1] : null;
31
31
  };
32
+ const getAllArgs = (argName) => {
33
+ const results = [];
34
+ let i = 2; // process.argv starts with node and script path
35
+
36
+ while (i < process.argv.length) {
37
+ if (process.argv[i] === argName) {
38
+ // Next two arguments are key and value
39
+ if (i + 2 < process.argv.length) {
40
+ results.push([process.argv[i + 1], process.argv[i + 2]]);
41
+ i += 3; // skip argName, key, value
42
+ } else {
43
+ console.error(`ERROR: --exposes requires two arguments (key path)`);
44
+ process.exit(1);
45
+ }
46
+ } else {
47
+ i++;
48
+ }
49
+ }
50
+ return results;
51
+ };
32
52
 
33
53
  const nodeModulesOutputDir = path.resolve(nodeModules, '@types/__federated_types/');
34
54
  const saveToNodeMoulesArg = hasArg('--saveToNodeModules');
@@ -44,6 +64,9 @@ const outputDirs =
44
64
  const configPathArg = getArg('--config');
45
65
  const configPath = configPathArg ? path.resolve(configPathArg) : null;
46
66
 
67
+ const nameArg = getArg('--name');
68
+ const exposesArgs = getAllArgs('--exposes');
69
+
47
70
  const findFederationConfig = (base) => {
48
71
  let files = fs.readdirSync(base);
49
72
  let queue = [];
@@ -63,21 +86,52 @@ const findFederationConfig = (base) => {
63
86
  }
64
87
  };
65
88
 
66
- if (configPath && !fs.existsSync(configPath)) {
67
- console.error(`ERROR: Unable to find a provided config: ${configPath}`);
68
- process.exit(1);
69
- }
89
+ let federationConfig;
70
90
 
71
- const federationConfigPath = configPath || findFederationConfig('./');
91
+ // Priority: inline config > --config > auto-find
92
+ if (nameArg || exposesArgs.length > 0) {
93
+ // Inline config mode
94
+ if (!nameArg || exposesArgs.length === 0) {
95
+ console.error('ERROR: Both --name and --exposes are required for inline config');
96
+ process.exit(1);
97
+ }
72
98
 
73
- if (federationConfigPath === undefined) {
74
- console.error(`ERROR: Unable to find a federation.config.json file in this package`);
75
- process.exit(1);
76
- }
99
+ if (configPath) {
100
+ console.warn('WARNING: Both inline config and --config provided. Using inline config.');
101
+ }
102
+
103
+ const exposes = {};
77
104
 
78
- console.log(`Using config file: ${federationConfigPath}`);
105
+ exposesArgs.forEach(([key, value]) => {
106
+ // Normalize key - add ./ if missing
107
+ const normalizedKey = key.startsWith('./') ? key : `./${key}`;
108
+ exposes[normalizedKey] = value;
109
+ });
110
+
111
+ federationConfig = {
112
+ name: nameArg,
113
+ exposes: exposes,
114
+ };
115
+
116
+ console.log('Using inline config:', JSON.stringify(federationConfig, null, 2));
117
+ } else {
118
+ // File-based config (current behavior)
119
+ if (configPath && !fs.existsSync(configPath)) {
120
+ console.error(`ERROR: Unable to find a provided config: ${configPath}`);
121
+ process.exit(1);
122
+ }
123
+
124
+ const federationConfigPath = configPath || findFederationConfig('./');
125
+
126
+ if (federationConfigPath === undefined) {
127
+ console.error(`ERROR: Unable to find a federation.config.json file in this package`);
128
+ process.exit(1);
129
+ }
130
+
131
+ console.log(`Using config file: ${federationConfigPath}`);
132
+ federationConfig = require(federationConfigPath);
133
+ }
79
134
 
80
- const federationConfig = require(federationConfigPath);
81
135
  const compileFiles = Object.values(federationConfig.exposes);
82
136
  const compileKeys = Object.keys(federationConfig.exposes);
83
137
 
@@ -122,9 +176,10 @@ try {
122
176
 
123
177
  moduleNames.forEach((name) => {
124
178
  // exposeName - relative name of exposed component (if not found - just take moduleName)
125
- const [exposeName = name, ...aliases] = compileKeys.filter((key) =>
126
- federationConfig.exposes[key].endsWith(name)
127
- );
179
+ const [exposeName = name, ...aliases] = compileKeys.filter((key) => {
180
+ const normalizedPath = federationConfig.exposes[key].replace(/\.(tsx?|jsx?)$/, '');
181
+ return normalizedPath.endsWith(name);
182
+ });
128
183
  const regex = RegExp(`"${name}"`, 'g');
129
184
 
130
185
  const moduleDeclareName = getModuleDeclareName(exposeName);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@touk/federated-types",
3
3
  "description": "share typings for your federated typescript packages around your mono-repo",
4
- "version": "1.2.2-beta.1",
4
+ "version": "1.3.0-beta.1",
5
5
  "author": "Julian Wielga <j@touk.pl>",
6
6
  "bin": {
7
7
  "make-federated-types": "./cli.js"