Skip to content

Commit 774684b

Browse files
authored
feat: add rollup and webpack plugin (#2)
1 parent efc230b commit 774684b

File tree

10 files changed

+76
-33
lines changed

10 files changed

+76
-33
lines changed

.DS_Store

6 KB
Binary file not shown.

examples/.DS_Store

6 KB
Binary file not shown.

examples/rollup/rollup.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export default {
2626
format: "esm",
2727
},
2828
plugins: [
29+
VueSource({}),
2930
vue({
3031
exposeFilename: true,
3132
}),
@@ -46,7 +47,6 @@ export default {
4647
svg({
4748
base64: true,
4849
}),
49-
VueSource({}),
5050
liveServer({
5151
port: 3000,
5252
wait: 1000,

examples/vite/src/App.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<script setup lang="ts">
1+
<script setup lang="tsx">
22
import HelloWorld from './components/HelloWorld.vue';
33
</script>
44

src/.DS_Store

6 KB
Binary file not shown.

src/core/constants.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@ export const ElementTypes = <const>{
88
ELEMENT: 0,
99
COMPONENT: 1,
1010
};
11+
12+
export const TagTypes = [ElementTypes.ELEMENT, ElementTypes.COMPONENT];

src/core/index.ts

Lines changed: 12 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,32 @@
1-
import { relative } from "path";
21
import type { UnpluginFactory } from "unplugin";
32
import { createUnplugin } from "unplugin";
4-
import { parse, transform } from "@vue/compiler-dom";
5-
import MagicString from "magic-string";
63
import type { Options } from "../types";
7-
import { ElementTypes, NodeTypes, TRACE_ID } from "./constants";
4+
import { parse_ID } from "./parse_ID";
5+
import { transform_SFC } from "./transform_SFC";
6+
// import { transform_JSX } from "./transform_JSX";
87

9-
const filterRE = /.(vue|jsx|tsx)$/;
10-
const TagTypes = [ElementTypes.ELEMENT, ElementTypes.COMPONENT];
8+
const includeRE = /.((vue\?vue)|(vue|jsx|tsx)$)/;
119

1210
export const unpluginFactory: UnpluginFactory<Options> = (options = {}) => {
13-
const { rootDir = process.cwd() } = options;
14-
1511
if (process.env.NODE_ENV !== "development") {
1612
return {
1713
name: "unplugin-vue-source",
1814
};
1915
}
2016

17+
const { rootDir = process.cwd() } = options;
18+
2119
return {
2220
name: "unplugin-vue-source",
2321
enforce: "pre",
2422
transformInclude(id) {
25-
return filterRE.test(id);
23+
return includeRE.test(id);
2624
},
27-
transform(raw, id) {
28-
const relativePath = `/${relative(rootDir, id)}`;
29-
30-
const s = new MagicString(raw);
31-
transform(parse(raw), {
32-
nodeTransforms: [
33-
(node) => {
34-
if (
35-
node.type === NodeTypes.ELEMENT &&
36-
TagTypes.includes(node.tagType as any)
37-
) {
38-
const { line, column, offset } = node.loc.start;
39-
const startIndex = offset + node.tag.length + 1;
40-
s.prependLeft(
41-
startIndex,
42-
` ${TRACE_ID}="${relativePath}:${line}:${column}"`
43-
);
44-
}
45-
},
46-
],
47-
});
48-
return s.toString();
25+
transform(code, id) {
26+
const { filename, query } = parse_ID(id, rootDir);
27+
if (!query.type || query.type === "template") {
28+
return transform_SFC(filename, code);
29+
}
4930
},
5031
};
5132
};

src/core/parse_ID.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { extname } from "path";
2+
3+
export interface VueQuery {
4+
vue?: boolean;
5+
src?: string;
6+
type?: "script" | "template" | "style" | "custom";
7+
lang?: string;
8+
}
9+
10+
export function parse_ID(
11+
id: string,
12+
rootDir: string
13+
): {
14+
filename: string;
15+
ext: string;
16+
query: VueQuery;
17+
} {
18+
const [filename, rawQuery] = id.split(`?`, 2);
19+
const query = Object.fromEntries(new URLSearchParams(rawQuery)) as VueQuery;
20+
if (query.vue != null) {
21+
query.vue = true;
22+
}
23+
24+
return {
25+
filename: filename.replace(rootDir, ""),
26+
ext: extname(filename).slice(1),
27+
query,
28+
};
29+
}

src/core/transform_JSX.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export function transform_JSX(filename: string, code: string, tsx: boolean) {
2+
return undefined;
3+
}

src/core/transform_SFC.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { parse, transform } from "@vue/compiler-dom";
2+
import MagicString from "magic-string";
3+
import { NodeTypes, TRACE_ID, TagTypes } from "./constants";
4+
5+
export function transform_SFC(filename: string, code: string) {
6+
const s = new MagicString(code);
7+
8+
const ast = parse(code);
9+
transform(ast, {
10+
nodeTransforms: [
11+
(node) => {
12+
if (
13+
node.type === NodeTypes.ELEMENT &&
14+
TagTypes.includes(node.tagType as any)
15+
) {
16+
const { line, column, offset } = node.loc.start;
17+
const startIndex = offset + node.tag.length + 1;
18+
s.prependLeft(
19+
startIndex,
20+
` ${TRACE_ID}="${filename}:${line}:${column}"`
21+
);
22+
}
23+
},
24+
],
25+
});
26+
27+
return s.toString();
28+
}

0 commit comments

Comments
 (0)