Refactor dependencies to parse file on select

This commit is contained in:
Bogdan Lyashenko
2018-12-01 12:49:52 +01:00
parent d384ef2d59
commit e8b8a195bc
23 changed files with 614 additions and 789 deletions

View File

@@ -1,9 +1,12 @@
const path = require('path');
const madge = require('madge');
const babylon = require('@babel/parser');
const babelTraverse = require('@babel/traverse');
const astParseConfig = require('../../../shared/astParse').config;
const { convertRelativeToAbsolutePath } = require('./path');
const getImports = (fileCode, path) => {
const getImports = (fileCode, itemPath) => {
let ast = {};
const importedDependencies = [];
@@ -11,6 +14,7 @@ const getImports = (fileCode, path) => {
try {
ast = babylon.parse(fileCode, astParseConfig);
// TODO: combine with codecrumbs babelTraverse, no need to do babelTraverse twice per file
babelTraverse.default(ast, {
enter(path) {
const node = path.node;
@@ -18,7 +22,7 @@ const getImports = (fileCode, path) => {
if (node.type === 'ImportDeclaration') {
importedDependencies.push({
node,
sourceFile: node.source && node.source.value,
sourceFile: node.source && convertRelativeToAbsolutePath(itemPath, node.source.value),
specifiers: node.specifiers.map(({ type, imported, local }) => ({
type,
name: (imported || local || {}).name
@@ -28,13 +32,38 @@ const getImports = (fileCode, path) => {
}
});
return importedDependencies;
return importedDependencies.filter(({ sourceFile }) => !!sourceFile);
} catch (e) {
console.log(path, e);
console.log(itemPath, e);
return importedDependencies;
}
};
module.exports = {
getImports
const getDependencies = (entryPoint, projectDir, webpackConfigPath) => {
const rootPath = path.resolve();
return madge(entryPoint, {
webpackConfig: webpackConfigPath,
baseDir: projectDir,
// TODO: this filter will be extended based on how much dependencies is needed
dependencyFilter: (depPath, sourcePath) => sourcePath === `${rootPath}/${entryPoint}`
})
.then(res => res.obj())
.then(obj =>
Object.entries(obj).reduce((tree, [key, value]) => {
const moduleName = `${projectDir}/${key}`;
tree[moduleName] = {
moduleName,
importedModuleNames: value.map(v => `${projectDir}/${v}`)
};
return tree;
}, {})
);
};
module.exports = {
getImports,
getDependencies
};

View File

@@ -0,0 +1,23 @@
const convertRelativeToAbsolutePath = (base, relative = '') => {
const stack = base.split('/'),
parts = relative.split('/');
// TODO: here also webpack paths/aliases could be, now skip 'react', etc
if (parts.length <= 1) {
return null;
}
stack.pop();
for (let i = 0; i < parts.length; i++) {
if (parts[i] === '.') continue;
if (parts[i] === '..') stack.pop();
else stack.push(parts[i]);
}
return stack.join('/');
};
module.exports = {
convertRelativeToAbsolutePath
};

View File

@@ -1,42 +1,51 @@
const codecrumbs = require('./codecrumbs/');
const dependencies = require('./dependencies/');
const { getCrumbs } = require('./codecrumbs/');
const { getImports, getDependencies } = require('./dependencies/');
const file = require('../utils/file');
const parseFile = (itemPath, { parseCodeCrumbs, parseDependencies } = {}) =>
file.read(itemPath, 'utf8').then(code => {
const item = {};
const parseFile = (
itemPath,
projectDir,
{ parseCodeCrumbs, parseImports, parseDependencies, attachCode } = {}
) =>
Promise.all([
parseDependencies && getDependencies(itemPath, projectDir),
file.read(itemPath, 'utf8')
]).then(([dependencies, code]) => {
const item = {
dependencies: parseDependencies && dependencies,
fileCode: attachCode && code
};
// TODO: if parseCodeCrumbs
const codecrumbsList = codecrumbs.getCrumbs(code, itemPath);
if (codecrumbsList.length) {
item.children = codecrumbsList;
item.hasCodecrumbs = true;
item.flows = codecrumbsList
.filter(cc => cc.params.flow)
.map(cc => cc.params)
.reduce((acc, { flow }) => {
acc[flow] = true;
return acc;
}, {});
} else {
item.children = undefined;
item.hasCodecrumbs = false;
item.flows = undefined;
if (parseCodeCrumbs) {
const codecrumbsList = getCrumbs(code, itemPath);
if (codecrumbsList.length) {
item.children = codecrumbsList;
item.hasCodecrumbs = true;
item.flows = codecrumbsList
.filter(cc => cc.params.flow)
.map(cc => cc.params)
.reduce((acc, { flow }) => {
acc[flow] = true;
return acc;
}, {});
} else {
item.children = undefined;
item.hasCodecrumbs = false;
item.flows = undefined;
}
}
// TODO: if parseDependencies
// TODO: same here add parsing to build dependencies tree
const importedDependencies = dependencies.getImports(code, itemPath);
if (importedDependencies.length) {
item.importedDependencies = importedDependencies;
item.hasDependenciesImports = true;
} else {
item.importedDependencies = undefined;
item.hasDependenciesImports = false;
if (parseImports) {
const importedDependencies = getImports(code, itemPath);
if (importedDependencies.length) {
item.importedDependencies = importedDependencies;
item.hasDependenciesImports = true;
} else {
item.importedDependencies = undefined;
item.hasDependenciesImports = false;
}
}
// TODO: load on click
item.fileCode = code;
return item;
});