Skip to content

Commit

Permalink
feat(addons public-assets): use buildStart to build a more solid map …
Browse files Browse the repository at this point in the history
…of addons public-assets instead of reading package.json in the middleware and make suppositions to find the owner addon
  • Loading branch information
BlueCutOfficial committed Mar 12, 2024
1 parent 10137c9 commit dc5063a
Showing 1 changed file with 25 additions and 16 deletions.
41 changes: 25 additions & 16 deletions packages/vite/src/public-assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,33 @@ import { join } from 'path';
import send from 'send';
import type { Plugin } from 'vite';

// This Vite middleware relies on the ResolverLoader to locate the public assets in app and addons
// This Vite plugin relies on the ResolverLoader to locate the public assets in app and addons
export function publicAssets(): Plugin {
const resolverLoader = new ResolverLoader(process.cwd());
const resolverOptions = resolverLoader.resolver.options;
const excludedUrls = ['/@fs', '/@id/embroider_virtual:', '/@vite/client'];

let publicAssetsMap = new Map();

return {
name: 'embroider-public-assets',

buildStart() {
// We build a map of all public assets referenced in the active addons,
// regardless they are actively used in the app. The key is the requested
// URL when the asset is used, and the value is the full path to locate it.
let appActiveAddons = resolverOptions.engines[0].activeAddons;
for (const addon of appActiveAddons) {
let addonConfig = readFileSync(`${addon.root}/package.json`);
let addonAssets = JSON.parse(addonConfig.toString())['ember-addon']['public-assets'];
if (addonAssets) {
for (const [leftPath, rightPath] of Object.entries(addonAssets)) {
publicAssetsMap.set(join('.', `${rightPath}`), join(addon.root, leftPath));
}
}
}
},

configureServer(server) {
server.middlewares.use((req, res, next) => {
// TODO: Is there another way to handle the minimum amount of requests (without forcing the user to list the addons)?
Expand All @@ -24,22 +43,12 @@ export function publicAssets(): Plugin {
return send(req, maybePublic).pipe(res);
}

// TODO: Is it the right thing to look at?
let appActiveAddons = resolverOptions.engines[0].activeAddons;
let maybeAddonName = req.originalUrl.split('/')[1];
let ownerAddon = appActiveAddons.find(({ name }) => name === maybeAddonName);
if (!ownerAddon) return next();

let ownerAddonConfig = readFileSync(`${ownerAddon.root}/package.json`);
let ownerAddonAssets = JSON.parse(ownerAddonConfig.toString())['ember-addon']['public-assets'];
let pathInAddon = Object.keys(ownerAddonAssets).find(leftPath =>
// public-assets can contain "./my-url" for "/my-url" request, so we can't use === operator
ownerAddonAssets[leftPath].includes(req.originalUrl)
);
if (!pathInAddon) return next();

// TODO: the map contains an entry '/assets/vite-app.css' from package '/@embroider/synthesized-styles'
// Not sure we want this?
let maybeAddonAsset = publicAssetsMap.get(join('.', req.originalUrl));
if (!maybeAddonAsset) return next();
// @ts-ignore TODO: how to handle the types properly?
send(req, join(ownerAddon.root, pathInAddon)).pipe(res);
send(req, maybeAddonAsset).pipe(res);
});
},
};
Expand Down

0 comments on commit dc5063a

Please sign in to comment.