From 90282f39c654cce568dcb74d60b7414fdc0323a1 Mon Sep 17 00:00:00 2001 From: Joren Broekema Date: Mon, 14 Oct 2024 23:17:15 +0200 Subject: [PATCH] Add package entrypoints (#170) https://github.com/stevenpetryk/mafs/issues/163 https://github.com/stevenpetryk/mafs/issues/147 These issues are related. "type": "module" was removed but in our instance this actually causes issues for NextJS when trying to import (named imports specifically) from mafs, such as: ![image](https://github.com/user-attachments/assets/3704e279-cea0-4bc9-9fff-d7350657ec88) I think the correct solution should have been to keep "type": "module" and use the "cjs" extension for the CJS output. That fixes both our issues and those listed in the 2 issues above, removing the type module field and using .mjs unfortunately only solves the issue for CJS users, but not for ESM users. Even better is to just use package entrypoints so there is no confusion. Reason being that the "module" field next to the "main" field is an unspecced conventional field that only *some* tools respect, and "main" is technically a legacy field now. The future-proof method is package entrypoints, and has the benefit of locking down your public API, which means users won't accidentally rely on private API by using direct filepath imports. This gives the maintainer the freedom to structure the published files in any way they please without causing breaking changes. --------- Co-authored-by: Steven Petryk --- package.json | 11 +++++++++-- scripts/build.ts | 3 ++- scripts/testgen.ts | 6 +++--- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index c5c7520c..2e6af742 100644 --- a/package.json +++ b/package.json @@ -6,8 +6,15 @@ "homepage": "https://mafs.dev", "repository": "github:stevenpetryk/mafs", "source": "src/index.tsx", - "main": "build/index.js", - "module": "build/index.mjs", + "type": "module", + "exports": { + ".": { + "import": "./build/index.js", + "require": "./build/index.cjs" + }, + "./core.css": "./core.css", + "./font.css": "./font.css" + }, "types": "build/index.d.ts", "packageManager": "pnpm@9.5.0", "engines": { diff --git a/scripts/build.ts b/scripts/build.ts index b72804b9..0e8e1cdf 100644 --- a/scripts/build.ts +++ b/scripts/build.ts @@ -5,7 +5,8 @@ import typescript from "typescript" import invariant from "tiny-invariant" const packageJson = fs.readJsonSync("./package.json") -const { main: cjsOutFile, module: esmOutFile, peerDependencies, dependencies } = packageJson +const { exports, peerDependencies, dependencies } = packageJson +const { import: esmOutFile, require: cjsOutFile } = exports["."] async function main() { fs.emptyDirSync("build") diff --git a/scripts/testgen.ts b/scripts/testgen.ts index 34d35f08..cd5dd2b6 100644 --- a/scripts/testgen.ts +++ b/scripts/testgen.ts @@ -12,7 +12,7 @@ const SKIP = [ /latex/i, ] -const mafsRoot = path.join(__dirname, "..") +const mafsRoot = path.join(import.meta.dirname, "..") const guideExamplesFolder = path.join(mafsRoot, "docs/components/guide-examples") @@ -23,7 +23,7 @@ const examples = glob .filter((filepath) => !SKIP.some((skip) => skip.test(filepath))) let testFileContent = ` -// THIS FILE IS GENERATED BY ./${path.relative(mafsRoot, __filename)} +// THIS FILE IS GENERATED BY ./${path.relative(mafsRoot, import.meta.filename)} /* eslint-disable @typescript-eslint/no-explicit-any */ import { expect, test } from "@playwright/experimental-ct-react" @@ -72,7 +72,7 @@ for (const example of examples) { ` } -prettier.resolveConfig(__filename).then(async (config) => { +prettier.resolveConfig(import.meta.filename).then(async (config) => { const formattedTestFileContent = await prettier.format(testFileContent, { parser: "typescript", ...config,