Skip to content

Commit

Permalink
Merge pull request #13 from etsy/mpmartinez.WEBPLAT-4156
Browse files Browse the repository at this point in the history
allowing kevin to map entrypoints to multiple configs
  • Loading branch information
mpmartinez-etsy authored Sep 9, 2021
2 parents 3ea0d0e + ee1e80b commit 246f53a
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 10 deletions.
24 changes: 21 additions & 3 deletions lib/middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,22 @@ class Kevin {
// the middleware will store things as `app-a/a1`, but requests will be for `/app-a/a1.js`.
getAssetName = (requestPath, req, res) =>
requestPath.replace(/^\//, "").replace(/\.js$/, ""),
// Given a request path and a set of configNames, return the name of the config
// we're interested in using to handle this request
selectConfigName = (reqPath, configNames) => {
if (!configNames) {
return null;
}
if (configNames.length > 1) {
logError(
`Multiple configNames found for ${reqPath}: ${configNames.join(
","
)}. Using first one.`
);
}

return configNames[0];
},
// Only build assets; don't handle serving them. This is useful if you want to do
// something with the built asset before serving it.
buildOnly = false,
Expand Down Expand Up @@ -78,6 +94,7 @@ class Kevin {
this.maxCompilers = maxCompilers;
this.getAssetName = getAssetName;
this.buildOnly = buildOnly;
this.selectConfigName = selectConfigName;
this.kevinPublicPath = kevinPublicPath;
this.kevinApiPrefix = kevinApiPrefix;
this.additionalOverlayInfo = additionalOverlayInfo;
Expand All @@ -94,8 +111,9 @@ class Kevin {
* @param {array} configs — array of webpack config objects
* @returns {string|null} - the name of the config, or null if there is none
*/
getConfigForAssetName(assetName, configs) {
const configName = this.entryMap[assetName];
getConfigForAssetName(reqPath, assetName, configs) {
const configNames = this.entryMap[assetName];
const configName = this.selectConfigName(reqPath, configNames);
if (!configName) {
return null;
}
Expand Down Expand Up @@ -410,7 +428,7 @@ class Kevin {
// Mangle the url to get asset name
const assetName = this.getAssetName(reqPath, req, res);
// Select appropriate config for given asset
const config = this.getConfigForAssetName(assetName, this.configs);
const config = this.getConfigForAssetName(reqPath, assetName, this.configs);
// Bail if none are found (this path may be handled by another middleware)
if (!config) {
// TODO: It may be a chunk file!! Make sure we either serve static
Expand Down
14 changes: 7 additions & 7 deletions lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,10 @@ const validateConfigs = function (configs) {
/**
* Given an array of webpack configs (i.e. a multicompiler config), generate a mapping
* from entrypoints to the name of the config responsible for it.
* Throw an excption if we find two configs that handle the same asset.
* That may be extreme, but if it is we can fix it when it becomes a problem.
*
* This used to throw an exception if multiple configs were capable of handling the same
* entrypoint. Now it will return a list of possible configs, and it is up to whoever is
* utilizing this map to correctly extract the correct config name.
* @param {array} configs
*/
const initializeEntryMap = function (configs) {
Expand All @@ -130,12 +132,10 @@ const initializeEntryMap = function (configs) {
} else {
Object.keys(entry).forEach((key) => {
if (entryMap[key]) {
throw new Error(
`Entrypoint ${key} is built by both ${entryMap[key]} ` +
`and ${configName}. Only one config should handle an entry.`
);
entryMap[key].push(configName);
} else {
entryMap[key] = [configName];
}
entryMap[key] = configName;
});
}
});
Expand Down
27 changes: 27 additions & 0 deletions test/lib/utils.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,30 @@ describe("kevin's validateConfigs utility", () => {
}).toThrowError(/your configs share a name/);
});
});
describe("initializeEntryMap", () => {
const { initializeEntryMap } = require("../../lib/utils");

it("returns a list of names of all configs able to handle entrypoint", () => {
const configs = [
{
name: "someConfigEntry",
entry: {
someEntryPoint: `./someEntryPoint`,
},
},
{
name: "someOtherConfigEntry",
entry: {
someEntryPoint: `./someEntryPoint`,
},
},
];

const entryMap = initializeEntryMap(configs);

expect(entryMap.someEntryPoint).toEqual([
"someConfigEntry",
"someOtherConfigEntry",
]);
});
});

0 comments on commit 246f53a

Please sign in to comment.