Skip to content

Commit

Permalink
fix(vite): set ssr.noExternal even if not present in project packag…
Browse files Browse the repository at this point in the history
…e.json
  • Loading branch information
mcous committed Oct 11, 2024
1 parent f4b1508 commit fd05580
Show file tree
Hide file tree
Showing 4 changed files with 235 additions and 1 deletion.
2 changes: 2 additions & 0 deletions src/__tests__/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ export const IS_JSDOM = window.navigator.userAgent.includes('jsdom')

export const IS_HAPPYDOM = !IS_JSDOM // right now it's happy or js

export const IS_JEST = Boolean(process.env.JEST_WORKER_ID)

export const IS_SVELTE_5 = SVELTE_VERSION >= '5'

export const MODE_LEGACY = 'legacy'
Expand Down
186 changes: 186 additions & 0 deletions src/__tests__/vite-plugin.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
import { beforeEach, describe, expect, test, vi } from 'vitest'

import { svelteTesting } from '../vite.js'
import { IS_JEST } from './utils.js'

describe.skipIf(IS_JEST)('vite plugin', () => {
beforeEach(() => {
vi.stubEnv('VITEST', '1')
})

test('does not modify config if disabled', () => {
const subject = svelteTesting({
resolveBrowser: false,
autoCleanup: false,
noExternal: false,
})

const config = {}
subject.config(config)

expect(config).toEqual({})
})

test('does not modify config if not Vitest', () => {
vi.stubEnv('VITEST', '')

const subject = svelteTesting()
const config = {}

subject.config(config)

expect(config).toEqual({})
})

test.each([
{
config: { resolve: { conditions: ['node'] } },
expectedConditions: ['browser', 'node'],
},
{
config: { resolve: { conditions: ['svelte', 'node'] } },
expectedConditions: ['svelte', 'browser', 'node'],
},
])(
'adds browser condition if necessary',
({ config, expectedConditions }) => {
const subject = svelteTesting()
const viteConfig = structuredClone(config)

Check failure on line 48 in src/__tests__/vite-plugin.test.js

View workflow job for this annotation

GitHub Actions / Node 16, Svelte 3, test:vitest:jsdom

src/__tests__/vite-plugin.test.js > vite plugin > adds browser condition if necessary

ReferenceError: structuredClone is not defined ❯ src/__tests__/vite-plugin.test.js:48:26

Check failure on line 48 in src/__tests__/vite-plugin.test.js

View workflow job for this annotation

GitHub Actions / Node 16, Svelte 3, test:vitest:jsdom

src/__tests__/vite-plugin.test.js > vite plugin > adds browser condition if necessary

ReferenceError: structuredClone is not defined ❯ src/__tests__/vite-plugin.test.js:48:26

Check failure on line 48 in src/__tests__/vite-plugin.test.js

View workflow job for this annotation

GitHub Actions / Node 16, Svelte 3, test:vitest:happy-dom

src/__tests__/vite-plugin.test.js > vite plugin > adds browser condition if necessary

ReferenceError: structuredClone is not defined ❯ src/__tests__/vite-plugin.test.js:48:26

Check failure on line 48 in src/__tests__/vite-plugin.test.js

View workflow job for this annotation

GitHub Actions / Node 16, Svelte 3, test:vitest:happy-dom

src/__tests__/vite-plugin.test.js > vite plugin > adds browser condition if necessary

ReferenceError: structuredClone is not defined ❯ src/__tests__/vite-plugin.test.js:48:26

Check failure on line 48 in src/__tests__/vite-plugin.test.js

View workflow job for this annotation

GitHub Actions / Node 16, Svelte 4, test:vitest:jsdom

src/__tests__/vite-plugin.test.js > vite plugin > adds browser condition if necessary

ReferenceError: structuredClone is not defined ❯ src/__tests__/vite-plugin.test.js:48:26

Check failure on line 48 in src/__tests__/vite-plugin.test.js

View workflow job for this annotation

GitHub Actions / Node 16, Svelte 4, test:vitest:jsdom

src/__tests__/vite-plugin.test.js > vite plugin > adds browser condition if necessary

ReferenceError: structuredClone is not defined ❯ src/__tests__/vite-plugin.test.js:48:26

Check failure on line 48 in src/__tests__/vite-plugin.test.js

View workflow job for this annotation

GitHub Actions / Node 16, Svelte 4, test:vitest:happy-dom

src/__tests__/vite-plugin.test.js > vite plugin > adds browser condition if necessary

ReferenceError: structuredClone is not defined ❯ src/__tests__/vite-plugin.test.js:48:26

Check failure on line 48 in src/__tests__/vite-plugin.test.js

View workflow job for this annotation

GitHub Actions / Node 16, Svelte 4, test:vitest:happy-dom

src/__tests__/vite-plugin.test.js > vite plugin > adds browser condition if necessary

ReferenceError: structuredClone is not defined ❯ src/__tests__/vite-plugin.test.js:48:26

subject.config(viteConfig)

expect(viteConfig).toMatchObject({
resolve: {
conditions: expectedConditions,
},
})
}
)

test.each([
{
config: {},
expectedConditions: [],
},
{
config: { resolve: { conditions: [] } },
expectedConditions: [],
},
{
config: { resolve: { conditions: ['svelte'] } },
expectedConditions: ['svelte'],
},
])(
'skips browser condition if possible',
({ config, expectedConditions }) => {
const subject = svelteTesting()
const viteConfig = structuredClone(config)

Check failure on line 77 in src/__tests__/vite-plugin.test.js

View workflow job for this annotation

GitHub Actions / Node 16, Svelte 3, test:vitest:jsdom

src/__tests__/vite-plugin.test.js > vite plugin > skips browser condition if possible

ReferenceError: structuredClone is not defined ❯ src/__tests__/vite-plugin.test.js:77:26

Check failure on line 77 in src/__tests__/vite-plugin.test.js

View workflow job for this annotation

GitHub Actions / Node 16, Svelte 3, test:vitest:jsdom

src/__tests__/vite-plugin.test.js > vite plugin > skips browser condition if possible

ReferenceError: structuredClone is not defined ❯ src/__tests__/vite-plugin.test.js:77:26

Check failure on line 77 in src/__tests__/vite-plugin.test.js

View workflow job for this annotation

GitHub Actions / Node 16, Svelte 3, test:vitest:jsdom

src/__tests__/vite-plugin.test.js > vite plugin > skips browser condition if possible

ReferenceError: structuredClone is not defined ❯ src/__tests__/vite-plugin.test.js:77:26

Check failure on line 77 in src/__tests__/vite-plugin.test.js

View workflow job for this annotation

GitHub Actions / Node 16, Svelte 3, test:vitest:happy-dom

src/__tests__/vite-plugin.test.js > vite plugin > skips browser condition if possible

ReferenceError: structuredClone is not defined ❯ src/__tests__/vite-plugin.test.js:77:26

Check failure on line 77 in src/__tests__/vite-plugin.test.js

View workflow job for this annotation

GitHub Actions / Node 16, Svelte 3, test:vitest:happy-dom

src/__tests__/vite-plugin.test.js > vite plugin > skips browser condition if possible

ReferenceError: structuredClone is not defined ❯ src/__tests__/vite-plugin.test.js:77:26

Check failure on line 77 in src/__tests__/vite-plugin.test.js

View workflow job for this annotation

GitHub Actions / Node 16, Svelte 3, test:vitest:happy-dom

src/__tests__/vite-plugin.test.js > vite plugin > skips browser condition if possible

ReferenceError: structuredClone is not defined ❯ src/__tests__/vite-plugin.test.js:77:26

Check failure on line 77 in src/__tests__/vite-plugin.test.js

View workflow job for this annotation

GitHub Actions / Node 16, Svelte 4, test:vitest:jsdom

src/__tests__/vite-plugin.test.js > vite plugin > skips browser condition if possible

ReferenceError: structuredClone is not defined ❯ src/__tests__/vite-plugin.test.js:77:26

Check failure on line 77 in src/__tests__/vite-plugin.test.js

View workflow job for this annotation

GitHub Actions / Node 16, Svelte 4, test:vitest:jsdom

src/__tests__/vite-plugin.test.js > vite plugin > skips browser condition if possible

ReferenceError: structuredClone is not defined ❯ src/__tests__/vite-plugin.test.js:77:26

Check failure on line 77 in src/__tests__/vite-plugin.test.js

View workflow job for this annotation

GitHub Actions / Node 16, Svelte 4, test:vitest:jsdom

src/__tests__/vite-plugin.test.js > vite plugin > skips browser condition if possible

ReferenceError: structuredClone is not defined ❯ src/__tests__/vite-plugin.test.js:77:26

Check failure on line 77 in src/__tests__/vite-plugin.test.js

View workflow job for this annotation

GitHub Actions / Node 16, Svelte 4, test:vitest:happy-dom

src/__tests__/vite-plugin.test.js > vite plugin > skips browser condition if possible

ReferenceError: structuredClone is not defined ❯ src/__tests__/vite-plugin.test.js:77:26

Check failure on line 77 in src/__tests__/vite-plugin.test.js

View workflow job for this annotation

GitHub Actions / Node 16, Svelte 4, test:vitest:happy-dom

src/__tests__/vite-plugin.test.js > vite plugin > skips browser condition if possible

ReferenceError: structuredClone is not defined ❯ src/__tests__/vite-plugin.test.js:77:26

Check failure on line 77 in src/__tests__/vite-plugin.test.js

View workflow job for this annotation

GitHub Actions / Node 16, Svelte 4, test:vitest:happy-dom

src/__tests__/vite-plugin.test.js > vite plugin > skips browser condition if possible

ReferenceError: structuredClone is not defined ❯ src/__tests__/vite-plugin.test.js:77:26

subject.config(viteConfig)

expect(viteConfig).toMatchObject({
resolve: {
conditions: expectedConditions,
},
})
}
)

test.each([
{
config: {},
expectedSetupFiles: [expect.stringMatching(/src\/vitest.js$/u)],
},
{
config: { test: { setupFiles: [] } },
expectedSetupFiles: [expect.stringMatching(/src\/vitest.js$/u)],
},
{
config: { test: { setupFiles: 'other-file.js' } },
expectedSetupFiles: [
'other-file.js',
expect.stringMatching(/src\/vitest.js$/u),
],
},
])('adds cleanup', ({ config, expectedSetupFiles }) => {
const subject = svelteTesting()
const viteConfig = structuredClone(config)

Check failure on line 107 in src/__tests__/vite-plugin.test.js

View workflow job for this annotation

GitHub Actions / Node 16, Svelte 3, test:vitest:jsdom

src/__tests__/vite-plugin.test.js > vite plugin > adds cleanup

ReferenceError: structuredClone is not defined ❯ src/__tests__/vite-plugin.test.js:107:24

Check failure on line 107 in src/__tests__/vite-plugin.test.js

View workflow job for this annotation

GitHub Actions / Node 16, Svelte 3, test:vitest:jsdom

src/__tests__/vite-plugin.test.js > vite plugin > adds cleanup

ReferenceError: structuredClone is not defined ❯ src/__tests__/vite-plugin.test.js:107:24

Check failure on line 107 in src/__tests__/vite-plugin.test.js

View workflow job for this annotation

GitHub Actions / Node 16, Svelte 3, test:vitest:jsdom

src/__tests__/vite-plugin.test.js > vite plugin > adds cleanup

ReferenceError: structuredClone is not defined ❯ src/__tests__/vite-plugin.test.js:107:24

Check failure on line 107 in src/__tests__/vite-plugin.test.js

View workflow job for this annotation

GitHub Actions / Node 16, Svelte 3, test:vitest:happy-dom

src/__tests__/vite-plugin.test.js > vite plugin > adds cleanup

ReferenceError: structuredClone is not defined ❯ src/__tests__/vite-plugin.test.js:107:24

Check failure on line 107 in src/__tests__/vite-plugin.test.js

View workflow job for this annotation

GitHub Actions / Node 16, Svelte 3, test:vitest:happy-dom

src/__tests__/vite-plugin.test.js > vite plugin > adds cleanup

ReferenceError: structuredClone is not defined ❯ src/__tests__/vite-plugin.test.js:107:24

Check failure on line 107 in src/__tests__/vite-plugin.test.js

View workflow job for this annotation

GitHub Actions / Node 16, Svelte 3, test:vitest:happy-dom

src/__tests__/vite-plugin.test.js > vite plugin > adds cleanup

ReferenceError: structuredClone is not defined ❯ src/__tests__/vite-plugin.test.js:107:24

Check failure on line 107 in src/__tests__/vite-plugin.test.js

View workflow job for this annotation

GitHub Actions / Node 16, Svelte 4, test:vitest:jsdom

src/__tests__/vite-plugin.test.js > vite plugin > adds cleanup

ReferenceError: structuredClone is not defined ❯ src/__tests__/vite-plugin.test.js:107:24

Check failure on line 107 in src/__tests__/vite-plugin.test.js

View workflow job for this annotation

GitHub Actions / Node 16, Svelte 4, test:vitest:jsdom

src/__tests__/vite-plugin.test.js > vite plugin > adds cleanup

ReferenceError: structuredClone is not defined ❯ src/__tests__/vite-plugin.test.js:107:24

Check failure on line 107 in src/__tests__/vite-plugin.test.js

View workflow job for this annotation

GitHub Actions / Node 16, Svelte 4, test:vitest:jsdom

src/__tests__/vite-plugin.test.js > vite plugin > adds cleanup

ReferenceError: structuredClone is not defined ❯ src/__tests__/vite-plugin.test.js:107:24

Check failure on line 107 in src/__tests__/vite-plugin.test.js

View workflow job for this annotation

GitHub Actions / Node 16, Svelte 4, test:vitest:happy-dom

src/__tests__/vite-plugin.test.js > vite plugin > adds cleanup

ReferenceError: structuredClone is not defined ❯ src/__tests__/vite-plugin.test.js:107:24

Check failure on line 107 in src/__tests__/vite-plugin.test.js

View workflow job for this annotation

GitHub Actions / Node 16, Svelte 4, test:vitest:happy-dom

src/__tests__/vite-plugin.test.js > vite plugin > adds cleanup

ReferenceError: structuredClone is not defined ❯ src/__tests__/vite-plugin.test.js:107:24

Check failure on line 107 in src/__tests__/vite-plugin.test.js

View workflow job for this annotation

GitHub Actions / Node 16, Svelte 4, test:vitest:happy-dom

src/__tests__/vite-plugin.test.js > vite plugin > adds cleanup

ReferenceError: structuredClone is not defined ❯ src/__tests__/vite-plugin.test.js:107:24

subject.config(viteConfig)

expect(viteConfig).toMatchObject({
test: {
setupFiles: expectedSetupFiles,
},
})
})

test.each([
{
config: { ssr: { noExternal: [] } },
expectedNoExternal: ['@testing-library/svelte'],
},
{
config: {},
expectedNoExternal: ['@testing-library/svelte'],
},
{
config: { ssr: { noExternal: 'other-file.js' } },
expectedNoExternal: ['other-file.js', '@testing-library/svelte'],
},
{
config: { ssr: { noExternal: /other/u } },
expectedNoExternal: [/other/u, '@testing-library/svelte'],
},
])('adds noExternal rule', ({ config, expectedNoExternal }) => {
const subject = svelteTesting()
const viteConfig = structuredClone(config)

Check failure on line 137 in src/__tests__/vite-plugin.test.js

View workflow job for this annotation

GitHub Actions / Node 16, Svelte 3, test:vitest:jsdom

src/__tests__/vite-plugin.test.js > vite plugin > adds noExternal rule

ReferenceError: structuredClone is not defined ❯ src/__tests__/vite-plugin.test.js:137:24

Check failure on line 137 in src/__tests__/vite-plugin.test.js

View workflow job for this annotation

GitHub Actions / Node 16, Svelte 3, test:vitest:jsdom

src/__tests__/vite-plugin.test.js > vite plugin > adds noExternal rule

ReferenceError: structuredClone is not defined ❯ src/__tests__/vite-plugin.test.js:137:24

Check failure on line 137 in src/__tests__/vite-plugin.test.js

View workflow job for this annotation

GitHub Actions / Node 16, Svelte 3, test:vitest:happy-dom

src/__tests__/vite-plugin.test.js > vite plugin > adds noExternal rule

ReferenceError: structuredClone is not defined ❯ src/__tests__/vite-plugin.test.js:137:24

Check failure on line 137 in src/__tests__/vite-plugin.test.js

View workflow job for this annotation

GitHub Actions / Node 16, Svelte 3, test:vitest:happy-dom

src/__tests__/vite-plugin.test.js > vite plugin > adds noExternal rule

ReferenceError: structuredClone is not defined ❯ src/__tests__/vite-plugin.test.js:137:24

Check failure on line 137 in src/__tests__/vite-plugin.test.js

View workflow job for this annotation

GitHub Actions / Node 16, Svelte 4, test:vitest:jsdom

src/__tests__/vite-plugin.test.js > vite plugin > adds noExternal rule

ReferenceError: structuredClone is not defined ❯ src/__tests__/vite-plugin.test.js:137:24

Check failure on line 137 in src/__tests__/vite-plugin.test.js

View workflow job for this annotation

GitHub Actions / Node 16, Svelte 4, test:vitest:jsdom

src/__tests__/vite-plugin.test.js > vite plugin > adds noExternal rule

ReferenceError: structuredClone is not defined ❯ src/__tests__/vite-plugin.test.js:137:24

Check failure on line 137 in src/__tests__/vite-plugin.test.js

View workflow job for this annotation

GitHub Actions / Node 16, Svelte 4, test:vitest:happy-dom

src/__tests__/vite-plugin.test.js > vite plugin > adds noExternal rule

ReferenceError: structuredClone is not defined ❯ src/__tests__/vite-plugin.test.js:137:24

Check failure on line 137 in src/__tests__/vite-plugin.test.js

View workflow job for this annotation

GitHub Actions / Node 16, Svelte 4, test:vitest:happy-dom

src/__tests__/vite-plugin.test.js > vite plugin > adds noExternal rule

ReferenceError: structuredClone is not defined ❯ src/__tests__/vite-plugin.test.js:137:24

subject.config(viteConfig)

expect(viteConfig).toMatchObject({
ssr: {
noExternal: expectedNoExternal,
},
})
})

test.each([
{
config: { ssr: { noExternal: true } },
expectedNoExternal: true,
},
{
config: { ssr: { noExternal: '@testing-library/svelte' } },
expectedNoExternal: '@testing-library/svelte',
},
{
config: { ssr: { noExternal: /svelte/u } },
expectedNoExternal: /svelte/u,
},
])('skips noExternal if able', ({ config, expectedNoExternal }) => {
const subject = svelteTesting()
const viteConfig = structuredClone(config)

subject.config(viteConfig)

expect(viteConfig).toMatchObject({
ssr: {
noExternal: expectedNoExternal,
},
})
})

test('bails on noExternal if input is unexpected', () => {
const subject = svelteTesting()
const viteConfig = structuredClone({ ssr: { noExternal: false } })

subject.config(viteConfig)

expect(viteConfig).toMatchObject({
ssr: {
noExternal: false,
},
})
})
})
47 changes: 46 additions & 1 deletion src/vite.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@ import { fileURLToPath } from 'node:url'
* Ensures Svelte is imported correctly in tests
* and that the DOM is cleaned up after each test.
*
* @param {{resolveBrowser?: boolean, autoCleanup?: boolean}} options
* @param {{resolveBrowser?: boolean, autoCleanup?: boolean, noExternal?: boolean}} options
* @returns {import('vite').Plugin}
*/
export const svelteTesting = ({
resolveBrowser = true,
autoCleanup = true,
noExternal = true,
} = {}) => ({
name: 'vite-plugin-svelte-testing-library',
config: (config) => {
Expand All @@ -27,6 +28,10 @@ export const svelteTesting = ({
if (autoCleanup) {
addAutoCleanup(config)
}

if (noExternal) {
addNoExternal(config)
}
},
})

Expand Down Expand Up @@ -73,3 +78,43 @@ const addAutoCleanup = (config) => {
test.setupFiles = setupFiles
config.test = test
}

/**
* Add `@testing-library/svelte` to Vite's noExternal rules, if not present.
*
* This ensures `@testing-library/svelte` is processed by `@sveltejs/vite-plugin-svelte`
* in certain monorepo setups.
*/
const addNoExternal = (config) => {
const ssr = config.ssr ?? {}
let noExternal = ssr.noExternal ?? []

if (noExternal === true) {
return
}

if (typeof noExternal === 'string' || noExternal instanceof RegExp) {
noExternal = [noExternal]
}

if (!Array.isArray(noExternal)) {
return
}

for (const rule of noExternal) {
if (typeof rule === 'string' && rule === '@testing-library/svelte') {
return
}

if (
noExternal instanceof RegExp &&
noExternal.test('@testing-library/svelte')
) {
return
}
}

noExternal.push('@testing-library/svelte')
ssr.noExternal = noExternal
config.ssr = ssr
}
1 change: 1 addition & 0 deletions vite.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export default defineConfig({
setupFiles: ['./src/__tests__/_vitest-setup.js'],
mockReset: true,
unstubGlobals: true,
unstubEnvs: true,
coverage: {
provider: 'v8',
include: ['src/**/*'],
Expand Down

0 comments on commit fd05580

Please sign in to comment.