Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 11 additions & 12 deletions packages/code-infra/src/cli/cmdBuild.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { $ } from 'execa';
import set from 'lodash-es/set.js';
import * as fs from 'node:fs/promises';
import * as path from 'node:path';
import { getOutExtension, isMjsBuild } from '../utils/build.mjs';
import { getOutExtension, isMjsBuild, validatePkgJson } from '../utils/build.mjs';

/**
* @typedef {Object} Args
Expand All @@ -16,6 +16,7 @@ import { getOutExtension, isMjsBuild } from '../utils/build.mjs';
* @property {boolean} skipTsc - Whether to build types for the package.
* @property {boolean} skipBabelRuntimeCheck - Whether to skip checking for Babel runtime dependencies in the package.
* @property {boolean} skipPackageJson - Whether to skip generating the package.json file in the bundle output.
* @property {boolean} skipMainCheck - Whether to skip checking for main field in package.json.
* @property {string[]} ignore - Globs to be ignored by Babel.
*/

Expand Down Expand Up @@ -291,6 +292,12 @@ export default /** @type {import('yargs').CommandModule<{}, Args>} */ ({
type: 'boolean',
default: false,
description: 'Skip generating the package.json file in the bundle output.',
})
.option('skipMainCheck', {
// Currently added only to support @mui/icons-material. To be removed separately.
type: 'boolean',
default: false,
description: 'Skip checking for main field in package.json.',
});
},
async handler(args) {
Expand All @@ -310,17 +317,9 @@ export default /** @type {import('yargs').CommandModule<{}, Args>} */ ({
const cwd = process.cwd();
const pkgJsonPath = path.join(cwd, 'package.json');
const packageJson = JSON.parse(await fs.readFile(pkgJsonPath, { encoding: 'utf8' }));
const buildDirBase = packageJson.publishConfig?.directory;
if (!buildDirBase) {
throw new Error(
`No build directory specified in "${packageJson.name}" package.json. Specify it in the "publishConfig.directory" field.`,
);
}
if (packageJson.private === false) {
throw new Error(
`Remove the field "private": false from "${packageJson.name}" package.json. This is redundant.`,
);
}
validatePkgJson(packageJson, { skipMainCheck: args.skipMainCheck });

const buildDirBase = /** @type {string} */ (packageJson.publishConfig?.directory);
const buildDir = path.join(cwd, buildDirBase);

console.log(`Selected output directory: "${buildDirBase}"`);
Expand Down
50 changes: 50 additions & 0 deletions packages/code-infra/src/utils/build.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,53 @@ export function getOutExtension(bundle, isType = false) {
}
return bundle === 'esm' ? '.mjs' : '.js';
}

/**
* Validates the package.json before building.
* @param {Record<string, any>} packageJson
* @param {Object} [options]
* @param {boolean} [options.skipMainCheck=false] - Whether to skip checking for main field in package.json.
*/
export function validatePkgJson(packageJson, options = {}) {
const { skipMainCheck = false } = options;
/**
* @type {string[]}
*/
const errors = [];
const buildDirBase = packageJson.publishConfig?.directory;
if (!buildDirBase) {
errors.push(
`No build directory specified in "${packageJson.name}" package.json. Specify it in the "publishConfig.directory" field.`,
);
}
if (packageJson.private === false) {
errors.push(
`Remove the field "private": false from "${packageJson.name}" package.json. This is redundant.`,
);
}

if (!skipMainCheck) {
if (packageJson.main) {
errors.push(
`Remove the field "main" from "${packageJson.name}" package.json. Add it as "exports["."]" instead.`,
);
}

if (packageJson.module) {
errors.push(
`Remove the field "module" from "${packageJson.name}" package.json. Add it as "exports["."]" instead.`,
);
}

if (packageJson.types || packageJson.typings) {
errors.push(
`Remove the field "types/typings" from "${packageJson.name}" package.json. Add it as "exports["."]" instead.`,
);
}
}

if (errors.length > 0) {
const error = new Error(errors.join('\n'));
throw error;
}
}
Loading