Skip to content

Commit

Permalink
Handle entry points that end in '/index'
Browse files Browse the repository at this point in the history
  • Loading branch information
mbeckem committed Jun 28, 2024
1 parent e4ae880 commit d9a0c1b
Show file tree
Hide file tree
Showing 11 changed files with 63 additions and 40 deletions.
5 changes: 5 additions & 0 deletions .changeset/nice-humans-add.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@open-pioneer/build-common": patch
---

Use timestamps instead of request ids to import build configs
8 changes: 2 additions & 6 deletions packages/build-common/src/buildConfig/loadBuildConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,14 @@ import type * as API from "../../types";

type LoadBuildConfig = typeof API.loadBuildConfig;

let requestId = 0;

export const loadBuildConfig: LoadBuildConfig = async function loadBuildConfig(path) {
if (!existsSync(path)) {
throw new Error(`The configuration file at ${path} does not exist`);
}

const fileURL = pathToFileURL(path);
const importedModule = (await import(`${fileURL}?id=${++requestId}`)) as Record<
string,
unknown
>;
const moduleId = `${fileURL}?ts=${new Date().getTime()}`;
const importedModule = (await import(moduleId)) as Record<string, unknown>;
if (!importedModule || !importedModule.default) {
throw new Error(`The configuration file at ${path} must provide a default export`);
}
Expand Down
14 changes: 6 additions & 8 deletions packages/build-package/src/generatePackageJson.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
// SPDX-License-Identifier: Apache-2.0
import { Service, PackageMetadataV1 as V1 } from "@open-pioneer/build-common";
import { existsSync } from "node:fs";
import posix from "node:path/posix";
import nativePath from "node:path";
import { PackageModel } from "./model/PackageModel";
import { Logger } from "./utils/Logger";
import { ValidationReporter } from "./utils/ValidationReporter";
import { ResolvedValidationOptions } from "./model/Options";
import { getExportedName } from "./utils/entryPoints";

type SimplePackageModel = Pick<
PackageModel,
Expand Down Expand Up @@ -129,7 +129,7 @@ function generateExports(model: SimplePackageModel, validationErrors: Validation
};
addEntryPoint("./package.json", "./package.json");
for (const entryPoint of model.jsEntryPoints) {
const exportedName = getExportName(entryPoint.outputModuleId);
const exportedName = getPackageExportsKey(entryPoint.outputModuleId);
const jsPath = `./${entryPoint.outputModuleId}.js`;
const exportEntry: Record<string, string> = {
import: jsPath
Expand All @@ -149,14 +149,12 @@ function generateExports(model: SimplePackageModel, validationErrors: Validation
return exportedModules;
}

function getExportName(moduleId: string) {
if (moduleId === "index") {
function getPackageExportsKey(moduleId: string) {
const name = getExportedName(moduleId);
if (!name) {
return ".";
}
if (posix.basename(moduleId) === "index") {
return "./" + posix.dirname(moduleId);
}
return `./${moduleId}`;
return `./${name}`;
}

function generateMetadata(model: SimplePackageModel): unknown {
Expand Down
35 changes: 15 additions & 20 deletions packages/build-package/src/rollup/checkImports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import { fileURLToPath, pathToFileURL } from "url";
import { loadPackageJson } from "../model/InputModel";
import { getEntryPointsFromBuildConfig } from "../model/PackageModel";
import { createDebugger } from "../utils/debug";
import { NormalizedEntryPoint } from "../utils/entryPoints";
import { getFileNameWithQuery, isInDirectory } from "../utils/pathUtils";
import { getExportedName } from "../utils/entryPoints";

export interface CheckImportsOptions {
packageJson: Record<string, unknown>;
Expand Down Expand Up @@ -153,8 +153,8 @@ interface TrailsPackageInfo {
packageJson: Record<string, unknown>;

// Parsed entry points from build config
entryPointsByModuleId: Map<string, NormalizedEntryPoint>;
servicesEntryPoint: NormalizedEntryPoint | undefined;
exportedModules: Set<string>;
servicesModule: string | undefined;
}

class CheckImportsState {
Expand Down Expand Up @@ -377,15 +377,6 @@ class CheckImportsState {
throw new Error(`Internal error: expected '${moduleId}' to start with ${packageName}`);
}

// Use the 'main' field as a fallback
let packageMain = trailsInfo.packageJson.main as string | undefined;
if (packageMain) {
packageMain = packageMain.replace(/\.[^/.]+$/, ""); // strip extension
}
if (!relativeModuleId) {
relativeModuleId = packageMain || "index";
}

isDebug &&
debug(
"Checking relative module id '%s' in trails package %s",
Expand All @@ -394,19 +385,15 @@ class CheckImportsState {
);

// The module must be an entry point.
const entryPoint = trailsInfo.entryPointsByModuleId.get(relativeModuleId);
if (!entryPoint) {
if (!trailsInfo.exportedModules.has(relativeModuleId)) {
importCtx.warn(
`Failed to import '${moduleId}': '${relativeModuleId}' is not an entry point of ${packageName}`
);
return false;
}

// It must _not_ be the services entry point.
if (
trailsInfo.servicesEntryPoint &&
trailsInfo.servicesEntryPoint.outputModuleId === entryPoint.outputModuleId
) {
if (trailsInfo.servicesModule != null && relativeModuleId === trailsInfo.servicesModule) {
importCtx.warn(
`Failed to import '${moduleId}': the module is the package's services entry point, which should not be imported directly`
);
Expand Down Expand Up @@ -495,12 +482,20 @@ class CheckImportsState {
(..._args) => undefined // don't report anything for foreign packages
);

const exportedModules = new Set<string>(
Array.from(jsEntryPointsByModuleId.values()).map((ep) =>
getExportedName(ep.outputModuleId)
)
);
const servicesModule = servicesEntryPoint
? getExportedName(servicesEntryPoint.outputModuleId)
: undefined;
const result: TrailsPackageInfo = {
rawPackagePath: importedPackageDir,
resolvedPackagePath: realImportedPackageDir,
packageJson,
entryPointsByModuleId: jsEntryPointsByModuleId,
servicesEntryPoint
exportedModules,
servicesModule
};
isDebug && debug("Detected trails package %s: %O", packageName, result);
return result;
Expand Down
13 changes: 11 additions & 2 deletions packages/build-package/src/utils/entryPoints.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)
// SPDX-License-Identifier: Apache-2.0
import { describe, expect, it } from "vitest";
import { normalizeEntryPoints } from "./entryPoints";
import { getExportedName, normalizeEntryPoints } from "./entryPoints";

const EXTS = [".js", ".ts"];

describe("entryPoints", function () {
describe("normalizeEntryPoints", function () {
it("normalizes valid entry point specifiers", function () {
const rawEntryPoints = [
"./index",
Expand Down Expand Up @@ -67,3 +67,12 @@ describe("entryPoints", function () {
);
});
});

describe("getExportedName", function () {
it("returns the expected exported name", function () {
expect(getExportedName("index")).toBe("");
expect(getExportedName("foo")).toBe("foo");
expect(getExportedName("foo/bar/baz")).toBe("foo/bar/baz");
expect(getExportedName("foo/bar/index")).toBe("foo/bar");
});
});
21 changes: 20 additions & 1 deletion packages/build-package/src/utils/entryPoints.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)
// SPDX-License-Identifier: Apache-2.0

import { getExtension } from "./pathUtils";
import posix from "node:path/posix";

// TODO: Refactor, use common resolve function

Expand Down Expand Up @@ -78,3 +78,22 @@ export function normalizeEntryPoint(entryPoint: string, supportedExtensions: str
}
return normalized;
}

/**
* Returns the name of the module that can be imported from outside of the package.
* The `outputModuleId` should be taken from a {@link NormalizedEntryPoint}.
*
* Examples:
* - `"index"` -> `""`
* - `"foo/bar/baz"` -> `"foo/bar/baz"`
* - `"foo/bar/index"` -> `"foo/bar"`
*/
export function getExportedName(outputModuleId: string) {
if (outputModuleId === "index") {
return "";
}
if (posix.basename(outputModuleId) === "index") {
return posix.dirname(outputModuleId);
}
return outputModuleId;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { defineBuildConfig } from "@open-pioneer/build-support";

export default defineBuildConfig({
entryPoints: ["main-entry.js", "other-entry.js"]
entryPoints: ["index.js", "other-entry.js", "nested/index.js"]
});
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const NESTED = "nested";
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{
"name": "package-b",
"version": "0.0.1",
"main": "main-entry.js",
"dependencies": {},
"publishConfig": {
"directory": "dist"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
import { A } from "package-a";
import { MAIN } from "package-b";
import { OTHER } from "package-b/other-entry";
console.log(A, MAIN, OTHER);
import { NESTED } from "package-b/nested";
console.log(A, MAIN, OTHER, NESTED);

0 comments on commit d9a0c1b

Please sign in to comment.