diff --git a/babel.config.js b/babel.config.js index 12d09a03c23b33..c826266bb05b1d 100644 --- a/babel.config.js +++ b/babel.config.js @@ -103,7 +103,7 @@ module.exports = function getBabelConfig(api) { ]); } - if (process.env.MUI_ADD_IMPORT_EXTENSIONS === 'true') { + if (!process.env.SKIP_CORE_EXPORTS_FORMAT) { plugins.push(['babel-plugin-add-import-extension', { extension: useESModules ? 'mjs' : 'js' }]); } diff --git a/package.json b/package.json index 17795c8bf039ef..04e53983a7c895 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,7 @@ "test:karma": "cross-env NODE_ENV=test karma start test/karma.conf.js", "test:karma:profile": "cross-env NODE_ENV=test karma start test/karma.conf.profile.js", "test:regressions": "cross-env NODE_ENV=production pnpm test:regressions:build && concurrently --success first --kill-others \"pnpm test:regressions:run\" \"pnpm test:regressions:server\"", - "test:regressions:build": "webpack --config test/regressions/webpack.config.js", + "test:regressions:build": "cross-env SKIP_CORE_EXPORTS_FORMAT=true webpack --config test/regressions/webpack.config.js", "test:regressions:dev": "concurrently \"pnpm test:regressions:build --watch\" \"pnpm test:regressions:server\"", "test:regressions:run": "mocha --config test/regressions/.mocharc.js --delay 'test/regressions/**/*.test.js'", "test:regressions:server": "serve test/regressions -p 5001", diff --git a/packages/mui-core-downloads-tracker/package.json b/packages/mui-core-downloads-tracker/package.json index cd2845f18da7b1..331c1d2b821ab4 100644 --- a/packages/mui-core-downloads-tracker/package.json +++ b/packages/mui-core-downloads-tracker/package.json @@ -21,7 +21,7 @@ }, "scripts": { "build": "mkdir build && pnpm build:copy-files", - "build:copy-files": "node ../../scripts/copyFiles.mjs --skipExportsField", + "build:copy-files": "cross-env SKIP_CORE_EXPORTS_FORMAT=true node ../../scripts/copyFiles.mjs", "prebuild": "rimraf build", "release": "pnpm build && pnpm publish" }, diff --git a/packages/mui-icons-material/package.json b/packages/mui-icons-material/package.json index b79d44fcab79aa..252fa287b05455 100644 --- a/packages/mui-icons-material/package.json +++ b/packages/mui-icons-material/package.json @@ -33,9 +33,9 @@ "build:lib:clean": "rimraf lib/ && pnpm build:lib", "build:legacy": "echo 'Skip legacy build'", "build:modern": "echo 'Skip modern build'", - "build:node": "node ../../scripts/build.mjs node --largeFiles --outDir lib", - "build:stable": "node ../../scripts/build.mjs stable --largeFiles --outDir lib", - "build:copy-files": "node ../../scripts/copyFiles.mjs --skipExportsField", + "build:node": "cross-env SKIP_CORE_EXPORTS_FORMAT=true node ../../scripts/build.mjs node --largeFiles --outDir lib", + "build:stable": "cross-env SKIP_CORE_EXPORTS_FORMAT=true node ../../scripts/build.mjs stable --largeFiles --outDir lib", + "build:copy-files": "cross-env SKIP_CORE_EXPORTS_FORMAT=true node ../../scripts/copyFiles.mjs", "build:typings": "node ./scripts/create-typings.mjs", "prebuild": "rimraf build", "release": "pnpm build && pnpm publish", diff --git a/packages/mui-material/package.json b/packages/mui-material/package.json index 29e2ce960aba0a..1445e8cfc691e6 100644 --- a/packages/mui-material/package.json +++ b/packages/mui-material/package.json @@ -32,7 +32,7 @@ "build:modern": "node ../../scripts/build.mjs modern", "build:node": "node ../../scripts/build.mjs node", "build:stable": "node ../../scripts/build.mjs stable", - "build:umd": "cross-env BABEL_ENV=rollup rollup -c scripts/rollup.config.mjs", + "build:umd": "cross-env BABEL_ENV=rollup SKIP_CORE_EXPORTS_FORMAT=true rollup -c scripts/rollup.config.mjs", "build:copy-files": "node ../../scripts/copyFiles.mjs", "build:types": "node ../../scripts/buildTypes.mjs", "prebuild": "rimraf build tsconfig.build.tsbuildinfo", diff --git a/scripts/build.mjs b/scripts/build.mjs index c238e2c47f86a0..702a3642dc88c9 100644 --- a/scripts/build.mjs +++ b/scripts/build.mjs @@ -31,7 +31,6 @@ async function run(argv) { NODE_ENV: 'production', BABEL_ENV: bundle, MUI_BUILD_VERBOSE: verbose, - MUI_ADD_IMPORT_EXTENSIONS: true, }; const babelConfigPath = path.resolve(getWorkspaceRoot(), 'babel.config.js'); const srcDir = path.resolve('./src'); @@ -70,8 +69,6 @@ async function run(argv) { }[bundle], ); - const outExtension = bundle === 'node' ? '.js' : '.mjs'; - const babelArgs = [ '--config-file', babelConfigPath, @@ -80,8 +77,6 @@ async function run(argv) { srcDir, '--out-dir', outDir, - '--out-file-extension', - outExtension, '--ignore', // Need to put these patterns in quotes otherwise they might be evaluated by the used terminal. `"${ignore.join('","')}"`, @@ -90,6 +85,11 @@ async function run(argv) { babelArgs.push('--compact false'); } + if (!process.env.SKIP_CORE_EXPORTS_FORMAT) { + const outExtension = bundle === 'node' ? '.js' : `.mjs`; + babelArgs.push('--out-file-extension', outExtension); + } + const command = ['pnpm babel', ...babelArgs].join(' '); if (verbose) { diff --git a/scripts/copyFiles.mjs b/scripts/copyFiles.mjs index 418840604e70be..dbe3e29a7ca49f 100644 --- a/scripts/copyFiles.mjs +++ b/scripts/copyFiles.mjs @@ -1,6 +1,5 @@ /* eslint-disable no-console */ import path from 'path'; -import yargs from 'yargs'; import { createModulePackages, createPackageFile, @@ -14,6 +13,7 @@ const buildPath = path.join(packagePath, './build'); const srcPath = path.join(packagePath, './src'); async function addLicense(packageData) { + const esmExtension = process.env.SKIP_CORE_EXPORTS_FORMAT ? 'js' : 'mjs'; const license = `/** * ${packageData.name} v${packageData.version} * @@ -24,9 +24,9 @@ async function addLicense(packageData) { `; await Promise.all( [ - './index.mjs', - './legacy/index.mjs', - './modern/index.mjs', + `./index.${esmExtension}`, + `./legacy/index.${esmExtension}`, + `./modern/index.${esmExtension}`, './node/index.js', './umd/material-ui.development.js', './umd/material-ui.production.min.js', @@ -44,14 +44,14 @@ async function addLicense(packageData) { ); } -async function run(argv) { - const { extraFiles, skipExportsField } = argv; +async function run() { + const extraFiles = process.argv.slice(2); try { // TypeScript await typescriptCopy({ from: srcPath, to: buildPath }); - const packageData = await createPackageFile(skipExportsField); + const packageData = await createPackageFile(); await Promise.all( ['./README.md', '../../CHANGELOG.md', '../../LICENSE', ...extraFiles].map(async (file) => { @@ -69,26 +69,4 @@ async function run(argv) { } } -yargs(process.argv.slice(2)) - .command({ - command: '$0 [extraFiles..]', - description: 'copy files', - builder: (command) => { - return command - .positional('extraFiles', { - type: 'array', - default: [], - }) - .option('skipExportsField', { - type: 'boolean', - default: false, - describe: - 'Set to `true` if you wish to skip adding the exports field. Adding the exports field is only supported for top level ESM packages.', - }); - }, - handler: run, - }) - .help() - .strict(true) - .version(false) - .parse(); +run(); diff --git a/scripts/copyFilesUtils.mjs b/scripts/copyFilesUtils.mjs index b6e5c5a3d6cb77..41636a97b33dbe 100644 --- a/scripts/copyFilesUtils.mjs +++ b/scripts/copyFilesUtils.mjs @@ -33,6 +33,7 @@ export async function includeFileInBuild(file, target = path.basename(file)) { * @param {string} param0.to */ export async function createModulePackages({ from, to }) { + const esmExtension = process.env.SKIP_CORE_EXPORTS_FORMAT ? 'js' : 'mjs'; const directoryPackages = glob.sync('*/index.{js,ts,tsx}', { cwd: from }).map(path.dirname); await Promise.all( @@ -45,8 +46,8 @@ export async function createModulePackages({ from, to }) { const packageJson = { sideEffects: false, module: topLevelPathImportsAreCommonJSModules - ? path.posix.join('../esm', directoryPackage, 'index.mjs') - : './index.mjs', + ? path.posix.join('../esm', directoryPackage, `index.${esmExtension}`) + : `./index.${esmExtension}`, main: topLevelPathImportsAreCommonJSModules ? './index.js' : path.posix.join('../node', directoryPackage, 'index.js'), @@ -91,12 +92,43 @@ export async function typescriptCopy({ from, to }) { return Promise.all(cmds); } +/** + * Returns the Core exports field. + * @returns {object} + */ +function getCoreExportsField() { + const coreExportsField = {}; + + const hasIndexMjs = fse.existsSync(path.resolve(buildPath, './index.mjs')); + if (hasIndexMjs) { + // Asumes the types file and node build are set up correctly + coreExportsField['.'] = { + types: './index.d.ts', + import: './index.mjs', + default: './node/index.js', + }; + } + + const hasNestedIndexFiles = glob.sync('*/index.mjs', { cwd: buildPath }).length > 0; + if (hasNestedIndexFiles) { + // Asumes the types files and node build are set up correctly + coreExportsField['./*'] = { + types: './*/index.d.ts', + import: './*/index.mjs', + default: './node/*/index.js', + }; + } + + return coreExportsField; +} + /** * Creates a package.json in the build directory. * @param {boolean} skipExportsField Whether to skip the exports field in the package.json. Only top level ESM packages are supported. * @returns {Promise} */ -export async function createPackageFile(skipExportsField = false) { +export async function createPackageFile() { + const esmExtension = process.env.SKIP_CORE_EXPORTS_FORMAT ? 'js' : 'mjs'; const packageData = await fse.readFile(path.resolve(packagePath, './package.json'), 'utf8'); const { nyc, scripts, devDependencies, workspaces, ...packageDataOther } = JSON.parse(packageData); @@ -109,9 +141,9 @@ export async function createPackageFile(skipExportsField = false) { main: fse.existsSync(path.resolve(buildPath, './node/index.js')) ? './node/index.js' : './index.js', - module: fse.existsSync(path.resolve(buildPath, './esm/index.mjs')) - ? './esm/index.mjs' - : './index.mjs', + module: fse.existsSync(path.resolve(buildPath, `./esm/index.${esmExtension}`)) + ? `./esm/index.${esmExtension}` + : `./index.${esmExtension}`, } : {}), }; @@ -121,32 +153,10 @@ export async function createPackageFile(skipExportsField = false) { newPackageData.types = './index.d.ts'; } - if (!skipExportsField) { - const addedExports = {}; - - const hasIndexMjs = fse.existsSync(path.resolve(buildPath, './index.mjs')); - if (hasIndexMjs) { - // Asumes the types file and node build are set up correctly - addedExports['.'] = { - types: './index.d.ts', - import: './index.mjs', - default: './node/index.js', - }; - } - - const hasNestedIndexFiles = glob.sync('*/index.mjs', { cwd: buildPath }).length > 0; - if (hasNestedIndexFiles) { - // Asumes the types files and node build are set up correctly - addedExports['./*'] = { - types: './*/index.d.ts', - import: './*/index.mjs', - default: './node/*/index.js', - }; - } - + if (!process.env.SKIP_CORE_EXPORTS_FORMAT) { newPackageData.exports = { ...packageDataOther.exports, - ...addedExports, + ...getCoreExportsField(), }; }