Skip to content

Commit 753bd9a

Browse files
committed
Added ability to quickly convert js to typescript
1 parent 14b59ac commit 753bd9a

8 files changed

Lines changed: 186 additions & 13 deletions

File tree

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@
33
Refactor React Native source code extracting inline styles from the VSCode menu
44

55
![demo](assets/demo.gif)
6+
7+
![demo](assets/demo2.gif)

assets/demo2.gif

806 KB
Loading

package.json

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
"vscode": "^1.42.0"
2323
},
2424
"activationEvents": [
25+
"*",
26+
"onLanguage:jsx",
2527
"onLanguage:tsx",
2628
"onLanguage:jsx",
2729
"onLanguage:javascript",
@@ -35,6 +37,10 @@
3537
{
3638
"command": "react-toolkit.extractStyle",
3739
"title": "Extract style to StyleSheet"
40+
},
41+
{
42+
"command": "react-toolkit.readFile",
43+
"title": "Convert to Typescript"
3844
}
3945
],
4046
"menus": {
@@ -44,6 +50,12 @@
4450
"command": "react-toolkit.extractStyle",
4551
"group": "1_modification@1"
4652
}
53+
],
54+
"explorer/context": [
55+
{
56+
"command": "react-toolkit.readFile",
57+
"group": "1_modification@1"
58+
}
4759
]
4860
}
4961
},
@@ -57,6 +69,7 @@
5769
"release": "npx standard-version"
5870
},
5971
"devDependencies": {
72+
"@types/fs-extra": "^8.0.1",
6073
"@types/glob": "^7.1.1",
6174
"@types/mocha": "^7.0.1",
6275
"@types/node": "^12.11.7",
@@ -69,5 +82,8 @@
6982
"typescript": "^3.7.5",
7083
"vscode-test": "^1.3.0"
7184
},
72-
"dependencies": {}
85+
"dependencies": {
86+
"fs-extra": "^8.1.0",
87+
"react-js-to-ts": "^1.4.0"
88+
}
7389
}

src/commands.ts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import * as vscode from 'vscode';
2-
import { editorContext, showInputBox, camelCase } from './utils';
2+
import * as fs from 'fs-extra';
3+
import { run as convertToTypeScript } from 'react-js-to-ts';
4+
5+
import { editorContext, showInputBox, camelCase, getNewFileName, isJsx } from './utils';
36

47
const { Position } = vscode;
58
export const activeEditor = () => vscode.window.activeTextEditor;
@@ -37,3 +40,23 @@ export async function extractStyle() {
3740
});
3841
});
3942
}
43+
44+
export const convertFileToTypescript = async (uri: vscode.Uri) => {
45+
const { path } = uri;
46+
47+
vscode.workspace
48+
.openTextDocument(uri)
49+
.then(async (document) => {
50+
const text = document.getText();
51+
const newFile = getNewFileName(path, isJsx(text) ? 'tsx' : 'ts');
52+
53+
await fs.rename(path, newFile);
54+
const result = convertToTypeScript(newFile);
55+
await fs.writeFile(newFile, result);
56+
const file = await vscode.workspace.openTextDocument(newFile);
57+
vscode.window.showTextDocument(file);
58+
})
59+
.then(() => {
60+
return vscode.commands.executeCommand('editor.action.formatDocument');
61+
});
62+
};

src/extension.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
import * as vscode from 'vscode';
2-
import { extractStyle } from './commands';
2+
import { extractStyle, convertFileToTypescript } from './commands';
33

44
export function activate(context: vscode.ExtensionContext) {
55
console.log('Congratulations, your extension "react-toolkit" is now active!');
66

7-
const disposable = vscode.commands.registerCommand('react-toolkit.extractStyle', extractStyle);
7+
const commandExtractStyle = vscode.commands.registerCommand('react-toolkit.extractStyle', extractStyle);
8+
const commandReadFile = vscode.commands.registerCommand('react-toolkit.readFile', convertFileToTypescript);
89

9-
context.subscriptions.push(disposable);
10+
context.subscriptions.push(commandExtractStyle);
11+
context.subscriptions.push(commandReadFile);
1012
}
1113

1214
export function deactivate() {}

src/utils.ts

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as vscode from 'vscode';
2-
import { InputBoxOptions } from 'vscode';
2+
import * as path from 'path';
33

44
export const editorContext = (
55
callback: (editor: vscode.TextEditor, selection: vscode.Selection, original: string, text: string) => any,
@@ -15,15 +15,38 @@ export const editorContext = (
1515
}
1616
};
1717

18-
export const showInputBox = (defaultValue: InputBoxOptions['value'], placeHolder: InputBoxOptions['placeHolder']) =>
18+
export const showInputBox = (
19+
defaultValue: vscode.InputBoxOptions['value'],
20+
placeHolder: vscode.InputBoxOptions['placeHolder'],
21+
) =>
1922
vscode.window.showInputBox({
2023
value: defaultValue,
2124
placeHolder,
2225
});
2326

24-
export const camelCase = (string: string) =>
25-
string
27+
export const camelCase = (string: string) => {
28+
return string
2629
.toLowerCase()
2730
.trim()
2831
.split(/[.\-_\s]/g)
2932
.reduce((string, word) => string + word[0].toUpperCase() + word.slice(1));
33+
};
34+
35+
export const getFilePath = () => {
36+
const activeEditor = vscode.window.activeTextEditor;
37+
const document = activeEditor && activeEditor.document;
38+
39+
return document && document.fileName;
40+
};
41+
42+
export const getNewFileName = (fileName: string, type: 'tsx' | 'ts') => {
43+
const ext = path.extname(fileName).replace(/^\./, '');
44+
const extNameRegex = new RegExp(`${ext}$`);
45+
return fileName.replace(extNameRegex, type);
46+
};
47+
48+
export const isJsx = (content: string) => {
49+
const reg = /<([A-z])/gm;
50+
51+
return reg.test(content);
52+
};

tsconfig.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
"removeComments": true,
1111
"allowSyntheticDefaultImports": true,
1212
"noUnusedParameters": true,
13-
"noUnusedLocals": true
13+
"noUnusedLocals": true,
14+
"skipLibCheck": true
1415
},
1516
"exclude": ["node_modules", ".vscode-test"]
1617
}

0 commit comments

Comments
 (0)