Home > Mobile >  package.json not honouring exports property for esm and cjs npm package
package.json not honouring exports property for esm and cjs npm package

Time:08-26

I am having difficulty getting my npm library to support subpath imports/requires via the exports field in the package.json. For context, package.json supports a field "exports" which allows you to conditonally expose files based on the runtime (i.e. commonjs OR ecmascript.

When importing the npm library in my typescript project, I get the following error:

// How I import
import logger from '@myorg/custom-logger/src/logger';

// The error I get in vscode
Cannot find module '@myorg/custom-logger/src/logger' or its corresponding type declarations.

The tsc compiler error:

TSError: ⨯ Unable to compile TypeScript:
src/config/winston.ts:1:20 - error TS2307: Cannot find module '@myorg/custom-logger/src/logger' or its corresponding type declarations.

The custom-logger package comes with support for commonjs and esm. It is built & deployed to npm with the following structure:

esm/
--- src/
--- index.js
--- logger.js
--- index.d.ts
--- logger.d.ts
--- package.json which contains { "type": "module" } (also tried without this - same issue occurs) 
cjs/
--- src/
--- index.js
--- logger.js
--- index.d.ts
--- logger.d.ts
--- package.json which contains { "type": "commonjs" } (also tried without this - same issue occurs) 
package.json which contains (see below)

The main package.json in the @myorg/custom-logger package contains the following:

{
  "name": "@myorg/custom-logger",
  "version": "0.1.4",
  "dependencies": {
    "app-root-path": "^3.0.0",
    "winston": "^3.8.1"
  },
  "devDependencies": {
    "@types/app-root-path": "^1.2.4",
    "@types/winston": "^2.4.4"
  },
  "types": "./esm/src/index.d.ts",
  "typings": "./esm/src/index.d.ts",
  "module": "./esm/src/index.js",
  "main": "./cjs/src/index.js",
  "exports": {
    "./src/*": {
      "types": "./esm/src/*.d.ts",
      "import": "./esm/src/*.js",
      "require": "./cjs/src/*.js"
    },
    ".": {
      "types": "./esm/src/index.d.ts",
      "import": "./esm/src/index.js",
      "require": "./cjs/src/index.js"
    }
  }
}

The issues I am having are as follows:

  • Typescript and vscode doesn't seem to honour the exports logic (it throws the errors seen above)

What I am trying to achieve is:

  • Be able to import subpaths. i.e. import mylib from '@myorg/custom-logger/src/logger'

I am using "typescript": "4.7.4", and am using esm (ecmascript) natively in node.

CodePudding user response:

So to get this working, I had to update my tsconfig "moduleResolution" config.

Here is my new config (notice how I have "moduleResolution": "Node16" set):

  • You can also use NodeNext as the moduleResolution
{
  "compilerOptions": {
    "target": "ESNEXT",                  /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */
    "module": "ESNext",                /* Specify module code generation: 'none', commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
    "moduleResolution": "Node16",
    "outDir": "build/" /* Redirect output structure to the directory. */,
    /* Strict Type-Checking Options */
    "strict": true /* Enable all strict type-checking options. */,
    "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
    "rootDir": "./",
    "resolveJsonModule": true
  },
  "include": ["src/", "e2e"],
  "exclude": ["node_modules", "build", "logs", "db"],
  "resolveJsonModule": true,
  "esModuleInterop": true
}

Before this, the moduleResolution value was set to node. After further investigation, the node moduleResolution does not support the "exports" field in the package.json. Here is a great answer that explains it in more detail

  • Related