From b7101cc8803e847b82d74a10e0cb7c7dfa8668ef Mon Sep 17 00:00:00 2001 From: zhang han Date: Mon, 25 Mar 2024 15:09:53 +0800 Subject: [PATCH] feat: add debugPlugin & fix plugin types intellisense (#315) --- CHANGELOG.md | 5 ++ package.json | 2 +- packages/create-app/package.json | 2 +- .../templates/react-dapp-ts/package.json | 2 +- .../templates/react-dapp/package.json | 2 +- .../templates/react-gun-dapp/package.json | 2 +- .../templates/react-static/package.json | 2 +- .../templates/solidjs-dapp/package.json | 2 +- .../templates/solidjs-static/package.json | 2 +- .../templates/svelte-dapp/package.json | 2 +- .../templates/svelte-static/package.json | 2 +- .../templates/vue-dapp/package.json | 2 +- .../templates/vue-static/package.json | 2 +- .../templates/vue2-dapp/package.json | 2 +- .../templates/vue2-static/package.json | 2 +- plugins/vite-plugin-blocklet/index.js | 36 ++++++--- plugins/vite-plugin-blocklet/libs/client.js | 37 ++++++++- plugins/vite-plugin-blocklet/libs/config.js | 4 +- plugins/vite-plugin-blocklet/libs/debug.js | 81 +++++++++++++++++++ plugins/vite-plugin-blocklet/libs/hmr.js | 7 ++ plugins/vite-plugin-blocklet/libs/loading.js | 30 +++---- plugins/vite-plugin-blocklet/libs/meta.js | 2 +- plugins/vite-plugin-blocklet/package.json | 3 +- plugins/vite-plugin-wss-hmr/package.json | 2 +- pnpm-lock.yaml | 3 + version | 2 +- website/docs/blocklet.yml | 2 +- website/pages/blocklet.yml | 2 +- 28 files changed, 192 insertions(+), 52 deletions(-) create mode 100644 plugins/vite-plugin-blocklet/libs/debug.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 0bc3f942..c4378407 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.7.5 (2024-3-25) + +- feat: support cache vite port in .env.development.local file +- feat: add debugPlugin & fix plugin types intellisense + ## 0.7.4 (2024-3-20) - fix(api): force use png format logo as favicon diff --git a/package.json b/package.json index e9788bd8..eee747dc 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "create-blocklet", "private": true, - "version": "0.7.4", + "version": "0.7.5", "description": "", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", diff --git a/packages/create-app/package.json b/packages/create-app/package.json index 7801cd8d..94e893d3 100644 --- a/packages/create-app/package.json +++ b/packages/create-app/package.json @@ -1,6 +1,6 @@ { "name": "create-blocklet", - "version": "0.7.4", + "version": "0.7.5", "exports": "./index.js", "type": "module", "repository": "git@github.com:blocklet/create-blocklet.git", diff --git a/packages/create-app/templates/react-dapp-ts/package.json b/packages/create-app/templates/react-dapp-ts/package.json index 0ab513a4..71feb63e 100644 --- a/packages/create-app/templates/react-dapp-ts/package.json +++ b/packages/create-app/templates/react-dapp-ts/package.json @@ -79,7 +79,7 @@ "ts-node": "^10.9.2", "typescript": "^5.3.3", "vite": "^5.0.10", - "vite-plugin-blocklet": "^0.7.4", + "vite-plugin-blocklet": "^0.7.5", "vite-plugin-svgr": "^4.2.0", "zx": "^7.2.3" }, diff --git a/packages/create-app/templates/react-dapp/package.json b/packages/create-app/templates/react-dapp/package.json index 0c2c2793..95308509 100644 --- a/packages/create-app/templates/react-dapp/package.json +++ b/packages/create-app/templates/react-dapp/package.json @@ -69,7 +69,7 @@ "npm-run-all": "^4.1.5", "prettier": "^3.1.1", "vite": "^5.0.10", - "vite-plugin-blocklet": "^0.7.4", + "vite-plugin-blocklet": "^0.7.5", "vite-plugin-svgr": "^4.2.0", "zx": "^7.2.3" } diff --git a/packages/create-app/templates/react-gun-dapp/package.json b/packages/create-app/templates/react-gun-dapp/package.json index f2cf7d7a..e14f93e3 100644 --- a/packages/create-app/templates/react-gun-dapp/package.json +++ b/packages/create-app/templates/react-gun-dapp/package.json @@ -70,7 +70,7 @@ "prettier": "^3.1.1", "rimraf": "^3.0.2", "vite": "^5.0.10", - "vite-plugin-blocklet": "^0.7.4", + "vite-plugin-blocklet": "^0.7.5", "vite-plugin-svgr": "^4.2.0", "zx": "^7.2.3" } diff --git a/packages/create-app/templates/react-static/package.json b/packages/create-app/templates/react-static/package.json index cf1df43f..d5861a66 100644 --- a/packages/create-app/templates/react-static/package.json +++ b/packages/create-app/templates/react-static/package.json @@ -53,7 +53,7 @@ "prettier": "^3.1.1", "rimraf": "^3.0.2", "vite": "^5.0.10", - "vite-plugin-blocklet": "^0.7.4", + "vite-plugin-blocklet": "^0.7.5", "vite-plugin-svgr": "^4.2.0", "zx": "^7.2.3" } diff --git a/packages/create-app/templates/solidjs-dapp/package.json b/packages/create-app/templates/solidjs-dapp/package.json index d2fc9c65..fa9ab083 100644 --- a/packages/create-app/templates/solidjs-dapp/package.json +++ b/packages/create-app/templates/solidjs-dapp/package.json @@ -33,7 +33,7 @@ "prettier": "^3.1.1", "rimraf": "^3.0.2", "vite": "^5.0.10", - "vite-plugin-blocklet": "^0.7.4", + "vite-plugin-blocklet": "^0.7.5", "vite-plugin-solid": "^2.8.0", "zx": "^7.2.3" }, diff --git a/packages/create-app/templates/solidjs-static/package.json b/packages/create-app/templates/solidjs-static/package.json index b1ee9f3f..d2d9453c 100644 --- a/packages/create-app/templates/solidjs-static/package.json +++ b/packages/create-app/templates/solidjs-static/package.json @@ -29,7 +29,7 @@ "prettier": "^3.1.1", "rimraf": "^3.0.2", "vite": "^5.0.10", - "vite-plugin-blocklet": "^0.7.4", + "vite-plugin-blocklet": "^0.7.5", "vite-plugin-solid": "^2.8.0", "zx": "^7.2.3" }, diff --git a/packages/create-app/templates/svelte-dapp/package.json b/packages/create-app/templates/svelte-dapp/package.json index fafd8094..203977c9 100644 --- a/packages/create-app/templates/svelte-dapp/package.json +++ b/packages/create-app/templates/svelte-dapp/package.json @@ -45,7 +45,7 @@ "rimraf": "^3.0.2", "svelte": "^4.2.8", "vite": "^5.0.10", - "vite-plugin-blocklet": "^0.7.4", + "vite-plugin-blocklet": "^0.7.5", "zx": "^7.2.3" }, "lint-staged": { diff --git a/packages/create-app/templates/svelte-static/package.json b/packages/create-app/templates/svelte-static/package.json index 88849fc2..ad204892 100644 --- a/packages/create-app/templates/svelte-static/package.json +++ b/packages/create-app/templates/svelte-static/package.json @@ -30,7 +30,7 @@ "rimraf": "^3.0.2", "svelte": "^4.2.8", "vite": "^5.0.10", - "vite-plugin-blocklet": "^0.7.4", + "vite-plugin-blocklet": "^0.7.5", "zx": "^7.2.3" }, "lint-staged": { diff --git a/packages/create-app/templates/vue-dapp/package.json b/packages/create-app/templates/vue-dapp/package.json index c59e5062..b6d2e59c 100644 --- a/packages/create-app/templates/vue-dapp/package.json +++ b/packages/create-app/templates/vue-dapp/package.json @@ -47,7 +47,7 @@ "prettier": "^3.1.1", "rimraf": "^3.0.2", "vite": "^5.0.10", - "vite-plugin-blocklet": "^0.7.4", + "vite-plugin-blocklet": "^0.7.5", "zx": "^7.2.3" }, "lint-staged": { diff --git a/packages/create-app/templates/vue-static/package.json b/packages/create-app/templates/vue-static/package.json index 9674226b..b443a3f9 100644 --- a/packages/create-app/templates/vue-static/package.json +++ b/packages/create-app/templates/vue-static/package.json @@ -31,7 +31,7 @@ "prettier": "^3.1.1", "rimraf": "^3.0.2", "vite": "^5.0.10", - "vite-plugin-blocklet": "^0.7.4", + "vite-plugin-blocklet": "^0.7.5", "zx": "^7.2.3" }, "lint-staged": { diff --git a/packages/create-app/templates/vue2-dapp/package.json b/packages/create-app/templates/vue2-dapp/package.json index 16d9c04c..02b0bff1 100644 --- a/packages/create-app/templates/vue2-dapp/package.json +++ b/packages/create-app/templates/vue2-dapp/package.json @@ -47,7 +47,7 @@ "prettier": "^3.1.1", "rimraf": "^3.0.2", "vite": "^5.0.10", - "vite-plugin-blocklet": "^0.7.4", + "vite-plugin-blocklet": "^0.7.5", "zx": "^7.2.3" }, "lint-staged": { diff --git a/packages/create-app/templates/vue2-static/package.json b/packages/create-app/templates/vue2-static/package.json index 4f6f9157..c1ec1b8e 100644 --- a/packages/create-app/templates/vue2-static/package.json +++ b/packages/create-app/templates/vue2-static/package.json @@ -31,7 +31,7 @@ "prettier": "^3.1.1", "rimraf": "^3.0.2", "vite": "^5.0.10", - "vite-plugin-blocklet": "^0.7.4", + "vite-plugin-blocklet": "^0.7.5", "zx": "^7.2.3" }, "lint-staged": { diff --git a/plugins/vite-plugin-blocklet/index.js b/plugins/vite-plugin-blocklet/index.js index 0af95d0c..e8e7b672 100644 --- a/plugins/vite-plugin-blocklet/index.js +++ b/plugins/vite-plugin-blocklet/index.js @@ -3,26 +3,32 @@ import createHmrPlugin from './libs/hmr.js'; import createConfigPlugin from './libs/config.js'; import createMetaPlugin from './libs/meta.js'; import createLoadingPlugin from './libs/loading.js'; +import createDebugPlugin from './libs/debug.js'; import setupClient from './libs/client.js'; /** - * @typedef {{ - * disableNodePolyfills?: boolean; - * disableConfig?: boolean; - * disableMeta?: boolean; - * disableHmr?: boolean; - * disableLoading?: boolean; + * Plugin options. * - * loadingElementId?: string; - * loadingColor?: string; - * loadingImage?: string; - * }} PluginOptions + * @typedef {Object} PluginOptions + * @property {boolean} [disableNodePolyfills=false] - Disable node polyfills. + * @property {boolean} [disableConfig=false] - Disable config plugin. + * @property {boolean} [disableMeta=false] - Disable meta plugin. + * @property {boolean} [disableHmr=false] - Disable hmr plugin. + * @property {boolean} [disableLoading=false] - Disable loading plugin. + * @property {boolean} [disableDebug=false] - Disable debug plugin. + * + * @property {string} [loadingElementId] + * @property {string} [loadingColor] + * @property {string} [loadingImage] + * @property {'all'|'mobile'|'desktop'} [debugPlatform='mobile'] + * @property {string} [debugScript] */ /** + * Create blocklet plugins. * * @param {PluginOptions} options - * @returns + * @returns {import('vite').Plugin[]} */ export function createBlockletPlugin(options = {}) { const { @@ -33,9 +39,13 @@ export function createBlockletPlugin(options = {}) { disableMeta = false, disableHmr = false, disableLoading = false, + disableDebug = false, ...restOptions } = options; + + /** @type {import('vite').Plugin[]} */ const plugins = []; + if (!disableMeta) { plugins.push(createMetaPlugin(restOptions)); } @@ -51,6 +61,9 @@ export function createBlockletPlugin(options = {}) { if (!disableLoading) { plugins.push(createLoadingPlugin(restOptions)); } + if (!disableDebug) { + plugins.push(createDebugPlugin(restOptions)); + } return plugins; } @@ -61,5 +74,6 @@ export { createConfigPlugin as createBlockletConfig, createMetaPlugin as createBlockletMeta, createLoadingPlugin as createBlockletLoading, + createDebugPlugin as createBlockletDebug, nodePolyfills, }; diff --git a/plugins/vite-plugin-blocklet/libs/client.js b/plugins/vite-plugin-blocklet/libs/client.js index 66925f66..031a7670 100644 --- a/plugins/vite-plugin-blocklet/libs/client.js +++ b/plugins/vite-plugin-blocklet/libs/client.js @@ -1,3 +1,5 @@ +import fs from 'node:fs'; +import path from 'node:path'; import getPort from 'get-port'; import { createServer } from 'vite'; import mri from 'mri'; @@ -5,6 +7,18 @@ import mri from 'mri'; const argv = process.argv.slice(2); const isProduction = process.env.NODE_ENV === 'production' || process.env.ABT_NODE_SERVICE_ENV === 'production'; +/** + * Sets up the client for the application. + * + * @param {Object} app - The application object. + * @param {Object} [options={}] - The options object. + * @param {string} [options.host='127.0.0.1'] - The host for the server. + * @param {string} [options.protocol='ws'] - The protocol for the server. + * @param {number} [options.port] - The port for the server. + * @param {string} [options.configFile=''] - The path to the config file. + * @param {string} [options.appType='spa'] - The type of the application. + * @return {Promise} A promise that resolves to the Vite server object. + */ export default async function setupClient(app, options = {}) { if (!isProduction) { const params = mri(argv, { @@ -13,7 +27,28 @@ export default async function setupClient(app, options = {}) { }, }); const { host = '127.0.0.1', protocol = 'ws', port: inputPort, configFile = '', appType = 'spa' } = options; - const port = await getPort({ port: inputPort }); + let skipWritePort = true; + let envAppendContent = ''; + const envFile = path.join(process.cwd(), '.env.development.local'); + let port; + + if (!fs.existsSync(envFile)) { + skipWritePort = false; + port = await getPort({ port: inputPort }); + envAppendContent = `VITE_BLOCKLET_PORT=${port}`; + } else { + port = await getPort({ port: inputPort }); + const content = await fs.promises.readFile(envFile, 'utf-8'); + if (!content.includes('VITE_BLOCKLET_PORT')) { + skipWritePort = false; + envAppendContent = `${content}\nVITE_BLOCKLET_PORT=${port}`; + } else { + port = process.env.VITE_BLOCKLET_PORT; + } + } + if (!skipWritePort && envAppendContent) { + await fs.promises.writeFile(envFile, envAppendContent); + } // 以中间件模式创建 Vite 服务器 const vite = await createServer({ configFile: params.config || configFile || undefined, diff --git a/plugins/vite-plugin-blocklet/libs/config.js b/plugins/vite-plugin-blocklet/libs/config.js index c8565969..c98da168 100644 --- a/plugins/vite-plugin-blocklet/libs/config.js +++ b/plugins/vite-plugin-blocklet/libs/config.js @@ -1,5 +1,5 @@ -import fs from 'fs'; -import path from 'path'; +import fs from 'node:fs'; +import path from 'node:path'; import YAML from 'yaml'; import { toBlockletDid, isInBlocklet } from './utils.js'; diff --git a/plugins/vite-plugin-blocklet/libs/debug.js b/plugins/vite-plugin-blocklet/libs/debug.js new file mode 100644 index 00000000..a5df05a9 --- /dev/null +++ b/plugins/vite-plugin-blocklet/libs/debug.js @@ -0,0 +1,81 @@ +import isMobile from 'ismobilejs'; +import { isInBlocklet } from './utils.js'; + +/** + * Creates a config plugin for Vite development server. + * + * @param {object} options - The options for the plugin. + * @param {'all'|'mobile'|'desktop'} [options.debugPlatform='mobile'] - The platforms to enable debug mode for. + * @param {string} [options.debugScript] - The initialization code for the debug script. + * @return {object} The Vite config plugin. + */ +export default function createConfigPlugin(options) { + return { + name: 'blocklet:debug', // plugin name + /** + * Configure server + * @param {import('vite').ViteDevServer} server vite server + */ + configureServer(server) { + if (isInBlocklet) { + server.middlewares.use((req, res, next) => { + /** + * Enabled debug mode by platform + * @type {boolean} + */ + let enabled = false; + const debugPlatform = options.debugPlatform || 'mobile'; + if (debugPlatform.includes('all')) { + enabled = true; + } + const isMobileFn = isMobile.default ? isMobile.default : isMobile; + if (isMobileFn(req.headers['user-agent']).any) { + if (debugPlatform.includes('mobile')) { + enabled = true; + } + } else { + if (debugPlatform.includes('desktop')) { + enabled = true; + } + } + if (enabled) { + try { + const url = new URL(req.url, 'http://localhost'); + if (url.pathname === '/') { + url.searchParams.set('debug', ''); + req.originalUrl = url.pathname + url.search; + } + } catch {} + } + return next(); + }); + } + }, + /** + * Transform index html + * @param {string} html original html content + * @param {import('vite').IndexHtmlTransformContext} ctx vite context + * @returns {import('vite').IndexHtmlTransformResult} + */ + transformIndexHtml(html, ctx) { + const debugScript = + options.debugScript || "import('https://esm.run/vconsole').then(({ default: vConsole }) => new vConsole())"; + try { + const url = new URL(ctx.originalUrl, 'http://localhost'); + if (url.searchParams.has('debug')) { + return { + html, + tags: [ + { + tag: 'script', + children: debugScript, + injectTo: 'body', + }, + ], + }; + } + } catch {} + return html; + }, + }; +} diff --git a/plugins/vite-plugin-blocklet/libs/hmr.js b/plugins/vite-plugin-blocklet/libs/hmr.js index c17d9dec..34d5ce4b 100644 --- a/plugins/vite-plugin-blocklet/libs/hmr.js +++ b/plugins/vite-plugin-blocklet/libs/hmr.js @@ -2,6 +2,13 @@ import { version as viteVersion } from 'vite'; import semver from 'semver'; import { isInBlocklet } from './utils.js'; +/** + * Creates a HMR plugin with the given options. + * + * @param {Object} options - The options for the HMR plugin. + * @param {string} options.version - The version of the vite version. + * @return {Object} The HMR plugin object. + */ export default function createHmrPlugin(options = {}) { const { version = viteVersion } = options; return { diff --git a/plugins/vite-plugin-blocklet/libs/loading.js b/plugins/vite-plugin-blocklet/libs/loading.js index 0f9398a6..b915b626 100644 --- a/plugins/vite-plugin-blocklet/libs/loading.js +++ b/plugins/vite-plugin-blocklet/libs/loading.js @@ -1,20 +1,10 @@ /** - * @typedef {{ - * color: string; - * image: string; - * }} GenerateOptions - */ -/** - * @typedef {{ - * loadingElementId?: string; - * loadingColor?: string; - * loadingImage?: string; - * }} LoadingPluginOptions - */ - -/** + * Generates an HTML string containing a spinner with optional color and image. * - * @param {GenerateOptions} options + * @param {Object} options - The options for generating the HTML. + * @param {string} options.color - The color of the spinner. Defaults to "#333". + * @param {string} options.image - The URL of the image to display alongside the spinner. + * @return {string} The generated HTML string. */ function generateHtml({ color, image }) { return `