Page MenuHomePhabricator

Importing Codex ES module in Node.js doesn't work
Closed, ResolvedPublicBUG REPORT

Description

Currently the codex packages have "main" and "module" entries in their package.json:

"main": "dist/codex.umd.js",
"module": "dist/codex.es.js"

I don't know what's a valid mechanism to import components from the es module in a non-MW environment. For instance when trying to build a VitePress project which imports Codex components as import { CdxButton } from '@wikimedia/codex'; the following error is yield:

import { CdxDialog, CdxButton } from "@wikimedia/codex";
                    ^^^^^^^^^
SyntaxError: Named export 'CdxButton' not found. The requested module '@wikimedia/codex' 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 '@wikimedia/codex';
const { CdxDialog, CdxButton } = pkg;

Have you considered using package.json "exports" entry? I was able to import the es Codex components and icons by adding an "exports" entry as follows:

"main": "dist/codex.umd.js",
"module": "dist/codex.es.mjs",
"exports": {
  "import": "./dist/codex.es.mjs",
  "require": "./dist/codex.umd.js"
}

(Note in my tests I had to use the .mjs extension to get it working, not sure why). Before that I had also tried "type":"module" in the project package.json but didn't work. I think for that we would need to change the "main" entry. Is there a preferred mechanism to import from the es module that I'm missing?

We need to rename codex.es.js to have an .mjs extension, and explicitly expose it using the "exports" property in package.json

Event Timeline

Restricted Application added a subscriber: Aklapper. · View Herald Transcript
Restricted Application triaged this task as High priority. · View Herald TranscriptFeb 18 2023, 12:26 AM

Change 889986 had a related patch set uploaded (by Catrope; author: Sergio Gimeno):

[design/codex@main] build: Expose ES module build correctly, rename to .mjs

https://gerrit.wikimedia.org/r/889986

Change 889986 merged by jenkins-bot:

[design/codex@main] build: Expose ES module build correctly, rename to .mjs

https://gerrit.wikimedia.org/r/889986

I just tried this out in a dummy Node project and can confirm that things are working as expected now.

I'm using Node.js v16.19.0.

package.json
{
  "name": "codex-npm-test",
  "version": "1.0.0",
  "description": "Test test",
  "main": "index.js",
  "type": "module",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@wikimedia/codex": "^0.6.1"
  }
}
index.js
import { CdxButton } from "@wikimedia/codex";
console.log( CdxButton );

Example output:

$> node index.js

{
  name: 'CdxButton',
  props: {
    action: {
      type: [Function: String],
      default: 'default',
      validator: [Function (anonymous)]
    },
    type: {
      type: [Function: String],
      default: 'normal',
      validator: [Function (anonymous)]
    }
  },
  emits: [ 'click' ],
  setup: [Function: setup],
  render: [Function: fn]
}

Looks like for users of more recent Node versions, you can *either* use an .mjs file in your consuming code, or you can just set "type": "module" in your package.json file. If you are using some specific build tool (Vite, Rollup, etc) then this might not be necessary.

Thanks for the quick reaction and working on this!

Change 893051 had a related patch set uploaded (by VolkerE; author: VolkerE):

[mediawiki/core@master] Update Codex from v0.6.0 to v0.6.2

https://gerrit.wikimedia.org/r/893051

Change 893051 merged by jenkins-bot:

[mediawiki/core@master] Update Codex from v0.6.0 to v0.6.2

https://gerrit.wikimedia.org/r/893051