@zhin.js/dependency 1.0.1 → 1.0.3
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/README.md +414 -613
- package/dist/dependency.d.ts +18 -12
- package/dist/dependency.d.ts.map +1 -1
- package/dist/dependency.js +196 -131
- package/dist/dependency.js.map +1 -1
- package/dist/hook-registry.d.ts +4 -2
- package/dist/hook-registry.d.ts.map +1 -1
- package/dist/hook-registry.js +11 -4
- package/dist/hook-registry.js.map +1 -1
- package/dist/hooks.d.ts +4 -2
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +18 -8
- package/dist/hooks.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +8 -0
- package/dist/types.d.ts.map +1 -1
- package/loaders/bun-plugin.ts +8 -5
- package/loaders/transform-utils.mjs +108 -27
- package/loaders/tsx-loader.mjs +4 -3
- package/package.json +6 -1
package/dist/hook-registry.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { Dependency } from './dependency.js';
|
|
2
|
+
import path from 'path';
|
|
1
3
|
const dependencyStack = [];
|
|
2
4
|
export function setCurrentDependency(dep) {
|
|
3
5
|
if (dep) {
|
|
@@ -7,7 +9,7 @@ export function setCurrentDependency(dep) {
|
|
|
7
9
|
dependencyStack.pop();
|
|
8
10
|
}
|
|
9
11
|
}
|
|
10
|
-
function getCurrentDependency() {
|
|
12
|
+
export function getCurrentDependency() {
|
|
11
13
|
return dependencyStack.length > 0 ? dependencyStack[dependencyStack.length - 1] : null;
|
|
12
14
|
}
|
|
13
15
|
class HookRegistry {
|
|
@@ -43,10 +45,15 @@ class HookRegistry {
|
|
|
43
45
|
if (!config) {
|
|
44
46
|
throw new Error(`Hook "${name}" is not registered. Please registerHook it first using registerHook().`);
|
|
45
47
|
}
|
|
46
|
-
|
|
48
|
+
let currentDep = this.getCurrentDependency();
|
|
47
49
|
if (!currentDep) {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
+
if (name !== 'importModule') {
|
|
51
|
+
console.warn(`No current dependency context for hook "${name}".`);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
currentDep = new Dependency(args[1] || path.join(process.cwd(), './src/index'));
|
|
55
|
+
Dependency['globalDepMap'].set(currentDep.filePath, currentDep);
|
|
56
|
+
setCurrentDependency(currentDep);
|
|
50
57
|
}
|
|
51
58
|
return config.handler(currentDep, ...args);
|
|
52
59
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hook-registry.js","sourceRoot":"","sources":["../src/hook-registry.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"hook-registry.js","sourceRoot":"","sources":["../src/hook-registry.ts"],"names":[],"mappings":"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"}
|
package/dist/hooks.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { Dependency } from './dependency.js';
|
|
1
2
|
export declare function addListener(event: string, listener: () => void): () => void;
|
|
3
|
+
export declare function useDependency(): Dependency;
|
|
2
4
|
export declare function onMount(hook: () => void | Promise<void>): void;
|
|
3
|
-
export declare function onDispose(hook: () => void | Promise<void
|
|
4
|
-
export declare function importModule(importPath: string): Promise<void>;
|
|
5
|
+
export declare function onDispose(hook: () => void | Promise<void>, inner?: boolean): void;
|
|
6
|
+
export declare function importModule(importPath: string, importModulePath?: string): Promise<void>;
|
|
5
7
|
export { registerHook, unregisterHook, useHook, hasHook, getAllHooks } from './hook-registry.js';
|
|
6
8
|
//# sourceMappingURL=hooks.d.ts.map
|
package/dist/hooks.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAqE7C,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAE3E;AACD,wBAAgB,aAAa,IAAI,UAAU,CAE1C;AAKD,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAE9D;AAQD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,GAAE,OAAe,GAAG,IAAI,CAExF;AAMD,wBAAsB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAC,gBAAgB,CAAC,EAAC,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE7F;AAID,OAAO,EACL,YAAY,EACZ,cAAc,EACd,OAAO,EACP,OAAO,EACP,WAAW,EACZ,MAAM,oBAAoB,CAAC"}
|
package/dist/hooks.js
CHANGED
|
@@ -14,31 +14,41 @@ registerHook({
|
|
|
14
14
|
},
|
|
15
15
|
description: 'registerHook a mount hook for the current dependency'
|
|
16
16
|
});
|
|
17
|
+
registerHook({
|
|
18
|
+
name: 'useDependency',
|
|
19
|
+
handler: (dep) => {
|
|
20
|
+
return dep;
|
|
21
|
+
},
|
|
22
|
+
description: 'use the current dependency'
|
|
23
|
+
});
|
|
17
24
|
registerHook({
|
|
18
25
|
name: 'onDispose',
|
|
19
|
-
handler: (dep, hook) => {
|
|
20
|
-
dep.addDisposeHook(hook);
|
|
26
|
+
handler: (dep, hook, inner = false) => {
|
|
27
|
+
dep.addDisposeHook(hook, inner);
|
|
21
28
|
},
|
|
22
29
|
description: 'registerHook a dispose hook for the current dependency'
|
|
23
30
|
});
|
|
24
31
|
registerHook({
|
|
25
32
|
name: 'importModule',
|
|
26
|
-
handler: async (dep, importPath) => {
|
|
27
|
-
await dep.importChild(importPath);
|
|
33
|
+
handler: async (dep, importPath, importModulePath) => {
|
|
34
|
+
await dep.importChild(importPath, importModulePath);
|
|
28
35
|
},
|
|
29
36
|
description: 'Import a module and create a child dependency'
|
|
30
37
|
});
|
|
31
38
|
export function addListener(event, listener) {
|
|
32
39
|
return useHook('addListener')(event, listener);
|
|
33
40
|
}
|
|
41
|
+
export function useDependency() {
|
|
42
|
+
return useHook('useDependency')();
|
|
43
|
+
}
|
|
34
44
|
export function onMount(hook) {
|
|
35
45
|
return useHook('onMount')(hook);
|
|
36
46
|
}
|
|
37
|
-
export function onDispose(hook) {
|
|
38
|
-
return useHook('onDispose')(hook);
|
|
47
|
+
export function onDispose(hook, inner = false) {
|
|
48
|
+
return useHook('onDispose')(hook, inner);
|
|
39
49
|
}
|
|
40
|
-
export async function importModule(importPath) {
|
|
41
|
-
return useHook('importModule')(importPath);
|
|
50
|
+
export async function importModule(importPath, importModulePath) {
|
|
51
|
+
return useHook('importModule')(importPath, importModulePath);
|
|
42
52
|
}
|
|
43
53
|
export { registerHook, unregisterHook, useHook, hasHook, getAllHooks } from './hook-registry.js';
|
|
44
54
|
//# sourceMappingURL=hooks.js.map
|
package/dist/hooks.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAS3D,YAAY,CAAC;IACX,IAAI,EAAE,aAAa;IACnB,OAAO,EAAE,CAAC,GAAe,EAAE,KAAa,EAAE,QAAoB,EAAE,EAAE;QAChE,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QACxB,OAAO,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACxC,CAAC;IACD,WAAW,EAAE,iDAAiD;CAC/D,CAAC,CAAC;AAMH,YAAY,CAAC;IACX,IAAI,EAAE,SAAS;IACf,OAAO,EAAE,CAAC,GAAe,EAAE,IAAgC,EAAE,EAAE;QAC7D,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;IACzB,CAAC;IACD,WAAW,EAAE,sDAAsD;CACpE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAS3D,YAAY,CAAC;IACX,IAAI,EAAE,aAAa;IACnB,OAAO,EAAE,CAAC,GAAe,EAAE,KAAa,EAAE,QAAoB,EAAE,EAAE;QAChE,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QACxB,OAAO,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACxC,CAAC;IACD,WAAW,EAAE,iDAAiD;CAC/D,CAAC,CAAC;AAMH,YAAY,CAAC;IACX,IAAI,EAAE,SAAS;IACf,OAAO,EAAE,CAAC,GAAe,EAAE,IAAgC,EAAE,EAAE;QAC7D,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;IACzB,CAAC;IACD,WAAW,EAAE,sDAAsD;CACpE,CAAC,CAAC;AACH,YAAY,CAAC;IACX,IAAI,EAAE,eAAe;IACrB,OAAO,EAAE,CAAC,GAAe,EAAE,EAAE;QAC3B,OAAO,GAAG,CAAC;IACb,CAAC;IACD,WAAW,EAAE,4BAA4B;CAC1C,CAAC,CAAA;AAMF,YAAY,CAAC;IACX,IAAI,EAAE,WAAW;IACjB,OAAO,EAAE,CAAC,GAAe,EAAE,IAAgC,EAAE,QAAiB,KAAK,EAAE,EAAE;QACrF,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAClC,CAAC;IACD,WAAW,EAAE,wDAAwD;CACtE,CAAC,CAAC;AAMH,YAAY,CAAC;IACX,IAAI,EAAE,cAAc;IACpB,OAAO,EAAE,KAAK,EAAE,GAAe,EAAE,UAAkB,EAAC,gBAAwB,EAAE,EAAE;QAC9E,MAAM,GAAG,CAAC,WAAW,CAAC,UAAU,EAAC,gBAAgB,CAAC,CAAC;IACrD,CAAC;IACD,WAAW,EAAE,+CAA+C;CAC7D,CAAC,CAAC;AASH,MAAM,UAAU,WAAW,CAAC,KAAa,EAAE,QAAoB;IAC7D,OAAO,OAAO,CAAC,aAAa,CAAC,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;AACjD,CAAC;AACD,MAAM,UAAU,aAAa;IAC3B,OAAO,OAAO,CAAC,eAAe,CAAC,EAAE,CAAC;AACpC,CAAC;AAKD,MAAM,UAAU,OAAO,CAAC,IAAgC;IACtD,OAAO,OAAO,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC;AAClC,CAAC;AAQD,MAAM,UAAU,SAAS,CAAC,IAAgC,EAAE,QAAiB,KAAK;IAChF,OAAO,OAAO,CAAC,WAAW,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAC3C,CAAC;AAMD,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,UAAkB,EAAC,gBAAwB;IAC5E,OAAO,OAAO,CAAC,cAAc,CAAC,CAAC,UAAU,EAAC,gBAAgB,CAAC,CAAC;AAC9D,CAAC;AAID,OAAO,EACL,YAAY,EACZ,cAAc,EACd,OAAO,EACP,OAAO,EACP,WAAW,EACZ,MAAM,oBAAoB,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export * from './dependency.js';
|
|
2
2
|
export * from './hooks.js';
|
|
3
|
+
export { getCurrentDependency } from './hook-registry.js';
|
|
3
4
|
export type { HookFunction, HookConfig, Hooks } from './hook-registry.js';
|
|
5
|
+
export type { Constructor, EffectCleanup, TimerId, ImmediateId, WrappedEffects } from './types.js';
|
|
4
6
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC1E,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
export type Constructor<T> = {
|
|
2
2
|
new (...args: any[]): T;
|
|
3
3
|
};
|
|
4
|
+
export type EffectCleanup = () => void;
|
|
5
|
+
export type TimerId = ReturnType<typeof setInterval> | ReturnType<typeof setTimeout>;
|
|
6
|
+
export type ImmediateId = ReturnType<typeof setImmediate>;
|
|
7
|
+
export interface WrappedEffects {
|
|
8
|
+
setInterval: typeof globalThis.setInterval;
|
|
9
|
+
setTimeout: typeof globalThis.setTimeout;
|
|
10
|
+
setImmediate: typeof globalThis.setImmediate;
|
|
11
|
+
}
|
|
4
12
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,CAAC,CAAC,IAAG;IACxB,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;CAC3B,CAAC"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,CAAC,CAAC,IAAG;IACxB,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;CAC3B,CAAC;AAKF,MAAM,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC;AAKvC,MAAM,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAKrF,MAAM,MAAM,WAAW,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AAK1D,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,OAAO,UAAU,CAAC,WAAW,CAAC;IAC3C,UAAU,EAAE,OAAO,UAAU,CAAC,UAAU,CAAC;IACzC,YAAY,EAAE,OAAO,UAAU,CAAC,YAAY,CAAC;CAC9C"}
|
package/loaders/bun-plugin.ts
CHANGED
|
@@ -37,10 +37,10 @@ export function createDependencyTreePlugin(): BunPlugin {
|
|
|
37
37
|
|
|
38
38
|
// 二次检查:使用统一的判断逻辑(支持 EXCLUDE)
|
|
39
39
|
if (!shouldTransformPath(args.path, ['.ts', '.js'])) {
|
|
40
|
-
//
|
|
40
|
+
// 不需要处理此文件,返回原内容
|
|
41
41
|
return {
|
|
42
42
|
contents: source,
|
|
43
|
-
loader: 'ts',
|
|
43
|
+
loader: args.path.endsWith('.ts') ? 'ts' : 'js',
|
|
44
44
|
};
|
|
45
45
|
}
|
|
46
46
|
|
|
@@ -53,19 +53,22 @@ export function createDependencyTreePlugin(): BunPlugin {
|
|
|
53
53
|
|
|
54
54
|
// 如果不是热重载,且已经转换过或没有相对导入,跳过转换
|
|
55
55
|
if (!isHotReload && (alreadyTransformed || !hasRelativeImports(source))) {
|
|
56
|
-
//
|
|
56
|
+
// 返回原内容
|
|
57
57
|
return {
|
|
58
58
|
contents: source,
|
|
59
|
-
loader: 'ts',
|
|
59
|
+
loader: args.path.endsWith('.ts') ? 'ts' : 'js',
|
|
60
60
|
};
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
// 转换相对路径的 import 语句
|
|
64
64
|
const transformed = transformImports(source, args.path, isHotReload, '__BUN_PLUGIN_TRANSFORMED__');
|
|
65
65
|
|
|
66
|
+
// 根据文件扩展名确定 loader
|
|
67
|
+
const loader = args.path.endsWith('.ts') ? 'ts' : 'js';
|
|
68
|
+
|
|
66
69
|
return {
|
|
67
70
|
contents: transformed,
|
|
68
|
-
loader: 'ts',
|
|
71
|
+
loader: loader as 'ts' | 'js',
|
|
69
72
|
};
|
|
70
73
|
});
|
|
71
74
|
},
|
|
@@ -11,6 +11,58 @@ export function hasRelativeImports(source) {
|
|
|
11
11
|
return /^import\s+['"](\.[^'"]+)['"]/m.test(source);
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
/**
|
|
15
|
+
* 生成副作用包装代码
|
|
16
|
+
* 包装全局副作用函数,自动添加清理逻辑到 onDispose
|
|
17
|
+
*/
|
|
18
|
+
function generateEffectWrappers() {
|
|
19
|
+
return [`
|
|
20
|
+
const __EFFECTS__=[];
|
|
21
|
+
const __globalSetInterval = globalThis.setInterval;
|
|
22
|
+
const __globalSetTimeout = globalThis.setTimeout;
|
|
23
|
+
const __globalSetImmediate = typeof setImmediate !== 'undefined' ? globalThis.setImmediate : null;
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
const setInterval = function(...args) {
|
|
27
|
+
const timerId = __globalSetInterval.apply(this, args);
|
|
28
|
+
__EFFECTS__.push(() => clearInterval(timerId));
|
|
29
|
+
return timerId;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const setTimeout = function(...args) {
|
|
33
|
+
const timerId = __globalSetTimeout.apply(this, args);
|
|
34
|
+
__EFFECTS__.push(() => clearTimeout(timerId));
|
|
35
|
+
return timerId;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
if (__globalSetImmediate) {
|
|
39
|
+
const setImmediate = function(...args) {
|
|
40
|
+
const immediateId = __globalSetImmediate.apply(this, args);
|
|
41
|
+
__EFFECTS__.push(() => clearImmediate(immediateId));
|
|
42
|
+
return immediateId;
|
|
43
|
+
};
|
|
44
|
+
}`,
|
|
45
|
+
`onDispose(async () => {
|
|
46
|
+
while(__EFFECTS__.length>0){
|
|
47
|
+
await __EFFECTS__.shift()();
|
|
48
|
+
}
|
|
49
|
+
}, true);`,
|
|
50
|
+
];
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* 检查是否启用副作用包装
|
|
55
|
+
* 通过环境变量 DEPENDENCY_WRAP_EFFECTS 控制
|
|
56
|
+
* 值为 'false' 或 '0' 时禁用,其他情况默认启用
|
|
57
|
+
*/
|
|
58
|
+
function shouldWrapEffects() {
|
|
59
|
+
const envValue = process.env.DEPENDENCY_WRAP_EFFECTS;
|
|
60
|
+
if (envValue === 'false' || envValue === '0') {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
return true; // 默认启用
|
|
64
|
+
}
|
|
65
|
+
|
|
14
66
|
/**
|
|
15
67
|
* 转换 import 语句
|
|
16
68
|
* @param {string} source - 源代码
|
|
@@ -19,36 +71,65 @@ export function hasRelativeImports(source) {
|
|
|
19
71
|
* @param {string} marker - 转换标记(如 '__LOADER_TRANSFORMED__' 或 '__BUN_PLUGIN_TRANSFORMED__')
|
|
20
72
|
*/
|
|
21
73
|
export function transformImports(source, currentPath, isHotReload = false, marker = '__LOADER_TRANSFORMED__') {
|
|
22
|
-
//
|
|
23
|
-
|
|
74
|
+
// 检查是否需要转换
|
|
75
|
+
const needsImportTransform = hasRelativeImports(source);
|
|
76
|
+
const wrapEffects = shouldWrapEffects();
|
|
77
|
+
const hooksPath = pkgJson.name;
|
|
78
|
+
|
|
79
|
+
if (wrapEffects) {
|
|
80
|
+
const hasOnDispose = source.includes('onDispose');
|
|
81
|
+
if (!hasOnDispose) {
|
|
82
|
+
source = `import { onDispose } from '${hooksPath}';\n` + source;
|
|
83
|
+
}
|
|
84
|
+
// 收集所有import 行(改为可选换行符,支持不同操作系统)
|
|
85
|
+
const importLines = source.match(/import\s+[^;]+from\s+(['"])([^'"]+)\1;[\r\n]*/gm) || [];
|
|
86
|
+
const lastImportLine = importLines[importLines.length - 1];
|
|
87
|
+
const [before,after] = generateEffectWrappers();
|
|
88
|
+
if (lastImportLine) {
|
|
89
|
+
source = source.replace(lastImportLine, lastImportLine + before);
|
|
90
|
+
} else {
|
|
91
|
+
// 没有 import 语句,在文件开头添加
|
|
92
|
+
source = before + source;
|
|
93
|
+
}
|
|
94
|
+
source = source + after;
|
|
95
|
+
}
|
|
96
|
+
// 如果不需要任何转换,直接返回原始代码
|
|
97
|
+
// 注意:如果启用了副作用包装,即使没有相对引用也需要继续处理
|
|
98
|
+
if (!needsImportTransform && !isHotReload && !wrapEffects) {
|
|
24
99
|
return source;
|
|
25
100
|
}
|
|
26
|
-
|
|
101
|
+
|
|
102
|
+
// 如果只启用了副作用包装,没有其他转换,直接返回已注入副作用包装的代码
|
|
103
|
+
if (!needsImportTransform && !isHotReload) {
|
|
104
|
+
return source;
|
|
105
|
+
}
|
|
106
|
+
|
|
27
107
|
// 添加标记(热重载时添加时间戳)
|
|
28
|
-
let result = isHotReload
|
|
108
|
+
let result = isHotReload
|
|
29
109
|
? `/* ${marker} (Hot Reload: ${Date.now()}) */\n`
|
|
30
110
|
: `/* ${marker} */\n`;
|
|
31
|
-
|
|
32
|
-
// 检查是否已有 importModule 导入
|
|
33
|
-
const hasImportModule = /import.*importModule.*from
|
|
34
|
-
|
|
35
|
-
//
|
|
36
|
-
if (!hasImportModule) {
|
|
37
|
-
const hooksPath = pkgJson.name;
|
|
111
|
+
|
|
112
|
+
// 2. 检查是否已有 importModule 导入
|
|
113
|
+
const hasImportModule = /import.*importModule.*from.*${hooksPath}/.test(source);
|
|
114
|
+
|
|
115
|
+
// 如果没有且需要转换 import,添加 importModule 导入
|
|
116
|
+
if (needsImportTransform && !hasImportModule) {
|
|
38
117
|
result += `import { importModule } from '${hooksPath}';\n`;
|
|
39
118
|
}
|
|
40
|
-
|
|
41
|
-
// 转换相对路径的 import
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
119
|
+
|
|
120
|
+
// 3. 转换相对路径的 import
|
|
121
|
+
let transformedSource = source;
|
|
122
|
+
if (needsImportTransform) {
|
|
123
|
+
transformedSource = source.replace(
|
|
124
|
+
/^import\s+(['"])(\.[^'"]+)\1;?\s*$/gm,
|
|
125
|
+
(match, quote, importPath) => {
|
|
126
|
+
return `await importModule(${quote}${importPath}${quote},${quote}${currentPath}${quote});`;
|
|
127
|
+
}
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
|
|
50
131
|
result += transformedSource;
|
|
51
|
-
|
|
132
|
+
|
|
52
133
|
return result;
|
|
53
134
|
}
|
|
54
135
|
|
|
@@ -73,13 +154,13 @@ export function transformImports(source, currentPath, isHotReload = false, marke
|
|
|
73
154
|
export function shouldTransformPath(path, extensions = ['.ts', '.js']) {
|
|
74
155
|
// 去除查询参数(如 ?t=timestamp)
|
|
75
156
|
const [actualPath] = path.split('?');
|
|
76
|
-
|
|
157
|
+
|
|
77
158
|
// 检查扩展名
|
|
78
159
|
const hasValidExtension = extensions.some(ext => actualPath.endsWith(ext));
|
|
79
160
|
if (!hasValidExtension) {
|
|
80
161
|
return false;
|
|
81
162
|
}
|
|
82
|
-
|
|
163
|
+
|
|
83
164
|
// 1. 检查 INCLUDE 路径(优先级最高,即使在 node_modules 中也处理)
|
|
84
165
|
const includePaths = process.env.DEPENDENCY_TREE_INCLUDE;
|
|
85
166
|
if (includePaths) {
|
|
@@ -88,7 +169,7 @@ export function shouldTransformPath(path, extensions = ['.ts', '.js']) {
|
|
|
88
169
|
return true; // 明确包含,直接返回 true
|
|
89
170
|
}
|
|
90
171
|
}
|
|
91
|
-
|
|
172
|
+
|
|
92
173
|
// 2. 检查 EXCLUDE 路径(优先级第二)
|
|
93
174
|
const excludePaths = process.env.DEPENDENCY_TREE_EXCLUDE;
|
|
94
175
|
if (excludePaths) {
|
|
@@ -97,12 +178,12 @@ export function shouldTransformPath(path, extensions = ['.ts', '.js']) {
|
|
|
97
178
|
return false; // 明确排除
|
|
98
179
|
}
|
|
99
180
|
}
|
|
100
|
-
|
|
181
|
+
|
|
101
182
|
// 3. 默认规则:排除所有 node_modules,除非明确 INCLUDE
|
|
102
183
|
if (actualPath.includes('/node_modules/')) {
|
|
103
184
|
return false;
|
|
104
185
|
}
|
|
105
|
-
|
|
186
|
+
|
|
106
187
|
return true;
|
|
107
188
|
}
|
|
108
189
|
|
package/loaders/tsx-loader.mjs
CHANGED
|
@@ -52,11 +52,12 @@ export async function load(url, context, nextLoad) {
|
|
|
52
52
|
// 转换相对路径的 import 语句
|
|
53
53
|
const transformed = transformImports(source, actualUrl, isHotReload, '__LOADER_TRANSFORMED__');
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
// 不使用 shortCircuit,让 tsx 继续处理 TypeScript 转译
|
|
56
|
+
return nextLoad(url, {
|
|
57
|
+
...context,
|
|
56
58
|
format: 'module',
|
|
57
59
|
source: transformed,
|
|
58
|
-
|
|
59
|
-
};
|
|
60
|
+
});
|
|
60
61
|
} catch (error) {
|
|
61
62
|
console.error('Loader error:', error);
|
|
62
63
|
return nextLoad(url, context);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zhin.js/dependency",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "A TypeScript dependency tree analyzer with ESM support",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -36,6 +36,11 @@
|
|
|
36
36
|
"@types/bun": "^1.2.0",
|
|
37
37
|
"typescript": "^5.3.0"
|
|
38
38
|
},
|
|
39
|
+
"repository": {
|
|
40
|
+
"type": "git",
|
|
41
|
+
"url": "git+https://github.com/zhinjs/zhin.git",
|
|
42
|
+
"directory": "basic/dependency"
|
|
43
|
+
},
|
|
39
44
|
"scripts": {
|
|
40
45
|
"build": "tsc",
|
|
41
46
|
"dev": "tsc --watch",
|