Closed chiptus closed 5 years ago
@chiptus good point. Its a bit tricky to implement since you may be exporting the component into an existing file. Ill try implementing this ASAP
can look for the import statement, or otherwise if importing to existing file, don't add the statement
@chiptus yep. Also various version of import need to be taken into account. For example, Typescript users usually do import * as React from 'react'
while babel users do a regular default import.
@chiptus wanna do a PR? Ill be glad to help
It would also be nice to import dependences of the extracted code :) If I have time ill start playing around with this
I'm also interested in this, I can also participate to the PR if needed.
I love the initiative! Ill be super glad to help out and point you guys in the right direction. I'd start here: https://github.com/wix/vscode-glean/blob/7d6791f9595bb9be4e5619f566c7c67276599d87/src/code-actions.ts#L25
This is baiscally the implementation of the "extract to component" refactoring, and the part where extracted component is added to the target file
Managed to get a prototype working. This does not import React but finds the required imports from the source file. Relative imports will not work yet
await appendSelectedTextToFile(selectionProccessingResult, filePath);
await prependImportsToFileIfNeeded(selectionProccessingResult, filePath);
const destinationImports: string = getImports(selectionProccessingResult.text);
prependTextToFile(destinationImports, filePath);
import { jsxToAst } from "./modules/jsx";
import { allText } from "./editor";
import traverse from "@babel/traverse";
import { File } from "@babel/types";
import { transformFromAstSync } from "@babel/core";
export default function getImports(code: string): string {
let imports: Array<string> = [];
let sourceAst: File = jsxToAst(allText());
sourceAst.program.body = sourceAst.program.body.filter(bodyItem => bodyItem.type === "ImportDeclaration");
const visitor = {
JSXIdentifier(path) {
console.log(path);
console.log(path.node.type);
if(path.container.type === "JSXOpeningElement") {
imports = [...imports, path.node.name];
}
}
};
const ast: File = jsxToAst(code);
traverse(ast, visitor);
sourceAst.program.body = sourceAst.program.body.filter(imp => {
imp.specifiers = imp.specifiers.filter(spec => imports.includes(spec.local.name));
if(imp.specifiers.length > 0) { return true; }
return false;
});
const importsFromSource: string = transformFromAstSync(sourceAst).code;
return importsFromSource;
}
@williamluke4 Thanks alot! Im having a bit of a hectic week. Ill have look at it ASAP
@williamluke4 i havent forgotten about this! Its been a bit hectic. Ill get to reviewing this week! Thank you!
hey @williamluke4, we are back in business :) Can you please create a branch? AFAIK, you want to import all missing imports, not just React?
BTW, there are several nuances that we needed take into account:
When Glean creates a stateful component, it extends Component
. So we need to check if there is already an existing import and either add to it (in case the file already contain another component) or add a new one
@williamluke4
Hey @borislit Will have a go this evening
@williamluke4 can you create a branch/fork?
React is needed to be imported for every component, an import statement should be added to the new component file