From 1dd69334240cea76e7db57b5ef1d70ed7f02c8f4 Mon Sep 17 00:00:00 2001 From: Bjorn Lu Date: Wed, 17 May 2023 14:21:48 +0800 Subject: [PATCH] refactor: move inspector to separate package (#646) Co-authored-by: dominikg --- .changeset/fresh-knives-reflect.md | 6 + .eslintrc.js | 8 +- .github/workflows/ci.yml | 4 + README.md | 8 +- docs/config.md | 102 +--------------- docs/inspector.md | 110 ++++++++++++++++++ packages/vite-plugin-svelte-inspector/LICENSE | 21 ++++ .../vite-plugin-svelte-inspector/README.md | 26 +++++ .../vite-plugin-svelte-inspector/package.json | 47 ++++++++ .../vite-plugin-svelte-inspector/src/debug.js | 3 + .../src/index.d.ts} | 68 +---------- .../src/index.js} | 67 ++++++----- .../src/options.js | 61 ++++++++++ .../src/runtime}/Inspector.svelte | 0 .../src/runtime}/load-inspector.js | 0 .../vite-plugin-svelte-inspector/src/utils.js | 8 ++ .../tsconfig.json | 19 +++ packages/vite-plugin-svelte/package.json | 4 +- packages/vite-plugin-svelte/src/index.ts | 3 +- .../src/ui/inspector/utils.ts | 13 --- .../vite-plugin-svelte/src/utils/options.ts | 3 +- pnpm-lock.yaml | 22 ++++ 22 files changed, 392 insertions(+), 211 deletions(-) create mode 100644 .changeset/fresh-knives-reflect.md create mode 100644 docs/inspector.md create mode 100644 packages/vite-plugin-svelte-inspector/LICENSE create mode 100644 packages/vite-plugin-svelte-inspector/README.md create mode 100644 packages/vite-plugin-svelte-inspector/package.json create mode 100644 packages/vite-plugin-svelte-inspector/src/debug.js rename packages/{vite-plugin-svelte/src/ui/inspector/options.ts => vite-plugin-svelte-inspector/src/index.d.ts} (51%) rename packages/{vite-plugin-svelte/src/ui/inspector/plugin.ts => vite-plugin-svelte-inspector/src/index.js} (55%) create mode 100644 packages/vite-plugin-svelte-inspector/src/options.js rename packages/{vite-plugin-svelte/src/ui/inspector => vite-plugin-svelte-inspector/src/runtime}/Inspector.svelte (100%) rename packages/{vite-plugin-svelte/src/ui/inspector => vite-plugin-svelte-inspector/src/runtime}/load-inspector.js (100%) create mode 100644 packages/vite-plugin-svelte-inspector/src/utils.js create mode 100644 packages/vite-plugin-svelte-inspector/tsconfig.json delete mode 100644 packages/vite-plugin-svelte/src/ui/inspector/utils.ts diff --git a/.changeset/fresh-knives-reflect.md b/.changeset/fresh-knives-reflect.md new file mode 100644 index 000000000..9a2958bdd --- /dev/null +++ b/.changeset/fresh-knives-reflect.md @@ -0,0 +1,6 @@ +--- +'@sveltejs/vite-plugin-svelte': minor +'@sveltejs/vite-plugin-svelte-inspector': patch +--- + +Refactor Svelte inspector as a separate package diff --git a/.eslintrc.js b/.eslintrc.js index 1f4d25288..d50e397ea 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -70,11 +70,17 @@ module.exports = { } }, { - files: ['packages/vite-plugin-svelte/src/ui/inspector/load-inspector.js'], + files: ['packages/vite-plugin-svelte-inspector/src/runtime/load-inspector.js'], env: { browser: true } }, + { + files: ['**/*.d.ts'], + rules: { + 'no-unused-vars': 'off' + } + }, { files: ['packages/e2e-tests/**', 'packages/playground/**'], rules: { diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 234dbb046..152ee6442 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -106,7 +106,11 @@ jobs: cache: 'pnpm' cache-dependency-path: '**/pnpm-lock.yaml' - name: install + if: matrix.node != 14 run: pnpm install --frozen-lockfile --prefer-offline --ignore-scripts + - name: install for node14 + if: matrix.node == 14 + run: pnpm install --no-frozen-lockfile --prefer-offline --ignore-scripts - name: build run: pnpm build:ci - name: install playwright chromium diff --git a/README.md b/README.md index 3a26d9f20..33b4ab0b8 100644 --- a/README.md +++ b/README.md @@ -31,13 +31,15 @@ export default defineConfig({ ## Documentation - [Plugin options](./docs/config.md) +- [Svelte Inspector](./docs/inspector.md) - [FAQ](./docs/faq.md) ## Packages -| Package | Changelog | -| ----------------------------------------------------------- | ----------------------------------------------------- | -| [@sveltejs/vite-plugin-svelte](packages/vite-plugin-svelte) | [Changelog](packages/vite-plugin-svelte/CHANGELOG.md) | +| Package | Changelog | +| ------------------------------------------------------------------------------- | --------------------------------------------------------------- | +| [@sveltejs/vite-plugin-svelte](packages/vite-plugin-svelte) | [Changelog](packages/vite-plugin-svelte/CHANGELOG.md) | +| [@sveltejs/vite-plugin-svelte-inspector](packages/vite-plugin-svelte-inspector) | [Changelog](packages/vite-plugin-svelte-inspector/CHANGELOG.md) | ## Got a question? / Need help? diff --git a/docs/config.md b/docs/config.md index 1a7332a5b..d88eea603 100644 --- a/docs/config.md +++ b/docs/config.md @@ -214,111 +214,13 @@ A [picomatch pattern](https://github.com/micromatch/picomatch), or array of patt ### inspector -- **Type:**`InspectorOptions | boolean` +- **Type:** `InspectorOptions | boolean` - **Default:** `unset` for dev, always `false` for build - ```ts - interface InspectorOptions { - /** - * define a key combo to toggle inspector, - * @default 'meta-shift' on mac, 'control-shift' on other os - * - * any number of modifiers `control` `shift` `alt` `meta` followed by zero or one regular key, separated by - - * examples: control-shift, control-o, control-alt-s meta-x control-meta - * Some keys have native behavior (e.g. alt-s opens history menu on firefox). - * To avoid conflicts or accidentally typing into inputs, modifier only combinations are recommended. - */ - toggleKeyCombo?: string; - - /** - * define keys to select elements with via keyboard - * @default {parent: 'ArrowUp', child: 'ArrowDown', next: 'ArrowRight', prev: 'ArrowLeft' } - * - * improves accessibility and also helps when you want to select elements that do not have a hoverable surface area - * due to tight wrapping - * - * parent: select closest parent - * child: select first child (or grandchild) - * next: next sibling (or parent if no next sibling exists) - * prev: previous sibling (or parent if no prev sibling exists) - */ - navKeys?: { parent: string; child: string; next: string; prev: string }; - - /** - * define key to open the editor for the currently selected dom node - * - * @default 'Enter' - */ - openKey?: string; - - /** - * inspector is automatically disabled when releasing toggleKeyCombo after holding it for a longpress - * @default true - */ - holdMode?: boolean; - - /** - * when to show the toggle button - * @default 'active' - */ - showToggleButton?: 'always' | 'active' | 'never'; - - /** - * where to display the toggle button - * @default top-right - */ - toggleButtonPos?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left'; - - /** - * inject custom styles when inspector is active - */ - customStyles?: boolean; - } - ``` - - Set to `true` or options object to enable svelte inspector during development. + Set to `true` or options object to enable svelte inspector during development. See the [inspector docs](./inspector.md) for the full configuration options. Inspector mode shows you the file location where the element under cursor is defined and you can click to quickly open your code editor at this location. - **Example:** - - ```js - // vite.config.js - export default defineConfig({ - plugins: [ - svelte({ - inspector: { - toggleKeyCombo: 'meta-shift', - holdMode: true, - showToggleButton: 'always', - toggleButtonPos: 'bottom-right' - } - }) - ] - }); - ``` - -#### Customizing Inspector options via environment - -Svelte Inspector toggle keys and other options are personal preferences. As such it isn't always convenient to define them in a shared svelte config file. -To allow you to use your own setup, svelte inspector can be configured via environment variables, both from shell and dotenv files. - -```shell -# just keycombo, unquoted string -SVELTE_INSPECTOR_TOGGLE=control-shift - -# options object as json, all options except appendTo are supported -SVELTE_INSPECTOR_OPTIONS='{"holdMode": false, "toggleButtonPos": "bottom-left"}' - -# disable completely -SVELTE_INSPECTOR_OPTIONS=false - -# force default options -SVELTE_INSPECTOR_OPTIONS=true -``` - -> Inspector options set on the environment take precedence over values set in svelte config and automatically enable svelte inspector during dev. - ## Experimental options These options are considered experimental and breaking changes to them can occur in any release! Specify them under the `experimental` option. diff --git a/docs/inspector.md b/docs/inspector.md new file mode 100644 index 000000000..249d38342 --- /dev/null +++ b/docs/inspector.md @@ -0,0 +1,110 @@ +# Inspector + +`@sveltejs/vite-plugin-svelte-inspector` is a Vite plugin that adds a Svelte inspector in the browser. It shows the file location where the element under cursor is defined and you can click to quickly open your code editor at this location. + +Note that `@sveltejs/vite-plugin-svelte` needs to be installed as a peer dependency as the inspector brings in Svelte components to be compiled. + +## Setup + +### with Svelte config + +```js +// svelte.config.js +export default { + vitePlugin: { + // set to true for defaults or customize with object + inspector: { + toggleKeyCombo: 'meta-shift', + showToggleButton: 'always', + toggleButtonPos: 'bottom-right' + } + } +}; +``` + +### with environment variables + +Svelte Inspector toggle keys and other options are personal preferences. As such it isn't always convenient to define them in a shared svelte config file. +To allow you to use your own setup, svelte inspector can be configured via environment variables, both from shell and dotenv files. + +```shell +# just keycombo, unquoted string +SVELTE_INSPECTOR_TOGGLE=control-shift + +# options object as json +SVELTE_INSPECTOR_OPTIONS='{"holdMode": false, "toggleButtonPos": "bottom-left"}' + +# disable completely +SVELTE_INSPECTOR_OPTIONS=false + +# force default options +SVELTE_INSPECTOR_OPTIONS=true +``` + +> Inspector options set on the environment take precedence over values set in svelte config and automatically enable svelte inspector during dev. + +## Plugin options + +### toggleKeyCombo + +- **Type:** `string` +- **Default:** `'meta-shift'` on mac, `'control-shift'` on other os + + Define a key combo to toggle inspector. + + The value is recommended to be any number of modifiers (e.g. `control`, `shift`, `alt`, `meta`) followed by zero or one regular key, separated by `-`. This helps avoid conflicts or accidentally typing into inputs. Note that some keys have native behavior (e.g. `alt-s` opens history menu on firefox). + + Examples: `control-shift`, `control-o`, `control-alt-s`, `meta-x`, `control-meta`. + +### navKeys + +- **Type:** `{ parent: string; child: string; next: string; prev: string }` +- **Default:** `{ parent: 'ArrowUp', child: 'ArrowDown', next: 'ArrowRight', prev: 'ArrowLeft' }` + + Define keys to select elements with via keyboard. This improves accessibility and helps selecting elements that do not have a hoverable surface area due to tight wrapping. + + - `parent`: select closest parent + - `child`: select first child (or grandchild) + - `next`: next sibling (or parent if no next sibling exists) + - `prev`: previous sibling (or parent if no prev sibling exists) + +### openKey + +- **Type:** `string` +- **Default:** `'Enter'` + + Define key to open the editor for the currently selected dom node. + +### holdMode + +- **Type:** `boolean` +- **Default:** `true` + + Inspector will only open when the `toggleKeyCombo` is held down, and close when released. + +### showToggleButton + +- **Type:** `'always' | 'active' | 'never'` +- **Default:** `'active'` + + When to show the toggle button. The toggle button allows you to click on-screen to enable/disable the inspector, rather than using the `toggleKeyCombo`. + + - `'always'`: always show the toggle button + - `'active'`: show the toggle button when the inspector is active + - `'never'`: never show the toggle button + +### toggleButtonPos + +- **Type:** `'top-right' | 'top-left' | 'bottom-right' | 'bottom-left'` +- **Default:** `'top-right'` + + Where to display the toggle button. + +### customStyles + +- **Type:** `boolean` +- **Default:** `true` + + Inject custom styles when inspector is active. This is useful if you want to customize the inspector styles to match your app. + + When the inspector is active, the `svelte-inspector-enabled` class is added to the `body` element, and the `svelte-inspector-active-target` class is added to the current active target (e.g. via hover or keyboard). diff --git a/packages/vite-plugin-svelte-inspector/LICENSE b/packages/vite-plugin-svelte-inspector/LICENSE new file mode 100644 index 000000000..c1a5d8f07 --- /dev/null +++ b/packages/vite-plugin-svelte-inspector/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 [these people](https://github.com/sveltejs/vite-plugin-svelte/graphs/contributors) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/vite-plugin-svelte-inspector/README.md b/packages/vite-plugin-svelte-inspector/README.md new file mode 100644 index 000000000..bbdf50c80 --- /dev/null +++ b/packages/vite-plugin-svelte-inspector/README.md @@ -0,0 +1,26 @@ +# @sveltejs/vite-plugin-svelte-inspector + +A [Svelte](https://svelte.dev) inspector plugin for [Vite](https://vitejs.dev). + +## Usage + +```js +// vite.config.js +import { defineConfig } from 'vite'; +import { svelte } from '@sveltejs/vite-plugin-svelte'; +import { svelteInspector } from '@sveltejs/vite-plugin-svelte-inspector'; + +export default defineConfig({ + plugins: [ + // the svelte plugin is required to work + svelte(), + svelteInspector({ + /* plugin options */ + }) + ] +}); +``` + +## License + +[MIT](./LICENSE) diff --git a/packages/vite-plugin-svelte-inspector/package.json b/packages/vite-plugin-svelte-inspector/package.json new file mode 100644 index 000000000..4f2eb72e3 --- /dev/null +++ b/packages/vite-plugin-svelte-inspector/package.json @@ -0,0 +1,47 @@ +{ + "name": "@sveltejs/vite-plugin-svelte-inspector", + "version": "1.0.0", + "license": "MIT", + "author": "dominikg", + "files": [ + "src" + ], + "type": "module", + "types": "src/index.d.ts", + "exports": { + ".": { + "types": "./src/index.d.ts", + "import": "./src/index.js" + } + }, + "engines": { + "node": "^14.18.0 || >= 16" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/sveltejs/vite-plugin-svelte.git", + "directory": "packages/vite-plugin-svelte-inspector" + }, + "keywords": [ + "vite-plugin", + "vite plugin", + "vite", + "svelte" + ], + "bugs": { + "url": "https://github.com/sveltejs/vite-plugin-svelte/issues" + }, + "homepage": "https://github.com/sveltejs/vite-plugin-svelte#readme", + "dependencies": { + "debug": "^4.3.4" + }, + "peerDependencies": { + "@sveltejs/vite-plugin-svelte": "^2.2.0", + "svelte": "^3.54.0", + "vite": "^4.0.0" + }, + "devDependencies": { + "@types/debug": "^4.1.7", + "svelte": "^3.59.1" + } +} diff --git a/packages/vite-plugin-svelte-inspector/src/debug.js b/packages/vite-plugin-svelte-inspector/src/debug.js new file mode 100644 index 000000000..0575a83fd --- /dev/null +++ b/packages/vite-plugin-svelte-inspector/src/debug.js @@ -0,0 +1,3 @@ +import _debug from 'debug'; + +export const debug = _debug('vite-plugin-svelte-inspector'); diff --git a/packages/vite-plugin-svelte/src/ui/inspector/options.ts b/packages/vite-plugin-svelte-inspector/src/index.d.ts similarity index 51% rename from packages/vite-plugin-svelte/src/ui/inspector/options.ts rename to packages/vite-plugin-svelte-inspector/src/index.d.ts index 6c3782c81..b5c2ce28b 100644 --- a/packages/vite-plugin-svelte/src/ui/inspector/options.ts +++ b/packages/vite-plugin-svelte-inspector/src/index.d.ts @@ -1,67 +1,6 @@ -import * as process from 'process'; -import { log } from '../../utils/log'; -import { loadEnv, ResolvedConfig } from 'vite'; -export const defaultInspectorOptions: InspectorOptions = { - toggleKeyCombo: process.platform === 'darwin' ? 'meta-shift' : 'control-shift', - navKeys: { parent: 'ArrowUp', child: 'ArrowDown', next: 'ArrowRight', prev: 'ArrowLeft' }, - openKey: 'Enter', - holdMode: true, - showToggleButton: 'active', - toggleButtonPos: 'top-right', - customStyles: true -}; +import type { Plugin } from 'vite'; -export function parseEnvironmentOptions( - config: ResolvedConfig -): Partial | boolean | void { - const env = loadEnv(config.mode, config.envDir ?? process.cwd(), 'SVELTE_INSPECTOR'); - const options = env?.SVELTE_INSPECTOR_OPTIONS; - const toggle = env?.SVELTE_INSPECTOR_TOGGLE; - if (options) { - try { - const parsed = JSON.parse(options); - const parsedType = typeof parsed; - if (parsedType === 'boolean') { - return parsed; - } else if (parsedType === 'object') { - if (Array.isArray(parsed)) { - throw new Error('invalid type, expected object map but got array'); - } - const parsedKeys = Object.keys(parsed); - const defaultKeys = Object.keys(defaultInspectorOptions); - const unknownKeys = parsedKeys.filter((k) => !defaultKeys.includes(k)); - if (unknownKeys.length) { - log.warn( - `ignoring unknown options in environment SVELTE_INSPECTOR_OPTIONS: ${unknownKeys.join( - ', ' - )}.`, - undefined, - 'inspector' - ); - for (const key of unknownKeys) { - delete parsed[key]; - } - } - log.debug('loaded environment config', parsed, 'inspector'); - return parsed; - } - } catch (e) { - log.error( - `failed to parse inspector options from environment SVELTE_INSPECTOR_OPTIONS="${options}"`, - e, - 'inspector' - ); - } - } else if (toggle) { - const keyConfig = { - toggleKeyCombo: toggle - }; - log.debug('loaded environment config', keyConfig, 'inspector'); - return keyConfig; - } -} - -export interface InspectorOptions { +export interface Options { /** * define a key combo to toggle inspector, * @default 'meta-shift' on mac, 'control-shift' on other os @@ -104,6 +43,7 @@ export interface InspectorOptions { * @default true */ holdMode?: boolean; + /** * when to show the toggle button * @default 'active' @@ -129,3 +69,5 @@ export interface InspectorOptions { base: string; }; } + +export declare function svelteInspector(options?: Options): Plugin; diff --git a/packages/vite-plugin-svelte/src/ui/inspector/plugin.ts b/packages/vite-plugin-svelte-inspector/src/index.js similarity index 55% rename from packages/vite-plugin-svelte/src/ui/inspector/plugin.ts rename to packages/vite-plugin-svelte-inspector/src/index.js index 881a9b5f0..fd289409c 100644 --- a/packages/vite-plugin-svelte/src/ui/inspector/plugin.ts +++ b/packages/vite-plugin-svelte-inspector/src/index.js @@ -1,66 +1,81 @@ -import { Plugin, normalizePath } from 'vite'; -import { log } from '../../utils/log'; +import { normalizePath } from 'vite'; +import fs from 'fs'; import path from 'path'; import { fileURLToPath } from 'url'; -import fs from 'fs'; -import { idToFile } from './utils'; -import { defaultInspectorOptions, type InspectorOptions, parseEnvironmentOptions } from './options'; +import { debug } from './debug.js'; +import { defaultInspectorOptions, parseEnvironmentOptions } from './options.js'; +import { cleanUrl } from './utils.js'; function getInspectorPath() { const pluginPath = normalizePath(path.dirname(fileURLToPath(import.meta.url))); - return pluginPath.replace(/\/vite-plugin-svelte\/dist$/, '/vite-plugin-svelte/src/ui/inspector/'); + return pluginPath.replace( + /\/vite-plugin-svelte-inspector\/src$/, + '/vite-plugin-svelte-inspector/src/runtime/' + ); } -export function svelteInspector(): Plugin { +/** @type {import('.').svelteInspector} */ +export function svelteInspector(options) { const inspectorPath = getInspectorPath(); - log.debug.enabled && log.debug(`svelte inspector path: ${inspectorPath}`); - let inspectorOptions: InspectorOptions; + debug(`svelte inspector path: ${inspectorPath}`); + + /** @type {import('vite').ResolvedConfig} */ + let viteConfig; + /** @type {import('.').Options} */ + let inspectorOptions; let disabled = false; return { - name: 'vite-plugin-svelte:inspector', + name: 'vite-plugin-svelte-inspector', apply: 'serve', enforce: 'pre', configResolved(config) { - const vps = config.plugins.find((p) => p.name === 'vite-plugin-svelte'); - if (!vps) { - log.warn('vite-plugin-svelte is missing, inspector disabled', undefined, 'inspector'); + viteConfig = config; + + const environmentOptions = parseEnvironmentOptions(config); + if (environmentOptions === false) { + debug(`environment options set to false, inspector disabled`); disabled = true; return; } + + // Handle config from svelte.config.js through vite-plugin-svelte + const vps = config.plugins.find((p) => p.name === 'vite-plugin-svelte'); const configFileOptions = vps?.api?.options?.inspector; - const environmentOptions = parseEnvironmentOptions(config); - if (!configFileOptions && !environmentOptions) { - log.debug('no options found, inspector disabled', undefined, 'inspector'); + + // vite-plugin-svelte can only pass options through it's `api` instead of `options`. + // that means this plugin could be created but should be disabled, so we check this case here. + if (vps && !options && !configFileOptions && !environmentOptions) { + debug(`vite-plugin-svelte didn't pass options, inspector disabled`); disabled = true; return; } + if (environmentOptions === true) { inspectorOptions = defaultInspectorOptions; } else { inspectorOptions = { ...defaultInspectorOptions, ...configFileOptions, + ...options, ...(environmentOptions || {}) }; } + inspectorOptions.__internal = { base: config.base?.replace(/\/$/, '') || '' }; }, - async resolveId(importee: string, importer, options) { + async resolveId(importee, _, options) { if (options?.ssr || disabled) { return; } if (importee.startsWith('virtual:svelte-inspector-options')) { return importee; } else if (importee.startsWith('virtual:svelte-inspector-path:')) { - const resolved = importee.replace('virtual:svelte-inspector-path:', inspectorPath); - log.debug.enabled && - log.debug(`resolved ${importee} with ${resolved}`, undefined, 'inspector'); - return resolved; + return importee.replace('virtual:svelte-inspector-path:', inspectorPath); } }, @@ -72,14 +87,12 @@ export function svelteInspector(): Plugin { return `export default ${JSON.stringify(inspectorOptions ?? {})}`; } else if (id.startsWith(inspectorPath)) { // read file ourselves to avoid getting shut out by vites fs.allow check - const file = idToFile(id); - if (fs.existsSync(file)) { + const file = cleanUrl(id); + if (fs.existsSync(id)) { return await fs.promises.readFile(file, 'utf-8'); } else { - log.error( - `failed to find file for svelte-inspector: ${file}, referenced by id ${id}.`, - undefined, - 'inspector' + viteConfig.logger.error( + `[vite-plugin-svelte-inspector] failed to find svelte-inspector: ${id}` ); } } diff --git a/packages/vite-plugin-svelte-inspector/src/options.js b/packages/vite-plugin-svelte-inspector/src/options.js new file mode 100644 index 000000000..9283df9b0 --- /dev/null +++ b/packages/vite-plugin-svelte-inspector/src/options.js @@ -0,0 +1,61 @@ +import { loadEnv } from 'vite'; +import { debug } from './debug.js'; + +/** @type {import('.').Options} */ +export const defaultInspectorOptions = { + toggleKeyCombo: process.platform === 'darwin' ? 'meta-shift' : 'control-shift', + navKeys: { parent: 'ArrowUp', child: 'ArrowDown', next: 'ArrowRight', prev: 'ArrowLeft' }, + openKey: 'Enter', + holdMode: true, + showToggleButton: 'active', + toggleButtonPos: 'top-right', + customStyles: true +}; + +/** + * @param {import('vite').ResolvedConfig} config + * @returns {Partial | boolean | void} + */ +export function parseEnvironmentOptions(config) { + const env = loadEnv(config.mode, config.envDir ?? process.cwd(), 'SVELTE_INSPECTOR'); + const options = env?.SVELTE_INSPECTOR_OPTIONS; + const toggle = env?.SVELTE_INSPECTOR_TOGGLE; + if (options) { + try { + const parsed = JSON.parse(options); + const parsedType = typeof parsed; + if (parsedType === 'boolean') { + return parsed; + } else if (parsedType === 'object') { + if (Array.isArray(parsed)) { + throw new Error('invalid type, expected object map but got array'); + } + const parsedKeys = Object.keys(parsed); + const defaultKeys = Object.keys(defaultInspectorOptions); + const unknownKeys = parsedKeys.filter((k) => !defaultKeys.includes(k)); + if (unknownKeys.length) { + config.logger.warn( + `[vite-plugin-svelte-inspector] ignoring unknown options in environment SVELTE_INSPECTOR_OPTIONS: ${unknownKeys.join( + ', ' + )}` + ); + for (const key of unknownKeys) { + delete parsed[key]; + } + } + debug('loaded environment config', parsed); + return parsed; + } + } catch (e) { + config.logger.error( + `[vite-plugin-svelte-inspector] failed to parse inspector options from environment SVELTE_INSPECTOR_OPTIONS="${options}"\n${e}` + ); + } + } else if (toggle) { + const keyConfig = { + toggleKeyCombo: toggle + }; + debug('loaded environment config', keyConfig); + return keyConfig; + } +} diff --git a/packages/vite-plugin-svelte/src/ui/inspector/Inspector.svelte b/packages/vite-plugin-svelte-inspector/src/runtime/Inspector.svelte similarity index 100% rename from packages/vite-plugin-svelte/src/ui/inspector/Inspector.svelte rename to packages/vite-plugin-svelte-inspector/src/runtime/Inspector.svelte diff --git a/packages/vite-plugin-svelte/src/ui/inspector/load-inspector.js b/packages/vite-plugin-svelte-inspector/src/runtime/load-inspector.js similarity index 100% rename from packages/vite-plugin-svelte/src/ui/inspector/load-inspector.js rename to packages/vite-plugin-svelte-inspector/src/runtime/load-inspector.js diff --git a/packages/vite-plugin-svelte-inspector/src/utils.js b/packages/vite-plugin-svelte-inspector/src/utils.js new file mode 100644 index 000000000..bcb43f9fc --- /dev/null +++ b/packages/vite-plugin-svelte-inspector/src/utils.js @@ -0,0 +1,8 @@ +const postfixRE = /[?#].*$/s; + +/** + * @param {string} url + */ +export function cleanUrl(url) { + return url.replace(postfixRE, ''); +} diff --git a/packages/vite-plugin-svelte-inspector/tsconfig.json b/packages/vite-plugin-svelte-inspector/tsconfig.json new file mode 100644 index 000000000..c0543ef45 --- /dev/null +++ b/packages/vite-plugin-svelte-inspector/tsconfig.json @@ -0,0 +1,19 @@ +{ + "include": ["src"], + "exclude": ["**/*.spec.ts"], + "compilerOptions": { + "outDir": "dist", + "target": "ES2020", + "module": "ES2020", + "moduleResolution": "node", + "strict": true, + "declaration": true, + "sourceMap": true, + "noUnusedLocals": true, + "esModuleInterop": true, + "baseUrl": ".", + "resolveJsonModule": true, + // see https://devblogs.microsoft.com/typescript/announcing-typescript-4-4-beta/#use-unknown-catch-variables + "useUnknownInCatchVariables": false + } +} diff --git a/packages/vite-plugin-svelte/package.json b/packages/vite-plugin-svelte/package.json index d3e99680a..eab854fc8 100644 --- a/packages/vite-plugin-svelte/package.json +++ b/packages/vite-plugin-svelte/package.json @@ -15,8 +15,7 @@ "types": "./dist/index.d.ts", "import": "./dist/index.js" }, - "./package.json": "./package.json", - "./src/ui/*": "./src/ui/*" + "./package.json": "./package.json" }, "scripts": { "dev": "pnpm build:ci --sourcemap --watch src", @@ -42,6 +41,7 @@ }, "homepage": "https://github.com/sveltejs/vite-plugin-svelte#readme", "dependencies": { + "@sveltejs/vite-plugin-svelte-inspector": "workspace:^", "debug": "^4.3.4", "deepmerge": "^4.3.1", "kleur": "^4.1.5", diff --git a/packages/vite-plugin-svelte/src/index.ts b/packages/vite-plugin-svelte/src/index.ts index fe4e9b29b..554b886a1 100644 --- a/packages/vite-plugin-svelte/src/index.ts +++ b/packages/vite-plugin-svelte/src/index.ts @@ -9,6 +9,8 @@ import { version as viteVersion } from 'vite'; // eslint-disable-next-line node/no-missing-import +import { svelteInspector } from '@sveltejs/vite-plugin-svelte-inspector'; +// eslint-disable-next-line node/no-missing-import import { isDepExcluded } from 'vitefu'; import { handleHotUpdate } from './handle-hot-update'; import { log, logCompilerWarnings } from './utils/log'; @@ -29,7 +31,6 @@ import { resolveViaPackageJsonSvelte } from './utils/resolve'; import { PartialResolvedId } from 'rollup'; import { toRollupError } from './utils/error'; import { saveSvelteMetadata } from './utils/optimizer'; -import { svelteInspector } from './ui/inspector/plugin'; import { VitePluginSvelteCache } from './utils/vite-plugin-svelte-cache'; import { loadRaw } from './utils/load-raw'; import { FAQ_LINK_CONFLICTS_IN_SVELTE_RESOLVE } from './utils/constants'; diff --git a/packages/vite-plugin-svelte/src/ui/inspector/utils.ts b/packages/vite-plugin-svelte/src/ui/inspector/utils.ts deleted file mode 100644 index 946f47428..000000000 --- a/packages/vite-plugin-svelte/src/ui/inspector/utils.ts +++ /dev/null @@ -1,13 +0,0 @@ -const FS_PREFIX = `/@fs/`; -const IS_WINDOWS = process.platform === 'win32'; -const queryRE = /\?.*$/s; -const hashRE = /#.*$/s; - -export function idToFile(id: string): string { - // strip /@fs/ but keep leading / on non-windows - if (id.startsWith(FS_PREFIX)) { - id = id = id.slice(IS_WINDOWS ? FS_PREFIX.length : FS_PREFIX.length - 1); - } - // strip query and hash - return id.replace(hashRE, '').replace(queryRE, ''); -} diff --git a/packages/vite-plugin-svelte/src/utils/options.ts b/packages/vite-plugin-svelte/src/utils/options.ts index 52a03dd8e..856a9d856 100644 --- a/packages/vite-plugin-svelte/src/utils/options.ts +++ b/packages/vite-plugin-svelte/src/utils/options.ts @@ -18,6 +18,8 @@ import type { Processed // eslint-disable-next-line node/no-missing-import } from 'svelte/types/compiler/preprocess'; +// eslint-disable-next-line node/no-missing-import +import type { Options as InspectorOptions } from '@sveltejs/vite-plugin-svelte-inspector'; import path from 'path'; import { esbuildSveltePlugin, facadeEsbuildSveltePluginName } from './esbuild'; @@ -35,7 +37,6 @@ import { import { isCommonDepWithoutSvelteField } from './dependencies'; import { VitePluginSvelteStats } from './vite-plugin-svelte-stats'; import { VitePluginSvelteCache } from './vite-plugin-svelte-cache'; -import type { InspectorOptions } from '../ui/inspector/options'; const allowedPluginOptions = new Set([ 'include', diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2d8f908e3..b4d9275ff 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -747,6 +747,9 @@ importers: packages/vite-plugin-svelte: dependencies: + '@sveltejs/vite-plugin-svelte-inspector': + specifier: workspace:^ + version: link:../vite-plugin-svelte-inspector debug: specifier: ^4.3.4 version: 4.3.4 @@ -785,6 +788,25 @@ importers: specifier: ^4.3.5 version: 4.3.5(@types/node@18.16.8)(sass@1.62.1)(stylus@0.59.0) + packages/vite-plugin-svelte-inspector: + dependencies: + '@sveltejs/vite-plugin-svelte': + specifier: ^2.2.0 + version: link:../vite-plugin-svelte + debug: + specifier: ^4.3.4 + version: 4.3.4 + vite: + specifier: ^4.0.0 + version: 4.3.5(@types/node@18.16.8)(sass@1.62.1)(stylus@0.59.0) + devDependencies: + '@types/debug': + specifier: ^4.1.7 + version: 4.1.7 + svelte: + specifier: ^3.59.1 + version: 3.59.1 + packages: /@adobe/css-tools@4.2.0: