From c5786ff2f3fb9ebca2405bb8d6cc53268b12674f Mon Sep 17 00:00:00 2001
From: Josh Black <joshblack@github.com>
Date: Wed, 13 Mar 2024 12:20:36 -0500
Subject: [PATCH] feat(octicons_react): add support for ESM import (#1008)

* feat(octicons_react): add support for ESM import

* chore: add changeset
---
 .changeset/tasty-countries-grow.md  |  5 ++++
 lib/octicons_react/package.json     | 10 ++++---
 lib/octicons_react/rollup.config.js | 42 +++++++++++++++++++++++------
 lib/octicons_react/script/types.js  | 24 ++++++++---------
 4 files changed, 58 insertions(+), 23 deletions(-)
 create mode 100644 .changeset/tasty-countries-grow.md

diff --git a/.changeset/tasty-countries-grow.md b/.changeset/tasty-countries-grow.md
new file mode 100644
index 000000000..c426c4358
--- /dev/null
+++ b/.changeset/tasty-countries-grow.md
@@ -0,0 +1,5 @@
+---
+'@primer/octicons-react': minor
+---
+
+Update ESM import to use mjs extension when in parent CommonJS module
diff --git a/lib/octicons_react/package.json b/lib/octicons_react/package.json
index 90965470c..e63a16eea 100644
--- a/lib/octicons_react/package.json
+++ b/lib/octicons_react/package.json
@@ -5,11 +5,15 @@
   "homepage": "https://primer.style/octicons",
   "author": "GitHub, Inc.",
   "license": "MIT",
+  "type": "commonjs",
   "main": "dist/index.umd.js",
-  "module": "dist/index.esm.js",
+  "module": "dist/index.esm.mjs",
   "exports": {
-    "types": "./dist/index.d.ts",
-    "import": "./dist/index.esm.js",
+    "types": {
+      "import": "./dist/index.d.mts",
+      "require": "./dist/index.d.ts"
+    },
+    "import": "./dist/index.esm.mjs",
     "require": "./dist/index.umd.js"
   },
   "sideEffects": false,
diff --git a/lib/octicons_react/rollup.config.js b/lib/octicons_react/rollup.config.js
index 1b04c208a..23cfa253a 100644
--- a/lib/octicons_react/rollup.config.js
+++ b/lib/octicons_react/rollup.config.js
@@ -1,10 +1,20 @@
 import babel from '@rollup/plugin-babel'
 import commonjs from '@rollup/plugin-commonjs'
+import packageJson from './package.json'
 
-const formats = ['esm', 'umd'] // 'cjs' ?
+const dependencies = [
+  ...Object.keys(packageJson.peerDependencies ?? {}),
+  ...Object.keys(packageJson.dependencies ?? {}),
+  ...Object.keys(packageJson.devDependencies ?? {})
+]
 
-export default {
+function createPackageRegex(name) {
+  return new RegExp(`^${name}(/.*)?`)
+}
+
+const baseConfig = {
   input: 'src/index.js',
+  external: dependencies.map(createPackageRegex),
   plugins: [
     babel({
       babelrc: false,
@@ -20,10 +30,26 @@ export default {
       babelHelpers: 'bundled'
     }),
     commonjs()
-  ],
-  output: formats.map(format => ({
-    file: `dist/index.${format}.js`,
-    format,
-    name: 'reocticons'
-  }))
+  ]
 }
+
+export default [
+  {
+    ...baseConfig,
+    output: {
+      file: `dist/index.esm.mjs`,
+      format: 'esm'
+    }
+  },
+  {
+    ...baseConfig,
+    output: {
+      file: `dist/index.umd.js`,
+      format: 'umd',
+      name: 'reocticons',
+      globals: {
+        react: 'React'
+      }
+    }
+  }
+]
diff --git a/lib/octicons_react/script/types.js b/lib/octicons_react/script/types.js
index 99860a8ad..43cecec2a 100755
--- a/lib/octicons_react/script/types.js
+++ b/lib/octicons_react/script/types.js
@@ -10,17 +10,17 @@ const destDir = resolve(__dirname, '../dist')
 const iconsDest = join(destDir, 'icons.d.ts')
 const indexDest = join(destDir, 'index.d.ts')
 
-fse
-  .copy(iconsSrc, iconsDest)
-  .then(() => {
-    return fse
-      .readFile(indexSrc, 'utf8')
-      .then(content => content.replace(/.\/__generated__\//g, './'))
-      .then(content => fse.writeFile(indexDest, content, 'utf8'))
-  })
-  .catch(die)
+async function main() {
+  await fse.copy(iconsSrc, iconsDest)
 
-function die(err) {
-  console.error(err.stack)
-  process.exitCode = 1
+  let contents = await fse.readFile(indexSrc, 'utf8')
+  contents = contents.replace(/.\/__generated__\//g, './')
+
+  await fse.writeFile(indexDest, contents, 'utf8')
+  await fse.writeFile(join(destDir, 'index.d.mts'), contents, 'utf8')
 }
+
+main().catch(error => {
+  console.error(error)
+  process.exitCode = 1
+})