vite-plugin-performance 2.0.8 → 2.1.0

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/dist/index.d.ts CHANGED
@@ -1,77 +1,70 @@
1
- import { Plugin } from 'vite';
2
-
1
+ import { Plugin } from "vite";
3
2
  /**
4
3
  * @description Vite 插件 hook 名称
5
4
  */
6
- type PluginHookName = Extract<keyof Plugin, string>;
5
+ export type PluginHookName = Extract<keyof Plugin, string>;
7
6
  /**
8
7
  * @description hook 执行上下文
9
8
  */
10
- interface HookExecutionContext {
11
- pluginName: string;
12
- hookName: PluginHookName;
13
- args: unknown[];
14
- duration: number;
9
+ export interface HookExecutionContext {
10
+ pluginName: string;
11
+ hookName: PluginHookName;
12
+ args: unknown[];
13
+ duration: number;
15
14
  }
16
15
  /**
17
16
  * @description 日志输出函数
18
17
  */
19
- type HookLogger = (message: string, context: HookExecutionContext) => void;
18
+ export type HookLogger = (message: string, context: HookExecutionContext) => void;
20
19
  /**
21
20
  * @description 日志格式化函数
22
21
  */
23
- type HookFormatter = (context: HookExecutionContext) => string;
22
+ export type HookFormatter = (context: HookExecutionContext) => string;
24
23
  /**
25
24
  * @description 自定义计时函数
26
25
  */
27
- type HookClock = () => number;
28
- interface WrapPluginOptions {
29
- /** 仅包裹这些 hooks;传入 `all` 表示包裹插件上的所有函数 hook。 */
30
- hooks?: PluginHookName[] | 'all';
31
- /** 触发日志/通知的最小耗时(毫秒)。 */
32
- threshold?: number;
33
- /** 关闭默认日志输出。 */
34
- silent?: boolean;
35
- /** 自定义日志函数,默认使用 `console.log`。 */
36
- logger?: HookLogger;
37
- /** 自定义日志格式化函数。 */
38
- formatter?: HookFormatter;
39
- /** hook 执行完成后的回调。 */
40
- onHookExecution?: (context: HookExecutionContext) => void;
41
- /** 自定义高精度计时函数。 */
42
- clock?: HookClock;
43
- /** @deprecated 兼容旧拼写 */
44
- slient?: boolean;
26
+ export type HookClock = () => number;
27
+ export interface WrapPluginOptions {
28
+ /** 仅包裹这些 hooks;传入 `all` 表示包裹插件上的所有函数 hook。 */
29
+ hooks?: PluginHookName[] | 'all';
30
+ /** 触发日志/通知的最小耗时(毫秒)。 */
31
+ threshold?: number;
32
+ /** 关闭默认日志输出。 */
33
+ silent?: boolean;
34
+ /** 自定义日志函数,默认使用 `console.log`。 */
35
+ logger?: HookLogger;
36
+ /** 自定义日志格式化函数。 */
37
+ formatter?: HookFormatter;
38
+ /** hook 执行完成后的回调。 */
39
+ onHookExecution?: (context: HookExecutionContext) => void;
40
+ /** 自定义高精度计时函数。 */
41
+ clock?: HookClock;
42
+ /** @deprecated 兼容旧拼写 */
43
+ slient?: boolean;
45
44
  }
46
45
  /**
47
46
  * @description 解析后的插件配置
48
47
  */
49
- interface ResolvedWrapPluginOptions {
50
- hooks: PluginHookName[] | 'all';
51
- threshold: number;
52
- silent: boolean;
53
- logger: HookLogger;
54
- formatter: HookFormatter;
55
- onHookExecution?: (context: HookExecutionContext) => void;
56
- clock: HookClock;
48
+ export interface ResolvedWrapPluginOptions {
49
+ hooks: PluginHookName[] | 'all';
50
+ threshold: number;
51
+ silent: boolean;
52
+ logger: HookLogger;
53
+ formatter: HookFormatter;
54
+ onHookExecution?: (context: HookExecutionContext) => void;
55
+ clock: HookClock;
57
56
  }
58
-
59
57
  /**
60
58
  * @description 默认需要包裹的插件 hooks
61
59
  */
62
- declare const DEFAULT_PLUGIN_HOOKS: PluginHookName[];
60
+ export declare const DEFAULT_PLUGIN_HOOKS: PluginHookName[];
63
61
  /**
64
62
  * @description 默认耗时阈值(毫秒)
65
63
  */
66
- declare const DEFAULT_THRESHOLD = 0;
67
-
64
+ export declare const DEFAULT_THRESHOLD = 0;
68
65
  /**
69
66
  * @description 解析插件配置并补全默认值
70
67
  */
71
- declare function resolveOptions(options?: Partial<WrapPluginOptions>): ResolvedWrapPluginOptions;
72
-
73
- declare function wrapPlugin(maybePlugin: Plugin, options?: Partial<WrapPluginOptions>): Plugin;
74
- declare function wrapPlugin(maybePlugin: Plugin[], options?: Partial<WrapPluginOptions>): Plugin[];
75
-
76
- export { DEFAULT_PLUGIN_HOOKS, DEFAULT_THRESHOLD, resolveOptions, wrapPlugin };
77
- export type { HookClock, HookExecutionContext, HookFormatter, HookLogger, PluginHookName, ResolvedWrapPluginOptions, WrapPluginOptions };
68
+ export declare function resolveOptions(options?: Partial<WrapPluginOptions>): ResolvedWrapPluginOptions;
69
+ export declare function wrapPlugin(maybePlugin: Plugin, options?: Partial<WrapPluginOptions>): Plugin;
70
+ export declare function wrapPlugin(maybePlugin: Plugin[], options?: Partial<WrapPluginOptions>): Plugin[];
package/dist/index.mjs CHANGED
@@ -1,122 +1,143 @@
1
+ // src/constants.ts
2
+ /**
3
+ * @description 默认需要包裹的插件 hooks
4
+ */
1
5
  const DEFAULT_PLUGIN_HOOKS = [
2
- "options",
3
- "config",
4
- "configResolved",
5
- "configureServer",
6
- "buildStart",
7
- "resolveId",
8
- "load",
9
- "transform",
10
- "buildEnd",
11
- "generateBundle",
12
- "renderChunk",
13
- "writeBundle"
6
+ "options",
7
+ "config",
8
+ "configResolved",
9
+ "configureServer",
10
+ "buildStart",
11
+ "resolveId",
12
+ "load",
13
+ "transform",
14
+ "buildEnd",
15
+ "generateBundle",
16
+ "renderChunk",
17
+ "writeBundle"
14
18
  ];
19
+ /**
20
+ * @description 默认耗时阈值(毫秒)
21
+ */
15
22
  const DEFAULT_THRESHOLD = 0;
23
+ /**
24
+ * @description 未命名插件的默认名称
25
+ */
16
26
  const ANONYMOUS_PLUGIN_NAME = "anonymous-plugin";
27
+ /**
28
+ * @description 默认日志格式化器
29
+ */
17
30
  const DEFAULT_FORMATTER = ({ pluginName, hookName, duration }) => {
18
- const paddedHook = hookName.padEnd(20);
19
- const formattedDuration = duration.toFixed(2).padStart(7);
20
- return `[${pluginName}] ${paddedHook} \u23F1 ${formattedDuration} ms`;
31
+ return `[${pluginName}] ${hookName.padEnd(20)} ⏱ ${duration.toFixed(2).padStart(7)} ms`;
21
32
  };
33
+ /**
34
+ * @description 默认日志输出
35
+ */
22
36
  const DEFAULT_LOGGER = (message) => {
23
- console.log(message);
37
+ console.log(message);
24
38
  };
25
-
26
- const hasPerformanceNow = typeof globalThis !== "undefined" && typeof globalThis.performance?.now === "function";
27
- const defaultClock = hasPerformanceNow ? () => globalThis.performance.now() : () => Date.now();
39
+ // src/options.ts
40
+ const defaultClock = typeof globalThis !== "undefined" && typeof globalThis.performance?.now === "function" ? () => globalThis.performance.now() : () => Date.now();
41
+ /**
42
+ * @description 解析插件配置并补全默认值
43
+ */
28
44
  function resolveOptions(options = {}) {
29
- const {
30
- hooks = DEFAULT_PLUGIN_HOOKS,
31
- threshold = DEFAULT_THRESHOLD,
32
- silent = options.slient ?? false,
33
- logger = DEFAULT_LOGGER,
34
- formatter = DEFAULT_FORMATTER,
35
- onHookExecution,
36
- clock = defaultClock
37
- } = options;
38
- return {
39
- hooks,
40
- threshold,
41
- silent,
42
- logger,
43
- formatter,
44
- onHookExecution,
45
- clock
46
- };
45
+ const { hooks = DEFAULT_PLUGIN_HOOKS, threshold = 0, silent = options.slient ?? false, logger = DEFAULT_LOGGER, formatter = DEFAULT_FORMATTER, onHookExecution, clock = defaultClock } = options;
46
+ return {
47
+ hooks,
48
+ threshold,
49
+ silent,
50
+ logger,
51
+ formatter,
52
+ onHookExecution,
53
+ clock
54
+ };
47
55
  }
56
+ /**
57
+ * @description 解析插件名称(为空时回退默认值)
58
+ */
48
59
  function resolvePluginName(rawName) {
49
- return rawName && rawName.length > 0 ? rawName : ANONYMOUS_PLUGIN_NAME;
60
+ return rawName && rawName.length > 0 ? rawName : ANONYMOUS_PLUGIN_NAME;
50
61
  }
51
-
62
+ // src/utils.ts
63
+ /**
64
+ * @description 统一为数组
65
+ */
52
66
  function ensureArray(value) {
53
- return Array.isArray(value) ? value : [value];
67
+ return Array.isArray(value) ? value : [value];
54
68
  }
69
+ /**
70
+ * @description 判断是否为 Promise-like
71
+ */
55
72
  function isPromiseLike(value) {
56
- return typeof value === "object" && value !== null && "then" in value;
73
+ return typeof value === "object" && value !== null && "then" in value;
57
74
  }
58
-
75
+ // src/wrapPlugin.ts
59
76
  function resolveHooks(plugin, hooks) {
60
- if (hooks === "all") {
61
- return Object.keys(plugin).filter((key) => typeof plugin[key] === "function");
62
- }
63
- return [...hooks];
77
+ if (hooks === "all") return Object.keys(plugin).filter((key) => typeof plugin[key] === "function");
78
+ return [...hooks];
64
79
  }
65
80
  function reportExecution(params) {
66
- const { pluginName, hookName, args, start, options } = params;
67
- const duration = Math.max(0, options.clock() - start);
68
- const context = {
69
- pluginName,
70
- hookName,
71
- args,
72
- duration
73
- };
74
- if (duration >= options.threshold) {
75
- if (!options.silent) {
76
- const message = options.formatter(context);
77
- options.logger(message, context);
78
- }
79
- options.onHookExecution?.(context);
80
- }
81
+ const { pluginName, hookName, args, start, options } = params;
82
+ const duration = Math.max(0, options.clock() - start);
83
+ const context = {
84
+ pluginName,
85
+ hookName,
86
+ args,
87
+ duration
88
+ };
89
+ if (duration >= options.threshold) {
90
+ if (!options.silent) {
91
+ const message = options.formatter(context);
92
+ options.logger(message, context);
93
+ }
94
+ options.onHookExecution?.(context);
95
+ }
81
96
  }
82
97
  function wrapSinglePlugin(plugin, options) {
83
- const wrapped = { ...plugin };
84
- const pluginName = resolvePluginName(plugin.name);
85
- const hooksToWrap = resolveHooks(plugin, options.hooks);
86
- for (const hookName of hooksToWrap) {
87
- const original = plugin[hookName];
88
- if (typeof original !== "function") {
89
- continue;
90
- }
91
- wrapped[hookName] = function performanceHook(...args) {
92
- const start = options.clock();
93
- const invoke = () => original.apply(this, args);
94
- const finalize = (result) => {
95
- reportExecution({ pluginName, hookName, args, start, options });
96
- return result;
97
- };
98
- const handleError = (error) => {
99
- reportExecution({ pluginName, hookName, args, start, options });
100
- throw error;
101
- };
102
- try {
103
- const result = invoke();
104
- if (isPromiseLike(result)) {
105
- return result.then(finalize, handleError);
106
- }
107
- return finalize(result);
108
- } catch (error) {
109
- return handleError(error);
110
- }
111
- };
112
- }
113
- return wrapped;
98
+ const wrapped = { ...plugin };
99
+ const pluginName = resolvePluginName(plugin.name);
100
+ const hooksToWrap = resolveHooks(plugin, options.hooks);
101
+ for (const hookName of hooksToWrap) {
102
+ const original = plugin[hookName];
103
+ if (typeof original !== "function") continue;
104
+ wrapped[hookName] = function performanceHook(...args) {
105
+ const start = options.clock();
106
+ const invoke = () => original.apply(this, args);
107
+ const finalize = (result) => {
108
+ reportExecution({
109
+ pluginName,
110
+ hookName,
111
+ args,
112
+ start,
113
+ options
114
+ });
115
+ return result;
116
+ };
117
+ const handleError = (error) => {
118
+ reportExecution({
119
+ pluginName,
120
+ hookName,
121
+ args,
122
+ start,
123
+ options
124
+ });
125
+ throw error;
126
+ };
127
+ try {
128
+ const result = invoke();
129
+ if (isPromiseLike(result)) return result.then(finalize, handleError);
130
+ return finalize(result);
131
+ } catch (error) {
132
+ return handleError(error);
133
+ }
134
+ };
135
+ }
136
+ return wrapped;
114
137
  }
115
138
  function wrapPlugin(maybePlugin, options) {
116
- const resolvedOptions = resolveOptions(options);
117
- const plugins = ensureArray(maybePlugin);
118
- const wrapped = plugins.map((plugin) => wrapSinglePlugin(plugin, resolvedOptions));
119
- return Array.isArray(maybePlugin) ? wrapped : wrapped[0];
139
+ const resolvedOptions = resolveOptions(options);
140
+ const wrapped = ensureArray(maybePlugin).map((plugin) => wrapSinglePlugin(plugin, resolvedOptions));
141
+ return Array.isArray(maybePlugin) ? wrapped : wrapped[0];
120
142
  }
121
-
122
143
  export { DEFAULT_PLUGIN_HOOKS, DEFAULT_THRESHOLD, resolveOptions, wrapPlugin };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "vite-plugin-performance",
3
3
  "type": "module",
4
- "version": "2.0.8",
4
+ "version": "2.1.0",
5
5
  "description": "vite-plugin-performance tools and runtime components for modern WeChat and multi-platform mini-program development.",
6
6
  "author": "ice breaker <1324318532@qq.com>",
7
7
  "license": "MIT",
@@ -37,16 +37,16 @@
37
37
  "dist"
38
38
  ],
39
39
  "engines": {
40
- "node": "^20.19.0 || >=22.12.0"
40
+ "node": "^22.23.4 || ^24.22.1 || >=26.12.1"
41
41
  },
42
42
  "publishConfig": {
43
43
  "access": "public",
44
44
  "registry": "https://registry.npmjs.org"
45
45
  },
46
46
  "scripts": {
47
- "dev": "unbuild --stub",
48
- "build:watch": "unbuild --watch --sourcemap",
49
- "build": "unbuild",
47
+ "dev": "tsdown -w --sourcemap",
48
+ "build:watch": "tsdown -w --sourcemap",
49
+ "build": "tsdown",
50
50
  "test": "vitest run",
51
51
  "test:dev": "vitest",
52
52
  "typecheck": "tsc --noEmit",
package/dist/index.d.mts DELETED
@@ -1,77 +0,0 @@
1
- import { Plugin } from 'vite';
2
-
3
- /**
4
- * @description Vite 插件 hook 名称
5
- */
6
- type PluginHookName = Extract<keyof Plugin, string>;
7
- /**
8
- * @description hook 执行上下文
9
- */
10
- interface HookExecutionContext {
11
- pluginName: string;
12
- hookName: PluginHookName;
13
- args: unknown[];
14
- duration: number;
15
- }
16
- /**
17
- * @description 日志输出函数
18
- */
19
- type HookLogger = (message: string, context: HookExecutionContext) => void;
20
- /**
21
- * @description 日志格式化函数
22
- */
23
- type HookFormatter = (context: HookExecutionContext) => string;
24
- /**
25
- * @description 自定义计时函数
26
- */
27
- type HookClock = () => number;
28
- interface WrapPluginOptions {
29
- /** 仅包裹这些 hooks;传入 `all` 表示包裹插件上的所有函数 hook。 */
30
- hooks?: PluginHookName[] | 'all';
31
- /** 触发日志/通知的最小耗时(毫秒)。 */
32
- threshold?: number;
33
- /** 关闭默认日志输出。 */
34
- silent?: boolean;
35
- /** 自定义日志函数,默认使用 `console.log`。 */
36
- logger?: HookLogger;
37
- /** 自定义日志格式化函数。 */
38
- formatter?: HookFormatter;
39
- /** hook 执行完成后的回调。 */
40
- onHookExecution?: (context: HookExecutionContext) => void;
41
- /** 自定义高精度计时函数。 */
42
- clock?: HookClock;
43
- /** @deprecated 兼容旧拼写 */
44
- slient?: boolean;
45
- }
46
- /**
47
- * @description 解析后的插件配置
48
- */
49
- interface ResolvedWrapPluginOptions {
50
- hooks: PluginHookName[] | 'all';
51
- threshold: number;
52
- silent: boolean;
53
- logger: HookLogger;
54
- formatter: HookFormatter;
55
- onHookExecution?: (context: HookExecutionContext) => void;
56
- clock: HookClock;
57
- }
58
-
59
- /**
60
- * @description 默认需要包裹的插件 hooks
61
- */
62
- declare const DEFAULT_PLUGIN_HOOKS: PluginHookName[];
63
- /**
64
- * @description 默认耗时阈值(毫秒)
65
- */
66
- declare const DEFAULT_THRESHOLD = 0;
67
-
68
- /**
69
- * @description 解析插件配置并补全默认值
70
- */
71
- declare function resolveOptions(options?: Partial<WrapPluginOptions>): ResolvedWrapPluginOptions;
72
-
73
- declare function wrapPlugin(maybePlugin: Plugin, options?: Partial<WrapPluginOptions>): Plugin;
74
- declare function wrapPlugin(maybePlugin: Plugin[], options?: Partial<WrapPluginOptions>): Plugin[];
75
-
76
- export { DEFAULT_PLUGIN_HOOKS, DEFAULT_THRESHOLD, resolveOptions, wrapPlugin };
77
- export type { HookClock, HookExecutionContext, HookFormatter, HookLogger, PluginHookName, ResolvedWrapPluginOptions, WrapPluginOptions };