Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: relative base #7644

Merged
merged 39 commits into from
May 18, 2022
Merged
Changes from 1 commit
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
cb42862
feat: relative base
patak-dev Apr 7, 2022
bdacc9f
fix: don't use template string in dev
patak-dev Apr 7, 2022
7e4484a
fix: windows
patak-dev Apr 8, 2022
7744ca3
chore: stringifyAsTemplateLiteral util
patak-dev Apr 8, 2022
3bd450d
chore: typo
patak-dev Apr 13, 2022
2db74e8
chore: merge main
patak-dev Apr 13, 2022
1491bb9
chore: remove unused regex
patak-dev Apr 14, 2022
77a05e3
fix: resolve worker TODO
patak-dev Apr 15, 2022
69d872f
fix: apply fix by @locriacyber
patak-dev Apr 29, 2022
41d9884
chore: typo
patak-dev Apr 29, 2022
d69f214
chore: merge main
patak-dev May 9, 2022
1d955db
chore: merge main
patak-dev May 9, 2022
80dacfb
chore: update
patak-dev May 9, 2022
e1f49c7
refactor: back to JSON.stringify
patak-dev May 12, 2022
a0b232c
chore: merge main
patak-dev May 12, 2022
2cbd9ef
chore: update
patak-dev May 12, 2022
a4cef7e
chore: comment
patak-dev May 12, 2022
51c863c
chore: merge main and refactor worker with relative base
patak-dev May 13, 2022
26eb46d
chore: update
patak-dev May 13, 2022
638945c
chore: update
patak-dev May 13, 2022
9681aca
chore: allow custom assetFileNames
patak-dev May 13, 2022
a354401
feat: support custom file names in module preload
patak-dev May 14, 2022
b2a9967
chore: remove unneded worker options formatting
patak-dev May 14, 2022
cba14d8
fix: rework assets and worker assets handling
patak-dev May 14, 2022
f61c30e
fix: import.meta.url param position
patak-dev May 15, 2022
7f7fbf9
chore: use absolute URL for assets in CSS
patak-dev May 15, 2022
c3d0821
fix: worker hash to url cache
patak-dev May 17, 2022
77e1f39
feat: absolute public urls in JS, asset paths in CSS
patak-dev May 17, 2022
7ee53f6
test: add relative base asset test cases
patak-dev May 17, 2022
96bc8c5
test: fix serve
patak-dev May 17, 2022
8afe78e
test: bump assetsInlineLimit to 8kb
patak-dev May 17, 2022
3a09a2c
chore: improve asset paths in CSS handling
patak-dev May 17, 2022
79240a7
fix: relative CSS path
patak-dev May 17, 2022
46c15af
feat: support assetFileNames functional form
patak-dev May 17, 2022
7629352
chore: naming
patak-dev May 17, 2022
f785bed
test: worker with relative base
patak-dev May 17, 2022
b5b0a84
chore: merge main
patak-dev May 17, 2022
7f7d763
test: skip invalid serve tests for relative base
patak-dev May 17, 2022
277f967
fix: urls in windows
patak-dev May 17, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
test: worker with relative base
patak-dev committed May 17, 2022
commit f785bed5d2d6c5726dd329f48f6744c415c7e6d0
7 changes: 5 additions & 2 deletions packages/vite/src/node/plugins/worker.ts
Original file line number Diff line number Diff line change
@@ -156,7 +156,7 @@ function encodeWorkerAssetFileName(
): string {
const { fileNameHash } = workerCache
const hash = getHash(fileName)
if (!fileNameHash.get(fileName)) {
if (!fileNameHash.get(hash)) {
fileNameHash.set(hash, fileName)
}
return `__VITE_WORKER_ASSET__${hash}__`
@@ -297,10 +297,13 @@ export function webWorkerPlugin(config: ResolvedConfig): Plugin {
while ((match = workerAssetUrlRE.exec(code))) {
const [full, hash] = match
const filename = fileNameHash.get(hash)!
const outputFilepath = path.relative(
let outputFilepath = path.relative(
path.dirname(chunk.fileName),
filename
)
if (!outputFilepath.startsWith('.')) {
outputFilepath = './' + outputFilepath
}
const replacement = JSON.stringify(outputFilepath).slice(1, -1)
s.overwrite(match.index, match.index + full.length, replacement, {
contentOnly: true
127 changes: 127 additions & 0 deletions playground/worker/__tests__/relative-base/relative-base-worker.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
import fs from 'fs'
import path from 'path'
import type { Page } from 'playwright-chromium'
import { isBuild, page, testDir, untilUpdated } from '~utils'

test('normal', async () => {
await page.click('.ping')
await untilUpdated(() => page.textContent('.pong'), 'pong')
await untilUpdated(
() => page.textContent('.mode'),
isBuild ? 'production' : 'development'
)
await untilUpdated(
() => page.textContent('.bundle-with-plugin'),
'worker bundle with plugin success!'
)
})

test('TS output', async () => {
await page.click('.ping-ts-output')
await untilUpdated(() => page.textContent('.pong-ts-output'), 'pong')
})

test('inlined', async () => {
await page.click('.ping-inline')
await untilUpdated(() => page.textContent('.pong-inline'), 'pong')
})

const waitSharedWorkerTick = (
(resolvedSharedWorkerCount: number) => async (page: Page) => {
await untilUpdated(async () => {
const count = await page.textContent('.tick-count')
// ignore the initial 0
return count === '1' ? 'page loaded' : ''
}, 'page loaded')
// test.concurrent sequential is not guaranteed
// force page to wait to ensure two pages overlap in time
resolvedSharedWorkerCount++
if (resolvedSharedWorkerCount < 2) return

await untilUpdated(() => {
return resolvedSharedWorkerCount === 2 ? 'all pages loaded' : ''
}, 'all pages loaded')
}
)(0)

test.each([[true], [false]])('shared worker', async (doTick) => {
if (doTick) {
await page.click('.tick-shared')
}
await waitSharedWorkerTick(page)
})

test('worker emitted and import.meta.url in nested worker (serve)', async () => {
expect(await page.textContent('.nested-worker')).toMatch(
'worker-nested-worker'
)
expect(await page.textContent('.nested-worker-module')).toMatch('sub-worker')
expect(await page.textContent('.nested-worker-constructor')).toMatch(
'"type":"constructor"'
)
})

describe.runIf(isBuild)('build', () => {
// assert correct files
test('inlined code generation', async () => {
const chunksDir = path.resolve(testDir, 'dist/chunks')
const files = fs.readdirSync(chunksDir)
const index = files.find((f) => f.includes('main-module'))
const content = fs.readFileSync(path.resolve(chunksDir, index), 'utf-8')
const workerEntriesDir = path.resolve(testDir, 'dist/worker-entries')
const workerFiles = fs.readdirSync(workerEntriesDir)
const worker = workerFiles.find((f) => f.includes('worker_entry.my-worker'))
const workerContent = fs.readFileSync(
path.resolve(workerEntriesDir, worker),
'utf-8'
)

// worker should have all imports resolved and no exports
expect(workerContent).not.toMatch(`import`)
expect(workerContent).not.toMatch(`export`)
// chunk
expect(content).toMatch(`new Worker("../worker-entries/`)
expect(content).toMatch(`new SharedWorker("../worker-entries/`)
// inlined
expect(content).toMatch(`(window.URL||window.webkitURL).createObjectURL`)
expect(content).toMatch(`window.Blob`)
})

test('worker emitted and import.meta.url in nested worker (build)', async () => {
expect(await page.textContent('.nested-worker-module')).toMatch(
'"type":"module"'
)
expect(await page.textContent('.nested-worker-constructor')).toMatch(
'"type":"constructor"'
)
})
})

test('module worker', async () => {
expect(await page.textContent('.shared-worker-import-meta-url')).toMatch(
'A string'
)
})

// TODO: Maybe we can modify classic-worker.js and classic-shared-worker.js to take into account the different asset paths
test('classic worker', async () => {
expect(await page.textContent('.classic-worker')).toMatch('A classic')
expect(await page.textContent('.classic-shared-worker')).toMatch('A classic')
})

test('emit chunk', async () => {
expect(await page.textContent('.emit-chunk-worker')).toMatch(
'["A string",{"type":"emit-chunk-sub-worker","data":"A string"},{"type":"module-and-worker:worker","data":"A string"},{"type":"module-and-worker:module","data":"module and worker"},{"type":"emit-chunk-sub-worker","data":{"module":"module and worker","msg1":"module1","msg2":"module2","msg3":"module3"}}]'
)
expect(await page.textContent('.emit-chunk-dynamic-import-worker')).toMatch(
'"A string./"'
)
})

test('import.meta.glob in worker', async () => {
expect(await page.textContent('.importMetaGlob-worker')).toMatch('["')
})

test('import.meta.glob with eager in worker', async () => {
expect(await page.textContent('.importMetaGlobEager-worker')).toMatch('["')
})
1 change: 1 addition & 0 deletions playground/worker/__tests__/relative-base/vite.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('../../vite.config-relative-base')
5 changes: 4 additions & 1 deletion playground/worker/classic-shared-worker.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
importScripts(`/${self.location.pathname.split('/')[1]}/classic.js`)
let base = `/${self.location.pathname.split('/')[1]}`
if (base === `/worker-entries`) base = '' // relative base

importScripts(`${base}/classic.js`)

self.onconnect = (event) => {
const port = event.ports[0]
5 changes: 4 additions & 1 deletion playground/worker/classic-worker.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
importScripts(`/${self.location.pathname.split("/")[1]}/classic.js`)
let base = `/${self.location.pathname.split('/')[1]}`
if (base === `/worker-entries`) base = '' // relative base

importScripts(`${base}/classic.js`)

self.addEventListener('message', () => {
self.postMessage(self.constant)
3 changes: 3 additions & 0 deletions playground/worker/package.json
Original file line number Diff line number Diff line change
@@ -18,6 +18,9 @@
"dev:sourcemap-inline": "cross-env WORKER_MODE=inline vite --config ./vite.config-sourcemap.js dev",
"build:sourcemap-inline": "cross-env WORKER_MODE=inline vite --config ./vite.config-sourcemap.js build",
"preview:sourcemap-inline": "cross-env WORKER_MODE=inline vite --config ./vite.config-sourcemap.js preview",
"dev:relative-base": "cross-env WORKER_MODE=inline vite --config ./vite.config-relative-base.js dev",
"build:relative-base": "cross-env WORKER_MODE=inline vite --config ./vite.config-relative-base.js build",
"preview:relative-base": "cross-env WORKER_MODE=inline vite --config ./vite.config-relative-base.js preview",
"debug": "node --inspect-brk ../../packages/vite/bin/vite"
},
"devDependencies": {
42 changes: 42 additions & 0 deletions playground/worker/vite.config-relative-base.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
const vueJsx = require('@vitejs/plugin-vue-jsx')
const vite = require('vite')
const path = require('path')

module.exports = vite.defineConfig({
base: './',
enforce: 'pre',
worker: {
format: 'es',
plugins: [vueJsx()],
rollupOptions: {
output: {
assetFileNames: 'worker-assets/worker_asset.[name]-[hash].[ext]',
chunkFileNames: 'worker-chunks/worker_chunk.[name]-[hash].js',
entryFileNames: 'worker-entries/worker_entry.[name]-[hash].js'
}
}
},
build: {
outDir: 'dist',
rollupOptions: {
output: {
assetFileNames: 'other-assets/[name]-[hash].[ext]',
chunkFileNames: 'chunks/[name]-[hash].js',
entryFileNames: 'entries/[name]-[hash].js'
}
}
},
plugins: [
{
name: 'resolve-format-es',
transform(code, id) {
if (id.includes('main.js')) {
return code.replace(
`/* flag: will replace in vite config import("./format-es.js") */`,
`import("./main-format-es")`
)
}
}
}
]
})