Yarn won't publish/add both ESM and CJS versions of package?

1k Views Asked by At

We have an application bundled with Parcel that consumes a UI library (react components). The UI library is bundled with Rollup and published as a private package on NPM.

I've been trying to migrate our application to use Parcel 2, but Parcel complains that it cannot locate the ESM version of the UI library within the dist folder. Sure enough, when I check my node_modules directory, the dist folder for the UI lib includes only one file: index.cjs.js.

The weird part is that the UI lib is set up to build in both CJS and ESM formats with sourcemaps. When I build the project locally, Rollup produces both CJS and ESM files and their sourcemaps: index.cjs.js, index.cjs.js.map, index.esm.js, and index.esm.js.map. So, somehow, it seems that either: (1) Yarn is only publishing the CJS version of the library to NPM or (2) When the UI lib is added to the application, only the CJS version is being built. Neither of those situations makes sense to me.

Here's the relevant sections of our package.json and rollup.config.js files:

{
 "name": "@thecb/components",
  "version": "4.0.23",
  "description": "Common lib for CityBase react components",
  "main": "dist/index.cjs.js",
  "module": "dist/index.esm.js",
  "source": "src/index.js",
  "scripts": {
    "storybook": "start-storybook",
    "build": "rollup -cm"
  },
import resolve from "rollup-plugin-node-resolve";
import commonjs from "rollup-plugin-commonjs";
import babel from "rollup-plugin-babel";
import json from "rollup-plugin-json";
import visualizer from "rollup-plugin-visualizer";
import pkg from "./package.json";

import * as formattedInput from "formatted-input";

const globals = {
  react: "React",
  "react-dom": "ReactDOM"
};

const plugins = [
  resolve({ preferBuiltins: false }),
  babel({
    exclude: "node_modules/**",
    presets: ["@babel/env", "@babel/preset-react"]
  }),
  json(),
  commonjs({
    include: "node_modules/**",
    namedExports: {
      "formatted-input": Object.keys(formattedInput)
    }
  }),
  visualizer()
];

const external = [...Object.keys(pkg.peerDependencies || {})];

const output_data = [
  {
    file: pkg.main,
    format: "cjs"
  },
  {
    file: pkg.module,
    format: "esm"
  }
];

export default output_data.map(({ file, format }) => ({
  input: "src/index.js",
  output: {
    file,
    format,
    globals
  },
  plugins,
  external
}));

Anyone have any idea why the ESM version of this lib either wouldn't be published or installed?

1

There are 1 best solutions below

0
On BEST ANSWER

Late reply but I ran into something very similar today. Not using rollup but rather tsc directly to output dist/cjs/* and dist/esm/*.

I found that my build process locally produced both outputs but the tarball produced by yarn publish only contained dist/cjs/*. TBH I'm not sure why; my current theory is that yarn is somehow using the "main": "dist/cjs/index.js" and inferring some defaults for package inclusion from that.

What I can tell you is that by adding "files": "dist" to my package.json I got yarn to behave itself and add both dist/cjs/* and dist/esm/* to the package tarball as I initially expected.

https://docs.npmjs.com/cli/v7/configuring-npm/package-json#files