Skip to content

Commit 867e481

Browse files
committed
feat: support write file close #1
1 parent 702315c commit 867e481

File tree

10 files changed

+159
-108
lines changed

10 files changed

+159
-108
lines changed

package.json

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,18 @@
22
"name": "vue3-script-to-setup",
33
"type": "module",
44
"version": "0.0.0",
5+
"author": "clencat <2091927351@qq.com>",
56
"packageManager": "pnpm@7.12.0",
6-
"description": "",
7+
"description": "transform your vue3 script to setup mode",
78
"license": "MIT",
89
"repository": {
910
"type": "git",
10-
"url": "git+https://github.com/antfu/vue3-script-to-setup.git"
11+
"url": "git+https://github.com/a145789/vue3-script-to-setup"
1112
},
12-
"bugs": "https://github.com/antfu/vue3-script-to-setup/issues",
13-
"keywords": [],
13+
"bugs": "https://github.com/a145789/vue3-script-to-setup/issues",
14+
"keywords": [
15+
"vue3"
16+
],
1417
"sideEffects": false,
1518
"exports": {
1619
".": {
@@ -36,6 +39,9 @@
3639
"files": [
3740
"dist"
3841
],
42+
"engines": {
43+
"node": ">=14"
44+
},
3945
"scripts": {
4046
"build": "unbuild",
4147
"dev": "unbuild --stub",

rome.json

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"rules": {
55
"recommended": true,
66
"correctness": {
7-
"noUnusedVariables": "warn"
7+
"noUnusedVariables": "error"
88
},
99
"suspicious": {
1010
"noExplicitAny": "warn"
@@ -14,8 +14,5 @@
1414
"formatter": {
1515
"indentStyle": "space",
1616
"indentSize": 2
17-
},
18-
"javascript": {
19-
"formatter": {}
2017
}
2118
}

src/index.ts

Lines changed: 4 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,7 @@
1-
import { findUpSync } from "find-up";
2-
import { getTheFileAbsolutePath, output, useConfigPath } from "./utils";
3-
import { parseSfc } from "./transform";
4-
import { CommandsOption } from "./constants";
1+
import { DefaultOption } from "./constants";
2+
import setup from "./setup";
53

6-
const CONFIG_FILE_NAME = "tosetup.config" as const;
7-
8-
async function setup() {
9-
const argv = process.argv.slice(2).filter(Boolean);
10-
11-
let { pathNames, commands } = argv.reduce<{
12-
pathNames: string[];
13-
commands: CommandsOption;
14-
}>(
15-
(p, c) => {
16-
if (c.startsWith("--")) {
17-
switch (c.split("--")[1] as keyof typeof p.commands) {
18-
case "propsNotOnlyTs":
19-
p.commands.propsNotOnlyTs = true;
20-
break;
21-
case "notUseNewFile":
22-
p.commands.notUseNewFile = true;
23-
break;
24-
25-
default:
26-
break;
27-
}
28-
return p;
29-
}
30-
31-
const absolutePath = getTheFileAbsolutePath(c);
32-
if (absolutePath) {
33-
p.pathNames.push(absolutePath);
34-
}
35-
36-
return p;
37-
},
38-
{ pathNames: [], commands: {} },
39-
);
40-
41-
if (!pathNames.length) {
42-
const configPath = findUpSync(CONFIG_FILE_NAME);
43-
if (!configPath) {
44-
output.error(
45-
`Please enter a file path or use a ${CONFIG_FILE_NAME} file.`,
46-
);
47-
process.exit(1);
48-
}
49-
50-
const config = await useConfigPath(CONFIG_FILE_NAME);
51-
52-
pathNames = config.pathNames;
53-
54-
commands = { ...commands, ...config.option };
55-
}
56-
57-
parseSfc(pathNames, commands);
4+
export function defineConfig(option: DefaultOption) {
5+
return option;
586
}
59-
607
setup();

src/setup.ts

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import { findUpSync } from "find-up";
2+
import { getTheFileAbsolutePath, output, useConfigPath } from "./utils";
3+
import { transformSfc } from "./transform";
4+
import { CommandsOption } from "./constants";
5+
import writeFile from "./writeFile";
6+
7+
const CONFIG_FILE_NAME = "tosetup.config" as const;
8+
9+
async function setup() {
10+
output.log("tosetup begin...\n");
11+
const argv = process.argv.slice(2).filter(Boolean);
12+
13+
let { pathNames, commands } = argv.reduce<{
14+
pathNames: string[];
15+
commands: CommandsOption;
16+
}>(
17+
(p, c) => {
18+
if (c.startsWith("--")) {
19+
switch (c.split("--")[1] as keyof typeof p.commands) {
20+
case "propsNotOnlyTs":
21+
p.commands.propsNotOnlyTs = true;
22+
break;
23+
case "notUseNewFile":
24+
p.commands.notUseNewFile = true;
25+
break;
26+
27+
default:
28+
break;
29+
}
30+
return p;
31+
}
32+
33+
const absolutePath = getTheFileAbsolutePath(c);
34+
if (absolutePath) {
35+
p.pathNames.push(absolutePath);
36+
}
37+
38+
return p;
39+
},
40+
{ pathNames: [], commands: {} },
41+
);
42+
43+
if (!pathNames.length) {
44+
const configPath = findUpSync(CONFIG_FILE_NAME);
45+
if (!configPath) {
46+
output.error(
47+
`Please enter a file path or use a ${CONFIG_FILE_NAME} file.`,
48+
);
49+
process.exit(1);
50+
}
51+
52+
const config = await useConfigPath(CONFIG_FILE_NAME);
53+
54+
pathNames = config.pathNames;
55+
56+
commands = { ...commands, ...config.option };
57+
}
58+
for (const path of pathNames) {
59+
output.log(`File ${path} start of transform...`);
60+
const code = transformSfc(path, commands);
61+
if (code) {
62+
try {
63+
const file = writeFile(code, path, commands);
64+
output.success(`File ${file} transform success.\n`);
65+
} catch (error) {
66+
output.error(`write ${path} failure.\n`);
67+
console.log(error);
68+
}
69+
} else {
70+
output.error(`File ${path} transform failure.\n`);
71+
}
72+
}
73+
output.log("\ntosetup end.");
74+
}
75+
76+
export default setup;

src/transform/attrsAndSlots.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import type {
66
TsType,
77
} from "@swc/core";
88
import { Config, SetupAst, USE_ATTRS, USE_SLOTS } from "../constants";
9-
import Visitor from "@swc/core/Visitor";
9+
import { Visitor } from "@swc/core/Visitor";
1010
import { getSetupSecondParams } from "../utils";
1111
import MagicString from "magic-string";
1212

src/transform/index.ts

Lines changed: 1 addition & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1 @@
1-
import { parse } from "vue/compiler-sfc";
2-
import { readFileSync } from "fs";
3-
import { CommandsOption, FileType } from "../constants";
4-
import transformScript from "./transformScript";
5-
import { output } from "../utils";
6-
7-
export function parseSfc(pathNames: string[], option: CommandsOption) {
8-
for (const path of pathNames) {
9-
const sfc = readFileSync(path).toString();
10-
const {
11-
descriptor: { script, scriptSetup },
12-
} = parse(sfc);
13-
14-
if (scriptSetup || !script) {
15-
continue;
16-
}
17-
18-
let code: string | null = null;
19-
try {
20-
code = transformScript({
21-
...option,
22-
fileType: script.lang === "ts" ? FileType.ts : FileType.js,
23-
script: script.content,
24-
offset: 0,
25-
fileAbsolutePath: path,
26-
setupScript: "",
27-
});
28-
} catch (error) {
29-
output.error(`transform script failed in the ${path}`);
30-
console.log(error);
31-
} finally {
32-
if (!code) {
33-
}
34-
}
35-
}
36-
}
1+
export { transformSfc } from "./sfc";

src/transform/transformScript.ts renamed to src/transform/script.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import type {
1515
import { transformSync } from "@swc/core";
1616

1717
import { parseSync } from "@swc/core";
18-
import Visitor from "@swc/core/Visitor";
18+
import { Visitor } from "@swc/core/Visitor";
1919

2020
import {
2121
Config,

src/transform/sfc.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { parse } from "vue/compiler-sfc";
2+
import { readFileSync } from "fs";
3+
import { CommandsOption, FileType } from "../constants";
4+
import transformScript from "./script";
5+
import { output } from "../utils";
6+
import MagicString from "magic-string";
7+
8+
export function transformSfc(path: string, option: CommandsOption) {
9+
const sfc = readFileSync(path).toString();
10+
const {
11+
descriptor: { script, scriptSetup },
12+
} = parse(sfc);
13+
14+
if (scriptSetup || !script) {
15+
return null;
16+
}
17+
18+
let code: string | null = null;
19+
try {
20+
code = transformScript({
21+
...option,
22+
fileType: script.lang === "ts" ? FileType.ts : FileType.js,
23+
script: script.content,
24+
offset: 0,
25+
fileAbsolutePath: path,
26+
setupScript: "",
27+
});
28+
} catch (error) {
29+
output.error(`transform script failed in the ${path}`);
30+
console.log(error);
31+
} finally {
32+
if (code) {
33+
const ms = new MagicString(sfc);
34+
ms.update(script.loc.start.offset, script.loc.end.offset, `\n${code}`);
35+
ms.replaceAll(/\<\bscript\b.*\>/g, (str) => {
36+
const lastIdx = str.length - 1;
37+
return `${str.slice(0, lastIdx)} setup${str[lastIdx]}`;
38+
});
39+
40+
return ms.toString();
41+
} else {
42+
return null;
43+
}
44+
}
45+
}
46+
47+
export default transformSfc;

src/utils.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import type {
1212
Options,
1313
TsTypeReference,
1414
} from "@swc/core";
15-
import Visitor from "@swc/core/Visitor";
15+
import { Visitor } from "@swc/core/Visitor";
1616
import { blue, green, red, yellow } from "colorette";
1717
import slash from "slash";
1818
import { DefaultOption, SetupAst, VisitorCb } from "./constants";
@@ -76,10 +76,6 @@ function getFgVueFile(paths: string[]) {
7676
return fg.sync(paths).filter((p) => p.endsWith(".vue"));
7777
}
7878

79-
export function defineConfig(option: DefaultOption) {
80-
return option;
81-
}
82-
8379
export function getPropsValueIdentifier(
8480
ast: Expression,
8581
keyValue: string,

src/writeFile.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { writeFileSync } from "fs";
2+
import { CommandsOption } from "./constants";
3+
4+
function writeFile(
5+
code: string,
6+
path: string,
7+
{ notUseNewFile }: CommandsOption,
8+
) {
9+
const index = path.indexOf(".vue");
10+
const file = notUseNewFile ? path : `${path.slice(0, index)}.new.vue`;
11+
12+
writeFileSync(file, code);
13+
14+
return file;
15+
}
16+
17+
export default writeFile;

0 commit comments

Comments
 (0)