@bleedingdev/modern-js-plugin 3.2.0-ultramodern.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.
Files changed (217) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +26 -0
  3. package/dist/cjs/cli/api.js +119 -0
  4. package/dist/cjs/cli/context.js +85 -0
  5. package/dist/cjs/cli/hooks.js +65 -0
  6. package/dist/cjs/cli/index.js +71 -0
  7. package/dist/cjs/cli/run/config/createLoadedConfig.js +87 -0
  8. package/dist/cjs/cli/run/config/createResolvedConfig.js +48 -0
  9. package/dist/cjs/cli/run/config/loadConfig.js +113 -0
  10. package/dist/cjs/cli/run/create.js +198 -0
  11. package/dist/cjs/cli/run/index.js +56 -0
  12. package/dist/cjs/cli/run/run.js +57 -0
  13. package/dist/cjs/cli/run/types.js +18 -0
  14. package/dist/cjs/cli/run/utils/checkIsDuplicationPlugin.js +45 -0
  15. package/dist/cjs/cli/run/utils/commander.js +56 -0
  16. package/dist/cjs/cli/run/utils/createFileWatcher.js +112 -0
  17. package/dist/cjs/cli/run/utils/debug.js +37 -0
  18. package/dist/cjs/cli/run/utils/initAppDir.js +55 -0
  19. package/dist/cjs/cli/run/utils/mergeConfig.js +66 -0
  20. package/dist/cjs/hooks.js +169 -0
  21. package/dist/cjs/index.js +55 -0
  22. package/dist/cjs/manager.js +135 -0
  23. package/dist/cjs/runtime/api.js +95 -0
  24. package/dist/cjs/runtime/context.js +60 -0
  25. package/dist/cjs/runtime/hooks.js +46 -0
  26. package/dist/cjs/runtime/index.js +51 -0
  27. package/dist/cjs/runtime/run/create.js +79 -0
  28. package/dist/cjs/runtime/run/index.js +37 -0
  29. package/dist/cjs/runtime/run/types.js +18 -0
  30. package/dist/cjs/server/api.js +96 -0
  31. package/dist/cjs/server/context.js +75 -0
  32. package/dist/cjs/server/hooks.js +43 -0
  33. package/dist/cjs/server/index.js +54 -0
  34. package/dist/cjs/server/run/create.js +79 -0
  35. package/dist/cjs/server/run/index.js +40 -0
  36. package/dist/cjs/server/run/types.js +18 -0
  37. package/dist/cjs/types/cli/api.js +18 -0
  38. package/dist/cjs/types/cli/context.js +18 -0
  39. package/dist/cjs/types/cli/hooks.js +18 -0
  40. package/dist/cjs/types/cli/index.js +18 -0
  41. package/dist/cjs/types/cli/plugin.js +18 -0
  42. package/dist/cjs/types/hooks.js +18 -0
  43. package/dist/cjs/types/index.js +18 -0
  44. package/dist/cjs/types/plugin.js +18 -0
  45. package/dist/cjs/types/runtime/api.js +18 -0
  46. package/dist/cjs/types/runtime/context.js +18 -0
  47. package/dist/cjs/types/runtime/hooks.js +18 -0
  48. package/dist/cjs/types/runtime/index.js +18 -0
  49. package/dist/cjs/types/runtime/plugin.js +18 -0
  50. package/dist/cjs/types/server/api.js +18 -0
  51. package/dist/cjs/types/server/context.js +18 -0
  52. package/dist/cjs/types/server/hooks.js +18 -0
  53. package/dist/cjs/types/server/index.js +18 -0
  54. package/dist/cjs/types/server/plugin.js +18 -0
  55. package/dist/cjs/types/utils.js +18 -0
  56. package/dist/esm/cli/api.mjs +85 -0
  57. package/dist/esm/cli/context.mjs +38 -0
  58. package/dist/esm/cli/hooks.mjs +31 -0
  59. package/dist/esm/cli/index.mjs +6 -0
  60. package/dist/esm/cli/run/config/createLoadedConfig.mjs +53 -0
  61. package/dist/esm/cli/run/config/createResolvedConfig.mjs +14 -0
  62. package/dist/esm/cli/run/config/loadConfig.mjs +60 -0
  63. package/dist/esm/cli/run/create.mjs +158 -0
  64. package/dist/esm/cli/run/index.mjs +7 -0
  65. package/dist/esm/cli/run/run.mjs +23 -0
  66. package/dist/esm/cli/run/types.mjs +0 -0
  67. package/dist/esm/cli/run/utils/checkIsDuplicationPlugin.mjs +11 -0
  68. package/dist/esm/cli/run/utils/commander.mjs +16 -0
  69. package/dist/esm/cli/run/utils/createFileWatcher.mjs +68 -0
  70. package/dist/esm/cli/run/utils/debug.mjs +3 -0
  71. package/dist/esm/cli/run/utils/initAppDir.mjs +11 -0
  72. package/dist/esm/cli/run/utils/mergeConfig.mjs +32 -0
  73. package/dist/esm/hooks.mjs +120 -0
  74. package/dist/esm/index.mjs +2 -0
  75. package/dist/esm/manager.mjs +101 -0
  76. package/dist/esm/runtime/api.mjs +61 -0
  77. package/dist/esm/runtime/context.mjs +23 -0
  78. package/dist/esm/runtime/hooks.mjs +12 -0
  79. package/dist/esm/runtime/index.mjs +4 -0
  80. package/dist/esm/runtime/run/create.mjs +45 -0
  81. package/dist/esm/runtime/run/index.mjs +3 -0
  82. package/dist/esm/runtime/run/types.mjs +0 -0
  83. package/dist/esm/server/api.mjs +59 -0
  84. package/dist/esm/server/context.mjs +38 -0
  85. package/dist/esm/server/hooks.mjs +9 -0
  86. package/dist/esm/server/index.mjs +4 -0
  87. package/dist/esm/server/run/create.mjs +45 -0
  88. package/dist/esm/server/run/index.mjs +3 -0
  89. package/dist/esm/server/run/types.mjs +0 -0
  90. package/dist/esm/types/cli/api.mjs +0 -0
  91. package/dist/esm/types/cli/context.mjs +0 -0
  92. package/dist/esm/types/cli/hooks.mjs +0 -0
  93. package/dist/esm/types/cli/index.mjs +0 -0
  94. package/dist/esm/types/cli/plugin.mjs +0 -0
  95. package/dist/esm/types/hooks.mjs +0 -0
  96. package/dist/esm/types/index.mjs +0 -0
  97. package/dist/esm/types/plugin.mjs +0 -0
  98. package/dist/esm/types/runtime/api.mjs +0 -0
  99. package/dist/esm/types/runtime/context.mjs +0 -0
  100. package/dist/esm/types/runtime/hooks.mjs +0 -0
  101. package/dist/esm/types/runtime/index.mjs +0 -0
  102. package/dist/esm/types/runtime/plugin.mjs +0 -0
  103. package/dist/esm/types/server/api.mjs +0 -0
  104. package/dist/esm/types/server/context.mjs +0 -0
  105. package/dist/esm/types/server/hooks.mjs +0 -0
  106. package/dist/esm/types/server/index.mjs +0 -0
  107. package/dist/esm/types/server/plugin.mjs +0 -0
  108. package/dist/esm/types/utils.mjs +0 -0
  109. package/dist/esm-node/cli/api.mjs +86 -0
  110. package/dist/esm-node/cli/context.mjs +39 -0
  111. package/dist/esm-node/cli/hooks.mjs +32 -0
  112. package/dist/esm-node/cli/index.mjs +7 -0
  113. package/dist/esm-node/cli/run/config/createLoadedConfig.mjs +54 -0
  114. package/dist/esm-node/cli/run/config/createResolvedConfig.mjs +15 -0
  115. package/dist/esm-node/cli/run/config/loadConfig.mjs +63 -0
  116. package/dist/esm-node/cli/run/create.mjs +159 -0
  117. package/dist/esm-node/cli/run/index.mjs +8 -0
  118. package/dist/esm-node/cli/run/run.mjs +24 -0
  119. package/dist/esm-node/cli/run/types.mjs +1 -0
  120. package/dist/esm-node/cli/run/utils/checkIsDuplicationPlugin.mjs +12 -0
  121. package/dist/esm-node/cli/run/utils/commander.mjs +17 -0
  122. package/dist/esm-node/cli/run/utils/createFileWatcher.mjs +69 -0
  123. package/dist/esm-node/cli/run/utils/debug.mjs +4 -0
  124. package/dist/esm-node/cli/run/utils/initAppDir.mjs +12 -0
  125. package/dist/esm-node/cli/run/utils/mergeConfig.mjs +33 -0
  126. package/dist/esm-node/hooks.mjs +121 -0
  127. package/dist/esm-node/index.mjs +3 -0
  128. package/dist/esm-node/manager.mjs +102 -0
  129. package/dist/esm-node/runtime/api.mjs +62 -0
  130. package/dist/esm-node/runtime/context.mjs +24 -0
  131. package/dist/esm-node/runtime/hooks.mjs +13 -0
  132. package/dist/esm-node/runtime/index.mjs +5 -0
  133. package/dist/esm-node/runtime/run/create.mjs +46 -0
  134. package/dist/esm-node/runtime/run/index.mjs +4 -0
  135. package/dist/esm-node/runtime/run/types.mjs +1 -0
  136. package/dist/esm-node/server/api.mjs +60 -0
  137. package/dist/esm-node/server/context.mjs +39 -0
  138. package/dist/esm-node/server/hooks.mjs +10 -0
  139. package/dist/esm-node/server/index.mjs +5 -0
  140. package/dist/esm-node/server/run/create.mjs +46 -0
  141. package/dist/esm-node/server/run/index.mjs +4 -0
  142. package/dist/esm-node/server/run/types.mjs +1 -0
  143. package/dist/esm-node/types/cli/api.mjs +1 -0
  144. package/dist/esm-node/types/cli/context.mjs +1 -0
  145. package/dist/esm-node/types/cli/hooks.mjs +1 -0
  146. package/dist/esm-node/types/cli/index.mjs +1 -0
  147. package/dist/esm-node/types/cli/plugin.mjs +1 -0
  148. package/dist/esm-node/types/hooks.mjs +1 -0
  149. package/dist/esm-node/types/index.mjs +1 -0
  150. package/dist/esm-node/types/plugin.mjs +1 -0
  151. package/dist/esm-node/types/runtime/api.mjs +1 -0
  152. package/dist/esm-node/types/runtime/context.mjs +1 -0
  153. package/dist/esm-node/types/runtime/hooks.mjs +1 -0
  154. package/dist/esm-node/types/runtime/index.mjs +1 -0
  155. package/dist/esm-node/types/runtime/plugin.mjs +1 -0
  156. package/dist/esm-node/types/server/api.mjs +1 -0
  157. package/dist/esm-node/types/server/context.mjs +1 -0
  158. package/dist/esm-node/types/server/hooks.mjs +1 -0
  159. package/dist/esm-node/types/server/index.mjs +1 -0
  160. package/dist/esm-node/types/server/plugin.mjs +1 -0
  161. package/dist/esm-node/types/utils.mjs +1 -0
  162. package/dist/types/cli/api.d.ts +8 -0
  163. package/dist/types/cli/context.d.ts +19 -0
  164. package/dist/types/cli/hooks.d.ts +42 -0
  165. package/dist/types/cli/index.d.ts +6 -0
  166. package/dist/types/cli/run/config/createLoadedConfig.d.ts +2 -0
  167. package/dist/types/cli/run/config/createResolvedConfig.d.ts +3 -0
  168. package/dist/types/cli/run/config/loadConfig.d.ts +25 -0
  169. package/dist/types/cli/run/create.d.ts +24 -0
  170. package/dist/types/cli/run/index.d.ts +13 -0
  171. package/dist/types/cli/run/run.d.ts +2 -0
  172. package/dist/types/cli/run/types.d.ts +32 -0
  173. package/dist/types/cli/run/utils/checkIsDuplicationPlugin.d.ts +1 -0
  174. package/dist/types/cli/run/utils/commander.d.ts +5 -0
  175. package/dist/types/cli/run/utils/createFileWatcher.d.ts +3 -0
  176. package/dist/types/cli/run/utils/debug.d.ts +1 -0
  177. package/dist/types/cli/run/utils/initAppDir.d.ts +1 -0
  178. package/dist/types/cli/run/utils/mergeConfig.d.ts +2 -0
  179. package/dist/types/hooks.d.ts +7 -0
  180. package/dist/types/index.d.ts +7 -0
  181. package/dist/types/manager.d.ts +5 -0
  182. package/dist/types/runtime/api.d.ts +9 -0
  183. package/dist/types/runtime/context.d.ts +11 -0
  184. package/dist/types/runtime/hooks.d.ts +2 -0
  185. package/dist/types/runtime/index.d.ts +5 -0
  186. package/dist/types/runtime/run/create.d.ts +7 -0
  187. package/dist/types/runtime/run/index.d.ts +5 -0
  188. package/dist/types/runtime/run/types.d.ts +6 -0
  189. package/dist/types/server/api.d.ts +9 -0
  190. package/dist/types/server/context.d.ts +13 -0
  191. package/dist/types/server/hooks.d.ts +9 -0
  192. package/dist/types/server/index.d.ts +4 -0
  193. package/dist/types/server/run/create.d.ts +7 -0
  194. package/dist/types/server/run/index.d.ts +8 -0
  195. package/dist/types/server/run/types.d.ts +22 -0
  196. package/dist/types/types/cli/api.d.ts +49 -0
  197. package/dist/types/types/cli/context.d.ts +42 -0
  198. package/dist/types/types/cli/hooks.d.ts +72 -0
  199. package/dist/types/types/cli/index.d.ts +4 -0
  200. package/dist/types/types/cli/plugin.d.ts +17 -0
  201. package/dist/types/types/hooks.d.ts +27 -0
  202. package/dist/types/types/index.d.ts +4 -0
  203. package/dist/types/types/plugin.d.ts +45 -0
  204. package/dist/types/types/runtime/api.d.ts +21 -0
  205. package/dist/types/types/runtime/context.d.ts +13 -0
  206. package/dist/types/types/runtime/hooks.d.ts +39 -0
  207. package/dist/types/types/runtime/index.d.ts +4 -0
  208. package/dist/types/types/runtime/plugin.d.ts +14 -0
  209. package/dist/types/types/server/api.d.ts +19 -0
  210. package/dist/types/types/server/context.d.ts +28 -0
  211. package/dist/types/types/server/hooks.d.ts +24 -0
  212. package/dist/types/types/server/index.d.ts +4 -0
  213. package/dist/types/types/server/plugin.d.ts +14 -0
  214. package/dist/types/types/utils.d.ts +7 -0
  215. package/package.json +111 -0
  216. package/rslib.config.mts +4 -0
  217. package/rstest.config.mts +5 -0
@@ -0,0 +1,159 @@
1
+ import "node:module";
2
+ import { createDebugger, logger } from "@modern-js/utils";
3
+ import { program } from "@modern-js/utils/commander";
4
+ import { loadEnv } from "@rsbuild/core";
5
+ import { createPluginManager } from "../../manager.mjs";
6
+ import { initPluginAPI } from "../api.mjs";
7
+ import { createContext, initAppContext } from "../context.mjs";
8
+ import { createLoadedConfig } from "./config/createLoadedConfig.mjs";
9
+ import { createResolveConfig } from "./config/createResolvedConfig.mjs";
10
+ import { checkIsDuplicationPlugin } from "./utils/checkIsDuplicationPlugin.mjs";
11
+ import { initCommandsMap, setProgramVersion } from "./utils/commander.mjs";
12
+ import { createFileWatcher } from "./utils/createFileWatcher.mjs";
13
+ import { initAppDir } from "./utils/initAppDir.mjs";
14
+ const debug = createDebugger('plugin');
15
+ const createCli = ()=>{
16
+ let initOptions;
17
+ const pluginManager = createPluginManager();
18
+ const existListenerMap = new Map();
19
+ function createExistListener(event, context) {
20
+ return async function(err) {
21
+ await context.hooks.onBeforeExit.call();
22
+ let hasError = false;
23
+ if (err instanceof Error) {
24
+ logger.error(err.stack);
25
+ hasError = true;
26
+ } else if (err && ('unhandledRejection' === event || 'uncaughtException' === event)) {
27
+ console.trace('Unknown Error', err);
28
+ hasError = true;
29
+ }
30
+ process.nextTick(()=>{
31
+ process.exit(hasError ? 1 : 0);
32
+ });
33
+ };
34
+ }
35
+ async function init(options) {
36
+ pluginManager.clear();
37
+ initOptions = options;
38
+ const { metaName = 'modern-js', configFile, config, command, version, internalPlugins, handleSetupResult } = options;
39
+ const appDirectory = await initAppDir(options?.cwd);
40
+ initCommandsMap();
41
+ setProgramVersion(version);
42
+ const envName = 'modern-js' === metaName ? 'MODERN' : metaName;
43
+ loadEnv({
44
+ cwd: appDirectory,
45
+ mode: process.env[`${envName.toUpperCase()}_ENV`] || process.env.NODE_ENV,
46
+ prefixes: [
47
+ `${envName.toUpperCase()}_`
48
+ ]
49
+ });
50
+ const loaded = await createLoadedConfig(appDirectory, configFile, config);
51
+ const allPlugins = [
52
+ ...internalPlugins || [],
53
+ ...loaded.config.plugins || []
54
+ ];
55
+ checkIsDuplicationPlugin(allPlugins.map((plugin)=>plugin.name));
56
+ pluginManager.addPlugins(allPlugins);
57
+ const plugins = await pluginManager.getPlugins();
58
+ debug('CLI Plugins:', plugins.map((p)=>p.name));
59
+ const context = await createContext({
60
+ appContext: initAppContext({
61
+ packageName: loaded.packageName,
62
+ configFile: loaded.configFile,
63
+ command: command,
64
+ appDirectory,
65
+ plugins,
66
+ metaName
67
+ }),
68
+ config: loaded.config,
69
+ normalizedConfig: {}
70
+ });
71
+ const pluginAPI = initPluginAPI({
72
+ context,
73
+ pluginManager
74
+ });
75
+ context.pluginAPI = pluginAPI;
76
+ for (const plugin of plugins){
77
+ const setupResult = await plugin.setup?.(pluginAPI);
78
+ if (handleSetupResult) await handleSetupResult(setupResult, pluginAPI);
79
+ }
80
+ [
81
+ 'SIGINT',
82
+ 'SIGTERM',
83
+ 'unhandledRejection',
84
+ 'uncaughtException'
85
+ ].forEach((event)=>{
86
+ if (existListenerMap.get(event)) process.off(event, existListenerMap.get(event));
87
+ const existListener = createExistListener(event, context);
88
+ existListenerMap.set(event, existListener);
89
+ process.on(event, existListener);
90
+ });
91
+ const extraConfigs = await context.hooks.config.call();
92
+ const normalizedConfig = await createResolveConfig(loaded, extraConfigs);
93
+ const resolved = await context.hooks.modifyResolvedConfig.call(normalizedConfig);
94
+ context.normalizedConfig = resolved || normalizedConfig;
95
+ await pluginAPI.updateAppContext(context);
96
+ await context.hooks.onPrepare.call();
97
+ await context.hooks?.onAfterPrepare?.call();
98
+ return {
99
+ appContext: context
100
+ };
101
+ }
102
+ async function run(options) {
103
+ const { appContext } = await init(options);
104
+ await appContext.hooks.addCommand.call({
105
+ program: program
106
+ });
107
+ await createFileWatcher(appContext);
108
+ program.parse(process.argv);
109
+ if (!program.commands?.length) logger.warn('No command found, please make sure you have registered plugins correctly.');
110
+ }
111
+ return {
112
+ init,
113
+ run,
114
+ getPrevInitOptions: ()=>initOptions
115
+ };
116
+ };
117
+ const createConfigOptions = async (options)=>{
118
+ const pluginManager = createPluginManager();
119
+ pluginManager.clear();
120
+ const { configFile, cwd, metaName = 'modern-js', command } = options;
121
+ const appDirectory = await initAppDir(cwd);
122
+ const loaded = await createLoadedConfig(appDirectory, configFile, options.config);
123
+ loaded.config = options.modifyModernConfig ? await options.modifyModernConfig(loaded.config || {}) : loaded.config;
124
+ pluginManager.addPlugins(loaded.config.plugins || []);
125
+ const plugins = await pluginManager.getPlugins();
126
+ const context = await createContext({
127
+ appContext: initAppContext({
128
+ packageName: loaded.packageName,
129
+ configFile: loaded.configFile,
130
+ appDirectory,
131
+ command,
132
+ plugins,
133
+ metaName
134
+ }),
135
+ config: loaded.config,
136
+ normalizedConfig: {}
137
+ });
138
+ const pluginAPI = initPluginAPI({
139
+ context,
140
+ pluginManager
141
+ });
142
+ context.pluginAPI = pluginAPI;
143
+ for (const plugin of plugins)await plugin.setup?.(pluginAPI);
144
+ const extraConfigs = await context.hooks.config.call();
145
+ const normalizedConfig = await createResolveConfig(loaded, extraConfigs);
146
+ const resolved = await context.hooks.modifyResolvedConfig.call(normalizedConfig);
147
+ const finalConfig = resolved || normalizedConfig;
148
+ context.normalizedConfig = finalConfig;
149
+ await pluginAPI.updateAppContext(context);
150
+ return {
151
+ config: finalConfig,
152
+ getAppContext: ()=>pluginAPI.getAppContext()
153
+ };
154
+ };
155
+ const createStorybookOptions = (options)=>createConfigOptions({
156
+ ...options,
157
+ command: 'storybook'
158
+ });
159
+ export { createCli, createConfigOptions, createStorybookOptions };
@@ -0,0 +1,8 @@
1
+ import "node:module";
2
+ import { createCli } from "./create.mjs";
3
+ const cli = createCli();
4
+ export { createLoadedConfig } from "./config/createLoadedConfig.mjs";
5
+ export { loadTypeScriptFile } from "./config/loadConfig.mjs";
6
+ export { run } from "./run.mjs";
7
+ export { initAppDir } from "./utils/initAppDir.mjs";
8
+ export { cli, createCli };
@@ -0,0 +1,24 @@
1
+ import "node:module";
2
+ import { logger } from "@modern-js/utils";
3
+ import { cli } from "./index.mjs";
4
+ const run = async (options)=>{
5
+ const { initialLog, version, cwd, configFile, ...params } = options;
6
+ if (initialLog) logger.greet(` ${initialLog}\n`);
7
+ const command = process.argv[2];
8
+ if (!process.env.NODE_ENV) if ([
9
+ 'build',
10
+ 'serve',
11
+ 'deploy',
12
+ 'analyze'
13
+ ].includes(command)) process.env.NODE_ENV = 'production';
14
+ else if ('test' === command) process.env.NODE_ENV = 'test';
15
+ else process.env.NODE_ENV = 'development';
16
+ await cli.run({
17
+ version,
18
+ cwd,
19
+ command,
20
+ configFile,
21
+ ...params
22
+ });
23
+ };
24
+ export { run };
@@ -0,0 +1 @@
1
+ import "node:module";
@@ -0,0 +1,12 @@
1
+ import "node:module";
2
+ import { logger } from "@modern-js/utils";
3
+ function checkIsDuplicationPlugin(plugins) {
4
+ const set = new Set();
5
+ const duplicationPlugins = [];
6
+ plugins.filter((plugin)=>'string' == typeof plugin).forEach((plugin)=>{
7
+ if (set.has(plugin)) duplicationPlugins.push(plugin);
8
+ else set.add(plugin);
9
+ });
10
+ if (duplicationPlugins.length > 0) logger.warn(`Duplicate registration plugins: ${duplicationPlugins.join(',')}.`);
11
+ }
12
+ export { checkIsDuplicationPlugin };
@@ -0,0 +1,17 @@
1
+ import "node:module";
2
+ import { program } from "@modern-js/utils";
3
+ const setProgramVersion = (version = 'unknown')=>{
4
+ const name = process.argv[1];
5
+ program.name(name).usage('<command> [options]').version(version);
6
+ };
7
+ function initCommandsMap() {
8
+ if (!program.hasOwnProperty('commandsMap')) Object.defineProperty(program, 'commandsMap', {
9
+ get () {
10
+ const map = new Map();
11
+ for (const command of program.commands)map.set(command._name, command);
12
+ return map;
13
+ },
14
+ configurable: false
15
+ });
16
+ }
17
+ export { initCommandsMap, program, setProgramVersion };
@@ -0,0 +1,69 @@
1
+ import "node:module";
2
+ import { chokidar, createDebugger, isDevCommand } from "@modern-js/utils";
3
+ import crypto_0 from "crypto";
4
+ import * as __rspack_external_fs from "fs";
5
+ import * as __rspack_external_path from "path";
6
+ const debug = createDebugger('watch-files');
7
+ const hashMap = new Map();
8
+ const md5 = (data)=>crypto_0.createHash('md5').update(data).digest('hex');
9
+ const createFileWatcher = async (appContext)=>{
10
+ if (isDevCommand()) {
11
+ const { appDirectory } = appContext;
12
+ const extraFiles = await appContext.hooks.addWatchFiles.call();
13
+ const watched = extraFiles.filter((extra)=>Array.isArray(extra)).flat();
14
+ const privateWatched = extraFiles.filter((extra)=>!Array.isArray(extra) && extra.isPrivate).map((extra)=>extra.files).flat();
15
+ const isPrivate = (filename)=>privateWatched.some((ff)=>__rspack_external_path.resolve(appDirectory, filename).startsWith(ff));
16
+ debug("watched: %o", watched);
17
+ const watcher = chokidar.watch([
18
+ ...watched,
19
+ ...privateWatched
20
+ ], {
21
+ cwd: appDirectory,
22
+ ignoreInitial: true,
23
+ ignorePermissionErrors: true,
24
+ ignored: [
25
+ '**/__test__/**',
26
+ '**/*.test.(js|jsx|ts|tsx)',
27
+ '**/*.spec.(js|jsx|ts|tsx)',
28
+ '**/*.stories.(js|jsx|ts|tsx)'
29
+ ]
30
+ });
31
+ watcher.on('change', (changed)=>{
32
+ const lastHash = hashMap.get(changed);
33
+ const currentHash = md5(__rspack_external_fs.readFileSync(__rspack_external_path.join(appDirectory, changed), 'utf8'));
34
+ if (currentHash !== lastHash) {
35
+ debug("file change: %s", changed);
36
+ hashMap.set(changed, currentHash);
37
+ appContext.hooks.onFileChanged.call({
38
+ filename: changed,
39
+ eventType: 'change',
40
+ isPrivate: isPrivate(changed)
41
+ });
42
+ }
43
+ });
44
+ watcher.on('add', (changed)=>{
45
+ debug("add file: %s", changed);
46
+ const currentHash = md5(__rspack_external_fs.readFileSync(__rspack_external_path.join(appDirectory, changed), 'utf8'));
47
+ hashMap.set(changed, currentHash);
48
+ appContext.hooks.onFileChanged.call({
49
+ filename: changed,
50
+ eventType: 'add',
51
+ isPrivate: isPrivate(changed)
52
+ });
53
+ });
54
+ watcher.on('unlink', (changed)=>{
55
+ debug("remove file: %s", changed);
56
+ if (hashMap.has(changed)) hashMap.delete(changed);
57
+ appContext.hooks.onFileChanged.call({
58
+ filename: changed,
59
+ eventType: 'unlink',
60
+ isPrivate: isPrivate(changed)
61
+ });
62
+ });
63
+ watcher.on('error', (err)=>{
64
+ throw err;
65
+ });
66
+ return watcher;
67
+ }
68
+ };
69
+ export { createFileWatcher };
@@ -0,0 +1,4 @@
1
+ import "node:module";
2
+ import { createDebugger } from "@modern-js/utils";
3
+ const debug = createDebugger('plugin');
4
+ export { debug };
@@ -0,0 +1,12 @@
1
+ import "node:module";
2
+ import { pkgUp } from "@modern-js/utils";
3
+ import path from "path";
4
+ const initAppDir = async (currentDir)=>{
5
+ const cwd = currentDir || process.cwd();
6
+ const pkg = await pkgUp({
7
+ cwd
8
+ });
9
+ if (!pkg) throw new Error(`no package.json found in current work dir: ${cwd}`);
10
+ return path.dirname(pkg);
11
+ };
12
+ export { initAppDir };
@@ -0,0 +1,33 @@
1
+ import "node:module";
2
+ import { ensureArray, isOverriddenConfigKey } from "@modern-js/utils";
3
+ import { isEqual, isFunction, mergeWith } from "@modern-js/utils/lodash";
4
+ const mergeConfig = (configs)=>mergeWith({}, ...configs, (target, source, key)=>{
5
+ if (isOverriddenConfigKey(key)) return source ?? target;
6
+ if (Array.isArray(target) || Array.isArray(source)) {
7
+ if (void 0 === target) return source;
8
+ if (void 0 === source) return target;
9
+ const targetArray = ensureArray(target);
10
+ const sourceArray = ensureArray(source);
11
+ const allItems = [
12
+ ...targetArray,
13
+ ...sourceArray
14
+ ];
15
+ const seenNonFunc = [];
16
+ const result = [];
17
+ for (const item of allItems)if (isFunction(item)) result.push(item);
18
+ else if (!seenNonFunc.some((seen)=>isEqual(seen, item))) {
19
+ seenNonFunc.push(item);
20
+ result.push(item);
21
+ }
22
+ return result;
23
+ }
24
+ if (isFunction(target) || isFunction(source)) {
25
+ if (void 0 === source) return target;
26
+ if (void 0 === target) return source;
27
+ return [
28
+ target,
29
+ source
30
+ ];
31
+ }
32
+ });
33
+ export { mergeConfig };
@@ -0,0 +1,121 @@
1
+ import "node:module";
2
+ function createAsyncInterruptHook() {
3
+ const callbacks = [];
4
+ const tap = (cb)=>{
5
+ callbacks.push(cb);
6
+ };
7
+ const call = async (...params)=>{
8
+ let interrupted = false;
9
+ let interruptResult;
10
+ const interrupt = (info)=>{
11
+ interrupted = true;
12
+ interruptResult = info;
13
+ };
14
+ for (const callback of callbacks){
15
+ if (interrupted) break;
16
+ const result = await callback(...params, interrupt);
17
+ if (void 0 !== result) params[0] = result;
18
+ }
19
+ return interrupted ? interruptResult : params[0] || [];
20
+ };
21
+ return {
22
+ tap,
23
+ call
24
+ };
25
+ }
26
+ function createSyncHook() {
27
+ const callbacks = [];
28
+ const tap = (cb)=>{
29
+ callbacks.push(cb);
30
+ };
31
+ const call = (...params)=>{
32
+ for (const callback of callbacks){
33
+ const result = callback(...params);
34
+ if (void 0 !== result) params[0] = result;
35
+ }
36
+ return params[0];
37
+ };
38
+ return {
39
+ tap,
40
+ call
41
+ };
42
+ }
43
+ function createAsyncHook() {
44
+ const callbacks = [];
45
+ const tap = (cb)=>{
46
+ callbacks.push(cb);
47
+ };
48
+ const call = async (...params)=>{
49
+ for (const callback of callbacks){
50
+ const result = await callback(...params);
51
+ if (void 0 !== result) params[0] = result;
52
+ }
53
+ return params[0] || [];
54
+ };
55
+ return {
56
+ tap,
57
+ call
58
+ };
59
+ }
60
+ function createCollectAsyncHook() {
61
+ const callbacks = [];
62
+ const tap = (cb)=>{
63
+ callbacks.push(cb);
64
+ };
65
+ const call = async (...params)=>{
66
+ const results = [];
67
+ for (const callback of callbacks){
68
+ const result = await callback(...params);
69
+ if (void 0 !== result) results.push(result);
70
+ }
71
+ return results;
72
+ };
73
+ return {
74
+ tap,
75
+ call
76
+ };
77
+ }
78
+ function createCollectSyncHook() {
79
+ const callbacks = [];
80
+ const tap = (cb)=>{
81
+ callbacks.push(cb);
82
+ };
83
+ const call = (...params)=>{
84
+ const results = [];
85
+ for (const callback of callbacks){
86
+ const result = callback(...params);
87
+ if (void 0 !== result) results.push(result);
88
+ }
89
+ return results;
90
+ };
91
+ return {
92
+ tap,
93
+ call
94
+ };
95
+ }
96
+ function createAsyncPipelineHook() {
97
+ const callbacks = [];
98
+ const tap = (cb)=>{
99
+ callbacks.push(cb);
100
+ };
101
+ const call = async (...params)=>{
102
+ for (const callback of callbacks){
103
+ let runNext = false;
104
+ const next = (info)=>{
105
+ runNext = true;
106
+ if (info) params[0] = info;
107
+ };
108
+ const result = await callback(...params, next);
109
+ if (!runNext) {
110
+ params[0] = result;
111
+ break;
112
+ }
113
+ }
114
+ return params[0] || [];
115
+ };
116
+ return {
117
+ tap,
118
+ call
119
+ };
120
+ }
121
+ export { createAsyncHook, createAsyncInterruptHook, createAsyncPipelineHook, createCollectAsyncHook, createCollectSyncHook, createSyncHook };
@@ -0,0 +1,3 @@
1
+ import "node:module";
2
+ export { createAsyncHook, createAsyncInterruptHook, createAsyncPipelineHook, createCollectAsyncHook, createCollectSyncHook, createSyncHook } from "./hooks.mjs";
3
+ export { createPluginManager } from "./manager.mjs";
@@ -0,0 +1,102 @@
1
+ import "node:module";
2
+ const isFunction = (obj)=>'function' == typeof obj;
3
+ function validatePlugin(plugin) {
4
+ const type = typeof plugin;
5
+ if ('object' !== type || null === plugin) throw new Error(`Expect CLI Plugin instance to be an object, but got ${type}.`);
6
+ if (!plugin.setup) return;
7
+ if (isFunction(plugin.setup)) return;
8
+ throw new Error(`Expect CLI Plugin plugin.setup to be a function, but got ${type}.`);
9
+ }
10
+ function createPluginManager() {
11
+ const plugins = new Map();
12
+ const dependencies = new Map();
13
+ const addDependency = (plugin, dependency, type)=>{
14
+ if (!dependencies.has(dependency)) dependencies.set(dependency, {
15
+ pre: new Map(),
16
+ post: new Map()
17
+ });
18
+ if ('pre' === type) dependencies.get(plugin).pre.set(dependency, {
19
+ name: dependency,
20
+ isUse: false
21
+ });
22
+ else if ('post' === type) dependencies.get(plugin).post.set(dependency, {
23
+ name: dependency
24
+ });
25
+ else if ('use' === type) {
26
+ if (!dependencies.get(plugin).post.has(dependency) && !dependencies.get(dependency).pre.has(plugin)) dependencies.get(plugin).pre.set(dependency, {
27
+ name: dependency,
28
+ isUse: true
29
+ });
30
+ }
31
+ };
32
+ const addPlugin = (newPlugin)=>{
33
+ if (!newPlugin) return;
34
+ validatePlugin(newPlugin);
35
+ const { name, usePlugins = [], pre = [], post = [] } = newPlugin;
36
+ if (plugins.has(name)) return void console.warn(`Plugin ${name} already exists.`);
37
+ plugins.set(name, newPlugin);
38
+ dependencies.set(name, {
39
+ pre: new Map(),
40
+ post: new Map()
41
+ });
42
+ pre.forEach((dep)=>{
43
+ addDependency(name, dep, 'pre');
44
+ });
45
+ post.forEach((dep)=>{
46
+ addDependency(name, dep, 'post');
47
+ });
48
+ usePlugins.forEach((plugin)=>{
49
+ if (!plugins.has(plugin.name)) addPlugin(plugin);
50
+ addDependency(name, plugin.name, 'use');
51
+ });
52
+ };
53
+ const addPlugins = (newPlugins)=>{
54
+ for (const newPlugin of newPlugins)addPlugin(newPlugin);
55
+ };
56
+ const getPlugins = ()=>{
57
+ const visited = new Set();
58
+ const temp = new Set();
59
+ let result = [];
60
+ const visit = (name)=>{
61
+ if (temp.has(name)) throw new Error(`Circular dependency detected: ${name}`);
62
+ if (!visited.has(name) && plugins.get(name)) {
63
+ temp.add(name);
64
+ const { required = [] } = plugins.get(name);
65
+ required.forEach((dep)=>{
66
+ if (!plugins.get(dep)) throw new Error(`${name} plugin required plugin ${dep}, but not found.`);
67
+ });
68
+ const { pre } = dependencies.get(name);
69
+ Array.from(pre.values()).filter((dep)=>!dep.isUse).forEach((dep)=>visit(dep.name));
70
+ Array.from(pre.values()).filter((dep)=>dep.isUse).forEach((dep)=>visit(dep.name));
71
+ temp.delete(name);
72
+ visited.add(name);
73
+ result.push(plugins.get(name));
74
+ }
75
+ };
76
+ plugins.forEach((_, name)=>{
77
+ const { post } = dependencies.get(name);
78
+ post.forEach((dep)=>{
79
+ if (!dependencies.get(dep.name).pre.has(name)) dependencies.get(dep.name).pre.set(name, {
80
+ name,
81
+ isUse: false
82
+ });
83
+ });
84
+ });
85
+ plugins.forEach((_, name)=>{
86
+ visit(name);
87
+ });
88
+ result = result.filter((result)=>result);
89
+ return result;
90
+ };
91
+ const clear = ()=>{
92
+ plugins.clear();
93
+ dependencies.clear();
94
+ };
95
+ return {
96
+ getPlugins,
97
+ addPlugins,
98
+ clear,
99
+ isPluginExists: (name)=>plugins.has(name)
100
+ };
101
+ }
102
+ export { createPluginManager };
@@ -0,0 +1,62 @@
1
+ import "node:module";
2
+ import { merge } from "@modern-js/runtime-utils/merge";
3
+ function initPluginAPI({ context, plugins }) {
4
+ const { hooks, extendsHooks } = context;
5
+ function getRuntimeContext() {
6
+ if (context) {
7
+ const { hooks, extendsHooks, config, pluginAPI, ...runtimeContext } = context;
8
+ runtimeContext._internalContext = context;
9
+ return runtimeContext;
10
+ }
11
+ throw new Error('Cannot access context');
12
+ }
13
+ function updateRuntimeContext(updateContext) {
14
+ context = merge(context, updateContext);
15
+ }
16
+ function getHooks() {
17
+ return {
18
+ ...hooks,
19
+ ...extendsHooks
20
+ };
21
+ }
22
+ function getRuntimeConfig() {
23
+ if (context.config) return context.config;
24
+ throw new Error('Cannot access config');
25
+ }
26
+ const extendsPluginApi = {};
27
+ plugins.forEach((plugin)=>{
28
+ const { _registryApi } = plugin;
29
+ if (_registryApi) {
30
+ const apis = _registryApi(getRuntimeContext, updateRuntimeContext);
31
+ Object.keys(apis).forEach((apiName)=>{
32
+ extendsPluginApi[apiName] = apis[apiName];
33
+ });
34
+ }
35
+ });
36
+ if (extendsHooks) Object.keys(extendsHooks).forEach((hookName)=>{
37
+ extendsPluginApi[hookName] = extendsHooks[hookName].tap;
38
+ });
39
+ const pluginAPI = {
40
+ updateRuntimeContext,
41
+ getHooks,
42
+ getRuntimeConfig,
43
+ config: hooks.config.tap,
44
+ onBeforeRender: hooks.onBeforeRender.tap,
45
+ wrapRoot: hooks.wrapRoot.tap,
46
+ pickContext: hooks.pickContext.tap,
47
+ extendStringSSRCollectors: hooks.extendStringSSRCollectors.tap,
48
+ extendStreamSSR: hooks.extendStreamSSR.tap,
49
+ ...extendsPluginApi
50
+ };
51
+ if ("u" < typeof Proxy) return pluginAPI;
52
+ return new Proxy(pluginAPI, {
53
+ get (target, prop) {
54
+ if ('then' === prop) return;
55
+ if (prop in target) return target[prop];
56
+ return ()=>{
57
+ console.warn(`api.${prop.toString()} not exist`);
58
+ };
59
+ }
60
+ });
61
+ }
62
+ export { initPluginAPI };
@@ -0,0 +1,24 @@
1
+ import "node:module";
2
+ import { initHooks } from "./hooks.mjs";
3
+ function initRuntimeContext() {
4
+ return {};
5
+ }
6
+ function createRuntimeContext({ runtimeContext, config, plugins }) {
7
+ const extendsHooks = {};
8
+ plugins.forEach((plugin)=>{
9
+ const { registryHooks = {} } = plugin;
10
+ Object.keys(registryHooks).forEach((hookName)=>{
11
+ extendsHooks[hookName] = registryHooks[hookName];
12
+ });
13
+ });
14
+ return {
15
+ ...runtimeContext,
16
+ hooks: {
17
+ ...initHooks(),
18
+ ...extendsHooks
19
+ },
20
+ extendsHooks,
21
+ config
22
+ };
23
+ }
24
+ export { createRuntimeContext, initRuntimeContext };
@@ -0,0 +1,13 @@
1
+ import "node:module";
2
+ import { createAsyncInterruptHook, createCollectSyncHook, createSyncHook } from "../hooks.mjs";
3
+ function initHooks() {
4
+ return {
5
+ onBeforeRender: createAsyncInterruptHook(),
6
+ wrapRoot: createSyncHook(),
7
+ pickContext: createSyncHook(),
8
+ config: createCollectSyncHook(),
9
+ extendStringSSRCollectors: createCollectSyncHook(),
10
+ extendStreamSSR: createCollectSyncHook()
11
+ };
12
+ }
13
+ export { initHooks };