Skip to content

Fixing a minor inconvenience with Phosphor Icons

Posted on:June 12, 2023

I have been using Phosphor Icons for a while now and absolutely love them! They’re well-crafted and fit a huge range of needs when working with icons. However, the other day I wanted to upgrade to v2 which includes a massive amount of new icons. Alas, this version required upgrading from phosphor-react to @phosphor-icons/react, to remove a legacy dependency and unify all the separate packages under a single repo.

I get the reasoning behind this, and truly it’s not a huge deal, so I went about the upgrade.

Unfortunately, I immediately started receiving cryptic errors saying crazy stuff like:

 generating static routes
 error   Named export 'Envelope' not found. The requested module '@phosphor-icons/react' is a CommonJS module, which may not support all module.exports as named exports.
  CommonJS modules can always be imported via the default export, for example using:

  import pkg from '@phosphor-icons/react';
  const { Envelope } = pkg;

  File:
    /Users/.../node_modules/astro/dist/core/build/generate.js:169:22
  Code:
    168 |   }
    > 169 |   const pageModule = await pageModulePromise();
          |                      ^
      170 |   if (shouldSkipDraft(pageModule, opts.settings)) {
      171 |     info(opts.logging, null, `${magenta("\u26A0\uFE0F")}  Skipping draft ${pageData.route.component}`);
      172 |     return;

Which didn’t make immediate sense to me. However, I’ve learned that sometimes reading the error messages and doing what they suggest can be a good step forward.

So I tried the suggested import syntax:

import pkg from '@phosphor-icons/react';
const { Envelope } = pkg;

Which then led to this error:

 generating static routes
(node:85082) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
(Use `node --trace-warnings ...` to show where the warning was created)
/Users/.../node_modules/@phosphor-icons/react/dist/index.es.js:1
import { IconContext as o } from "./lib/context.es.js";
^^^^^^

SyntaxError: Cannot use import statement outside a module

A quick bit of Google-fu told me this could be resolved by setting "type": "module" in my package.json file. Alas, this too, did not resolve the problem. I had given up in defeat, when a GitHub user suggested I add "type": "module" to the package.json file of the @phosphor-icons/react package, rather than my project.

To my great delight——it worked!

However, I couldn’t build my project manually each time I wanted to deploy it. That just wouldn’t do.

So I wrote a tiny script to auto-inject that feature, in case my PR for the project was rejected.

Here’s the script I wrote:

const fs = require('fs');
const path = require('path');
const phosphorPackageFilePath = path.join(__dirname, 'node_modules/@phosphor-icons/react/package.json');
const phosphorPackage = JSON.parse(fs.readFileSync(phosphorPackageFilePath, 'utf8'));
phosphorPackage.type = "module";
fs.writeFileSync(phosphorPackageFilePath, JSON.stringify(phosphorPackage, null, 2));

And I added it to my package.json file:

{
    "scripts": {
        "build": "node fixPhosphorIcons.js && astro build"
    }
}

Et voi la! I can now use @phosphor-icons/react and the beefy new version 2 in my project, all without having to worry about whether or not the upstream project changes.