@touk/federated-types 1.3.0-beta.7 → 1.3.0-beta.8

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 (2) hide show
  1. package/cli.js +62 -9
  2. package/package.json +2 -3
package/cli.js CHANGED
@@ -2,7 +2,6 @@
2
2
 
3
3
  const path = require('path');
4
4
  const fs = require('fs');
5
- const findNodeModules = require('find-node-modules');
6
5
  const ts = require('typescript');
7
6
  const chalk = require('chalk');
8
7
 
@@ -20,7 +19,20 @@ function reportDiagnostic(diagnostic) {
20
19
  );
21
20
  }
22
21
 
23
- const [nodeModules] = findNodeModules({ cwd: process.argv[1], relative: false });
22
+ // nearest node_modules directory up from the CLI script
23
+ const findNodeModules = (start) => {
24
+ let dir = path.resolve(start);
25
+ while (!fs.existsSync(path.join(dir, 'node_modules'))) {
26
+ const parent = path.dirname(dir);
27
+ if (parent === dir) {
28
+ return path.resolve('node_modules');
29
+ }
30
+ dir = parent;
31
+ }
32
+ return path.join(dir, 'node_modules');
33
+ };
34
+
35
+ const nodeModules = findNodeModules(process.argv[1]);
24
36
 
25
37
  const hasArg = (argName) => {
26
38
  const argIndex = process.argv.indexOf(argName);
@@ -156,6 +168,35 @@ function getModuleDeclareName(exposeName) {
156
168
  return path.join(federationConfig.name, exposeName).replace(/[\\/]/g, '/');
157
169
  }
158
170
 
171
+ const toPosixPath = (value) => value.replace(/[\\/]/g, '/');
172
+ const stripSourceExtension = (file) => file.replace(/\.(d\.ts|[cm]?tsx?|[cm]?jsx?)$/, '');
173
+
174
+ /**
175
+ * Maps the absolute path (without extension) of every source file in the program to the module
176
+ * name tsc gives it in an outFile bundle: its path relative to the common source directory.
177
+ * Exposes outside of the exposing package (e.g. a package importing a sibling's sources) move
178
+ * that directory up, so the module name cannot be derived from the configured path alone.
179
+ */
180
+ function getEmittedModuleNames(program) {
181
+ // internal, but stable TypeScript API; fall back to suffix matching without it
182
+ if (typeof program.getCommonSourceDirectory !== 'function') {
183
+ return new Map();
184
+ }
185
+ const commonSourceDirectory = program.getCommonSourceDirectory();
186
+ return new Map(
187
+ program
188
+ .getSourceFiles()
189
+ .filter((sourceFile) => !sourceFile.isDeclarationFile)
190
+ .map((sourceFile) => {
191
+ const absolutePath = stripSourceExtension(path.resolve(sourceFile.fileName));
192
+ return [
193
+ toPosixPath(absolutePath),
194
+ toPosixPath(path.relative(commonSourceDirectory, absolutePath)),
195
+ ];
196
+ })
197
+ );
198
+ }
199
+
159
200
  // Matches the module specifier of `from "x"`, `import("x")`, `import "x"` and `require("x")`.
160
201
  const moduleReferenceRegex = /\b(?:from|import|require)\s*\(?\s*(["'])([^"'\n]+)\1/g;
161
202
  // Global or module augmentations take effect without being imported, so such modules are always kept.
@@ -252,14 +293,26 @@ try {
252
293
  let typing = fs.readFileSync(outFile, { encoding: 'utf8', flag: 'r' });
253
294
 
254
295
  const moduleRegex = RegExp(/declare module "(.*)"/, 'g');
255
- const exposedPaths = compileKeys.map((key) => [
256
- key,
257
- federationConfig.exposes[key].replace(/\.(tsx?|jsx?)$/, ''),
258
- ]);
296
+ const emittedModuleNames = getEmittedModuleNames(program);
297
+ const exposedModules = compileKeys.map((key) => {
298
+ const exposePath = federationConfig.exposes[key];
299
+ const absolutePath = toPosixPath(stripSourceExtension(path.resolve(exposePath)));
300
+ return {
301
+ key,
302
+ relativePath: exposePath.replace(/\.(tsx?|jsx?)$/, ''),
303
+ moduleName:
304
+ emittedModuleNames.get(absolutePath) ??
305
+ emittedModuleNames.get(`${absolutePath}/index`),
306
+ };
307
+ });
308
+ // Falls back to suffix matching of the configured path when the source file could not be
309
+ // resolved in the program.
259
310
  const findExposeKeys = (name) =>
260
- exposedPaths
261
- .filter(([, normalizedPath]) => normalizedPath.endsWith(name))
262
- .map(([key]) => key);
311
+ exposedModules
312
+ .filter(({ relativePath, moduleName }) =>
313
+ moduleName !== undefined ? moduleName === name : relativePath.endsWith(name)
314
+ )
315
+ .map(({ key }) => key);
263
316
 
264
317
  if (pruneArg) {
265
318
  typing = pruneUnreachableModules(typing, (name) => findExposeKeys(name).length > 0);
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.3.0-beta.7",
4
+ "version": "1.3.0-beta.8",
5
5
  "author": "Julian Wielga <j@touk.pl>",
6
6
  "bin": {
7
7
  "make-federated-types": "./cli.js"
@@ -10,8 +10,7 @@
10
10
  "Jonathan Greene <jgreene@pixability.com>"
11
11
  ],
12
12
  "dependencies": {
13
- "chalk": "^4.1.2",
14
- "find-node-modules": "2.1.3"
13
+ "chalk": "^4.1.2"
15
14
  },
16
15
  "devDependencies": {
17
16
  "@commitlint/cli": "^20.4.2",