I am currently developing a JavaScript library that I want to make importable via script tags, ES6 imports, and traditional Node requires, with or without TypeScript or any build systems. However, I am facing challenges in achieving this.
Within my package.json file, I have specified the following exports (simplified for clarity):
"exports": {
".": {
"require": "./dist/slim.copper.cjs",
"import": "./dist/slim.copper.js",
"types": "./dist/typed.copper.d.ts"
},
}
In a test TypeScript project, I import my library using the statement:
import Copper from "@jwrunge/copper";
While type hints and intellisense work well, and I can compile the code to JavaScript successfully, I encounter an error when running the JS code with Node:
C:\Users\jrunge\Documents\CODE\copper_test\src\index.js:3
var copper_1 = require("@jwrunge/copper");
^
The require statement for slim.copper.js within C:\Users\jrunge\Documents\CODE\copper_test\src\index.js needs to be changed to a dynamic import() as it is supported in all CommonJS modules.
at Object.<anonymous> (C:\Users\jrunge\Documents\CODE\copper_test\src\index.js:3:16) {
code: 'ERR_REQUIRE_ESM'
}
Although the JavaScript output from TypeScript retains the appropriate typing, it uses require as shown below:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var copper_1 = require("@jwrunge/copper");
var store1 = copper_1.default.store("foo", { value: 12 });
Interestingly, when I console.log
copper_1
in the JS output and comment out all other code, the result is:
{
store: [Function: store],
ustore: [Function: ustore],
getFunc: [Function: getFunc],
addFuncs: [Function: addFuncs],
config: [Function: config]
}
It seems that the imported copper_1
does not have a default property and is a direct import of the .cjs file, which aligns with the usage of require.
- Could it be that the JS output is utilizing the .cjs version of the library, which does not have an export property like the .js version?
- What would be a recommended solution to address this issue while still supporting require imports? I am open to simple instructions for my users, but I prefer a solution that allows for better compatibility with various use cases.
If I refrain from supporting require and only provide es (.js) module files, the following error occurs (when trying to require an ES module):
Error [ERR_REQUIRE_ESM]: require() of ES Module C:\Users\jrunge\Documents\CODE\pubsub\dist\slim.copper.js from C:\Users\jrunge\Documents\CODE\copper_test\src\index.js not supported.
Instead change the require of slim.copper.js in C:\Users\jrunge\Documents\CODE\copper_test\src\index.js to a dynamic import() which is available in all CommonJS modules.
at Object.<anonymous> (C:\Users\jrunge\Documents\CODE\copper_test\src\index.js:3:16) {
code: 'ERR_REQUIRE_ESM'
}