@modern-js/plugin-devtools 0.0.0-next-20240617070535 → 0.0.0-next-20240617090621

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/cli.d.ts CHANGED
@@ -1,9 +1,11 @@
1
- import type { AppTools, CliPlugin } from '@modern-js/app-tools';
1
+ import { type AppTools, type CliPlugin } from '@modern-js/app-tools';
2
2
  import { ClientDefinition } from '@modern-js/devtools-kit/node';
3
3
  import { DevtoolsPluginOptions } from './options';
4
+ import { Plugin } from './types';
4
5
  export type { DevtoolsPluginOptions };
5
6
  export type DevtoolsPlugin = CliPlugin<AppTools> & {
6
7
  setClientDefinition: (def: ClientDefinition) => void;
7
8
  };
9
+ export declare const BUILTIN_PLUGINS: Plugin[];
8
10
  export declare const devtoolsPlugin: (inlineOptions?: DevtoolsPluginOptions) => DevtoolsPlugin;
9
11
  export default devtoolsPlugin;
package/dist/cli.js CHANGED
@@ -28,259 +28,144 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
29
  var cli_exports = {};
30
30
  __export(cli_exports, {
31
+ BUILTIN_PLUGINS: () => BUILTIN_PLUGINS,
31
32
  default: () => cli_default,
32
33
  devtoolsPlugin: () => devtoolsPlugin
33
34
  });
34
35
  module.exports = __toCommonJS(cli_exports);
35
- var import_http = __toESM(require("http"));
36
- var import_path = __toESM(require("path"));
37
- var import_assert = __toESM(require("assert"));
38
- var import_url = require("url");
39
- var import_lodash = __toESM(require("@modern-js/utils/lodash"));
36
+ var import_app_tools = require("@modern-js/app-tools");
40
37
  var import_utils = require("@modern-js/utils");
41
- var import_hono = require("hono");
42
- var import_node_server = require("@hono/node-server");
43
- var import_serve_static = require("@hono/node-server/serve-static");
44
- var import_node = require("@modern-js/devtools-kit/node");
38
+ var import_p_defer = __toESM(require("p-defer"));
39
+ var import_hookable = require("hookable");
45
40
  var import_valtio = require("valtio");
46
41
  var import_options = require("./options");
47
- var import_rpc = require("./rpc");
48
- var import_socket = require("./utils/socket");
49
- var import_config = require("./utils/config");
42
+ var import_debug = require("./plugins/debug");
43
+ var import_http = require("./plugins/http");
44
+ var import_state = require("./plugins/state");
45
+ var import_watcher = require("./plugins/watcher");
46
+ var import_service_worker = require("./plugins/service-worker");
47
+ var import_html = require("./plugins/html");
48
+ var import_rpc = require("./plugins/rpc");
49
+ const BUILTIN_PLUGINS = [
50
+ import_debug.pluginDebug,
51
+ import_watcher.pluginWatcher,
52
+ import_service_worker.pluginServiceWorker,
53
+ import_html.pluginHtml,
54
+ // --- //
55
+ import_state.pluginState,
56
+ import_http.pluginHttp,
57
+ import_rpc.pluginRpc
58
+ ];
50
59
  const devtoolsPlugin = (inlineOptions = {}) => {
51
60
  const ctx = (0, import_valtio.proxy)((0, import_options.resolveContext)(inlineOptions));
52
- let watcher = null;
53
- const closeWatcher = () => {
54
- if (!watcher)
55
- return;
56
- watcher.close();
57
- watcher = null;
61
+ const setupBuilder = (0, import_p_defer.default)();
62
+ const setupFramework = (0, import_p_defer.default)();
63
+ const _sharedVars = {};
64
+ const api = {
65
+ builderHooks: (0, import_hookable.createHooks)(),
66
+ frameworkHooks: (0, import_hookable.createHooks)(),
67
+ setupBuilder: () => setupBuilder.promise,
68
+ setupFramework: () => setupFramework.promise,
69
+ get context() {
70
+ return ctx;
71
+ },
72
+ get vars() {
73
+ return _sharedVars;
74
+ }
75
+ };
76
+ const cleanup = () => {
77
+ setupBuilder.reject(new Error("Devtools Plugin is disabled"));
78
+ setupFramework.reject(new Error("Devtools Plugin is disabled"));
79
+ api.builderHooks.removeAllHooks();
80
+ api.frameworkHooks.removeAllHooks();
58
81
  };
82
+ for (const plugin of BUILTIN_PLUGINS) {
83
+ plugin.setup(api);
84
+ }
59
85
  return {
60
86
  name: "@modern-js/plugin-devtools",
61
87
  usePlugins: [],
62
88
  setClientDefinition(def) {
63
89
  Object.assign(ctx.def, def);
64
90
  },
65
- async setup(api) {
91
+ async setup(frameworkApi) {
66
92
  if (!ctx.enable)
67
93
  return {};
68
- const httpServer = await setupHttpServer();
69
- const socketServer = new import_socket.SocketServer({
70
- server: httpServer.instance,
71
- path: "/rpc"
72
- });
73
- const rpc = await (0, import_rpc.setupClientConnection)({
74
- api,
75
- ctx,
76
- server: socketServer
77
- });
94
+ setupFramework.resolve(frameworkApi);
78
95
  return {
79
96
  async prepare() {
80
- await rpc.hooks.prepare();
81
- const appConfig = api.useConfigContext();
82
- const appCtx = api.useAppContext();
83
- const { devtools: options = {} } = appConfig;
84
- (0, import_options.updateContext)(ctx, options);
85
- const basename = `${ctx.def.name.shortName}.runtime.json`;
86
- const watcher2 = import_utils.chokidar.watch((0, import_config.getConfigFilenames)(basename), {
87
- cwd: appCtx.appDirectory,
88
- ignorePermissionErrors: true
89
- });
90
- const refreshStoragePreset = async () => {
91
- const configs = await (0, import_config.loadConfigFiles)(basename, appCtx.appDirectory);
92
- if (!configs)
93
- return;
94
- ctx.storagePresets = [];
95
- (0, import_options.updateContext)(ctx, ...configs);
96
- };
97
- watcher2.on("add", refreshStoragePreset);
98
- watcher2.on("change", refreshStoragePreset);
99
- watcher2.on("unlink", refreshStoragePreset);
97
+ await api.frameworkHooks.callHook("prepare");
98
+ },
99
+ async modifyFileSystemRoutes(params) {
100
+ await api.frameworkHooks.callHook("modifyFileSystemRoutes", params);
101
+ return params;
102
+ },
103
+ async afterCreateCompiler(params) {
104
+ await api.frameworkHooks.callHook("afterCreateCompiler", params);
105
+ },
106
+ async modifyServerRoutes(params) {
107
+ await api.frameworkHooks.callHook("modifyServerRoutes", params);
108
+ return params;
100
109
  },
101
- modifyFileSystemRoutes: rpc.hooks.modifyFileSystemRoutes,
102
- afterCreateCompiler: rpc.hooks.afterCreateCompiler,
103
- beforeRestart() {
104
- closeWatcher();
105
- return new Promise((resolve, reject) => httpServer.instance.close((err) => err ? reject(err) : resolve()));
110
+ async beforeRestart() {
111
+ await api.frameworkHooks.callHook("beforeRestart");
112
+ cleanup();
106
113
  },
107
114
  beforeExit() {
108
- closeWatcher();
115
+ api.frameworkHooks.callHookWith((hooks) => hooks.forEach((hook) => hook()), "beforeExit");
116
+ cleanup();
109
117
  },
110
- modifyServerRoutes({ routes }) {
111
- routes.push({
112
- urlPath: "/sw-proxy.js",
113
- isSPA: true,
114
- isSSR: false,
115
- entryPath: "public/sw-proxy.js"
116
- });
117
- return {
118
- routes
119
- };
118
+ async afterBuild(params) {
119
+ api.frameworkHooks.callHook("afterBuild", params);
120
+ cleanup();
120
121
  },
121
122
  async config() {
122
123
  import_utils.logger.info(`${ctx.def.name.formalName} DevTools is enabled`);
123
- const swProxyEntry = require.resolve("@modern-js/devtools-client/sw-proxy");
124
- const clientOptions = import_lodash.default.pick(ctx, [
125
- "def",
126
- "endpoint",
127
- "dataSource"
128
- ]);
129
- Object.assign(clientOptions, {
130
- __keep: true
131
- });
132
- const serializedOptions = JSON.stringify(clientOptions);
133
- const tags = [
134
- {
135
- tag: "script",
136
- children: `window.__MODERN_JS_DEVTOOLS_OPTIONS__ = ${serializedOptions};`,
137
- head: true,
138
- append: false
139
- }
140
- ];
141
- const styles = [];
142
- const manifest = require("@modern-js/devtools-client/manifest");
143
- for (const src of manifest.routeAssets.mount.assets) {
144
- (0, import_assert.default)(typeof src === "string");
145
- if (src.endsWith(".js")) {
146
- tags.push({
147
- tag: "script",
148
- attrs: {
149
- src
150
- },
151
- head: true,
152
- append: false
124
+ const configs = await api.frameworkHooks.callHookParallel("config");
125
+ const builderPlugin = {
126
+ name: "builder-plugin-devtools",
127
+ setup(builderApi) {
128
+ setupBuilder.resolve(builderApi);
129
+ builderApi.modifyBundlerChain(async (options, utils) => {
130
+ await api.builderHooks.callHook("modifyBundlerChain", options, utils);
131
+ });
132
+ builderApi.modifyWebpackConfig(async (config, utils) => {
133
+ await api.builderHooks.callHook("modifyWebpackConfig", config, utils);
134
+ });
135
+ builderApi.modifyRspackConfig(async (config, utils) => {
136
+ await api.builderHooks.callHook("modifyRspackConfig", config, utils);
137
+ });
138
+ builderApi.onBeforeCreateCompiler(async (params) => {
139
+ await api.builderHooks.callHook("onBeforeCreateCompiler", params);
140
+ });
141
+ builderApi.onAfterCreateCompiler(async (params) => {
142
+ await api.builderHooks.callHook("onAfterCreateCompiler", params);
143
+ });
144
+ builderApi.onDevCompileDone(async (params) => {
145
+ await api.builderHooks.callHook("onDevCompileDone", params);
146
+ });
147
+ builderApi.onAfterBuild(async (params) => {
148
+ await api.builderHooks.callHook("onAfterBuild", params);
149
+ });
150
+ builderApi.onExit(() => {
151
+ api.builderHooks.callHookWith((hooks) => hooks.forEach((hook) => hook()), "onExit");
153
152
  });
154
- } else if (src.endsWith(".css")) {
155
- styles.push(src);
156
- }
157
- }
158
- tags.push({
159
- tag: "template",
160
- attrs: {
161
- id: "_modern_js_devtools_styles"
162
- },
163
- append: true,
164
- head: false,
165
- children: styles.map((src) => `<link rel="stylesheet" href="${src}">`).join("")
166
- });
167
- return {
168
- builderPlugins: [
169
- rpc.builderPlugin
170
- ],
171
- source: {},
172
- output: {
173
- copy: [
174
- {
175
- from: swProxyEntry,
176
- to: "public"
177
- }
178
- ]
179
- },
180
- html: {
181
- tags
182
- },
183
- tools: {
184
- devServer: {
185
- proxy: {
186
- [import_node.ROUTE_BASENAME]: {
187
- target: `http://127.0.0.1:${httpServer.port}`,
188
- pathRewrite: {
189
- [`^${import_node.ROUTE_BASENAME}`]: ""
190
- },
191
- ws: true,
192
- onProxyReq(proxyReq, req) {
193
- const addrInfo = req.socket.address();
194
- if ("address" in addrInfo) {
195
- const { address } = addrInfo;
196
- proxyReq.setHeader("X-Forwarded-For", address);
197
- } else {
198
- proxyReq.removeHeader("X-Forwarded-For");
199
- }
200
- }
201
- }
202
- }
203
- }
204
153
  }
205
154
  };
155
+ configs.push({
156
+ builderPlugins: [
157
+ builderPlugin
158
+ ]
159
+ });
160
+ return (0, import_app_tools.mergeConfig)(configs);
206
161
  }
207
162
  };
208
163
  }
209
164
  };
210
165
  };
211
166
  var cli_default = devtoolsPlugin;
212
- const setupHttpServer = async () => {
213
- const app = new import_hono.Hono();
214
- const port = await (0, import_utils.getPort)(8782, {
215
- slient: true
216
- });
217
- const clientServeDir = import_path.default.resolve(require.resolve("@modern-js/devtools-client/package.json"), "../dist");
218
- const handleCookieApi = async (c) => {
219
- const raw = c.req.header("Cookie");
220
- const { parse } = await import("cookie-es");
221
- const cookies = raw ? parse(raw) : {};
222
- const body = await c.req.json().catch(() => null);
223
- if (body === null || body === void 0 ? void 0 : body.setCookies) {
224
- const { setCookies } = body;
225
- (0, import_assert.default)(typeof setCookies === "object", "setCookies should be object");
226
- for (const [k, v] of Object.entries(setCookies)) {
227
- (0, import_assert.default)(typeof v === "string");
228
- const expires = new Date(Date.now() + 30 * 24 * 36e5).toUTCString();
229
- cookies[k] = v;
230
- c.header("Set-Cookie", `${k}=${v}; Expires=${expires}; Path=/`, {
231
- append: true
232
- });
233
- }
234
- }
235
- return c.json({
236
- cookies
237
- });
238
- };
239
- app.get("/api/cookies", handleCookieApi);
240
- app.post("/api/cookies", handleCookieApi);
241
- app.use(
242
- "/static/*",
243
- // Workaround for https://github.com/honojs/node-server/blob/dd0e0cd160b0b8f18abbcb28c5f5c39b72105d98/src/serve-static.ts#L56
244
- (0, import_serve_static.serveStatic)({
245
- root: import_path.default.relative(process.cwd(), clientServeDir)
246
- })
247
- );
248
- app.get(":filename{.+\\.hot-update\\.\\w+$}", async (c) => {
249
- if (process.env.NODE_ENV !== "development") {
250
- return c.text("Not found", 404);
251
- }
252
- const filename = c.req.param("filename");
253
- const target = new import_url.URL(filename, "http://127.0.0.1:8780");
254
- const { body, headers, status } = await fetch(target.href);
255
- const newResp = c.newResponse(body, {
256
- headers,
257
- status
258
- });
259
- if (newResp.headers.get("content-encoding") === "gzip") {
260
- newResp.headers.delete("content-encoding");
261
- }
262
- return newResp;
263
- });
264
- app.get("*", async (c) => {
265
- const filename = import_path.default.resolve(clientServeDir, "html/client/index.html");
266
- const content = await import_utils.fs.readFile(filename, "utf-8");
267
- return c.html(content);
268
- });
269
- const instance = (0, import_node_server.serve)({
270
- fetch: app.fetch,
271
- port,
272
- hostname: "127.0.0.1",
273
- serverOptions: {
274
- allowHTTP1: true
275
- }
276
- });
277
- (0, import_assert.default)(instance instanceof import_http.default.Server, "instance should be http.Server");
278
- return {
279
- instance,
280
- port
281
- };
282
- };
283
167
  // Annotate the CommonJS export names for ESM import in node:
284
168
  0 && (module.exports = {
169
+ BUILTIN_PLUGINS,
285
170
  devtoolsPlugin
286
171
  });
@@ -0,0 +1,2 @@
1
+ import { Plugin } from '../types';
2
+ export declare const pluginDebug: Plugin;
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var debug_exports = {};
20
+ __export(debug_exports, {
21
+ pluginDebug: () => pluginDebug
22
+ });
23
+ module.exports = __toCommonJS(debug_exports);
24
+ var import_utils = require("@modern-js/utils");
25
+ const logger = (0, import_utils.createLogger)({
26
+ level: process.env.LOG_LEVEL || "info"
27
+ });
28
+ const pluginDebug = {
29
+ async setup(api) {
30
+ await api.setupFramework();
31
+ logger.debug("setup framework api");
32
+ await api.setupBuilder();
33
+ logger.debug("setup builder api");
34
+ api.frameworkHooks.afterEach((e) => {
35
+ logger.debug("after framework hook:", e.name);
36
+ });
37
+ api.builderHooks.afterEach((e) => {
38
+ logger.debug("after builder hook:", e.name);
39
+ });
40
+ }
41
+ };
42
+ // Annotate the CommonJS export names for ESM import in node:
43
+ 0 && (module.exports = {
44
+ pluginDebug
45
+ });
@@ -0,0 +1,2 @@
1
+ import { Plugin } from '../types';
2
+ export declare const pluginHtml: Plugin;
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var html_exports = {};
30
+ __export(html_exports, {
31
+ pluginHtml: () => pluginHtml
32
+ });
33
+ module.exports = __toCommonJS(html_exports);
34
+ var import_assert = __toESM(require("assert"));
35
+ var import_lodash = __toESM(require("@modern-js/utils/lodash"));
36
+ const pluginHtml = {
37
+ async setup(api) {
38
+ api.frameworkHooks.hook("modifyServerRoutes", ({ routes }) => {
39
+ routes.push({
40
+ urlPath: "/sw-proxy.js",
41
+ isSPA: true,
42
+ isSSR: false,
43
+ entryPath: "public/sw-proxy.js"
44
+ });
45
+ });
46
+ api.frameworkHooks.hook("config", async () => {
47
+ const clientOptions = import_lodash.default.pick(api.context, [
48
+ "def",
49
+ "endpoint",
50
+ "dataSource"
51
+ ]);
52
+ Object.assign(clientOptions, {
53
+ __keep: true
54
+ });
55
+ const serializedOptions = JSON.stringify(clientOptions);
56
+ const tags = [
57
+ {
58
+ tag: "script",
59
+ children: `window.__MODERN_JS_DEVTOOLS_OPTIONS__ = ${serializedOptions};`,
60
+ head: true,
61
+ append: false
62
+ }
63
+ ];
64
+ const styles = [];
65
+ const manifest = require("@modern-js/devtools-client/manifest");
66
+ for (const src of manifest.routeAssets.mount.assets) {
67
+ (0, import_assert.default)(typeof src === "string");
68
+ if (src.endsWith(".js")) {
69
+ tags.push({
70
+ tag: "script",
71
+ attrs: {
72
+ src
73
+ },
74
+ head: true,
75
+ append: false
76
+ });
77
+ } else if (src.endsWith(".css")) {
78
+ styles.push(src);
79
+ }
80
+ }
81
+ tags.push({
82
+ tag: "template",
83
+ attrs: {
84
+ id: "_modern_js_devtools_styles"
85
+ },
86
+ append: true,
87
+ head: false,
88
+ children: styles.map((src) => `<link rel="stylesheet" href="${src}">`).join("")
89
+ });
90
+ const config = {
91
+ html: {
92
+ tags
93
+ }
94
+ };
95
+ return config;
96
+ });
97
+ }
98
+ };
99
+ // Annotate the CommonJS export names for ESM import in node:
100
+ 0 && (module.exports = {
101
+ pluginHtml
102
+ });
@@ -0,0 +1,9 @@
1
+ /// <reference types="node" />
2
+ import http from 'http';
3
+ import { Plugin } from '../types';
4
+ declare global {
5
+ interface DevtoolsPluginVars {
6
+ http: http.Server;
7
+ }
8
+ }
9
+ export declare const pluginHttp: Plugin;