From c8ed57e7117bb001f7bf3748d7f4d33875cb738a Mon Sep 17 00:00:00 2001 From: Kelly Mears <developers@tinypixel.dev> Date: Wed, 16 Aug 2023 13:05:41 -0400 Subject: [PATCH 1/3] =?UTF-8?q?=E2=9C=A8=20improve(patch):=20@roots/bud-cl?= =?UTF-8?q?ient=20export=20mapping?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sources/@roots/bud-client/package.json | 41 ++++++++- .../src/hot/{client.ts => client/index.ts} | 91 ++++++++----------- .../bud-client/src/hot/components/index.ts | 4 +- .../{indicator.component.ts => component.ts} | 2 +- ...{indicator.controller.ts => controller.ts} | 0 .../src/hot/components/indicator/index.ts | 4 +- .../{indicator.pulse.ts => pulse.ts} | 0 .../{overlay.component.ts => component.ts} | 0 .../{overlay.controller.ts => controller.ts} | 0 .../src/hot/components/overlay/index.ts | 4 +- .../src/hot/{events.ts => events/index.ts} | 0 sources/@roots/bud-client/src/hot/index.ts | 12 +-- .../src/hot/{log.ts => log/index.ts} | 0 .../src/hot/{options.ts => options/index.ts} | 0 sources/@roots/bud-client/src/index.ts | 4 +- sources/@roots/bud-client/src/lazy.ts | 18 ++-- .../@roots/bud-client/src/types/index.d.ts | 2 +- sources/@roots/bud-client/test/client.test.ts | 21 ++--- 18 files changed, 108 insertions(+), 95 deletions(-) rename sources/@roots/bud-client/src/hot/{client.ts => client/index.ts} (65%) rename sources/@roots/bud-client/src/hot/components/indicator/{indicator.component.ts => component.ts} (98%) rename sources/@roots/bud-client/src/hot/components/indicator/{indicator.controller.ts => controller.ts} (100%) rename sources/@roots/bud-client/src/hot/components/indicator/{indicator.pulse.ts => pulse.ts} (100%) rename sources/@roots/bud-client/src/hot/components/overlay/{overlay.component.ts => component.ts} (100%) rename sources/@roots/bud-client/src/hot/components/overlay/{overlay.controller.ts => controller.ts} (100%) rename sources/@roots/bud-client/src/hot/{events.ts => events/index.ts} (100%) rename sources/@roots/bud-client/src/hot/{log.ts => log/index.ts} (100%) rename sources/@roots/bud-client/src/hot/{options.ts => options/index.ts} (100%) diff --git a/sources/@roots/bud-client/package.json b/sources/@roots/bud-client/package.json index d51b8ad60a..7e78336c43 100644 --- a/sources/@roots/bud-client/package.json +++ b/sources/@roots/bud-client/package.json @@ -46,15 +46,48 @@ "type": "module", "exports": { ".": "./lib/index.js", + "./hot": "./lib/hot/index.js", + "./hot/client": "./lib/hot/client/index.js", + "./hot/components": "./lib/hot/components/index.js", + "./hot/components/indicator": "./lib/hot/components/indicator/index.js", + "./hot/components/overlay": "./lib/hot/components/overlay/index.js", + "./hot/events": "./lib/hot/events/index.js", + "./hot/log": "./lib/hot/log/index.js", + "./hot/options": "./lib/hot/options/index.js", "./dom-ready": "./lib/dom-ready.js", "./lazy": "./lib/lazy.js", - "./lib/*": "./lib/*" + "./lib/*": "./lib/*", + "./log": "./lib/log.js" }, "typesVersions": { "*": { ".": [ "./lib/index.d.ts" ], + "hot": [ + "./lib/hot/index.d.ts" + ], + "hot/client": [ + "./lib/hot/client/index.d.ts" + ], + "hot/components": [ + "./lib/hot/components/index.d.ts" + ], + "hot/components/indicator": [ + "./lib/hot/components/indicator/index.d.ts" + ], + "hot/components/overlay": [ + "./lib/hot/components/overlay/index.d.ts" + ], + "hot/events": [ + "./lib/hot/events/index.d.ts" + ], + "hot/log": [ + "./lib/hot/log/index.d.ts" + ], + "hot/options": [ + "./lib/hot/options/index.d.ts" + ], "dom-ready": [ "./lib/dom-ready.d.ts" ], @@ -63,6 +96,12 @@ ], "lib/*": [ "./lib/*" + ], + "log": [ + "./lib/log.d.ts" + ], + "types": [ + "./lib/types/index.d.ts" ] } }, diff --git a/sources/@roots/bud-client/src/hot/client.ts b/sources/@roots/bud-client/src/hot/client/index.ts similarity index 65% rename from sources/@roots/bud-client/src/hot/client.ts rename to sources/@roots/bud-client/src/hot/client/index.ts index 21beff6273..0c4efb18bf 100644 --- a/sources/@roots/bud-client/src/hot/client.ts +++ b/sources/@roots/bud-client/src/hot/client/index.ts @@ -2,15 +2,15 @@ /* global __resourceQuery */ /* global __webpack_hash__ */ -import * as components from './components/index.js' -import {injectEvents} from './events.js' -import {makeLogger} from './log.js' -import * as clientOptions from './options.js' +import * as components from '@roots/bud-client/hot/components' +import {injectEvents} from '@roots/bud-client/hot/events' +import {makeLogger} from '@roots/bud-client/hot/log' +import * as clientOptions from '@roots/bud-client/hot/options' /** * Initializes bud.js HMR handling */ -export const client = async ( +export const initializeClient = async ( queryString: string, webpackHot: __WebpackModuleApi.Hot, ) => { @@ -34,20 +34,18 @@ export const client = async ( /* Setup logger */ const logger = makeLogger(options) - if (typeof window.bud === `undefined`) { - window.bud = { - controllers: [], - current: {}, - hmr: {}, - listeners: {}, - } - } - - if (!window.bud.current[options.name]) { - window.bud.current[options.name] = null + window.bud = { + ...window.bud ?? {}, + controllers: [...window.bud?.controllers ?? []], + current: { + ...window.bud?.current ?? {}, + [options.name]: window.bud?.current?.[options.name] ?? null, + }, + hmr: {...window.bud?.hmr ?? {}}, + listeners: {...window.bud?.listeners ?? {}}, } - const isStale = (hash?: string) => { + const isStale = (hash?: string): boolean => { if (hash) window.bud.current[options.name] = hash return __webpack_hash__ === window.bud.current[options.name] } @@ -61,7 +59,25 @@ export const client = async ( requestAnimationFrame(async function whenReady() { if (webpackHot.status() === `ready`) { - await update() + await webpackHot + .apply({ + ignoreDeclined: true, + ignoreErrored: true, + ignoreUnaccepted: true, + onDeclined: onUnacceptedOrDeclined, + onErrored: (error: any) => { + window.bud.controllers.map( + controller => + controller?.update({ + errors: [error], + }), + ) + }, + onUnaccepted: onUnacceptedOrDeclined, + }) + .catch(logger.error) + + if (!isStale()) await check() } else { requestAnimationFrame(whenReady) } @@ -75,46 +91,12 @@ export const client = async ( const onUnacceptedOrDeclined = ( info: __WebpackModuleApi.HotNotifierInfo, ) => { - console.warn(`[${options.name}] ${info.type}`, info) + logger.warn(info.type, info) options.reload && window.location.reload() } - /** - * Webpack HMR error handler - */ - const onErrored = (error: any) => { - window.bud.controllers.map( - controller => - controller?.update({ - errors: [error], - }), - ) - } - - /** - * Webpack HMR update handler - */ - const update = async () => { - try { - await webpackHot.apply({ - ignoreDeclined: true, - ignoreErrored: true, - ignoreUnaccepted: true, - onDeclined: onUnacceptedOrDeclined, - onErrored, - onUnaccepted: onUnacceptedOrDeclined, - }) - - if (!isStale()) await check() - } catch (error) { - logger.error(error) - } - } - /* Instantiate indicator, overlay */ - try { - await components.make(options) - } catch (error) {} + await components.make(options).catch(err => {}) /* Instantiate eventSource */ const events = injectEvents(EventSource).make(options) @@ -127,6 +109,7 @@ export const client = async ( return window.location.reload() if (payload.name !== options.name) return + window.bud.controllers.map(controller => controller?.update(payload)) if (payload.errors?.length > 0) return diff --git a/sources/@roots/bud-client/src/hot/components/index.ts b/sources/@roots/bud-client/src/hot/components/index.ts index a12ae1bfe1..b3d91ebe34 100644 --- a/sources/@roots/bud-client/src/hot/components/index.ts +++ b/sources/@roots/bud-client/src/hot/components/index.ts @@ -1,5 +1,5 @@ -import * as Indicator from './indicator/index.js' -import * as Overlay from './overlay/index.js' +import * as Indicator from '@roots/bud-client/hot/components/indicator' +import * as Overlay from '@roots/bud-client/hot/components/overlay' export const make: ( options: Options, diff --git a/sources/@roots/bud-client/src/hot/components/indicator/indicator.component.ts b/sources/@roots/bud-client/src/hot/components/indicator/component.ts similarity index 98% rename from sources/@roots/bud-client/src/hot/components/indicator/indicator.component.ts rename to sources/@roots/bud-client/src/hot/components/indicator/component.ts index 6d88aa919f..ae4eb5ab2b 100644 --- a/sources/@roots/bud-client/src/hot/components/indicator/indicator.component.ts +++ b/sources/@roots/bud-client/src/hot/components/indicator/component.ts @@ -1,4 +1,4 @@ -import {pulse} from './indicator.pulse.js' +import {pulse} from './pulse.js' /** * Indicator web component diff --git a/sources/@roots/bud-client/src/hot/components/indicator/indicator.controller.ts b/sources/@roots/bud-client/src/hot/components/indicator/controller.ts similarity index 100% rename from sources/@roots/bud-client/src/hot/components/indicator/indicator.controller.ts rename to sources/@roots/bud-client/src/hot/components/indicator/controller.ts diff --git a/sources/@roots/bud-client/src/hot/components/indicator/index.ts b/sources/@roots/bud-client/src/hot/components/indicator/index.ts index e5a3766c6a..1ebeff1144 100644 --- a/sources/@roots/bud-client/src/hot/components/indicator/index.ts +++ b/sources/@roots/bud-client/src/hot/components/indicator/index.ts @@ -1,5 +1,5 @@ -import {Component} from './indicator.component.js' -import {Controller} from './indicator.controller.js' +import {Component} from './component.js' +import {Controller} from './controller.js' export const make = () => { if (customElements.get(`bud-activity-indicator`)) return diff --git a/sources/@roots/bud-client/src/hot/components/indicator/indicator.pulse.ts b/sources/@roots/bud-client/src/hot/components/indicator/pulse.ts similarity index 100% rename from sources/@roots/bud-client/src/hot/components/indicator/indicator.pulse.ts rename to sources/@roots/bud-client/src/hot/components/indicator/pulse.ts diff --git a/sources/@roots/bud-client/src/hot/components/overlay/overlay.component.ts b/sources/@roots/bud-client/src/hot/components/overlay/component.ts similarity index 100% rename from sources/@roots/bud-client/src/hot/components/overlay/overlay.component.ts rename to sources/@roots/bud-client/src/hot/components/overlay/component.ts diff --git a/sources/@roots/bud-client/src/hot/components/overlay/overlay.controller.ts b/sources/@roots/bud-client/src/hot/components/overlay/controller.ts similarity index 100% rename from sources/@roots/bud-client/src/hot/components/overlay/overlay.controller.ts rename to sources/@roots/bud-client/src/hot/components/overlay/controller.ts diff --git a/sources/@roots/bud-client/src/hot/components/overlay/index.ts b/sources/@roots/bud-client/src/hot/components/overlay/index.ts index 05c2f5a13c..b5e112f011 100644 --- a/sources/@roots/bud-client/src/hot/components/overlay/index.ts +++ b/sources/@roots/bud-client/src/hot/components/overlay/index.ts @@ -1,5 +1,5 @@ -import {Component} from './overlay.component.js' -import {Controller} from './overlay.controller.js' +import {Component} from './component.js' +import {Controller} from './controller.js' export const make = (): { update: (data: Payload) => void diff --git a/sources/@roots/bud-client/src/hot/events.ts b/sources/@roots/bud-client/src/hot/events/index.ts similarity index 100% rename from sources/@roots/bud-client/src/hot/events.ts rename to sources/@roots/bud-client/src/hot/events/index.ts diff --git a/sources/@roots/bud-client/src/hot/index.ts b/sources/@roots/bud-client/src/hot/index.ts index d175bbb30a..5b13792c02 100644 --- a/sources/@roots/bud-client/src/hot/index.ts +++ b/sources/@roots/bud-client/src/hot/index.ts @@ -2,15 +2,7 @@ /* global __resourceQuery */ /* global module */ -import {client} from './client.js' - -/** - * Client entrypoint - */ ;(async function () { - try { - await client(__resourceQuery, import.meta.webpackHot) - } catch (err) { - console.error(err) - } + const {initializeClient} = await import(`@roots/bud-client/hot/client`) + await initializeClient(__resourceQuery, import.meta.webpackHot).catch(console.error) })() diff --git a/sources/@roots/bud-client/src/hot/log.ts b/sources/@roots/bud-client/src/hot/log/index.ts similarity index 100% rename from sources/@roots/bud-client/src/hot/log.ts rename to sources/@roots/bud-client/src/hot/log/index.ts diff --git a/sources/@roots/bud-client/src/hot/options.ts b/sources/@roots/bud-client/src/hot/options/index.ts similarity index 100% rename from sources/@roots/bud-client/src/hot/options.ts rename to sources/@roots/bud-client/src/hot/options/index.ts diff --git a/sources/@roots/bud-client/src/index.ts b/sources/@roots/bud-client/src/index.ts index 8fcdc8afe7..60b6c1ea07 100644 --- a/sources/@roots/bud-client/src/index.ts +++ b/sources/@roots/bud-client/src/index.ts @@ -2,15 +2,13 @@ // Licensed under the MIT license. /** - * `@roots/bud` client scripts + * @roots/bud-client * * You should not import this root module. * Import the components from the submodules instead. * * @see https://bud.js.org * @see https://github.com/roots/bud - * - * @packageDocumentation */ import domReady from '@roots/bud-client/dom-ready' diff --git a/sources/@roots/bud-client/src/lazy.ts b/sources/@roots/bud-client/src/lazy.ts index 77d8ec4636..5f7cc67381 100644 --- a/sources/@roots/bud-client/src/lazy.ts +++ b/sources/@roots/bud-client/src/lazy.ts @@ -9,7 +9,7 @@ */ interface lazy { <T = any>( - module: Promise<{default: T}>, + module: Promise<T>, handler: (module: T) => Promise<unknown> | unknown, errorHandler?: (error: unknown) => unknown, ): Promise<unknown> @@ -25,16 +25,18 @@ const defaultErrorHandler = (error: unknown) => { } const lazy: lazy = async function lazy<T = any>( - module: Promise<{default: T}>, - handler: (module: T) => Promise<unknown> | unknown, - errorHandler?: (error: unknown) => unknown, + module: Promise<T>, + onImport: (module: T) => Promise<unknown> | unknown, + onError?: (error: unknown) => unknown, ) { try { - const {default: request} = await module - return await handler(request) + const request = await module + if (!request) throw new Error(`module not found: ${module}`) + const result = await onImport(request) + return result } catch (error: unknown) { - const handle = errorHandler ? errorHandler : defaultErrorHandler - handle(error) + const errorFn = onError ? onError : defaultErrorHandler + errorFn(error) } } diff --git a/sources/@roots/bud-client/src/types/index.d.ts b/sources/@roots/bud-client/src/types/index.d.ts index ce08c8ad86..d6c50c718b 100644 --- a/sources/@roots/bud-client/src/types/index.d.ts +++ b/sources/@roots/bud-client/src/types/index.d.ts @@ -49,6 +49,6 @@ declare var bud: { declare module global { interface Window { - bud: typeof bud + bud?: typeof bud } } diff --git a/sources/@roots/bud-client/test/client.test.ts b/sources/@roots/bud-client/test/client.test.ts index c9cdfb19b4..2b6b882016 100644 --- a/sources/@roots/bud-client/test/client.test.ts +++ b/sources/@roots/bud-client/test/client.test.ts @@ -1,14 +1,13 @@ -import '../src/types/index.d.ts' - -/* eslint-disable no-console */ /** * @vitest-environment jsdom */ + +import {initializeClient} from '@roots/bud-client/hot/client' +import {injectEvents} from '@roots/bud-client/hot/events' +import * as options from '@roots/bud-client/hot/options' import {describe, expect, it, vi} from 'vitest' -import {client} from '../src/hot/client.js' -import {injectEvents} from '../src/hot/events.js' -import * as options from '../src/hot/options.js' +import '../src/types/index.d.ts' // @ts-ignore global.EventSource = class Events { @@ -27,21 +26,21 @@ const webpackHotMock = { describe(`@roots/bud-client`, () => { it(`should be a fn module`, () => { - expect(client).toBeInstanceOf(Function) + expect(initializeClient).toBeInstanceOf(Function) }) it(`should add window.bud`, async () => { - await client(`?name=test`, webpackHotMock) + await initializeClient(`?name=test`, webpackHotMock) expect(window.bud).toBeDefined() }) it(`should add window.bud.hmr as an instance of EventSource`, async () => { - await client(`?name=test`, webpackHotMock) + await initializeClient(`?name=test`, webpackHotMock) expect(window.bud?.hmr?.test).toBeInstanceOf(EventSource) }) it(`should set clientOptions`, async () => { - await client(`?name=test`, webpackHotMock) + await initializeClient(`?name=test`, webpackHotMock) expect(options.data).toEqual( expect.objectContaining({ debug: true, @@ -57,7 +56,7 @@ describe(`@roots/bud-client`, () => { }) it(`should call listener from onmessage`, async () => { - await client(`?name=test`, webpackHotMock) + await initializeClient(`?name=test`, webpackHotMock) const events = Events.make(options.data) const listenerMock = vi.fn(async () => {}) From c0a0045276e9241af3a2849da3a8e07df31d8725 Mon Sep 17 00:00:00 2001 From: Kelly Mears <developers@tinypixel.dev> Date: Thu, 17 Aug 2023 11:33:43 -0400 Subject: [PATCH 2/3] =?UTF-8?q?=E2=9C=A8=20improve(patch):=20set=20strict?= =?UTF-8?q?=20mode=20for=20@roots/bud-client?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sources/@roots/bud-client/package.json | 14 ++--- .../@roots/bud-client/src/hot/client/index.ts | 59 ++++++++++--------- .../bud-client/src/hot/components/index.ts | 12 ++-- .../src/hot/components/indicator/component.ts | 32 +++++----- .../hot/components/indicator/controller.ts | 2 +- .../src/hot/components/overlay/component.ts | 11 ++-- .../src/hot/components/overlay/controller.ts | 6 +- .../src/hot/components/overlay/index.ts | 2 +- .../@roots/bud-client/src/hot/events/index.ts | 10 +++- sources/@roots/bud-client/src/hot/index.ts | 4 +- .../bud-client/src/hot/options/index.ts | 19 +++--- sources/@roots/bud-client/src/index.ts | 6 +- .../@roots/bud-client/src/intercept/index.ts | 50 +++++++--------- .../src/intercept/proxy-click-interceptor.ts | 11 +++- .../@roots/bud-client/src/types/index.d.ts | 2 +- sources/@roots/bud-client/tsconfig.json | 1 + yarn.lock | 6 +- 17 files changed, 124 insertions(+), 123 deletions(-) diff --git a/sources/@roots/bud-client/package.json b/sources/@roots/bud-client/package.json index 7e78336c43..8e2bc2af3d 100644 --- a/sources/@roots/bud-client/package.json +++ b/sources/@roots/bud-client/package.json @@ -46,6 +46,7 @@ "type": "module", "exports": { ".": "./lib/index.js", + "./dom-ready": "./lib/dom-ready.js", "./hot": "./lib/hot/index.js", "./hot/client": "./lib/hot/client/index.js", "./hot/components": "./lib/hot/components/index.js", @@ -54,16 +55,17 @@ "./hot/events": "./lib/hot/events/index.js", "./hot/log": "./lib/hot/log/index.js", "./hot/options": "./lib/hot/options/index.js", - "./dom-ready": "./lib/dom-ready.js", "./lazy": "./lib/lazy.js", - "./lib/*": "./lib/*", - "./log": "./lib/log.js" + "./lib/*": "./lib/*" }, "typesVersions": { "*": { ".": [ "./lib/index.d.ts" ], + "dom-ready": [ + "./lib/dom-ready.d.ts" + ], "hot": [ "./lib/hot/index.d.ts" ], @@ -88,18 +90,12 @@ "hot/options": [ "./lib/hot/options/index.d.ts" ], - "dom-ready": [ - "./lib/dom-ready.d.ts" - ], "lazy": [ "./lib/lazy.d.ts" ], "lib/*": [ "./lib/*" ], - "log": [ - "./lib/log.d.ts" - ], "types": [ "./lib/types/index.d.ts" ] diff --git a/sources/@roots/bud-client/src/hot/client/index.ts b/sources/@roots/bud-client/src/hot/client/index.ts index 0c4efb18bf..05ec742b5c 100644 --- a/sources/@roots/bud-client/src/hot/client/index.ts +++ b/sources/@roots/bud-client/src/hot/client/index.ts @@ -21,35 +21,45 @@ export const initializeClient = async ( ) return false } - /* Guard: webpackHot api availability */ - if (!webpackHot) { - console.error( - `[bud] hot module reload requires the webpack hot api to be available`, - ) - return false - } /* Set client options from URL params */ const options = clientOptions.setFromParameters(queryString) /* Setup logger */ const logger = makeLogger(options) + /** + * Setup window.bud + */ window.bud = { - ...window.bud ?? {}, - controllers: [...window.bud?.controllers ?? []], + ...(window.bud ?? {}), + controllers: window.bud?.controllers ?? [], current: { - ...window.bud?.current ?? {}, + ...(window.bud?.current ?? {}), [options.name]: window.bud?.current?.[options.name] ?? null, }, - hmr: {...window.bud?.hmr ?? {}}, - listeners: {...window.bud?.listeners ?? {}}, + hmr: window.bud?.hmr ?? {}, + listeners: window.bud?.listeners ?? {}, } + /** + * Is update stale? + */ const isStale = (hash?: string): boolean => { + if (!window.bud.current) return false if (hash) window.bud.current[options.name] = hash return __webpack_hash__ === window.bud.current[options.name] } + /** + * Unaccepted & declined module handler + */ + const onUnacceptedOrDeclined = ( + info: __WebpackModuleApi.HotNotifierInfo, + ) => { + logger.warn(info.type, info) + options.reload && window.location.reload() + } + /** * Webpack HMR check handler */ @@ -66,11 +76,8 @@ export const initializeClient = async ( ignoreUnaccepted: true, onDeclined: onUnacceptedOrDeclined, onErrored: (error: any) => { - window.bud.controllers.map( - controller => - controller?.update({ - errors: [error], - }), + window.bud.controllers?.map( + c => c?.update({errors: [error]}), ) }, onUnaccepted: onUnacceptedOrDeclined, @@ -85,22 +92,16 @@ export const initializeClient = async ( } } - /** - * Webpack HMR unaccepted module handler - */ - const onUnacceptedOrDeclined = ( - info: __WebpackModuleApi.HotNotifierInfo, - ) => { - logger.warn(info.type, info) - options.reload && window.location.reload() - } - /* Instantiate indicator, overlay */ await components.make(options).catch(err => {}) /* Instantiate eventSource */ const events = injectEvents(EventSource).make(options) + if (!window.bud.listeners) { + window.bud.listeners = {} + } + if (!window.bud.listeners?.[options.name]) { window.bud.listeners[options.name] = async payload => { if (!payload) return @@ -110,9 +111,9 @@ export const initializeClient = async ( if (payload.name !== options.name) return - window.bud.controllers.map(controller => controller?.update(payload)) + window.bud.controllers?.map(controller => controller?.update(payload)) - if (payload.errors?.length > 0) return + if (typeof payload.errors !== `undefined` && payload.errors.length > 0) return if (payload.action === `built` || payload.action === `sync`) { if (isStale(payload.hash)) return diff --git a/sources/@roots/bud-client/src/hot/components/index.ts b/sources/@roots/bud-client/src/hot/components/index.ts index b3d91ebe34..4d54605529 100644 --- a/sources/@roots/bud-client/src/hot/components/index.ts +++ b/sources/@roots/bud-client/src/hot/components/index.ts @@ -5,17 +5,19 @@ export const make: ( options: Options, ) => Promise<Array<Controller>> = async options => { if (options.indicator && !customElements.get(`bud-activity-indicator`)) { - maybePushController(Indicator.make()) + const indicator = Indicator.make() + if (indicator) maybePushController(indicator) } if (options.overlay && !customElements.get(`bud-error`)) { - maybePushController(Overlay.make()) + const overlay = Overlay.make() + if (overlay) maybePushController(overlay) } - return window.bud.controllers + return window.bud.controllers ?? [] } -const maybePushController = (controller: Controller | undefined) => { +const maybePushController = (controller: any) => { if (!controller) return - window.bud.controllers.push(controller) + window.bud.controllers?.push(controller) } diff --git a/sources/@roots/bud-client/src/hot/components/indicator/component.ts b/sources/@roots/bud-client/src/hot/components/indicator/component.ts index ae4eb5ab2b..d10246df23 100644 --- a/sources/@roots/bud-client/src/hot/components/indicator/component.ts +++ b/sources/@roots/bud-client/src/hot/components/indicator/component.ts @@ -17,7 +17,7 @@ export class Component extends HTMLElement { /** * Timer */ - public hideTimeout: NodeJS.Timer + public declare hideTimeout: NodeJS.Timer /** * Component name @@ -27,7 +27,7 @@ export class Component extends HTMLElement { /** * Has component rendered */ - public rendered: boolean + public declare rendered: boolean /** * Class constructor @@ -78,7 +78,7 @@ export class Component extends HTMLElement { */ public hide() { this.hideTimeout = setTimeout(() => { - this.shadowRoot.querySelector(this.selector).classList.remove(`show`) + this.shadowRoot?.querySelector(this.selector)?.classList.remove(`show`) }, 2000) } @@ -89,9 +89,9 @@ export class Component extends HTMLElement { this.show() this.shadowRoot - .querySelector(this.selector) - .classList.remove(`warning`, `success`, `pending`) - this.shadowRoot.querySelector(this.selector).classList.add(`error`) + ?.querySelector(this.selector) + ?.classList.remove(`warning`, `success`, `pending`) + this.shadowRoot?.querySelector(this.selector)?.classList.add(`error`) } /** @@ -101,10 +101,10 @@ export class Component extends HTMLElement { this.show() this.shadowRoot - .querySelector(this.selector) - .classList.remove(`error`, `warning`, `success`) + ?.querySelector(this.selector) + ?.classList.remove(`error`, `warning`, `success`) - this.shadowRoot.querySelector(this.selector).classList.add(`pending`) + this.shadowRoot?.querySelector(this.selector)?.classList.add(`pending`) this.hide() } @@ -116,10 +116,10 @@ export class Component extends HTMLElement { this.show() this.shadowRoot - .querySelector(this.selector) - .classList.remove(`error`, `warning`, `pending`) + ?.querySelector(this.selector) + ?.classList.remove(`error`, `warning`, `pending`) - this.shadowRoot.querySelector(this.selector).classList.add(`success`) + this.shadowRoot?.querySelector(this.selector)?.classList.add(`success`) this.hide() } @@ -131,10 +131,10 @@ export class Component extends HTMLElement { this.show() this.shadowRoot - .querySelector(this.selector) - .classList.remove(`error`, `success`, `pending`) + ?.querySelector(this.selector) + ?.classList.remove(`error`, `success`, `pending`) - this.shadowRoot.querySelector(this.selector).classList.add(`warning`) + this.shadowRoot?.querySelector(this.selector)?.classList.add(`warning`) } /** @@ -196,6 +196,6 @@ export class Component extends HTMLElement { */ public show() { this.hideTimeout && clearTimeout(this.hideTimeout) - this.shadowRoot.querySelector(this.selector).classList.add(`show`) + this.shadowRoot?.querySelector(this.selector)?.classList.add(`show`) } } diff --git a/sources/@roots/bud-client/src/hot/components/indicator/controller.ts b/sources/@roots/bud-client/src/hot/components/indicator/controller.ts index dcd568ce00..15cd573c3a 100644 --- a/sources/@roots/bud-client/src/hot/components/indicator/controller.ts +++ b/sources/@roots/bud-client/src/hot/components/indicator/controller.ts @@ -15,7 +15,7 @@ export class Controller { /** * Timer handler */ - public timer: NodeJS.Timeout + public declare timer: NodeJS.Timeout /** * Initialization diff --git a/sources/@roots/bud-client/src/hot/components/overlay/component.ts b/sources/@roots/bud-client/src/hot/components/overlay/component.ts index a9d4fc689c..37ae4bcc77 100644 --- a/sources/@roots/bud-client/src/hot/components/overlay/component.ts +++ b/sources/@roots/bud-client/src/hot/components/overlay/component.ts @@ -27,10 +27,13 @@ export class Component extends HTMLElement { if (this.getAttribute(`message`)) { document.body.style.overflow = `hidden` - this.shadowRoot.querySelector(`.overlay`).classList.add(`visible`) + this.shadowRoot?.querySelector(`.overlay`)?.classList.add(`visible`) - this.shadowRoot.querySelector(`.messages`).innerHTML = - this.getAttribute(`message`) + const message = this.getAttribute(`message`) + const messages = this.shadowRoot?.querySelector(`.messages`) + + if (messages && `innerHTML` in messages && typeof message === `string`) + messages.innerHTML = message return } @@ -39,7 +42,7 @@ export class Component extends HTMLElement { document.body.style.overflow = this.documentBodyStyle.overflow } - this.shadowRoot.querySelector(`.overlay`).classList.remove(`visible`) + this.shadowRoot?.querySelector(`.overlay`)?.classList.remove(`visible`) } public connectedCallback() { diff --git a/sources/@roots/bud-client/src/hot/components/overlay/controller.ts b/sources/@roots/bud-client/src/hot/components/overlay/controller.ts index 4fc2dd31f2..8e69c474d0 100644 --- a/sources/@roots/bud-client/src/hot/components/overlay/controller.ts +++ b/sources/@roots/bud-client/src/hot/components/overlay/controller.ts @@ -18,7 +18,7 @@ export class Controller { /** * HMR update */ - public payload: Payload + public declare payload: Payload /** * Class constructor @@ -39,7 +39,7 @@ export class Controller { /** * Formatted error message */ - public get message(): string { + public get message(): string | undefined { return this.payload.errors?.reduce((a, c) => { const msg = c?.message ?? c?.error ?? c if (!msg) return a @@ -65,7 +65,7 @@ export class Controller { this.element.setAttribute(`message`, this.message ?? ``) - if (this.payload.errors?.length > 0) { + if (this.payload.errors && this.payload.errors?.length > 0) { return this.createError() } diff --git a/sources/@roots/bud-client/src/hot/components/overlay/index.ts b/sources/@roots/bud-client/src/hot/components/overlay/index.ts index b5e112f011..f23ba3434f 100644 --- a/sources/@roots/bud-client/src/hot/components/overlay/index.ts +++ b/sources/@roots/bud-client/src/hot/components/overlay/index.ts @@ -3,7 +3,7 @@ import {Controller} from './controller.js' export const make = (): { update: (data: Payload) => void -} => { +} | undefined => { if (customElements.get(`bud-error`)) return customElements.define(`bud-error`, Component) diff --git a/sources/@roots/bud-client/src/hot/events/index.ts b/sources/@roots/bud-client/src/hot/events/index.ts index a4682a6f00..04cbb34344 100644 --- a/sources/@roots/bud-client/src/hot/events/index.ts +++ b/sources/@roots/bud-client/src/hot/events/index.ts @@ -14,12 +14,12 @@ export const injectEvents = (eventSource: EventSourceFactory) => { /** * Registered listeners */ - public listeners: Set<Listener> = new Set<Listener>() + public listeners: Set<Listener> = new Set<Listener>([]) /** * EventSource `onmessage` handler */ - public override onmessage = async function (payload: MessageEvent) { + public override onmessage = async function (this: any, payload: MessageEvent) { if (!payload?.data || payload.data == `\uD83D\uDC93`) { return } @@ -65,7 +65,11 @@ export const injectEvents = (eventSource: EventSourceFactory) => { public static make( options: Partial<Options> & {name: string; path: string}, ): Events { - if (typeof window.bud.hmr[options.name] === `undefined`) + if (typeof window.bud.hmr === `undefined`) { + window.bud.hmr = {} + } + + if (typeof window.bud.hmr?.[options.name] === `undefined`) Object.assign(window.bud.hmr, { [options.name]: new Events(options), }) diff --git a/sources/@roots/bud-client/src/hot/index.ts b/sources/@roots/bud-client/src/hot/index.ts index 5b13792c02..4b8af1b4ea 100644 --- a/sources/@roots/bud-client/src/hot/index.ts +++ b/sources/@roots/bud-client/src/hot/index.ts @@ -2,7 +2,9 @@ /* global __resourceQuery */ /* global module */ +import {initializeClient} from '@roots/bud-client/hot/client' + ;(async function () { - const {initializeClient} = await import(`@roots/bud-client/hot/client`) + if (!import.meta.webpackHot) return await initializeClient(__resourceQuery, import.meta.webpackHot).catch(console.error) })() diff --git a/sources/@roots/bud-client/src/hot/options/index.ts b/sources/@roots/bud-client/src/hot/options/index.ts index d95ed8712b..20023272ee 100644 --- a/sources/@roots/bud-client/src/hot/options/index.ts +++ b/sources/@roots/bud-client/src/hot/options/index.ts @@ -1,7 +1,7 @@ /** * Client options */ -let data: Options = { +const data: Record<string, any> = { debug: true, indicator: true, log: true, @@ -15,23 +15,20 @@ let data: Options = { /** * Get client option */ -const get = (name?: string, key?: string) => - key ? data[name][key] : data[name] - +const get = (name: `${keyof Options & string}`) => data[name] +const set = (name: `${keyof Options & string}`, value: any) => data[name] = value /** * Set client data based on URL parameters */ const setFromParameters = (query: string): Options => { - let parsedParams: Partial<Options> = {} - - new window.URLSearchParams(query).forEach((value, key) => { - parsedParams[key] = + new window.URLSearchParams(query).forEach((value: any, key: any) => { + data[key] = value === `true` ? true : value === `false` ? false : value }) - data[parsedParams.name] = {...data, ...parsedParams} + data[data.name] = {...data, ...data} - return data[parsedParams.name] + return data[data.name] } -export {data, get, setFromParameters} +export {data, get, set, setFromParameters} diff --git a/sources/@roots/bud-client/src/index.ts b/sources/@roots/bud-client/src/index.ts index 60b6c1ea07..5f97b3cdab 100644 --- a/sources/@roots/bud-client/src/index.ts +++ b/sources/@roots/bud-client/src/index.ts @@ -11,7 +11,5 @@ * @see https://github.com/roots/bud */ -import domReady from '@roots/bud-client/dom-ready' -import lazy from '@roots/bud-client/lazy' - -export {domReady, lazy} +export {default as domReady} from '@roots/bud-client/dom-ready' +export {default as lazy} from '@roots/bud-client/lazy' diff --git a/sources/@roots/bud-client/src/intercept/index.ts b/sources/@roots/bud-client/src/intercept/index.ts index d3d0d933a7..61b7024aa8 100644 --- a/sources/@roots/bud-client/src/intercept/index.ts +++ b/sources/@roots/bud-client/src/intercept/index.ts @@ -1,33 +1,25 @@ -type Target = HTMLAnchorElement | HTMLFormElement | HTMLLinkElement -type ElementTuple = [HTMLCollectionOf<Target>, any] +const intercept = (search: string, replace: string) => { + setInterval( + () => + [ + ...document.getElementsByTagName(`a`), + ...document.getElementsByTagName(`link`), + ].forEach(element => { + if (element.hasAttribute(`__bud_processed`)) return + if (!element.hasAttribute(`href`)) return + if (!element.getAttribute(`href`)?.startsWith(search)) return -const intercept = (...args: [string, string]) => { - args.every(arg => typeof arg === `string`) && - setInterval( - () => - [ - [document.getElementsByTagName(`a`), `href`], - [document.getElementsByTagName(`link`), `href`], - ] - .map( - ([elements, attribute]: ElementTuple): [ - Array<Target>, - any, - ] => [Array.from(elements), attribute], - ) - .forEach(([elements, attribute]: [Array<Target>, any]) => - elements - .filter(el => el.hasAttribute(attribute)) - .filter(el => !el.hasAttribute(`__bud_processed`)) - .filter(el => el.getAttribute(attribute).startsWith(args[0])) - .map(el => { - const value = el.getAttribute(attribute).replace(...args) - el.setAttribute(attribute, value) - el.toggleAttribute(`__bud_processed`) - }), - ), - 1000, - ) + const value = element + .getAttribute(`href`) + ?.replace(search, replace) + + if (!value) return + + element.setAttribute(`href`, value) + element.toggleAttribute(`__bud_processed`) + }), + 1000, + ) } export default intercept diff --git a/sources/@roots/bud-client/src/intercept/proxy-click-interceptor.ts b/sources/@roots/bud-client/src/intercept/proxy-click-interceptor.ts index 1bda3623a6..484eb03152 100644 --- a/sources/@roots/bud-client/src/intercept/proxy-click-interceptor.ts +++ b/sources/@roots/bud-client/src/intercept/proxy-click-interceptor.ts @@ -7,10 +7,15 @@ window.requestAnimationFrame(async function ready() { if (!__resourceQuery) return const params = new URLSearchParams(__resourceQuery) - if (!params || !params.has(`search`) || !params.has(`replace`)) return + if (!params) return - const search = decodeURI(params.get(`search`)) - const replace = decodeURI(params.get(`replace`)) + const searchUri = params.get(`search`) + if (!searchUri) return + const search = decodeURI(searchUri) + + const replaceUri = params.get(`replace`) + if (!replaceUri) return + const replace = decodeURI(replaceUri) return document.body ? intercept(search, replace) diff --git a/sources/@roots/bud-client/src/types/index.d.ts b/sources/@roots/bud-client/src/types/index.d.ts index d6c50c718b..492856b142 100644 --- a/sources/@roots/bud-client/src/types/index.d.ts +++ b/sources/@roots/bud-client/src/types/index.d.ts @@ -41,7 +41,7 @@ declare interface Options { } declare var bud: { - current?: Record<string, string> + current?: Record<string, string | null> controllers?: Array<Controller> hmr?: Record<string, Events & EventSource> listeners?: Record<string, Listener> diff --git a/sources/@roots/bud-client/tsconfig.json b/sources/@roots/bud-client/tsconfig.json index 58ec143fd6..fe58a3bc5d 100644 --- a/sources/@roots/bud-client/tsconfig.json +++ b/sources/@roots/bud-client/tsconfig.json @@ -5,6 +5,7 @@ "outDir": "./lib", "rootDir": "./src", "sourceMap": false, + "strict": true, "target": "ES2021", }, "files": [ diff --git a/yarn.lock b/yarn.lock index f50d5f0530..e223c07f67 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15449,9 +15449,9 @@ __metadata: linkType: hard "caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30001464, caniuse-lite@npm:^1.0.30001503, caniuse-lite@npm:^1.0.30001517": - version: 1.0.30001520 - resolution: "caniuse-lite@npm:1.0.30001520" - checksum: 59991ad8f36cf282f81abbcc6074c3097c21914cdd54bd2b3f73ac9462f57fc74e90371cd22bcdff4d085d09da42a07dcea384cb81e4ac260496e1bd79e1fe7c + version: 1.0.30001521 + resolution: "caniuse-lite@npm:1.0.30001521" + checksum: be2a2b2cd3be03401887aaa31b89f3e7c6230289e6ef704e224268389cc136480fca502ac9e5001a65ff1e50459d3d95f8c4b2d39f878ab9843af3d6f372c8bb languageName: node linkType: hard From 81f73244055f33abd3d5a1303b41ea8a88bf6742 Mon Sep 17 00:00:00 2001 From: Kelly Mears <developers@tinypixel.dev> Date: Fri, 18 Aug 2023 10:17:30 -0400 Subject: [PATCH 3/3] --- .../@roots/bud-client/src/hot/client/index.ts | 5 +-- .../@roots/bud-client/src/hot/events/index.ts | 10 +++--- .../bud-client/src/hot/options/index.ts | 25 ++++++------- .../@roots/bud-client/src/types/index.d.ts | 16 ++++----- sources/@roots/bud-client/test/client.test.ts | 10 ++++-- tests/reproductions/issue-1886.test.ts | 36 ++++++++----------- 6 files changed, 49 insertions(+), 53 deletions(-) diff --git a/sources/@roots/bud-client/src/hot/client/index.ts b/sources/@roots/bud-client/src/hot/client/index.ts index 05ec742b5c..f0197baa6e 100644 --- a/sources/@roots/bud-client/src/hot/client/index.ts +++ b/sources/@roots/bud-client/src/hot/client/index.ts @@ -24,6 +24,7 @@ export const initializeClient = async ( /* Set client options from URL params */ const options = clientOptions.setFromParameters(queryString) + if (!options.name || !options.path) return /* Setup logger */ const logger = makeLogger(options) @@ -45,6 +46,7 @@ export const initializeClient = async ( * Is update stale? */ const isStale = (hash?: string): boolean => { + if (!options.name) return true if (!window.bud.current) return false if (hash) window.bud.current[options.name] = hash return __webpack_hash__ === window.bud.current[options.name] @@ -95,7 +97,6 @@ export const initializeClient = async ( /* Instantiate indicator, overlay */ await components.make(options).catch(err => {}) - /* Instantiate eventSource */ const events = injectEvents(EventSource).make(options) if (!window.bud.listeners) { @@ -130,6 +131,6 @@ export const initializeClient = async ( * Instantiate HMR event source * and register client listeners */ - events.addListener(window.bud.listeners[options.name]) + options.name && events && events.addListener(window.bud.listeners[options.name]) } } diff --git a/sources/@roots/bud-client/src/hot/events/index.ts b/sources/@roots/bud-client/src/hot/events/index.ts index 04cbb34344..1cb642fff5 100644 --- a/sources/@roots/bud-client/src/hot/events/index.ts +++ b/sources/@roots/bud-client/src/hot/events/index.ts @@ -49,7 +49,7 @@ export const injectEvents = (eventSource: EventSourceFactory) => { * */ private constructor( - public options: Partial<Options> & {name: string; path: string}, + public options: {name: string; path: string}, ) { super(options.path) @@ -63,15 +63,17 @@ export const injectEvents = (eventSource: EventSourceFactory) => { * */ public static make( - options: Partial<Options> & {name: string; path: string}, - ): Events { + options: {name?: string; path?: string}, + ): Events | undefined { + if (!options?.name || !options?.path) return + if (typeof window.bud.hmr === `undefined`) { window.bud.hmr = {} } if (typeof window.bud.hmr?.[options.name] === `undefined`) Object.assign(window.bud.hmr, { - [options.name]: new Events(options), + [options.name]: new Events(options as any), }) return window.bud.hmr[options.name] diff --git a/sources/@roots/bud-client/src/hot/options/index.ts b/sources/@roots/bud-client/src/hot/options/index.ts index 20023272ee..c2e9efe583 100644 --- a/sources/@roots/bud-client/src/hot/options/index.ts +++ b/sources/@roots/bud-client/src/hot/options/index.ts @@ -1,7 +1,4 @@ -/** - * Client options - */ -const data: Record<string, any> = { +const defaultOptions: Options = { debug: true, indicator: true, log: true, @@ -12,23 +9,21 @@ const data: Record<string, any> = { timeout: 2000, } -/** - * Get client option - */ -const get = (name: `${keyof Options & string}`) => data[name] -const set = (name: `${keyof Options & string}`, value: any) => data[name] = value /** * Set client data based on URL parameters */ const setFromParameters = (query: string): Options => { - new window.URLSearchParams(query).forEach((value: any, key: any) => { - data[key] = + /** + * Client options + */ + const data: Partial<Options> = {...defaultOptions} + + new window.URLSearchParams(query).forEach((value: any, key: string) => { + data[key as unknown as `${keyof Options & string}`] = value === `true` ? true : value === `false` ? false : value }) - data[data.name] = {...data, ...data} - - return data[data.name] + return data } -export {data, get, set, setFromParameters} +export {setFromParameters} diff --git a/sources/@roots/bud-client/src/types/index.d.ts b/sources/@roots/bud-client/src/types/index.d.ts index 492856b142..a75bed03d8 100644 --- a/sources/@roots/bud-client/src/types/index.d.ts +++ b/sources/@roots/bud-client/src/types/index.d.ts @@ -30,14 +30,14 @@ declare interface Controller { } declare interface Options { - timeout: number - reload: boolean - debug: boolean - log: boolean - name: string - path: string - indicator: boolean - overlay: boolean + timeout?: number + reload?: boolean + debug?: boolean + log?: boolean + name?: string + path?: string + indicator?: boolean + overlay?: boolean } declare var bud: { diff --git a/sources/@roots/bud-client/test/client.test.ts b/sources/@roots/bud-client/test/client.test.ts index 2b6b882016..680523882c 100644 --- a/sources/@roots/bud-client/test/client.test.ts +++ b/sources/@roots/bud-client/test/client.test.ts @@ -41,12 +41,14 @@ describe(`@roots/bud-client`, () => { it(`should set clientOptions`, async () => { await initializeClient(`?name=test`, webpackHotMock) - expect(options.data).toEqual( + + const optionsObject = options.setFromParameters(`?name=test`) + expect(optionsObject).toEqual( expect.objectContaining({ debug: true, indicator: true, log: true, - name: `@roots/bud-client`, + name: `test`, overlay: true, path: `/bud/hot`, reload: true, @@ -57,7 +59,9 @@ describe(`@roots/bud-client`, () => { it(`should call listener from onmessage`, async () => { await initializeClient(`?name=test`, webpackHotMock) - const events = Events.make(options.data) + // @ts-ignore + const events = Events.make({name: `test`, path: `/bud/hot`}) + if (!events) throw new Error(`Events not defined`) const listenerMock = vi.fn(async () => {}) events.addListener(listenerMock) diff --git a/tests/reproductions/issue-1886.test.ts b/tests/reproductions/issue-1886.test.ts index 21c21e4d51..32f61d3bb2 100644 --- a/tests/reproductions/issue-1886.test.ts +++ b/tests/reproductions/issue-1886.test.ts @@ -1,6 +1,4 @@ -import {join} from 'node:path' - -import {paths} from '@repo/constants' +import {path} from '@repo/constants' import execa from '@roots/bud-support/execa' import {Filesystem} from '@roots/bud-support/filesystem' import {beforeAll, describe, expect, it} from 'vitest' @@ -11,26 +9,25 @@ describe(`issue-1886`, () => { beforeAll(async () => { fs = new Filesystem() await execa(`yarn`, [`bud`, `clean`], { - cwd: join(paths.tests, `reproductions`, `issue-1886`), + cwd: path(`tests`, `reproductions`, `issue-1886`), }) await execa(`yarn`, [`bud`, `build`], { - cwd: join(paths.tests, `reproductions`, `issue-1886`), + cwd: path(`tests`, `reproductions`, `issue-1886`), }) }) it(`should generate webp from png included in js source`, async () => { const manifest = await fs.read( - join( - paths.tests, + path(`tests`, `reproductions`, `issue-1886`, `dist`, `manifest.json`, ), ) - const path = manifest[`images/bud.png?as=webp`] + const imagePath = manifest[`images/bud.png?as=webp`] const image = await fs.read( - join(paths.tests, `reproductions`, `issue-1886`, `dist`, path), + path(`tests`, `reproductions`, `issue-1886`, `dist`, imagePath), `utf8`, ) expect(image.length).toMatchInlineSnapshot(`8377`) @@ -38,8 +35,7 @@ describe(`issue-1886`, () => { it(`should generate webp from png included in css source`, async () => { const manifest = await fs.read( - join( - paths.tests, + path(`tests`, `reproductions`, `issue-1886`, `dist`, @@ -47,11 +43,11 @@ describe(`issue-1886`, () => { ), ) - const path = + const imagePath = manifest[`images/bud-css.png?as=webp&width=1200&height=630`] const image = await fs.read( - join(paths.tests, `reproductions`, `issue-1886`, `dist`, path), + path(`tests`, `reproductions`, `issue-1886`, `dist`, imagePath), `utf8`, ) expect(image.length).toMatchInlineSnapshot(`8377`) @@ -59,8 +55,7 @@ describe(`issue-1886`, () => { it(`should inline svg when url appended with ?inline in css source`, async () => { const css = await fs.read( - join( - paths.tests, + path(`tests`, `reproductions`, `issue-1886`, `dist`, @@ -76,8 +71,7 @@ describe(`issue-1886`, () => { it(`should inline svg when url appended with ?inline in js source`, async () => { const js = await fs.read( - join( - paths.tests, + path(`tests`, `reproductions`, `issue-1886`, `dist`, @@ -93,17 +87,17 @@ describe(`issue-1886`, () => { it.skip(`should work with disk caching`, async () => { await execa(`yarn`, [`bud`, `clean`], { - cwd: join(paths.tests, `reproductions`, `issue-1886`), + cwd: path(`tests`, `reproductions`, `issue-1886`), }) const res1 = await execa(`yarn`, [`bud`, `build`, `--no-clean`], { - cwd: join(paths.tests, `reproductions`, `issue-1886`), + cwd: path(`tests`, `reproductions`, `issue-1886`), }) const res2 = await execa(`yarn`, [`bud`, `build`, `--no-clean`], { - cwd: join(paths.tests, `reproductions`, `issue-1886`), + cwd: path(`tests`, `reproductions`, `issue-1886`), }) const res3 = await execa(`yarn`, [`bud`, `build`, `--no-clean`], { - cwd: join(paths.tests, `reproductions`, `issue-1886`), + cwd: path(`tests`, `reproductions`, `issue-1886`), }) expect([res1.exitCode, res2.exitCode, res3.exitCode]).toEqual(