Skip to content

Commit

Permalink
fix(ssr): support externalized builtins for webworker (#15656)
Browse files Browse the repository at this point in the history
  • Loading branch information
bluwy authored Jan 19, 2024
1 parent 35ae4f8 commit 639bbd6
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 2 deletions.
13 changes: 11 additions & 2 deletions packages/vite/src/node/plugins/resolve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,11 @@ export function resolvePlugin(resolveOptions: InternalResolveOptions): Plugin {
preferRelative = false,
} = resolveOptions

const { target: ssrTarget, noExternal: ssrNoExternal } = ssrConfig ?? {}
const {
target: ssrTarget,
noExternal: ssrNoExternal,
external: ssrExternal,
} = ssrConfig ?? {}

// In unix systems, absolute paths inside root first needs to be checked as an
// absolute URL (/root/root/path-to-file) resulting in failed checks before falling
Expand Down Expand Up @@ -395,7 +399,12 @@ export function resolvePlugin(resolveOptions: InternalResolveOptions): Plugin {
// externalize if building for SSR, otherwise redirect to empty module
if (isBuiltin(id)) {
if (ssr) {
if (ssrNoExternal === true) {
if (
ssrNoExternal === true &&
// if both noExternal and external are true, noExternal will take the higher priority and bundle it.
// only if the id is explicitly listed in external, we will externalize it and skip this error.
(ssrExternal === true || !ssrExternal?.includes(id))
) {
let message = `Cannot bundle Node.js built-in "${id}"`
if (importer) {
message += ` imported from "${path.relative(
Expand Down
7 changes: 7 additions & 0 deletions playground/ssr-webworker/__tests__/ssr-webworker.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ test('respects browser export', async () => {
)
})

test('supports nodejs_compat', async () => {
await page.goto(url)
expect(await page.textContent('.nodejs-compat')).toMatch(
'[success] nodejs compat',
)
})

test.runIf(isBuild)('inlineDynamicImports', () => {
const dynamicJsContent = findAssetFile(/dynamic-[-\w]+\.js/, 'worker')
expect(dynamicJsContent).toBe('')
Expand Down
2 changes: 2 additions & 0 deletions playground/ssr-webworker/src/entry-worker.jsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { equal } from 'node:assert'
import { msg as linkedMsg } from '@vitejs/test-resolve-linked'
import browserExportsMessage from '@vitejs/test-browser-exports'
import workerExportsMessage from '@vitejs/test-worker-exports'
Expand All @@ -18,6 +19,7 @@ addEventListener('fetch', function (event) {
<p>dynamic: ${loaded}</p>
<p class="browser-exports">${browserExportsMessage}</p>
<p class="worker-exports">${workerExportsMessage}</p>
<p class="nodejs-compat">${equal('a', 'a') || '[success] nodejs compat'}</p>
`,
{
headers: {
Expand Down
3 changes: 3 additions & 0 deletions playground/ssr-webworker/vite.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ export default defineConfig({
ssr: {
target: 'webworker',
noExternal: ['this-should-be-replaced-by-the-boolean'],
// Some webworker builds may choose to externalize node builtins as they may be implemented
// in the runtime, and so we can externalize it when bundling.
external: ['node:assert'],
},
plugins: [
{
Expand Down
2 changes: 2 additions & 0 deletions playground/ssr-webworker/worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ export async function createServer(port) {
const mf = new Miniflare({
scriptPath: path.resolve(__dirname, 'dist/worker/entry-worker.js'),
port,
modules: true,
compatibilityFlags: ['nodejs_compat'],
})
await mf.ready
return { mf }
Expand Down

0 comments on commit 639bbd6

Please sign in to comment.