@solidjs/start 2.0.0-beta.0 → 2.0.0-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +71 -0
- package/dist/config/boundary-modules.d.ts +14 -0
- package/dist/config/boundary-modules.js +41 -0
- package/dist/config/dev-server.d.ts +3 -1
- package/dist/config/dev-server.js +25 -5
- package/dist/config/env.js +16 -12
- package/dist/config/fs-router.d.ts +1 -1
- package/dist/config/fs-router.js +28 -21
- package/dist/config/fs-routes/router.d.ts +2 -1
- package/dist/config/fs-routes/router.js +8 -10
- package/dist/config/index.js +42 -7
- package/dist/directives/index.js +39 -7
- package/dist/fns/handler.js +40 -4
- package/dist/fns/registration.d.ts +2 -1
- package/dist/fns/registration.js +4 -1
- package/dist/http/http.d.ts +81 -0
- package/dist/http/http.js +129 -0
- package/dist/http/index.d.ts +2 -81
- package/dist/http/index.js +6 -129
- package/dist/middleware/index.d.ts +1 -0
- package/dist/middleware/index.js +1 -0
- package/dist/server/StartServer.jsx +1 -1
- package/dist/server/handler.d.ts +3 -61
- package/dist/server/handler.js +4 -8
- package/dist/server/spa/StartServer.jsx +1 -1
- package/dist/server/spa/handler.d.ts +2 -30
- package/dist/server/web-stream.d.ts +9 -0
- package/dist/server/web-stream.js +26 -0
- package/dist/shared/HttpHeader.jsx +1 -1
- package/env.d.ts +12 -0
- package/package.json +14 -8
- package/scripts/build.js +0 -15
- package/scripts/validate-imports.js +0 -316
- package/src/client/StartClient.tsx +0 -34
- package/src/client/index.tsx +0 -2
- package/src/client/mount.ts +0 -1
- package/src/client/spa/index.tsx +0 -9
- package/src/config/constants.ts +0 -19
- package/src/config/dev-server.ts +0 -157
- package/src/config/env.ts +0 -105
- package/src/config/fs-router.ts +0 -162
- package/src/config/fs-routes/fs-watcher.ts +0 -66
- package/src/config/fs-routes/index.ts +0 -136
- package/src/config/fs-routes/router.ts +0 -184
- package/src/config/fs-routes/tree-shake.ts +0 -324
- package/src/config/index.ts +0 -239
- package/src/config/lazy.ts +0 -132
- package/src/config/manifest.ts +0 -120
- package/src/config/utils.ts +0 -5
- package/src/config/vite-utils.ts +0 -113
- package/src/directives/bubble-function-declaration.ts +0 -33
- package/src/directives/compile.ts +0 -54
- package/src/directives/generate-unique-name.ts +0 -22
- package/src/directives/get-descriptive-name.ts +0 -39
- package/src/directives/get-import-identifier.ts +0 -34
- package/src/directives/get-root-statement-path.ts +0 -14
- package/src/directives/index.ts +0 -233
- package/src/directives/is-statement-top-level.ts +0 -13
- package/src/directives/paths.ts +0 -63
- package/src/directives/plugin.ts +0 -389
- package/src/directives/remove-unused-variables.ts +0 -70
- package/src/directives/types.ts +0 -12
- package/src/directives/xxhash32.ts +0 -214
- package/src/env.d.ts +0 -17
- package/src/fns/client.ts +0 -141
- package/src/fns/handler.spec.ts +0 -85
- package/src/fns/handler.ts +0 -287
- package/src/fns/registration.ts +0 -19
- package/src/fns/serialization.ts +0 -250
- package/src/fns/server.ts +0 -46
- package/src/fns/shared.ts +0 -116
- package/src/http/index.ts +0 -216
- package/src/index.tsx +0 -7
- package/src/internal.d.ts +0 -14
- package/src/middleware/index.ts +0 -92
- package/src/router.tsx +0 -37
- package/src/server/StartServer.tsx +0 -58
- package/src/server/assets/PatchVirtualDevStyles.tsx +0 -31
- package/src/server/assets/index.ts +0 -70
- package/src/server/assets/render.tsx +0 -46
- package/src/server/collect-styles.ts +0 -70
- package/src/server/fetchEvent.spec.ts +0 -85
- package/src/server/fetchEvent.ts +0 -36
- package/src/server/handler.ts +0 -261
- package/src/server/index.tsx +0 -29
- package/src/server/manifest/client-manifest.ts +0 -8
- package/src/server/manifest/dev-client-manifest.ts +0 -21
- package/src/server/manifest/dev-ssr-manifest.ts +0 -23
- package/src/server/manifest/prod-client-manifest.ts +0 -21
- package/src/server/manifest/prod-ssr-manifest.ts +0 -109
- package/src/server/manifest/ssr-manifest.ts +0 -10
- package/src/server/routes.ts +0 -126
- package/src/server/spa/StartServer.tsx +0 -42
- package/src/server/spa/handler.ts +0 -29
- package/src/server/spa/index.tsx +0 -5
- package/src/server/types.ts +0 -82
- package/src/server/util.ts +0 -12
- package/src/shared/ErrorBoundary.tsx +0 -52
- package/src/shared/GET.ts +0 -8
- package/src/shared/HttpHeader.tsx +0 -42
- package/src/shared/HttpStatusCode.ts +0 -27
- package/src/shared/clientOnly.ts +0 -44
- package/src/shared/dev-overlay/CodeView.tsx +0 -90
- package/src/shared/dev-overlay/DevOverlayDialog.tsx +0 -316
- package/src/shared/dev-overlay/createStackFrame.ts +0 -74
- package/src/shared/dev-overlay/download.ts +0 -6
- package/src/shared/dev-overlay/env.d.ts +0 -4
- package/src/shared/dev-overlay/get-source-map.ts +0 -33
- package/src/shared/dev-overlay/icons.tsx +0 -456
- package/src/shared/dev-overlay/index.tsx +0 -63
- package/src/shared/dev-overlay/styles.css +0 -292
- package/src/shared/lazy.ts +0 -52
- package/src/shared/serverFunction.ts +0 -10
- package/src/utils/debounce.ts +0 -10
- package/src/virtual.d.ts +0 -27
- package/tsconfig.json +0 -24
- package/vitest.config.ts +0 -9
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
import { init, parse } from "es-module-lexer";
|
|
2
|
-
import esbuild from "esbuild";
|
|
3
|
-
import fg from "fast-glob";
|
|
4
|
-
import fs from "node:fs";
|
|
5
|
-
import micromatch from "micromatch";
|
|
6
|
-
import { posix } from "node:path";
|
|
7
|
-
import { pathToRegexp } from "path-to-regexp";
|
|
8
|
-
|
|
9
|
-
import { normalizePath } from "vite";
|
|
10
|
-
|
|
11
|
-
export { pathToRegexp };
|
|
12
|
-
|
|
13
|
-
export const glob = (path: string) => fg.sync(path, { absolute: true });
|
|
14
|
-
|
|
15
|
-
export type FileSystemRouterConfig = { dir: string; extensions: string[] };
|
|
16
|
-
type Route = { path: string } & Record<string, any>;
|
|
17
|
-
|
|
18
|
-
export function cleanPath(src: string, config: FileSystemRouterConfig) {
|
|
19
|
-
return src
|
|
20
|
-
.slice(config.dir.length)
|
|
21
|
-
.replace(new RegExp(`\.(${(config.extensions ?? []).join("|")})$`), "");
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export function analyzeModule(src: string) {
|
|
25
|
-
return parse(
|
|
26
|
-
esbuild.transformSync(fs.readFileSync(src, "utf-8"), {
|
|
27
|
-
jsx: "transform",
|
|
28
|
-
format: "esm",
|
|
29
|
-
loader: "tsx",
|
|
30
|
-
}).code,
|
|
31
|
-
src,
|
|
32
|
-
);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
type RouterEvent = CustomEvent<{ route: string; type: "update" | "remove" | "add" }>;
|
|
36
|
-
|
|
37
|
-
export class BaseFileSystemRouter extends EventTarget {
|
|
38
|
-
routes: Route[];
|
|
39
|
-
|
|
40
|
-
config: FileSystemRouterConfig;
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
*
|
|
44
|
-
* @param {} config
|
|
45
|
-
*/
|
|
46
|
-
constructor(config: FileSystemRouterConfig) {
|
|
47
|
-
super();
|
|
48
|
-
this.routes = [];
|
|
49
|
-
this.config = config;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
glob() {
|
|
53
|
-
return (
|
|
54
|
-
posix.join(fg.convertPathToPattern(this.config.dir), "**/*") +
|
|
55
|
-
`.{${this.config.extensions.join(",")}}`
|
|
56
|
-
);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
async buildRoutes(): Promise<any[]> {
|
|
60
|
-
await init;
|
|
61
|
-
for (var src of glob(this.glob())) {
|
|
62
|
-
await this.addRoute(src);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
return this.routes;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
isRoute(src: string) {
|
|
69
|
-
return Boolean(micromatch(src as any, this.glob())?.length);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
toPath(src: string) {
|
|
73
|
-
throw new Error("Not implemented");
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
toRoute(src: string): Route | undefined {
|
|
77
|
-
let path = this.toPath(src);
|
|
78
|
-
|
|
79
|
-
if (path === undefined) return;
|
|
80
|
-
|
|
81
|
-
const [_, exports] = analyzeModule(src);
|
|
82
|
-
|
|
83
|
-
if (!exports.find(e => e.n === "default")) {
|
|
84
|
-
console.warn("No default export", src);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
return {
|
|
88
|
-
$component: {
|
|
89
|
-
src: src,
|
|
90
|
-
pick: ["default", "$css"],
|
|
91
|
-
},
|
|
92
|
-
path,
|
|
93
|
-
// filePath: src
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* To be attached by vite plugin to the vite dev server
|
|
99
|
-
*/
|
|
100
|
-
update = undefined;
|
|
101
|
-
|
|
102
|
-
_addRoute(route: Route) {
|
|
103
|
-
const idx = this.routes.findIndex(r => r.path === route.path);
|
|
104
|
-
if (idx >= 0) this.routes.splice(idx, 1);
|
|
105
|
-
this.routes.push(route);
|
|
106
|
-
|
|
107
|
-
return idx >= 0;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
async addRoute(src: string) {
|
|
111
|
-
src = normalizePath(src);
|
|
112
|
-
if (this.isRoute(src)) {
|
|
113
|
-
try {
|
|
114
|
-
const route = this.toRoute(src);
|
|
115
|
-
if (route) {
|
|
116
|
-
this._addRoute(route);
|
|
117
|
-
this.reload(route.path, "add");
|
|
118
|
-
}
|
|
119
|
-
} catch (e) {
|
|
120
|
-
console.error(e);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
reload(route: string, type: "update" | "remove" | "add") {
|
|
126
|
-
this.dispatchEvent(
|
|
127
|
-
new CustomEvent("reload", {
|
|
128
|
-
detail: {
|
|
129
|
-
route,
|
|
130
|
-
type,
|
|
131
|
-
},
|
|
132
|
-
}),
|
|
133
|
-
);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
async updateRoute(src_: string) {
|
|
137
|
-
const src = normalizePath(src_);
|
|
138
|
-
if (this.isRoute(src)) {
|
|
139
|
-
try {
|
|
140
|
-
const route = this.toRoute(src);
|
|
141
|
-
if (route) {
|
|
142
|
-
const updated = this._addRoute(route);
|
|
143
|
-
this.reload(route.path, updated ? "update" : "add");
|
|
144
|
-
} else {
|
|
145
|
-
this.removeRoute(src_);
|
|
146
|
-
}
|
|
147
|
-
} catch (e) {
|
|
148
|
-
console.error(e);
|
|
149
|
-
}
|
|
150
|
-
// this.update?.();
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
removeRoute(src: string) {
|
|
155
|
-
src = normalizePath(src);
|
|
156
|
-
if (this.isRoute(src)) {
|
|
157
|
-
const path = this.toPath(src);
|
|
158
|
-
if (path === undefined) {
|
|
159
|
-
return;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
const idx = this.routes.findIndex(r => r.path === path);
|
|
163
|
-
if (idx === -1) return;
|
|
164
|
-
|
|
165
|
-
this.routes.splice(idx, 1);
|
|
166
|
-
this.reload(path, "remove");
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
on(type: string, cb: (evt: RouterEvent) => void) {
|
|
171
|
-
this.addEventListener(type, cb as any);
|
|
172
|
-
return () => this.removeEventListener(type, cb as any);
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
buildRoutesPromise?: Promise<any[]>;
|
|
176
|
-
|
|
177
|
-
async getRoutes() {
|
|
178
|
-
if (!this.buildRoutesPromise) {
|
|
179
|
-
this.buildRoutesPromise = this.buildRoutes();
|
|
180
|
-
}
|
|
181
|
-
await this.buildRoutesPromise;
|
|
182
|
-
return this.routes;
|
|
183
|
-
}
|
|
184
|
-
}
|
|
@@ -1,324 +0,0 @@
|
|
|
1
|
-
// All credit for this work goes to the amazing Next.js team.
|
|
2
|
-
// https://github.com/vercel/next.js/blob/canary/packages/next/build/babel/plugins/next-ssg-transform.ts
|
|
3
|
-
// This is adapted to work with routeData functions. It can be run in two modes, one which preserves the routeData and the Component in the same file, and one which creates a
|
|
4
|
-
|
|
5
|
-
import type * as Babel from "@babel/core";
|
|
6
|
-
import type { NodePath, PluginObj, PluginPass } from "@babel/core";
|
|
7
|
-
import type { Binding } from "@babel/traverse";
|
|
8
|
-
import { basename } from "pathe";
|
|
9
|
-
import type { Plugin } from "vite";
|
|
10
|
-
|
|
11
|
-
type State = Omit<PluginPass, "opts"> & {
|
|
12
|
-
opts: { pick: string[] };
|
|
13
|
-
refs: Set<any>;
|
|
14
|
-
done: boolean;
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
function treeShakeTransform({ types: t }: typeof Babel): PluginObj<State> {
|
|
18
|
-
function getIdentifier(path: any) {
|
|
19
|
-
const parentPath = path.parentPath;
|
|
20
|
-
if (parentPath.type === "VariableDeclarator") {
|
|
21
|
-
const pp = parentPath;
|
|
22
|
-
const name = pp.get("id");
|
|
23
|
-
return name.node.type === "Identifier" ? name : null;
|
|
24
|
-
}
|
|
25
|
-
if (parentPath.type === "AssignmentExpression") {
|
|
26
|
-
const pp = parentPath;
|
|
27
|
-
const name = pp.get("left");
|
|
28
|
-
return name.node.type === "Identifier" ? name : null;
|
|
29
|
-
}
|
|
30
|
-
if (path.node.type === "ArrowFunctionExpression") {
|
|
31
|
-
return null;
|
|
32
|
-
}
|
|
33
|
-
return path.node.id && path.node.id.type === "Identifier" ? path.get("id") : null;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function isIdentifierReferenced(ident: any) {
|
|
37
|
-
const b: Binding | undefined = ident.scope.getBinding(ident.node.name);
|
|
38
|
-
if (b?.referenced) {
|
|
39
|
-
if (b.path.type === "FunctionDeclaration") {
|
|
40
|
-
return !b.constantViolations
|
|
41
|
-
.concat(b.referencePaths)
|
|
42
|
-
.every(ref => ref.findParent(p => p === b.path));
|
|
43
|
-
}
|
|
44
|
-
return true;
|
|
45
|
-
}
|
|
46
|
-
return false;
|
|
47
|
-
}
|
|
48
|
-
function markFunction(path: any, state: any) {
|
|
49
|
-
const ident = getIdentifier(path);
|
|
50
|
-
if (ident && ident.node && isIdentifierReferenced(ident)) {
|
|
51
|
-
state.refs.add(ident);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
function markImport(path: any, state: any) {
|
|
55
|
-
const local = path.get("local");
|
|
56
|
-
if (isIdentifierReferenced(local)) {
|
|
57
|
-
state.refs.add(local);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
return {
|
|
62
|
-
visitor: {
|
|
63
|
-
Program: {
|
|
64
|
-
enter(path, state) {
|
|
65
|
-
state.refs = new Set();
|
|
66
|
-
state.done = false;
|
|
67
|
-
path.traverse(
|
|
68
|
-
{
|
|
69
|
-
VariableDeclarator(variablePath, variableState: any) {
|
|
70
|
-
if (variablePath.node.id.type === "Identifier") {
|
|
71
|
-
const local = variablePath.get("id");
|
|
72
|
-
if (isIdentifierReferenced(local)) {
|
|
73
|
-
variableState.refs.add(local);
|
|
74
|
-
}
|
|
75
|
-
} else if (variablePath.node.id.type === "ObjectPattern") {
|
|
76
|
-
const pattern = variablePath.get("id");
|
|
77
|
-
const properties = pattern.get("properties") as Array<NodePath>;
|
|
78
|
-
properties.forEach(p => {
|
|
79
|
-
const local = p.get(
|
|
80
|
-
p.node.type === "ObjectProperty"
|
|
81
|
-
? "value"
|
|
82
|
-
: p.node.type === "RestElement"
|
|
83
|
-
? "argument"
|
|
84
|
-
: (() => {
|
|
85
|
-
throw new Error("invariant");
|
|
86
|
-
})(),
|
|
87
|
-
);
|
|
88
|
-
if (isIdentifierReferenced(local)) {
|
|
89
|
-
variableState.refs.add(local);
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
} else if (variablePath.node.id.type === "ArrayPattern") {
|
|
93
|
-
const pattern = variablePath.get("id");
|
|
94
|
-
const elements = pattern.get("elements") as Array<NodePath>;
|
|
95
|
-
elements.forEach(e => {
|
|
96
|
-
let local: NodePath<any>;
|
|
97
|
-
if (e.node && e.node.type === "Identifier") {
|
|
98
|
-
local = e;
|
|
99
|
-
} else if (e.node && e.node.type === "RestElement") {
|
|
100
|
-
local = e.get("argument");
|
|
101
|
-
} else {
|
|
102
|
-
return;
|
|
103
|
-
}
|
|
104
|
-
if (isIdentifierReferenced(local)) {
|
|
105
|
-
variableState.refs.add(local);
|
|
106
|
-
}
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
},
|
|
110
|
-
ExportDefaultDeclaration(exportNamedPath) {
|
|
111
|
-
// if opts.keep is true, we don't remove the routeData export
|
|
112
|
-
if (state.opts.pick && !state.opts.pick.includes("default")) {
|
|
113
|
-
exportNamedPath.remove();
|
|
114
|
-
}
|
|
115
|
-
},
|
|
116
|
-
ExportNamedDeclaration(exportNamedPath) {
|
|
117
|
-
// if opts.keep is false, we don't remove the routeData export
|
|
118
|
-
if (!state.opts.pick) {
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
const specifiers = exportNamedPath.get("specifiers");
|
|
122
|
-
if (specifiers.length) {
|
|
123
|
-
specifiers.forEach(s => {
|
|
124
|
-
if (
|
|
125
|
-
t.isIdentifier(s.node.exported)
|
|
126
|
-
? s.node.exported.name
|
|
127
|
-
: state.opts.pick.includes(s.node.exported.value)
|
|
128
|
-
) {
|
|
129
|
-
s.remove();
|
|
130
|
-
}
|
|
131
|
-
});
|
|
132
|
-
if (exportNamedPath.node.specifiers.length < 1) {
|
|
133
|
-
exportNamedPath.remove();
|
|
134
|
-
}
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
137
|
-
const decl = exportNamedPath.get("declaration");
|
|
138
|
-
if (decl == null || decl.node == null) {
|
|
139
|
-
return;
|
|
140
|
-
}
|
|
141
|
-
switch (decl.node.type) {
|
|
142
|
-
case "FunctionDeclaration": {
|
|
143
|
-
const name = decl.node.id?.name;
|
|
144
|
-
if (name && state.opts.pick && !state.opts.pick.includes(name)) {
|
|
145
|
-
exportNamedPath.remove();
|
|
146
|
-
}
|
|
147
|
-
break;
|
|
148
|
-
}
|
|
149
|
-
case "VariableDeclaration": {
|
|
150
|
-
const inner = decl.get("declarations") as Array<NodePath<any>>;
|
|
151
|
-
inner.forEach(d => {
|
|
152
|
-
if (d.node.id.type !== "Identifier") {
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
155
|
-
const name = d.node.id.name;
|
|
156
|
-
if (state.opts.pick && !state.opts.pick.includes(name)) {
|
|
157
|
-
d.remove();
|
|
158
|
-
}
|
|
159
|
-
});
|
|
160
|
-
break;
|
|
161
|
-
}
|
|
162
|
-
default: {
|
|
163
|
-
break;
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
},
|
|
167
|
-
FunctionDeclaration: markFunction,
|
|
168
|
-
FunctionExpression: markFunction,
|
|
169
|
-
ArrowFunctionExpression: markFunction,
|
|
170
|
-
ImportSpecifier: markImport,
|
|
171
|
-
ImportDefaultSpecifier: markImport,
|
|
172
|
-
ImportNamespaceSpecifier: markImport,
|
|
173
|
-
ImportDeclaration: (path, state) => {
|
|
174
|
-
if (
|
|
175
|
-
path.node.source.value.endsWith(".css") &&
|
|
176
|
-
state.opts.pick &&
|
|
177
|
-
!state.opts.pick.includes("$css")
|
|
178
|
-
) {
|
|
179
|
-
path.remove();
|
|
180
|
-
}
|
|
181
|
-
},
|
|
182
|
-
},
|
|
183
|
-
state,
|
|
184
|
-
);
|
|
185
|
-
|
|
186
|
-
const refs = state.refs;
|
|
187
|
-
let count = 0;
|
|
188
|
-
const sweepFunction = (sweepPath: any) => {
|
|
189
|
-
const ident = getIdentifier(sweepPath);
|
|
190
|
-
if (ident && ident.node && refs.has(ident) && !isIdentifierReferenced(ident)) {
|
|
191
|
-
++count;
|
|
192
|
-
if (
|
|
193
|
-
t.isAssignmentExpression(sweepPath.parentPath) ||
|
|
194
|
-
t.isVariableDeclarator(sweepPath.parentPath)
|
|
195
|
-
) {
|
|
196
|
-
sweepPath.parentPath.remove();
|
|
197
|
-
} else {
|
|
198
|
-
sweepPath.remove();
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
};
|
|
202
|
-
function sweepImport(sweepPath: any) {
|
|
203
|
-
const local = sweepPath.get("local");
|
|
204
|
-
if (refs.has(local) && !isIdentifierReferenced(local)) {
|
|
205
|
-
++count;
|
|
206
|
-
sweepPath.remove();
|
|
207
|
-
if (sweepPath.parent.specifiers.length === 0) {
|
|
208
|
-
sweepPath.parentPath.remove();
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
do {
|
|
213
|
-
path.scope.crawl();
|
|
214
|
-
count = 0;
|
|
215
|
-
path.traverse({
|
|
216
|
-
VariableDeclarator(variablePath) {
|
|
217
|
-
if (variablePath.node.id.type === "Identifier") {
|
|
218
|
-
const local = variablePath.get("id");
|
|
219
|
-
if (refs.has(local) && !isIdentifierReferenced(local)) {
|
|
220
|
-
++count;
|
|
221
|
-
variablePath.remove();
|
|
222
|
-
}
|
|
223
|
-
} else if (variablePath.node.id.type === "ObjectPattern") {
|
|
224
|
-
const pattern = variablePath.get("id");
|
|
225
|
-
const beforeCount = count;
|
|
226
|
-
const properties = pattern.get("properties");
|
|
227
|
-
properties.forEach(p => {
|
|
228
|
-
const local = p.get(
|
|
229
|
-
p.node.type === "ObjectProperty"
|
|
230
|
-
? "value"
|
|
231
|
-
: p.node.type === "RestElement"
|
|
232
|
-
? "argument"
|
|
233
|
-
: (() => {
|
|
234
|
-
throw new Error("invariant");
|
|
235
|
-
})(),
|
|
236
|
-
);
|
|
237
|
-
if (refs.has(local) && !isIdentifierReferenced(local)) {
|
|
238
|
-
++count;
|
|
239
|
-
p.remove();
|
|
240
|
-
}
|
|
241
|
-
});
|
|
242
|
-
if (beforeCount !== count && pattern.get("properties").length < 1) {
|
|
243
|
-
variablePath.remove();
|
|
244
|
-
}
|
|
245
|
-
} else if (variablePath.node.id.type === "ArrayPattern") {
|
|
246
|
-
const pattern = variablePath.get("id");
|
|
247
|
-
const beforeCount = count;
|
|
248
|
-
const elements = pattern.get("elements");
|
|
249
|
-
elements.forEach(e => {
|
|
250
|
-
let local: NodePath<any> | undefined;
|
|
251
|
-
if (e.node && e.node.type === "Identifier") {
|
|
252
|
-
local = e;
|
|
253
|
-
} else if (e.node && e.node.type === "RestElement") {
|
|
254
|
-
local = e.get("argument");
|
|
255
|
-
} else {
|
|
256
|
-
return;
|
|
257
|
-
}
|
|
258
|
-
if (refs.has(local) && !isIdentifierReferenced(local)) {
|
|
259
|
-
++count;
|
|
260
|
-
e.remove();
|
|
261
|
-
}
|
|
262
|
-
});
|
|
263
|
-
if (beforeCount !== count && pattern.get("elements").length < 1) {
|
|
264
|
-
variablePath.remove();
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
},
|
|
268
|
-
FunctionDeclaration: sweepFunction,
|
|
269
|
-
FunctionExpression: sweepFunction,
|
|
270
|
-
ArrowFunctionExpression: sweepFunction,
|
|
271
|
-
ImportSpecifier: sweepImport,
|
|
272
|
-
ImportDefaultSpecifier: sweepImport,
|
|
273
|
-
ImportNamespaceSpecifier: sweepImport,
|
|
274
|
-
});
|
|
275
|
-
} while (count);
|
|
276
|
-
},
|
|
277
|
-
},
|
|
278
|
-
},
|
|
279
|
-
};
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
export function treeShake(): Plugin {
|
|
283
|
-
async function transform(id: string, code: string) {
|
|
284
|
-
const [path, queryString] = id.split("?");
|
|
285
|
-
const query = new URLSearchParams(queryString);
|
|
286
|
-
if (query.has("pick")) {
|
|
287
|
-
const babel = await import("@babel/core");
|
|
288
|
-
const transformed = await babel.transformAsync(code, {
|
|
289
|
-
plugins: [[treeShakeTransform, { pick: query.getAll("pick") }]],
|
|
290
|
-
parserOpts: {
|
|
291
|
-
plugins: ["jsx", "typescript"],
|
|
292
|
-
},
|
|
293
|
-
filename: basename(id),
|
|
294
|
-
ast: false,
|
|
295
|
-
sourceMaps: true,
|
|
296
|
-
configFile: false,
|
|
297
|
-
babelrc: false,
|
|
298
|
-
sourceFileName: id,
|
|
299
|
-
});
|
|
300
|
-
|
|
301
|
-
return transformed;
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
return {
|
|
305
|
-
name: "tree-shake",
|
|
306
|
-
enforce: "pre",
|
|
307
|
-
async transform(code, id) {
|
|
308
|
-
const [path, queryString] = id.split("?");
|
|
309
|
-
if (!path) return;
|
|
310
|
-
const query = new URLSearchParams(queryString);
|
|
311
|
-
const ext = path.split(".").pop();
|
|
312
|
-
if (!ext) return;
|
|
313
|
-
if (query.has("pick") && ["js", "jsx", "ts", "tsx"].includes(ext)) {
|
|
314
|
-
const transformed = await transform(id, code);
|
|
315
|
-
if (!transformed?.code) return;
|
|
316
|
-
|
|
317
|
-
return {
|
|
318
|
-
code: transformed.code,
|
|
319
|
-
map: transformed.map,
|
|
320
|
-
};
|
|
321
|
-
}
|
|
322
|
-
},
|
|
323
|
-
};
|
|
324
|
-
}
|