diff --git a/packages/vite/package.json b/packages/vite/package.json index bf46e0e4aa..4ea1a65e49 100644 --- a/packages/vite/package.json +++ b/packages/vite/package.json @@ -21,11 +21,13 @@ "jsdom": "^16.6.0", "source-map-url": "^0.4.1", "terser": "^5.7.0", - "fast-glob": "^3.3.2" + "fast-glob": "^3.3.2", + "send": "^0.18.0" }, "devDependencies": { "@embroider/core": "workspace:^", "@types/babel__core": "^7.20.1", + "@types/send": "^0.17.4", "@types/debug": "^4.1.5", "@types/jsdom": "^16.2.11", "@types/fs-extra": "^9.0.12", diff --git a/packages/vite/src/assets.ts b/packages/vite/src/assets.ts index df7aefc582..066f7e377b 100644 --- a/packages/vite/src/assets.ts +++ b/packages/vite/src/assets.ts @@ -1,21 +1,15 @@ import type { Resolver } from '@embroider/core'; -import { ResolverLoader, locateEmbroiderWorkingDir } from '@embroider/core'; +import { ResolverLoader } from '@embroider/core'; import type { Plugin } from 'vite'; import * as process from 'process'; -import { dirname, join } from 'path'; -import { copyFileSync, mkdirpSync, existsSync } from 'fs-extra'; +import { join } from 'path'; +import { existsSync, readFileSync } from 'fs-extra'; import glob from 'fast-glob'; +import send from 'send'; -function findPublicAsset(relativePath: string, resolver: Resolver, embroiderWorkingDir: string) { +function findPublicAsset(relativePath: string, resolver: Resolver) { const packageCache = resolver.packageCache; - const cwd = process.cwd(); - const publicDir = join(cwd, 'public'); - // check public path let pkg = packageCache.ownerOfFile(relativePath); - let p = join(publicDir, relativePath); - if (pkg && pkg.isV2App() && existsSync(p)) { - return '/' + p; - } for (const engine of resolver.options.engines) { for (const addon of engine.activeAddons) { @@ -23,13 +17,8 @@ function findPublicAsset(relativePath: string, resolver: Resolver, embroiderWork if (pkg && pkg.meta && pkg.isV2Addon() && pkg.meta['public-assets']) { const asset = Object.entries(pkg.meta['public-assets']).find(([_key, a]) => a === relativePath)?.[0]; let local = asset ? join(addon.root, asset) : null; - if (!local?.includes(embroiderWorkingDir) && asset) { - // remap to local path without symlinks so vite can find it - const localNodeModulePath = local?.split('/node_modules/').slice(-1)[0]!; - local = join('node_modules', localNodeModulePath); - } if (local && existsSync(local)) { - return '/' + local; + return local; } } } @@ -39,37 +28,38 @@ function findPublicAsset(relativePath: string, resolver: Resolver, embroiderWork export function assets(): Plugin { const cwd = process.cwd(); const resolverLoader = new ResolverLoader(cwd); - const embroiderWorkingDir = locateEmbroiderWorkingDir(cwd); + let mode: 'build' | 'serve' = 'build'; return { name: 'assets', - enforce: 'pre', - outputOptions(options) { - options.dir = join(process.cwd(), 'dist'); - }, + enforce: 'post', configureServer(server) { - server.middlewares.use((req, _res, next) => { + mode = server.config.command; + server.middlewares.use((req, res, next) => { if (req.originalUrl?.includes('?')) { return next(); } if (req.originalUrl && req.originalUrl.length > 1) { - const newUrl = findPublicAsset(req.originalUrl, resolverLoader.resolver, embroiderWorkingDir); - if (newUrl) { - req.originalUrl = newUrl; - (req as any).url = newUrl; + const assetUrl = findPublicAsset(req.originalUrl, resolverLoader.resolver); + if (assetUrl) { + return send(req, assetUrl).pipe(res); } } return next(); }); }, - async writeBundle(options) { + async buildStart() { + if (mode !== 'build') return; const engines = resolverLoader.resolver.options.engines; const pubDir = join(process.cwd(), 'public'); const publicAppFiles = glob.sync('**/*', { cwd: pubDir, }); for (const publicAppFile of publicAppFiles) { - mkdirpSync(dirname(join(options.dir!, publicAppFile))); - copyFileSync(join(pubDir, publicAppFile), join(options.dir!, publicAppFile)); + this.emitFile({ + type: 'asset', + source: readFileSync(join(pubDir, publicAppFile)), + fileName: publicAppFile, + }); } for (const engine of engines) { engine.activeAddons.forEach(addon => { @@ -77,8 +67,11 @@ export function assets(): Plugin { if (!pkg || !pkg.isV2Addon()) return; const assets = pkg.meta['public-assets'] || {}; Object.entries(assets).forEach(([path, dest]) => { - mkdirpSync(dirname(join(options.dir!, dest))); - copyFileSync(join(pkg.root, path), join(options.dir!, dest)); + this.emitFile({ + type: 'asset', + source: readFileSync(join(pkg.root, path)), + fileName: dest.slice(1), + }); }); }); } diff --git a/packages/vite/src/template-tag.ts b/packages/vite/src/template-tag.ts index 14506da965..61709f1276 100644 --- a/packages/vite/src/template-tag.ts +++ b/packages/vite/src/template-tag.ts @@ -1,7 +1,6 @@ import { createFilter } from '@rollup/pluginutils'; import type { Plugin } from 'vite'; import { Preprocessor } from 'content-tag'; -import { RollupModuleRequest } from './request'; const gjsFilter = createFilter('**/*.{gjs,gts}?(\\?)*'); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 89e3f5bd23..2fcded776b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -941,6 +941,9 @@ importers: jsdom: specifier: ^16.6.0 version: 16.7.0 + send: + specifier: ^0.18.0 + version: 0.18.0 source-map-url: specifier: ^0.4.1 version: 0.4.1 @@ -963,6 +966,9 @@ importers: '@types/jsdom': specifier: ^16.2.11 version: 16.2.15 + '@types/send': + specifier: ^0.17.4 + version: 0.17.4 rollup: specifier: ^3.23.0 version: 3.29.4 @@ -8377,6 +8383,9 @@ packages: /ajv-formats@2.1.1: resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} + peerDependenciesMeta: + ajv: + optional: true dependencies: ajv: 8.12.0