Skip to content

Commit

Permalink
feat: support overlay configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
fi3ework committed Feb 6, 2022
1 parent bdbe7f7 commit eed4464
Show file tree
Hide file tree
Showing 12 changed files with 168 additions and 49 deletions.
1 change: 1 addition & 0 deletions packages/runtime/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Watch and compile code with mock diagnostics and html without vite-plugin-checke

```sh
pnpm dev-local
pnpm preview
```

### with vite-plugin-checker
Expand Down
12 changes: 7 additions & 5 deletions packages/runtime/src/App.svelte
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
<script>
import List from './components/List.svelte'
import Badge from './components/Badge.svelte'
let collapsed = false
export let overlayConfig = {}
export let initialIsOpen = true
export let checkerResults
let collapsed = !initialIsOpen
const toggle = () => {
collapsed = !collapsed
}
export let checkerResults
</script>

<Badge {checkerResults} {collapsed} onClick={toggle} />
<Badge {checkerResults} {collapsed} position={overlayConfig.position} onClick={toggle} />
<main class={`window ${collapsed ? 'window-collapsed' : ''}`} on:click|stopPropagation>
<div class="list-scroll">
<List {checkerResults} ulStyle="margin-bottom: 48px;" />
<List {checkerResults} ulStyle="margin-bottom: 36px;" />
</div>
</main>

Expand Down
25 changes: 23 additions & 2 deletions packages/runtime/src/components/Badge.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
export let collapsed
export let checkerResults
export let onClick
export let position = 'bl'
function calcSummary(results) {
let errorCount = 0
Expand All @@ -28,7 +29,9 @@
</script>

<button
class={`badge-button ${collapsed ? `to-uncollpase ${bgColorClass}` : 'to-collpase'}`}
class={`badge-base ${
collapsed ? `to-uncollpase ${bgColorClass}` : 'to-collpase'
} badge-${position}`}
on:click|stopPropagation={onClick}
>
{#if collapsed}
Expand All @@ -42,7 +45,7 @@
</button>

<style>
.badge-button {
.badge-base {
appearance: none;
font-size: 0.9em;
font-weight: bold;
Expand All @@ -53,10 +56,28 @@
position: fixed;
z-index: 99999;
margin: 0.5em;
}
.badge-bl {
bottom: 0px;
left: 0px;
}
.badge-br {
bottom: 0px;
right: 0px;
}
.badge-tl {
top: 0px;
left: 0px;
}
.badge-tr {
top: 0px;
right: 0px;
}
.to-collpase {
color: white;
background: rgb(63, 78, 96);
Expand Down
14 changes: 13 additions & 1 deletion packages/runtime/src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,17 @@
import App from './App.svelte'

let enableOverlay = true
import { prepareListen, listenToCustomMessage, listenToReconnectMessage } from './ws'
import {
prepareListen,
listenToCustomMessage,
listenToReconnectMessage,
listenToConfigMessage,
} from './ws'

let overlayEle = null
let app = null
let checkerResultsStore = []
let overlayConfig = {}

class ErrorOverlay extends HTMLElement {
constructor() {
Expand Down Expand Up @@ -54,6 +60,7 @@ function updateErrorOverlay(payloads) {
target: overlayEle.root,
props: {
checkerResults: checkerResultsStore,
overlayConfig,
},
})
} else {
Expand All @@ -69,6 +76,10 @@ function resumeErrorOverlay(data) {
updateErrorOverlay(payloadsToResume)
}

function configOverlay(data) {
overlayConfig = data
}

function clearErrorOverlay() {
document.querySelectorAll(overlayId).forEach((n) => n.close())
overlayEle = null
Expand All @@ -79,5 +90,6 @@ export function inject() {
const ws = prepareListen()
listenToCustomMessage(updateErrorOverlay)
listenToReconnectMessage(resumeErrorOverlay)
listenToConfigMessage(configOverlay)
ws.start()
}
29 changes: 19 additions & 10 deletions packages/runtime/src/ws.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,20 @@ const socketProtocol = null || (location.protocol === 'https:' ? 'wss' : 'ws')
const socketHost = `${location.hostname}:${location.port}`
const socket = new WebSocket(`${socketProtocol}://${socketHost}`, 'vite-hmr')

// #region
// NOTE: sync modification with packages/vite-plugin-checker/client/index.ts
const WS_CHECKER_ERROR_EVENT = 'vite-plugin-checker:error'
const WS_CHECKER_RECONNECT_EVENT = 'vite-plugin-checker:reconnect'
const WS_CHECKER_CONFIG_RUNTIME_EVENT = 'vite-plugin-checker:config-runtime'
// #endregion

const onCustomMessage = []
const onReconnectMessage = []
const onConfigMessage = []

export function listenToConfigMessage(cb) {
onConfigMessage.push(cb)
}

export function listenToCustomMessage(cb) {
onCustomMessage.push(cb)
Expand All @@ -24,19 +33,19 @@ export function prepareListen() {
break
case 'full-reload':
break
default:
break
}

if (data.type === 'custom') {
if (data.event === WS_CHECKER_ERROR_EVENT) {
// updateErrorOverlay(data.data)
onCustomMessage.forEach((callbackfn) => callbackfn(data.data))
}

if (data.event === WS_CHECKER_RECONNECT_EVENT) {
onReconnectMessage.forEach((callbackfn) => callbackfn(data.data))
// resumeErrorOverlay(data.data)
switch (data.event) {
case WS_CHECKER_ERROR_EVENT:
onCustomMessage.forEach((callbackfn) => callbackfn(data.data))
break
case WS_CHECKER_RECONNECT_EVENT:
onReconnectMessage.forEach((callbackfn) => callbackfn(data.data))
break
case WS_CHECKER_CONFIG_RUNTIME_EVENT:
onConfigMessage.forEach((callbackfn) => callbackfn(data.data))
break
}
}
}
Expand Down
16 changes: 9 additions & 7 deletions packages/vite-plugin-checker/src/client/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import fs from 'fs'

const RUNTIME_PUBLIC_PATH = '/@vite-plugin-checker-runtime'
const RUNTIME_FILE_PATH = require.resolve('../@runtime/main.js')
const WS_CHECKER_ERROR_EVENT = 'vite-plugin-checker:error'
const WS_CHECKER_RECONNECT_EVENT = 'vite-plugin-checker:reconnect'
// #region
// NOTE: sync modification with packages/runtime/src/ws.js
export const RUNTIME_PUBLIC_PATH = '/@vite-plugin-checker-runtime'
export const RUNTIME_FILE_PATH = require.resolve('../@runtime/main.js')
export const WS_CHECKER_ERROR_EVENT = 'vite-plugin-checker:error'
export const WS_CHECKER_RECONNECT_EVENT = 'vite-plugin-checker:reconnect'
export const WS_CHECKER_CONFIG_RUNTIME_EVENT = 'vite-plugin-checker:config-runtime'
// #endregion

const runtimeCode = `${fs.readFileSync(RUNTIME_FILE_PATH, 'utf-8')};`

export { runtimeCode, RUNTIME_PUBLIC_PATH, WS_CHECKER_ERROR_EVENT, WS_CHECKER_RECONNECT_EVENT }
export const runtimeCode = `${fs.readFileSync(RUNTIME_FILE_PATH, 'utf-8')};`
25 changes: 22 additions & 3 deletions packages/vite-plugin-checker/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ import npmRunPath from 'npm-run-path'
import { ConfigEnv, Plugin } from 'vite'

import { Checker } from './Checker'
import { RUNTIME_PUBLIC_PATH, runtimeCode, WS_CHECKER_RECONNECT_EVENT } from './client/index'
import {
RUNTIME_PUBLIC_PATH,
runtimeCode,
WS_CHECKER_RECONNECT_EVENT,
WS_CHECKER_CONFIG_RUNTIME_EVENT,
} from './client/index'
import {
ACTION_TYPES,
BuildCheckBinStr,
Expand Down Expand Up @@ -42,7 +47,8 @@ function createCheckers(userConfig: UserPluginConfig, env: ConfigEnv): ServeAndB

export default function Plugin(userConfig: UserPluginConfig): Plugin {
const enableBuild = userConfig?.enableBuild ?? true
const enableOverlay = userConfig?.overlay ?? true
const enableOverlay = userConfig?.overlay !== false
const overlayConfig = typeof userConfig?.overlay === 'object' ? userConfig?.overlay : null
let checkers: ServeAndBuildChecker[] = []
let viteMode: ConfigEnv['command'] | undefined

Expand All @@ -59,7 +65,6 @@ export default function Plugin(userConfig: UserPluginConfig): Plugin {
checkers.forEach((checker) => {
const workerConfig = checker.serve.config
workerConfig({
// hmr: typeof hmr === 'object' ? { overlay: hmr.overlay } : hmr,
enableOverlay,
env,
})
Expand Down Expand Up @@ -120,6 +125,13 @@ export default function Plugin(userConfig: UserPluginConfig): Plugin {
let latestOverlayErrors: OverlayErrorAction['payload'][] = new Array(checkers.length)
// for dev mode (2/2)
// Get the server instance and keep reference in a closure
if (overlayConfig) {
server.ws.send({
type: 'custom',
event: WS_CHECKER_CONFIG_RUNTIME_EVENT,
data: overlayConfig,
})
}
checkers.forEach((checker, index) => {
const { worker, configureServer: workerConfigureServer } = checker.serve
workerConfigureServer({ root: server.config.root })
Expand All @@ -143,6 +155,13 @@ export default function Plugin(userConfig: UserPluginConfig): Plugin {
connectedTimes++
// if connectedCount !== 1, means Vite is doing a full-reload, so we don't need to send overlay again
if (connectedTimes > 1) {
if (overlayConfig) {
server.ws.send({
type: 'custom',
event: WS_CHECKER_CONFIG_RUNTIME_EVENT,
data: overlayConfig,
})
}
server.ws.send({
type: 'custom',
event: WS_CHECKER_RECONNECT_EVENT,
Expand Down
33 changes: 18 additions & 15 deletions packages/vite-plugin-checker/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,20 +69,24 @@ export interface SharedConfig {
* @defaultValue
* Same as [Vite config](https://vitejs.dev/config/#root)
*/
overlay: boolean
// TODO: not implemented
// | {
// /**
// * Set this true if you want the overlay to default to being open if errors/warnings are found.
// * @defaultValue `true`
// */
// initialIsOpen?: boolean
// /**
// * The position of the vite-plugin-checker badge to open and close the diagnostics panel
// * @default `bottom-left`
// */
// position?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'
// }
overlay:
| boolean
| {
/**
* Set this true if you want the overlay to default to being open if errors/warnings are found.
* @defaultValue `true`
*/
initialIsOpen?: boolean
/**
* The position of the vite-plugin-checker badge to open and close the diagnostics panel
* @default `bl`
*/
position?: 'tl' | 'tr' | 'bl' | 'br'
/**
* Use this to add extra style to the badge button
*/
badgeStyle?: string
}
}

export interface BuildInCheckers {
Expand Down Expand Up @@ -124,7 +128,6 @@ export interface OverlayErrorAction extends Action {
}

interface ConfigActionPayload {
// hmr?: { overlay?: boolean } | boolean
enableOverlay: boolean
env: ConfigEnv
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`overlay overlay prompts and changes 1`] = `"Argument of type 'number' is not assignable to parameter of type 'string | (() => string)'."`;
exports[`overlay-true overlay prompts and changes 1`] = `"Argument of type 'number' is not assignable to parameter of type 'string | (() => string)'."`;

exports[`overlay overlay prompts and changes 2`] = `"<PROJECT_ROOT>/temp/react-ts/src/App.tsx:6:46"`;
exports[`overlay-true overlay prompts and changes 2`] = `"<PROJECT_ROOT>/temp/react-ts/src/App.tsx:6:46"`;
exports[`overlay overlay prompts and changes 3`] = `
exports[`overlay-true overlay prompts and changes 3`] = `
" 4 |
5 | function App() {
> 6 | const [count, setCount] = useState<string>(1)
Expand All @@ -14,7 +14,7 @@ exports[`overlay overlay prompts and changes 3`] = `
9 | <header className=\\"App-header\\">"
`;
exports[`overlay overlay prompts and changes 4`] = `
exports[`overlay-true overlay prompts and changes 4`] = `
" 4 |
5 | function App() {
> 6 | const [count, setCount] = useState<string>(2)
Expand Down
50 changes: 50 additions & 0 deletions playground/react-ts/__tests__/overlay-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import {
getHmrOverlayText,
killServer,
preTest,
viteServe,
} from 'vite-plugin-checker/__tests__/e2e/Sandbox/Sandbox'
import {
editFile,
sleep,
testDir,
WORKER_CLEAN_TIMEOUT,
} from 'vite-plugin-checker/__tests__/e2e/testUtils'

import { copyCode } from '../../../scripts/jestSetupFilesAfterEnv'
import { serializers } from '../../../scripts/serializers'

expect.addSnapshotSerializer(serializers)

beforeAll(async () => {
await preTest()
})

afterAll(async () => {
await sleep(WORKER_CLEAN_TIMEOUT)
})

describe('overlay-config', () => {
beforeEach(async () => {
await copyCode()
})

afterEach(async () => {
await killServer()
})

it('overlay: config', async () => {
editFile('vite.config.ts', (code) =>
code.replace(
'typescript: true,',
`typescript: true, overlay: { position: 'br', initialIsOpen: false, },`
)
)

await viteServe({ cwd: testDir, launchPage: true })
await sleep(6000)
await expect(getHmrOverlayText()).rejects.toThrow(
'Invariant failed: <vite-plugin-checker-error-overlay> shadow dom is expected to be found, but got null'
)
})
})
2 changes: 1 addition & 1 deletion playground/react-ts/__tests__/overlay-false.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ afterAll(async () => {
await sleep(WORKER_CLEAN_TIMEOUT)
})

describe('overlay', () => {
describe('overlay-false', () => {
beforeEach(async () => {
await copyCode()
})
Expand Down
Loading

0 comments on commit eed4464

Please sign in to comment.