nx - configure main/module for generated package.json

Viewed 854

I've created a library in nx monorepo (build executer: @nrwl/web:package). The build task generates a library package.json which includes the properties "main" and "modules". Because of a custom rollup config, I'd like to overwrite these properties.

I can't find a documentation howto overwrite both properties. In generall, I don't understand why there is always mylib.umd.js for the main property, also when i just set --format=esm.

generated package.json:

{
  "name": "@scope/packagename",
  "version": "0.12.0",
  "repository": {
    "type": "git",
    "url": "https://github.com/package.git"
  },
  "main": "./mylib.umd.js",
  "module": "./mylib.esm.js",
  "typings": "./index.d.ts",
  "dependencies": {},
  "peerDependencies": {
    "styled-components": "5.3.3",
    "react": "17.0.2"
  }
}

my custom rollup config:

module.exports = options => {
  delete options.output.file;
  delete options.output.name;

  const config = {
    ...options,
    output: [
      {
        ...options.output,
        dir: "dist/libs/flightroute-banner/esm",
        format: "esm",
      },
      {
        ...options.output,
        dir: "dist/libs/flightroute-banner/cjs",
        format: "cjs",
      },
    ],
    plugins: [
      ...options.plugins,
      url(),
      svgr({ svgo: false, ref: true, titleProp: true }),
    ],
  };

  return config;
};

findings:
looks like the main definition is hardcoded to *.umd.js https://github.com/nrwl/nx/blob/master/packages/web/src/executors/package/package.impl.ts#L294

function updatePackageJson(
  options: NormalizedWebPackageOptions,
  context: ExecutorContext,
  target: ProjectGraphNode,
  dependencies: DependentBuildableProjectNode[],
  packageJson: any
) {
  const entryFileTmpl = `./${context.projectName}.<%= extension %>.js`;
  const typingsFile = relative(options.entryRoot, options.entryFile).replace(
    /\.[jt]sx?$/,
    '.d.ts'
  );
  packageJson.main = entryFileTmpl.replace('<%= extension %>', 'umd');
  packageJson.module = entryFileTmpl.replace('<%= extension %>', 'esm');
  packageJson.typings = `./${typingsFile}`;
  writeJsonFile(`${options.outputPath}/package.json`, packageJson);

  if (
    dependencies.length > 0 &&
    options.updateBuildableProjectDepsInPackageJson
  ) {
    updateBuildableProjectPackageJsonDependencies(
      context.root,
      context.projectName,
      context.targetName,
      context.configurationName,
      target,
      dependencies,
      options.buildableProjectDepsInPackageJsonType
    );
  }
}

workaround

I've created a custom executor to modify the generated package.json

export default async function packageExecutorMod(
  options: WebPackageOptions,
  context: ExecutorContext
) {
  await packageExecutor(options, context).next();

  const packageJson = readJsonFile(`${options.outputPath}/package.json`);

  const entryFileTmpl = `./${context.projectName}.<%= extension %>.js`;
  packageJson.main = entryFileTmpl.replace('<%= extension %>', options.format.includes('cjs') ? 'cjs' : 'umd');

  if(!options.format.includes("esm")) delete packageJson.module;

  writeJsonFile(`${options.outputPath}/package.json`, packageJson);

  return { success: true };
}

0 Answers
Related