rev-dep 1.0.0-alpha.2 → 1.0.0-alpha.5

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 CHANGED
@@ -1,16 +1,51 @@
1
1
  <h3 align="center">
2
- <code>rev🠄dep</code>
2
+ <code>revdep</code>
3
3
  </h3>
4
4
 
5
5
  <p align="center">
6
- A small tool for JavaScript project discovery
6
+ Dependency debugging tool for JavaScript and TypeScript projects
7
7
  </p>
8
8
 
9
9
  ---
10
10
 
11
11
  <img alt="rev-dep version" src="https://img.shields.io/npm/v/rev-dep"> <img alt="rev-dep license" src="https://img.shields.io/npm/l/rev-dep"> <img alt="rev-dep PRs welcome" src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square">
12
12
 
13
- ## Installation
13
+ ## About
14
+
15
+ The tool was created help with daily dev struggles by answering these questions:
16
+
17
+ - What entry points my codebase have
18
+ - Which entry points uses a given file
19
+ - Which dependencies a given file has
20
+
21
+ This helps to debug project dependencies, plan refactoring, optimize bundles or plan code splitting.
22
+
23
+ It's especially useful in JS world without TypeScript or tests coverage.
24
+
25
+ It also helps to identify and eliminate dead files, understand the complexity of the file dependencies
26
+
27
+ [Jump to CLI reference](#CLI-reference)
28
+
29
+ [`export * from` problem](#Export-from-problem)
30
+
31
+ ### Use cases
32
+
33
+ - You plan to refactor some file and you wonder which entry points are affected
34
+ - You are wondering wether a given source file is used
35
+ - You wonder if there are any dead files in your project
36
+ - You want to identify all dead files at once
37
+ - You want to verify if a given entry point imports only the required files
38
+ - You want to optimize the amount of files imported by an entry point
39
+
40
+ ### How about dependency or bundle graphs?
41
+
42
+ There are tool that can output nice, visual representation of project dependencies like [webpack-bundle-analyzer](https://www.npmjs.com/package/webpack-bundle-analyzer) or [dependency-cruiser](https://www.npmjs.com/package/dependency-cruiser) (_which btw rev-dep uses for non-TS codebases_)
43
+
44
+ While graphs can be useful to identify major problems like too big bundle size or to visualize mess in your deps, it's hard to take any action based on them (_at least it was hard for me_ 🤷‍♂️)
45
+
46
+ `rev-dep` visualize dependencies as lists, so it's really easy to see where to cut the line to solve the problem.
47
+
48
+ ## Getting Started
14
49
 
15
50
  ### Install globally to use as CLI tool
16
51
 
@@ -28,59 +63,31 @@ or
28
63
 
29
64
  `npm install rev-dep`
30
65
 
31
- ## Example
66
+ ## Recipes
32
67
 
33
- For this repo
68
+ ### How to identify where a file is used in the project?
34
69
 
35
- ```sh
36
- rev-dep resolve getDepsSet.js cli.js
37
- ```
70
+ ### How to check if a file is used in the project?
38
71
 
39
- will output
72
+ ### How to identify dead files in the project?
40
73
 
41
- ```
42
- Results:
43
-
44
- ➞ cli.js
45
- ➞ find.js
46
- ➞ getDepsSet.js
47
- ```
48
-
49
- Which says that `getDepsSet.js` file is used in `cli.js` entry point and is required through `find.js`
50
-
51
- ## About
52
-
53
- The tool was created to determine places in the project where a particular file is used, to test wether the refactoring do not break functionalities.
54
-
55
- It's especially useful in JS world without TypeScript or tests coverage.
74
+ ### How to check which files are imported by a given file?
56
75
 
57
- Except the reverse dependency resolution path, it can print statistics about how many times a particular module is required in the project, which might be helpful for code-splitting planning.
76
+ ### How to reduce amount of files imported by entry point?
58
77
 
59
78
  ## Usage
60
79
 
61
- Project can be used as a CLI tool or as a regular JS module
80
+ Project can be used as a CLI tool or as a module
62
81
 
63
82
  ### CLI Tool
64
83
 
65
- Avaliable commands:
66
-
67
- #### `resolve`
68
-
69
- ```sh
70
- rev-dep resolve <filePath> <entryPoints...>
71
- ```
72
-
73
- Available options are
74
-
75
- - `-cs or --compactSummary` - instead of file paths print a compact summary of reverse resolution with a count of found paths
76
- - `--verbose` - log currently performed operation
77
- - `-wc, --webpackConfig <path>` - path to webpack config to enable webpack aliases support
84
+ For CLI usage see [CLI reference](#CLI-reference)
78
85
 
79
86
  ### Module
80
87
 
81
88
  #### `find` Function
82
89
 
83
- ```js
90
+ ```ts
84
91
  import { find } from "rev-dep";
85
92
 
86
93
  const path = find({
@@ -91,25 +98,18 @@ const path = find({
91
98
  console.log(path);
92
99
  ```
93
100
 
94
- #### `find` Options
95
-
96
- - `entryPoints (Array)` - Array of entry points to build a tree for search. Usually it will be one entry point, but project can have many of them, eg. next.js application. **Required**
97
- - `filePath (String)` - A file that we want to find path for. **Required**
98
- - `skipRegex (String | RegExp)` - If a file path matches the pattern, we stop to traverse it's dependencies and do not include that file in the search tree. _Optional_, default: `'(node_modules|/__tests__|/__test__|/__mockContent__|.scss)'`
99
- - `verbose (Boolean)` - when set to true, will print current operation performed by find function. _Optional_, default: `false`
100
- - `cwd` - root for resolved files, must be an absolute path. _Optional_, default: `process.cwd()`
101
- - `webpackConfig (String)` - path to webpack config to enable webpack aliases support
102
-
103
- ### Additional setup may be required
104
-
105
- #### Resolving implicit file extensions
101
+ #### `find` Function
106
102
 
107
- A vast amount of JS/TS projects are configured in a way that allows (or even forces) to skip file extensions in import statements. Rev-dep is strongly based on [dependency-cruiser](https://github.com/sverweij/dependency-cruiser) which by default support implicit file extensions for `*.js, *.cjs, *.mjs, *.jsx` files (check [source](https://github.com/sverweij/dependency-cruiser/blob/96e34d0cf158034f2b7c8cafe9cec72dd74d8c45/src/extract/transpile/meta.js)).
108
- In order to resolve implicit extensions for other JS based languages it look for available corresponding compiler in `package.json`. If compiler is available, then extension is supported.
103
+ ```ts
104
+ import { find } from "rev-dep";
109
105
 
110
- If you installed `rev-dep` **globally**, you will have appropriate compiler installed **globally** as well. If you use it as a module, your project has to have compiler in it's package.json.
106
+ const path = find({
107
+ entryPoints: ["index.js"],
108
+ filePath: "utils.js",
109
+ });
111
110
 
112
- For example, to support `*.ts` and `*.tsx` implicit extensions in globally installed `rev-dep`, you have to also install globally `typescript` package (see [source](https://github.com/sverweij/dependency-cruiser/blob/96e34d0cf158034f2b7c8cafe9cec72dd74d8c45/src/extract/transpile/typescript-wrap.js))
111
+ console.log(path);
112
+ ```
113
113
 
114
114
  ## CLI reference
115
115
 
@@ -133,9 +133,8 @@ rev-dep resolve <filePath> [entryPoints...] [options]
133
133
 
134
134
  - `-wc, --webpackConfig <path>` - path to webpack config to enable webpack aliases support (_optional_)
135
135
  - `--cwd <path>` - path to a directory that should be used as a resolution root (_optional_)
136
- - `--rr reexportRewire <value>` - resolve actual dependencies for "export \* from" statements (_optional_)
137
- - `-i include <globs...>` - A list of globs to determine files included in entry points search (_optional_)
138
- - `-e exclude <globs...>` - A list of globs to determine files excluded in entry points search (_optional_)
136
+ - `-i --include <globs...>` - A list of globs to determine files included in entry points search (_optional_)
137
+ - `-e --exclude <globs...>` - A list of globs to determine files excluded in entry points search (_optional_)
139
138
  - `-cs, --compactSummary` - print a compact summary of reverse resolution with a count of found paths (_optional_)
140
139
  - `-a, --all` - finds all paths combination of a given dependency. Might work very slow or crash for some projects due to heavy usage of RAM (_optional_)
141
140
 
@@ -153,9 +152,8 @@ rev-dep entry-points [options]
153
152
 
154
153
  - `-wc, --webpackConfig <path>` - path to webpack config to enable webpack aliases support (_optional_)
155
154
  - `--cwd <path>` - path to a directory that should be used as a resolution root (_optional_)
156
- - `--rr reexportRewire <value>` - resolve actual dependencies for "export \* from" statements (_optional_)
157
- - `-i include <globs...>` - A list of globs to determine files included in entry points search (_optional_)
158
- - `-e exclude <globs...>` - A list of globs to determine files excluded in entry points search (_optional_)
155
+ - `-i --include <globs...>` - A list of globs to determine files included in entry points search (_optional_)
156
+ - `-e --exclude <globs...>` - A list of globs to determine files excluded in entry points search (_optional_)
159
157
  - `-pdc, --printDependenciesCount` - print count of entry point dependencies (_optional_)
160
158
  - `-c, --count` - print just count of found entry points (_optional_)
161
159
 
@@ -177,7 +175,6 @@ rev-dep files <entryPoint> [options]
177
175
 
178
176
  - `-wc, --webpackConfig <path>` - path to webpack config to enable webpack aliases support (_optional_)
179
177
  - `--cwd <path>` - path to a directory that should be used as a resolution root (_optional_)
180
- - `--rr reexportRewire <value>` - resolve actual dependencies for "export \* from" statements (_optional_)
181
178
  - `-c, --count` - print only count of entry point dependencies (_optional_)
182
179
 
183
180
  ### Command `docs`
@@ -199,6 +196,59 @@ rev-dep docs <outputPath> [options]
199
196
  - `-hl, --headerLevel <value>` - Initial header level (_optional_)
200
197
  <!-- cli-docs-end -->
201
198
 
199
+ ## Export from problem
200
+
201
+ `rev-dep` attempts to also solve `export * from` by a babel plugin that can be used as follows
202
+
203
+ ```js
204
+ // babel.config.js
205
+ module.exports = {
206
+ plugins: [
207
+ 'rev-dep/babel'
208
+ ]
209
+ };
210
+ ```
211
+
212
+ The plugins is currently **experimental** and might not work for all codebases!
213
+
214
+ It helps by rewiring paths to re-exported modules
215
+
216
+ ```ts
217
+ // file.ts
218
+ import { add } from "./utils";
219
+
220
+ // utils/index.ts
221
+
222
+ export * from "./math";
223
+ export * from "./otherModule";
224
+ export * from "./anotherModule";
225
+
226
+ // utils/math.ts
227
+
228
+ export const add = () => {};
229
+ ```
230
+
231
+ And for `file.ts` it would rewire the import like this
232
+
233
+ ```ts
234
+ // file.ts
235
+ import { add } from "./utils/math";
236
+ ```
237
+
238
+ So as a result, we don't implicitly require `./otherModule` and `./anotherModule` which we will not use anyway
239
+
240
+ ### Benefits
241
+
242
+ I don't have solid evidence for this, but I think it reduced RAM usage of the dev server I worked with (_blitz.js_). It crashed less often due to reaching heap size limit.
243
+
244
+ But for sure it reduced bundle size, _slightly_, but still 😀
245
+
246
+ It all depends on the the project dependencies structure.
247
+
248
+ By using the babel plugin you will reduce a risk of problems like implicitly importing `front-end` modules on the `server` or similar while still being able to benefit from short import paths.
249
+
250
+ Once I got an incident that, after a rebase with main branch, my project stopped compiling due to the problem caused by `export * from`. I spend a few hours debugging that, very frustrating.
251
+
202
252
  ## Contributing
203
253
 
204
254
  Project is open to contributions, just rise an issue if you have some ideas about features or you noticed a bug. After discussion we can approach implementation :)
@@ -207,16 +257,20 @@ Project is open to contributions, just rise an issue if you have some ideas abou
207
257
 
208
258
  1. Clone repo
209
259
  2. Install deps using `yarn`
210
- 3. Run tests using `yarn test --watch`
260
+ 3. Run `yarn build:watch`
211
261
  4. Code!
212
262
 
213
- For testing purpose you can install CLI tool from the file system using
263
+ For testing purpose use
264
+
265
+ `yarn dev [command] --cwd path/to/some/codebase`
266
+
267
+ or you can install CLI tool from the file system using
214
268
 
215
- `yarn global add file:ABSOLUTE_PATH_TO_REPO`
269
+ `yarn global add $PWD`
216
270
 
217
- or just
271
+ and then just run
218
272
 
219
- `yarn global add file:$(echo $PWD)`
273
+ `rev-dep`
220
274
 
221
275
  ## Made with 🧠 by [@jayu](https://github.com/jayu)
222
276
 
@@ -1,11 +1,13 @@
1
1
  "use strict";
2
2
  /*eslint-disable @typescript-eslint/no-var-requires */
3
+ Object.defineProperty(exports, "__esModule", { value: true });
3
4
  const node_path = require('path');
4
5
  const fs = require('fs');
5
6
  const parser = require('@babel/parser');
6
7
  const template = require('@babel/template').default;
8
+ const utils_1 = require("../lib/utils");
7
9
  const SKIP = Symbol('SKIP');
8
- module.exports = function plugin({ types }, { tsConfigPath }) {
10
+ module.exports = function plugin({ types }, { tsConfigPath = (0, utils_1.findTsConfig)() }) {
9
11
  const tsConfig = require(tsConfigPath);
10
12
  const aliases = tsConfig.compilerOptions.paths;
11
13
  const aliasesKeys = Object.keys(aliases);
@@ -164,11 +166,6 @@ module.exports = function plugin({ types }, { tsConfigPath }) {
164
166
  };
165
167
  return {
166
168
  visitor: {
167
- Program: {
168
- enter(_, { filename }) {
169
- //console.log(filename);
170
- }
171
- },
172
169
  ImportDeclaration(path, { filename, cwd }) {
173
170
  const sourceRelative = (source) => {
174
171
  const rel = node_path.relative(node_path.dirname(filename), source);
@@ -11,14 +11,14 @@ exports.cwdOption = [
11
11
  process.cwd()
12
12
  ];
13
13
  exports.reexportRewireOption = [
14
- '--rr reexportRewire <value>',
14
+ '-rr --reexportRewire <value>',
15
15
  'resolve actual dependencies for "export * from" statements'
16
16
  ];
17
17
  exports.includeOption = [
18
- '-i include <globs...>',
18
+ '-i --include <globs...>',
19
19
  'A list of globs to determine files included in entry points search'
20
20
  ];
21
21
  exports.excludeOption = [
22
- '-e exclude <globs...>',
22
+ '-e --exclude <globs...>',
23
23
  'A list of globs to determine files excluded in entry points search'
24
24
  ];
@@ -10,7 +10,7 @@ function createEntryPoints(program) {
10
10
  .description('Print list of entry points in current directory')
11
11
  .option(...commonOptions_1.webpackConfigOption)
12
12
  .option(...commonOptions_1.cwdOption)
13
- .option(...commonOptions_1.reexportRewireOption)
13
+ // .option(...reexportRewireOption)
14
14
  .option(...commonOptions_1.includeOption)
15
15
  .option(...commonOptions_1.excludeOption)
16
16
  .option('-pdc, --printDependenciesCount', 'print count of entry point dependencies', false)
@@ -11,7 +11,7 @@ function createFiles(program) {
11
11
  })
12
12
  .option(...commonOptions_1.webpackConfigOption)
13
13
  .option(...commonOptions_1.cwdOption)
14
- .option(...commonOptions_1.reexportRewireOption)
14
+ // .option(...reexportRewireOption)
15
15
  .option('-c, --count', 'print only count of entry point dependencies', false)
16
16
  .action(async (entryPoint, data) => {
17
17
  const { webpackConfig: webpackConfigPath, cwd, count } = data;
@@ -13,16 +13,15 @@ function createResolve(program) {
13
13
  })
14
14
  .option(...commonOptions_1.webpackConfigOption)
15
15
  .option(...commonOptions_1.cwdOption)
16
- .option(...commonOptions_1.reexportRewireOption)
16
+ // .option(...reexportRewireOption)
17
17
  .option(...commonOptions_1.includeOption)
18
18
  .option(...commonOptions_1.excludeOption)
19
19
  .option('-cs, --compactSummary', 'print a compact summary of reverse resolution with a count of found paths')
20
20
  .option('-a, --all', 'finds all paths combination of a given dependency. Might work very slow or crash for some projects due to heavy usage of RAM', false)
21
21
  .action(async (filePath, entryPoints, data) => {
22
22
  const { compactSummary, webpackConfig, all, cwd, exclude, include } = data;
23
- const sanitizedEntryPoints = (0, utils_1.sanitizeUserEntryPoints)(entryPoints);
24
23
  const [results, resolveEntryPoints] = await (0, find_1.resolve)({
25
- entryPoints: sanitizedEntryPoints,
24
+ entryPoints,
26
25
  filePath,
27
26
  webpackConfig,
28
27
  all,
@@ -12,7 +12,7 @@ const cleanupDpdmDeps = (deps) => {
12
12
  !id.includes('node_modules') &&
13
13
  dependencies !== null) {
14
14
  newDeps[id] = dependencies
15
- .filter(({ id }) => id && !id.includes('node_modules'))
15
+ .filter(({ id }) => id && !id.includes('node_modules') && !(0, is_builtin_module_1.default)(id))
16
16
  .map(({ id, request }) => ({
17
17
  id,
18
18
  request
package/dist/lib/find.js CHANGED
@@ -24,7 +24,8 @@ const resolve = async ({ entryPoints: _entryPoints, filePath, webpackConfig, cwd
24
24
  let deps, entryPoints;
25
25
  if (_entryPoints.length > 0) {
26
26
  entryPoints = _entryPoints;
27
- deps = await (0, getDepsTree_1.getDepsTree)(cwd, entryPoints, webpackConfig);
27
+ const sanitizedEntryPoints = (0, utils_1.sanitizeUserEntryPoints)(entryPoints);
28
+ deps = await (0, getDepsTree_1.getDepsTree)(cwd, sanitizedEntryPoints, webpackConfig);
28
29
  }
29
30
  else {
30
31
  ;
@@ -10,6 +10,7 @@ const promises_1 = __importDefault(require("fs/promises"));
10
10
  const utils_1 = require("./utils");
11
11
  const getDepsTree_1 = require("./getDepsTree");
12
12
  const ignore_1 = __importDefault(require("ignore"));
13
+ const glob_escape_1 = __importDefault(require("glob-escape"));
13
14
  const getDirectoriesForEntryPointsSearch = async (dir) => {
14
15
  const entries = await promises_1.default.readdir(dir);
15
16
  const directories = await (0, utils_1.asyncFilter)(entries, async (pathName) => {
@@ -48,7 +49,7 @@ const getEntryPoints = async ({ cwd, exclude, include, webpackConfigPath }) => {
48
49
  const dirs = await (0, exports.getDirectoriesForEntryPointsSearch)(cwd);
49
50
  const globs = dirs
50
51
  .map((dirName) => path_1.default.relative(cwd, dirName))
51
- .map((dirName) => `${dirName}/*`);
52
+ .map((dirName) => `${(0, glob_escape_1.default)(dirName)}/*`);
52
53
  const globsWithRoot = ['*', ...globs];
53
54
  const depsTree = await (0, getDepsTree_1.getDepsTree)(cwd, globsWithRoot, webpackConfigPath);
54
55
  const possibleEntryPoints = (0, exports.findEntryPointsInDepsTree)(depsTree, exclude, include);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rev-dep",
3
- "version": "1.0.0-alpha.2",
3
+ "version": "1.0.0-alpha.5",
4
4
  "description": "Reverse dependency resolution tool built with dependency-cruiser",
5
5
  "main": "lib/find.js",
6
6
  "bin": "bin.js",
@@ -1,277 +0,0 @@
1
- "use strict";
2
- /*eslint-disable @typescript-eslint/no-var-requires */
3
- const node_path = require('path');
4
- const fs = require('fs');
5
- const parser = require('@babel/parser');
6
- const template = require('@babel/template').default;
7
- const SKIP = Symbol('SKIP');
8
- module.exports = function plugin({ types }, { tsConfigPath }) {
9
- const tsConfig = require(tsConfigPath);
10
- const aliases = tsConfig.compilerOptions.paths;
11
- const aliasesKeys = Object.keys(aliases);
12
- const aliasesRegexes = Object.keys(aliases).map((alias) => {
13
- return new RegExp(`^${alias.replace('*', '(.)+')}$`);
14
- });
15
- const cache = new Map();
16
- const getFile = (original, paths) => {
17
- if (paths.length === 0) {
18
- throw new Error('Cannot resolve import ' + original);
19
- }
20
- const path = paths[0];
21
- try {
22
- return [path, fs.readFileSync(path).toString()];
23
- }
24
- catch (e) {
25
- return getFile(original, paths.slice(1));
26
- }
27
- };
28
- const isPathRelativeOrAliased = (path) => {
29
- const aliasRegexIdx = aliasesRegexes.findIndex((aliasRegex) => aliasRegex.test(path));
30
- const isRelative = path.startsWith('./') || path.startsWith('../');
31
- return aliasRegexIdx > -1 || isRelative;
32
- };
33
- const cacheKey = (identifier, filePath) => `${identifier}-${filePath}`;
34
- const lookup = (identifier, filePath, cwd) => {
35
- const cached = cache.get(cacheKey(identifier, filePath));
36
- if (cached) {
37
- return cached;
38
- }
39
- const withExtension = /(\.ts|\.tsx)$/.test(filePath)
40
- ? [filePath]
41
- : [
42
- `${filePath}.ts`,
43
- `${filePath}.tsx`,
44
- `${filePath}/index.ts`,
45
- `${filePath}/index.tsx`,
46
- `${filePath}.js`,
47
- `${filePath}.jsx`,
48
- `${filePath}/index.js`,
49
- `${filePath}/index.jsx`
50
- ];
51
- const [resolvedFilePath, file] = getFile(filePath, withExtension);
52
- const ast = parser.parse(file, {
53
- sourceType: 'module',
54
- plugins: [
55
- 'jsx',
56
- 'typescript',
57
- 'objectRestSpread',
58
- 'classProperties',
59
- 'asyncGenerators',
60
- 'decorators-legacy'
61
- ]
62
- });
63
- /**
64
- * {
65
- * identifier?: string,
66
- * source: string
67
- * }
68
- */
69
- const toLookup = [];
70
- let resolvedAs = null;
71
- ast.program.body.forEach((declaration) => {
72
- var _a;
73
- if (resolvedAs === null) {
74
- if (types.isExportNamedDeclaration(declaration)) {
75
- if (types.isVariableDeclaration(declaration.declaration)) {
76
- const hasIdentifier = declaration.declaration.declarations.find((declarator) => {
77
- return declarator.id.name === identifier;
78
- });
79
- if (hasIdentifier) {
80
- resolvedAs = {
81
- type: 'named',
82
- identifier,
83
- source: filePath
84
- };
85
- }
86
- }
87
- else if (types.isFunctionDeclaration(declaration.declaration) ||
88
- types.isClassDeclaration(declaration.declaration)) {
89
- if (declaration.declaration.id.name === identifier) {
90
- resolvedAs = {
91
- type: 'named',
92
- identifier,
93
- source: filePath
94
- };
95
- }
96
- }
97
- else {
98
- const source = (_a = declaration.source) === null || _a === void 0 ? void 0 : _a.value;
99
- declaration.specifiers.forEach((specifier) => {
100
- if (types.isExportSpecifier(specifier)) {
101
- if (specifier.exported.name === identifier) {
102
- if (specifier.local.name === 'default' && source) {
103
- resolvedAs = {
104
- type: 'default',
105
- identifier,
106
- source: getModulePath(source, resolvedFilePath, cwd)
107
- };
108
- }
109
- else if (source === undefined) {
110
- resolvedAs = {
111
- type: 'named',
112
- identifier,
113
- source: filePath
114
- };
115
- }
116
- else if (isPathRelativeOrAliased(source)) {
117
- toLookup.push({
118
- identifier: specifier.exported.local,
119
- source: getModulePath(source, resolvedFilePath, cwd)
120
- });
121
- }
122
- }
123
- }
124
- });
125
- }
126
- }
127
- else if (types.isExportAllDeclaration(declaration) &&
128
- isPathRelativeOrAliased(declaration.source.value)) {
129
- toLookup.push({
130
- identifier,
131
- source: getModulePath(declaration.source.value, resolvedFilePath, cwd)
132
- });
133
- }
134
- }
135
- });
136
- if (resolvedAs) {
137
- return resolvedAs;
138
- }
139
- const nestedResult = toLookup
140
- .map(({ identifier, source }) => lookup(identifier, source, cwd))
141
- .filter(Boolean);
142
- return nestedResult[0];
143
- };
144
- const getModulePath = (sourcePath, fileName, cwd) => {
145
- var _a;
146
- const aliasRegexIdx = aliasesRegexes.findIndex((aliasRegex) => aliasRegex.test(sourcePath));
147
- const relativeFileName = node_path.relative(cwd, fileName);
148
- const aliasKey = aliasesKeys[aliasRegexIdx];
149
- const alias = (_a = aliases[aliasKey]) === null || _a === void 0 ? void 0 : _a[0];
150
- let modulePath = '';
151
- if (alias) {
152
- let relative = alias;
153
- if (aliasKey.endsWith('*')) {
154
- const aliasKeyPrefix = aliasKey.replace('*', '');
155
- relative = alias.replace('*', sourcePath.replace(aliasKeyPrefix, ''));
156
- }
157
- modulePath = node_path.resolve(cwd, relative);
158
- }
159
- else {
160
- // we need ../ to skip current file name
161
- modulePath = node_path.resolve(relativeFileName, '../' + sourcePath);
162
- }
163
- return modulePath;
164
- };
165
- return {
166
- visitor: {
167
- Program: {
168
- enter(_, { filename }) {
169
- //console.log(filename);
170
- }
171
- },
172
- ImportDeclaration(path, { filename, cwd }) {
173
- const sourceRelative = (source) => {
174
- const rel = node_path.relative(node_path.dirname(filename), source);
175
- return rel.startsWith('.') ? rel : './' + rel;
176
- };
177
- const node = path.node;
178
- const source = node.source;
179
- if (source.type !== 'StringLiteral') {
180
- return;
181
- }
182
- const shouldSkip = node[SKIP] || !isPathRelativeOrAliased(source.value);
183
- if (shouldSkip) {
184
- return;
185
- }
186
- const modulePath = getModulePath(source.value, filename, cwd);
187
- const defaultSpecifier = node.specifiers.find((specifier) => specifier.type === 'ImportDefaultSpecifier');
188
- const namespaceSpecifier = node.specifiers.find((specifier) => specifier.type === 'ImportNamespaceSpecifier');
189
- const specifiers = node.specifiers.filter((specifier) => specifier.type === 'ImportSpecifier');
190
- const results = specifiers.map((specifier) => {
191
- const importedName = specifier.imported.name;
192
- const result = lookup(importedName, modulePath, cwd);
193
- if (!result) {
194
- return {
195
- identifier: importedName,
196
- local: specifier.local.name,
197
- source: source.value
198
- };
199
- }
200
- cache.set(cacheKey(importedName, modulePath), result);
201
- return {
202
- ...result,
203
- source: sourceRelative(result.source),
204
- local: specifier.local.name
205
- };
206
- });
207
- const defaultResult = defaultSpecifier
208
- ? lookup('default', modulePath, cwd)
209
- : null;
210
- if (defaultResult) {
211
- cache.set(cacheKey('default', modulePath), defaultResult);
212
- }
213
- const buildNamed = template(`
214
- import { %%IMPORT_NAME%% } from %%SOURCE%%;
215
- `);
216
- const buildNamedWithAlias = template(`
217
- import { %%IMPORTED_NAME%% as %%LOCAL_NAME%% } from %%SOURCE%%;
218
- `);
219
- const buildDefault = template(`
220
- import %%IMPORT_NAME%% from %%SOURCE%%;
221
- `);
222
- const buildNamespace = template(`
223
- import * as %%IMPORT_NAME%% from %%SOURCE%%;
224
- `);
225
- const defaultImport = defaultResult
226
- ? [
227
- buildDefault({
228
- IMPORT_NAME: types.identifier(defaultSpecifier.local.name),
229
- SOURCE: types.stringLiteral(sourceRelative(defaultResult.source))
230
- })
231
- ]
232
- : defaultSpecifier
233
- ? [
234
- buildDefault({
235
- IMPORT_NAME: types.identifier(defaultSpecifier.local.name),
236
- SOURCE: types.stringLiteral(source.value)
237
- })
238
- ]
239
- : [];
240
- const namespaceImport = namespaceSpecifier
241
- ? [
242
- buildNamespace({
243
- IMPORT_NAME: types.identifier(namespaceSpecifier.local.name),
244
- SOURCE: types.stringLiteral(source.value)
245
- })
246
- ]
247
- : [];
248
- const named = results.map(({ type, identifier, local, source }) => {
249
- if (type === 'default') {
250
- return buildDefault({
251
- IMPORT_NAME: types.identifier(identifier),
252
- SOURCE: types.stringLiteral(source)
253
- });
254
- }
255
- else if (identifier !== local) {
256
- return buildNamedWithAlias({
257
- IMPORTED_NAME: types.identifier(identifier),
258
- LOCAL_NAME: types.identifier(local),
259
- SOURCE: types.stringLiteral(source)
260
- });
261
- }
262
- else {
263
- return buildNamed({
264
- IMPORT_NAME: types.identifier(identifier),
265
- SOURCE: types.stringLiteral(source)
266
- });
267
- }
268
- });
269
- const newImports = [...namespaceImport, ...defaultImport, ...named].map((node) => {
270
- node[SKIP] = true;
271
- return node;
272
- });
273
- path.replaceWithMultiple(newImports);
274
- }
275
- }
276
- };
277
- };
@@ -1,21 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getMaxDepth = void 0;
4
- const getMaxDepth = (depth = 1, path = [], vertices = new Map()) => {
5
- return (tree) => {
6
- const depthFromCache = vertices.get(tree.path);
7
- if (depthFromCache) {
8
- return depthFromCache;
9
- }
10
- const newPath = [...path, tree.path];
11
- if (tree.children.length === 0) {
12
- return [depth, newPath];
13
- }
14
- const results = tree.children.map((0, exports.getMaxDepth)(depth + 1, newPath, vertices));
15
- const maxChildDepth = Math.max(...results.map(([depth]) => depth));
16
- const itemWithMaxDepth = results.find(([depth]) => depth === maxChildDepth);
17
- vertices.set(tree.path, itemWithMaxDepth);
18
- return itemWithMaxDepth;
19
- };
20
- };
21
- exports.getMaxDepth = getMaxDepth;