diff --git a/.circleci/config.yml b/.circleci/config.yml index bb3d6f3c3..cdf81b17b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -375,6 +375,19 @@ jobs: name: Run danger on PRs command: pnpm danger ci --fail-on-errors # TODO test bundle size https://github.com/mui/base-ui/issues/201 + test_package: + <<: *default-job + steps: + - checkout + - install_js: + react-version: << parameters.react-version >> + - run: + name: Build packages + command: pnpm release:build + - run: + name: Are the types wrong? + command: pnpm -r test:package-types + workflows: version: 2 pipeline: @@ -419,6 +432,10 @@ workflows: <<: *default-context requires: - checkout + - test_package: + <<: *default-context + requires: + - checkout profile: when: equal: [profile, << pipeline.parameters.workflow >>] diff --git a/babel.config.js b/babel.config.js index 600a3b4d3..03ec86281 100644 --- a/babel.config.js +++ b/babel.config.js @@ -8,12 +8,8 @@ function resolveAliasPath(relativeToBabelConf) { return `./${resolvedPath.replace('\\', '/')}`; } -const productionPlugins = [ - ['babel-plugin-react-remove-properties', { properties: ['data-mui-test'] }], -]; - module.exports = function getBabelConfig(api) { - const useESModules = api.env(['regressions', 'stable', 'rollup']); + const useESModules = !api.env(['node']); const defaultAlias = { '@base_ui/react': resolveAliasPath('./packages/mui-base/src'), @@ -70,9 +66,16 @@ module.exports = function getBabelConfig(api) { ], ]; - if (process.env.NODE_ENV === 'production') { - plugins.push(...productionPlugins); - } + const devPlugins = [ + [ + 'babel-plugin-module-resolver', + { + root: ['./'], + alias: defaultAlias, + }, + ], + 'babel-plugin-add-import-extension', + ]; return { assumptions: { @@ -98,39 +101,17 @@ module.exports = function getBabelConfig(api) { ], env: { coverage: { - plugins: [ - 'babel-plugin-istanbul', - [ - 'babel-plugin-module-resolver', - { - root: ['./'], - alias: defaultAlias, - }, - ], - ], + plugins: ['babel-plugin-istanbul', ...devPlugins], }, development: { - plugins: [ - [ - 'babel-plugin-module-resolver', - { - root: ['./'], - alias: defaultAlias, - }, - ], - ], + plugins: devPlugins, }, test: { sourceMaps: 'both', - plugins: [ - [ - 'babel-plugin-module-resolver', - { - root: ['./'], - alias: defaultAlias, - }, - ], - ], + plugins: devPlugins, + }, + production: { + plugins: ['babel-plugin-add-import-extension'], }, }, }; diff --git a/docs/vitest.config.ts b/docs/vitest.config.mts similarity index 85% rename from docs/vitest.config.ts rename to docs/vitest.config.mts index 272c2a82b..be2ef2a4b 100644 --- a/docs/vitest.config.ts +++ b/docs/vitest.config.mts @@ -1,5 +1,5 @@ import { mergeConfig, defineProject } from 'vitest/config'; -import sharedConfig from '../vitest.shared'; +import sharedConfig from '../vitest.shared.mts'; export default mergeConfig( sharedConfig, diff --git a/package.json b/package.json index 007d46508..da25cb0dc 100644 --- a/package.json +++ b/package.json @@ -102,6 +102,7 @@ "@vitest/coverage-v8": "^2.1.4", "@vitest/ui": "2.1.4", "babel-loader": "^9.2.1", + "babel-plugin-add-import-extension": "1.6.0", "babel-plugin-istanbul": "^6.1.1", "babel-plugin-macros": "^3.1.0", "babel-plugin-module-resolver": "^5.0.2", diff --git a/packages/mui-base/package.json b/packages/mui-base/package.json index 51fc377f9..4abcaf307 100644 --- a/packages/mui-base/package.json +++ b/packages/mui-base/package.json @@ -4,7 +4,6 @@ "private": false, "author": "MUI Team", "description": "Base UI is a library of headless ('unstyled') React components and low-level hooks. You gain complete control over your app's CSS and accessibility features.", - "main": "./src/index.ts", "keywords": [ "react", "react-component", @@ -26,15 +25,25 @@ "type": "opencollective", "url": "https://opencollective.com/mui-org" }, + "exports": { + ".": { + "import": "./src/index.ts" + }, + "./*": { + "import": "./src/*/index.ts" + } + }, "imports": { "#test-utils": "./test/index.ts" }, + "type": "commonjs", "scripts": { "build": "pnpm build:node && pnpm build:stable && pnpm build:types && pnpm build:copy-files", "build:node": "node ../../scripts/build.mjs node", "build:stable": "node ../../scripts/build.mjs stable", "build:copy-files": "node ../../scripts/copyFiles.mjs", - "build:types": "tsc -b tsconfig.build.json", + "build:types": "tsc -b tsconfig.build.json && tsc -b tsconfig.build.cjs.json && tsc-alias -p tsconfig.build.json", + "test:package-types": "attw --pack ./build --include-entrypoints ./Accordion ./Menu ./Tooltip", "prebuild": "rimraf --glob build build-tests \"*.tsbuildinfo\"", "release": "pnpm build && pnpm publish", "test": "cd ../../ && cross-env NODE_ENV=test mocha 'packages/mui-base/**/*.test.{js,ts,tsx}'", @@ -52,6 +61,7 @@ "use-sync-external-store": "^1.2.2" }, "devDependencies": { + "@arethetypeswrong/cli": "^0.16.4", "@mui/internal-test-utils": "https://pkg.csb.dev/mui/material-ui/commit/92c23999/@mui/internal-test-utils", "@testing-library/react": "^16.0.1", "@testing-library/user-event": "^14.5.2", @@ -68,6 +78,7 @@ "react": "19.0.0-rc-fb9a90fa48-20240614", "react-dom": "19.0.0-rc-fb9a90fa48-20240614", "sinon": "^19.0.2", + "tsc-alias": "^1.8.10", "typescript": "^5.6.3" }, "peerDependencies": { diff --git a/packages/mui-base/tsconfig.build.cjs.json b/packages/mui-base/tsconfig.build.cjs.json new file mode 100644 index 000000000..4b385e642 --- /dev/null +++ b/packages/mui-base/tsconfig.build.cjs.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.build.json", + "compilerOptions": { + "module": "node16", + "moduleResolution": "node16", + "outDir": "build/cjs" + } +} diff --git a/packages/mui-base/tsconfig.build.json b/packages/mui-base/tsconfig.build.json index 0ea89a8bd..75ef03aad 100644 --- a/packages/mui-base/tsconfig.build.json +++ b/packages/mui-base/tsconfig.build.json @@ -10,8 +10,11 @@ "moduleResolution": "bundler", "noEmit": false, "rootDir": "./src", - "outDir": "build" + "outDir": "build/esm" }, "include": ["src/**/*.ts*"], - "exclude": ["src/**/*.spec.ts*", "src/**/*.test.ts*"] + "exclude": ["src/**/*.spec.ts*", "src/**/*.test.ts*"], + "tsc-alias": { + "resolveFullPaths": true + } } diff --git a/packages/mui-base/vitest.config.ts b/packages/mui-base/vitest.config.mts similarity index 79% rename from packages/mui-base/vitest.config.ts rename to packages/mui-base/vitest.config.mts index b14b2143d..c38f436f8 100644 --- a/packages/mui-base/vitest.config.ts +++ b/packages/mui-base/vitest.config.mts @@ -1,5 +1,5 @@ import { mergeConfig, defineProject } from 'vitest/config'; -import sharedConfig from '../../vitest.shared'; +import sharedConfig from '../../vitest.shared.mts'; export default mergeConfig( sharedConfig, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9d94dd976..99d05b482 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -124,6 +124,9 @@ importers: babel-loader: specifier: ^9.2.1 version: 9.2.1(@babel/core@7.26.0)(webpack@5.94.0(webpack-cli@5.1.4(webpack-bundle-analyzer@4.10.2)(webpack@5.94.0))) + babel-plugin-add-import-extension: + specifier: 1.6.0 + version: 1.6.0(@babel/core@7.26.0) babel-plugin-istanbul: specifier: ^6.1.1 version: 6.1.1 @@ -642,6 +645,9 @@ importers: specifier: ^1.2.2 version: 1.2.2(react@19.0.0-rc-fb9a90fa48-20240614) devDependencies: + '@arethetypeswrong/cli': + specifier: ^0.16.4 + version: 0.16.4 '@mui/internal-test-utils': specifier: https://pkg.csb.dev/mui/material-ui/commit/92c23999/@mui/internal-test-utils version: https://pkg.csb.dev/mui/material-ui/commit/92c23999/@mui/internal-test-utils(@babel/core@7.26.0)(react-dom@19.0.0-rc-fb9a90fa48-20240614(react@19.0.0-rc-fb9a90fa48-20240614))(react@19.0.0-rc-fb9a90fa48-20240614)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) @@ -690,6 +696,9 @@ importers: sinon: specifier: ^19.0.2 version: 19.0.2 + tsc-alias: + specifier: ^1.8.10 + version: 1.8.10 typescript: specifier: ^5.6.3 version: 5.6.3 @@ -807,6 +816,18 @@ packages: resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} + '@andrewbranch/untar.js@1.0.3': + resolution: {integrity: sha512-Jh15/qVmrLGhkKJBdXlK1+9tY4lZruYjsgkDFj08ZmDiWVBLJcqkok7Z0/R0In+i1rScBpJlSvrTS2Lm41Pbnw==} + + '@arethetypeswrong/cli@0.16.4': + resolution: {integrity: sha512-qMmdVlJon5FtA+ahn0c1oAVNxiq4xW5lqFiTZ21XHIeVwAVIQ+uRz4UEivqRMsjVV1grzRgJSKqaOrq1MvlVyQ==} + engines: {node: '>=18'} + hasBin: true + + '@arethetypeswrong/core@0.16.4': + resolution: {integrity: sha512-RI3HXgSuKTfcBf1hSEg1P9/cOvmI0flsMm6/QL3L3wju4AlHDqd55JFPfXs4pzgEAgy5L9pul4/HPPz99x2GvA==} + engines: {node: '>=18'} + '@argos-ci/api-client@0.7.0': resolution: {integrity: sha512-oRCaqA4DZn+yxD78/dqPTcz7dJd5SIU+GwnlvqorGLw6bktQ3TMPmKND/jb/GOf8tUpOs9FrSrwxVwFjYfiVeg==} engines: {node: '>=18.0.0'} @@ -2849,6 +2870,10 @@ packages: '@sinclair/typebox@0.27.8': resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + '@sindresorhus/is@4.6.0': + resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} + engines: {node: '>=10'} + '@sindresorhus/merge-streams@2.3.0': resolution: {integrity: sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==} engines: {node: '>=18'} @@ -3565,12 +3590,16 @@ packages: resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} engines: {node: '>=8'} + ansi-escapes@7.0.0: + resolution: {integrity: sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==} + engines: {node: '>=18'} + ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - ansi-regex@6.0.1: - resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + ansi-regex@6.1.0: + resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} engines: {node: '>=12'} ansi-styles@3.2.1: @@ -3744,6 +3773,11 @@ packages: '@babel/core': ^7.26.0 webpack: '>=5' + babel-plugin-add-import-extension@1.6.0: + resolution: {integrity: sha512-JVSQPMzNzN/S4wPRoKQ7+u8PlkV//BPUMnfWVbr63zcE+6yHdU2Mblz10Vf7qe+6Rmu4svF5jG7JxdcPi9VvKg==} + peerDependencies: + '@babel/core': ^7.26.0 + babel-plugin-istanbul@6.1.1: resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} engines: {node: '>=8'} @@ -3970,6 +4004,10 @@ packages: resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + char-regex@1.0.2: + resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} + engines: {node: '>=10'} + character-entities-html4@2.1.0: resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} @@ -4012,6 +4050,9 @@ packages: resolution: {integrity: sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==} engines: {node: '>=8'} + cjs-module-lexer@1.4.1: + resolution: {integrity: sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA==} + clean-css@5.3.3: resolution: {integrity: sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==} engines: {node: '>= 10.0'} @@ -4032,6 +4073,11 @@ packages: resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} engines: {node: '>=8'} + cli-highlight@2.1.11: + resolution: {integrity: sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==} + engines: {node: '>=8.0.0', npm: '>=5.0.0'} + hasBin: true + cli-spinners@2.6.1: resolution: {integrity: sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==} engines: {node: '>=6'} @@ -4040,6 +4086,10 @@ packages: resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} engines: {node: '>=6'} + cli-table3@0.6.5: + resolution: {integrity: sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==} + engines: {node: 10.* || >= 12.*} + cli-width@3.0.0: resolution: {integrity: sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==} engines: {node: '>= 10'} @@ -4155,6 +4205,10 @@ packages: resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} engines: {node: '>= 12'} + commander@9.5.0: + resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} + engines: {node: ^12.20.0 || >=14} + common-ancestor-path@1.0.1: resolution: {integrity: sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==} @@ -4651,6 +4705,9 @@ packages: emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + emojilib@2.4.0: + resolution: {integrity: sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==} + encodeurl@1.0.2: resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} engines: {node: '>= 0.8'} @@ -4704,6 +4761,10 @@ packages: engines: {node: '>=4'} hasBin: true + environment@1.1.0: + resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} + engines: {node: '>=18'} + err-code@2.0.3: resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==} @@ -5601,6 +5662,9 @@ packages: headers-polyfill@4.0.3: resolution: {integrity: sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==} + highlight.js@10.7.3: + resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==} + hoist-non-react-statics@3.3.2: resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} @@ -6628,11 +6692,22 @@ packages: resolution: {integrity: sha512-wgp8yesWjFBL7bycA3hxwHRdsZGJhjhyP1dSxKVKrza0EPFYtn+mHtkVy6dvP1kGSjovyG5B8yNP6Frj0UFUJg==} engines: {node: '>=18'} + marked-terminal@7.2.1: + resolution: {integrity: sha512-rQ1MoMFXZICWNsKMiiHwP/Z+92PLKskTPXj+e7uwXmuMPkNn7iTqC+IvDekVm1MPeC9wYQeLxeFaOvudRR/XbQ==} + engines: {node: '>=16.0.0'} + peerDependencies: + marked: '>=1 <15' + marked@14.1.3: resolution: {integrity: sha512-ZibJqTULGlt9g5k4VMARAktMAjXoVnnr+Y3aCqW1oDftcV4BA3UmrBifzXoZyenHRk75csiPu9iwsTj4VNBT0g==} engines: {node: '>= 18'} hasBin: true + marked@9.1.6: + resolution: {integrity: sha512-jcByLnIFkd5gSXZmjNvS1TlmRhCXZjIzHYlaGkPlLIekG55JDR2Z4va9tZwCiP+/RDERiNhMOFu01xd6O5ct1Q==} + engines: {node: '>= 16'} + hasBin: true + mathml-tag-names@2.1.3: resolution: {integrity: sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==} @@ -7023,6 +7098,10 @@ packages: resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==} engines: {node: ^18.17.0 || >=20.5.0} + mylas@2.1.13: + resolution: {integrity: sha512-+MrqnJRtxdF+xngFfUUkIMQrUUL0KsxbADUkn23Z/4ibGg192Q+z+CQyiYwvWTsYjJygmMR8+w3ZDa98Zh6ESg==} + engines: {node: '>=12.0.0'} + mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} @@ -7085,6 +7164,10 @@ packages: resolution: {integrity: sha512-tmPX422rYgofd4epzrNoOXiE8XFZYOcCq1vD7MAXCDO+O+zndlA2ztdKKMa+EeuBG5tHETpr4ml4RGgpqDCCAg==} engines: {node: '>= 0.10.5'} + node-emoji@2.1.3: + resolution: {integrity: sha512-E2WEOVsgs7O16zsURJ/eH8BqhF029wGpEOnv7Urwdo2wmQanOACwJQh0devF9D9RhoZru0+9JXIS0dBXIAz+lA==} + engines: {node: '>=18'} + node-environment-flags@1.0.6: resolution: {integrity: sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==} @@ -7478,6 +7561,15 @@ packages: parse-url@8.1.0: resolution: {integrity: sha512-xDvOoLU5XRrcOZvnI6b8zA6n9O9ejNk/GExuz1yBuWUGn9KA97GI6HTs6u02wKara1CeVmZhH+0TZFdWScR89w==} + parse5-htmlparser2-tree-adapter@6.0.1: + resolution: {integrity: sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==} + + parse5@5.1.1: + resolution: {integrity: sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==} + + parse5@6.0.1: + resolution: {integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==} + parse5@7.1.2: resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==} @@ -7628,6 +7720,10 @@ packages: engines: {node: '>=18'} hasBin: true + plimit-lit@1.6.1: + resolution: {integrity: sha512-B7+VDyb8Tl6oMJT9oSO2CW8XC/T4UcJGrwOVoNGwOQsQYhlpfajmrMj5xeejqaASq3V/EqThyOeATEOMuSEXiA==} + engines: {node: '>=12'} + possible-typed-array-names@1.0.0: resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} engines: {node: '>= 0.4'} @@ -7899,6 +7995,10 @@ packages: querystringify@2.2.0: resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} + queue-lit@1.5.2: + resolution: {integrity: sha512-tLc36IOPeMAubu8BkW8YDBV+WyIgKlYU7zUNs0J5Vk9skSZ4JfGlPOqplP0aHdfv7HL0B2Pg6nwiq60Qc6M2Hw==} + engines: {node: '>=12'} + queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} @@ -8408,6 +8508,10 @@ packages: resolution: {integrity: sha512-BPwJGUeDaDCHihkORDchNyyTvWFhcusy1XMmhEVTQTwGeybFbp8YEmB+njbPnth1FibULBSBVwCQni25XlCUDg==} engines: {node: '>=18'} + skin-tone@2.0.0: + resolution: {integrity: sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==} + engines: {node: '>=8'} + slash@2.0.0: resolution: {integrity: sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==} engines: {node: '>=6'} @@ -8714,8 +8818,8 @@ packages: resolution: {integrity: sha512-HHi5kVSefKaJkGYXbDuKbUGRVxqnWGn3J2e39CYcNJEfWciGq2zYtOhXLTlvrOZW1QU7VX67w7fMmWafHX9Pfw==} engines: {node: '>=4'} - supports-hyperlinks@3.0.0: - resolution: {integrity: sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==} + supports-hyperlinks@3.1.0: + resolution: {integrity: sha512-2rn0BZ+/f7puLOHZm1HOJfwBggfaHXUpPUSSG/SWM4TWp5KCfmNYwnC3hruy2rZlMnmWZ+QAGpZfchu3f3695A==} engines: {node: '>=14.18'} supports-preserve-symlinks-flag@1.0.0: @@ -8903,6 +9007,10 @@ packages: ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + tsc-alias@1.8.10: + resolution: {integrity: sha512-Ibv4KAWfFkFdKJxnWfVtdOmB0Zi1RJVxcbPGiCDsFpCQSsmpWyuzHG3rQyI5YkobWwxFPEyQfu1hdo4qLG2zPw==} + hasBin: true + tsconfig-paths@3.15.0: resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} @@ -9015,6 +9123,11 @@ packages: types-react@19.0.0-rc.1: resolution: {integrity: sha512-RshndUfqTW6K3STLPis8BtAYCGOkMbtvYsi90gmVNDZBXUyUc5juf2PE9LfS/JmOlUIRO8cWTS/1MTnmhjDqyQ==} + typescript@5.6.1-rc: + resolution: {integrity: sha512-E3b2+1zEFu84jB0YQi9BORDjz9+jGbwwy1Zi3G0LUNw7a7cePUrHMRNy8aPh53nXpkFGVHSxIZo5vKTfYaFiBQ==} + engines: {node: '>=14.17'} + hasBin: true + typescript@5.6.3: resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==} engines: {node: '>=14.17'} @@ -9041,6 +9154,10 @@ packages: resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==} engines: {node: '>=4'} + unicode-emoji-modifier-base@1.0.0: + resolution: {integrity: sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==} + engines: {node: '>=4'} + unicode-match-property-ecmascript@2.0.0: resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==} engines: {node: '>=4'} @@ -9581,6 +9698,28 @@ snapshots: '@jridgewell/gen-mapping': 0.3.5 '@jridgewell/trace-mapping': 0.3.25 + '@andrewbranch/untar.js@1.0.3': {} + + '@arethetypeswrong/cli@0.16.4': + dependencies: + '@arethetypeswrong/core': 0.16.4 + chalk: 4.1.2 + cli-table3: 0.6.5 + commander: 10.0.1 + marked: 9.1.6 + marked-terminal: 7.2.1(marked@9.1.6) + semver: 7.6.3 + + '@arethetypeswrong/core@0.16.4': + dependencies: + '@andrewbranch/untar.js': 1.0.3 + cjs-module-lexer: 1.4.1 + fflate: 0.8.2 + lru-cache: 10.4.3 + semver: 7.6.3 + typescript: 5.6.1-rc + validate-npm-package-name: 5.0.1 + '@argos-ci/api-client@0.7.0': dependencies: debug: 4.3.7(supports-color@8.1.1) @@ -11936,6 +12075,8 @@ snapshots: '@sinclair/typebox@0.27.8': {} + '@sindresorhus/is@4.6.0': {} + '@sindresorhus/merge-streams@2.3.0': {} '@sindresorhus/merge-streams@4.0.0': {} @@ -12813,9 +12954,13 @@ snapshots: dependencies: type-fest: 0.21.3 + ansi-escapes@7.0.0: + dependencies: + environment: 1.1.0 + ansi-regex@5.0.1: {} - ansi-regex@6.0.1: {} + ansi-regex@6.1.0: {} ansi-styles@3.2.1: dependencies: @@ -12998,6 +13143,11 @@ snapshots: schema-utils: 4.2.0 webpack: 5.94.0(webpack-cli@5.1.4(webpack-bundle-analyzer@4.10.2)(webpack@5.94.0)) + babel-plugin-add-import-extension@1.6.0(@babel/core@7.26.0): + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 + babel-plugin-istanbul@6.1.1: dependencies: '@babel/helper-plugin-utils': 7.25.9 @@ -13314,6 +13464,8 @@ snapshots: chalk@5.3.0: {} + char-regex@1.0.2: {} + character-entities-html4@2.1.0: {} character-entities-legacy@3.0.0: {} @@ -13350,6 +13502,8 @@ snapshots: ci-info@4.0.0: {} + cjs-module-lexer@1.4.1: {} + clean-css@5.3.3: dependencies: source-map: 0.6.1 @@ -13366,10 +13520,25 @@ snapshots: dependencies: restore-cursor: 3.1.0 + cli-highlight@2.1.11: + dependencies: + chalk: 4.1.2 + highlight.js: 10.7.3 + mz: 2.7.0 + parse5: 5.1.1 + parse5-htmlparser2-tree-adapter: 6.0.1 + yargs: 16.2.0 + cli-spinners@2.6.1: {} cli-spinners@2.9.2: {} + cli-table3@0.6.5: + dependencies: + string-width: 4.2.3 + optionalDependencies: + '@colors/colors': 1.5.0 + cli-width@3.0.0: {} cli-width@4.1.0: {} @@ -13469,6 +13638,8 @@ snapshots: commander@8.3.0: {} + commander@9.5.0: {} + common-ancestor-path@1.0.1: {} common-path-prefix@3.0.0: {} @@ -13990,6 +14161,8 @@ snapshots: emoji-regex@9.2.2: {} + emojilib@2.4.0: {} + encodeurl@1.0.2: {} encodeurl@2.0.0: {} @@ -14047,6 +14220,8 @@ snapshots: envinfo@7.13.0: {} + environment@1.1.0: {} + err-code@2.0.3: {} error-ex@1.3.2: @@ -15367,6 +15542,8 @@ snapshots: headers-polyfill@4.0.3: {} + highlight.js@10.7.3: {} + hoist-non-react-statics@3.3.2: dependencies: react-is: 16.13.1 @@ -16532,8 +16709,21 @@ snapshots: markdown-it: 14.1.0 markdownlint-micromark: 0.1.10 + marked-terminal@7.2.1(marked@9.1.6): + dependencies: + ansi-escapes: 7.0.0 + ansi-regex: 6.1.0 + chalk: 5.3.0 + cli-highlight: 2.1.11 + cli-table3: 0.6.5 + marked: 9.1.6 + node-emoji: 2.1.3 + supports-hyperlinks: 3.1.0 + marked@14.1.3: {} + marked@9.1.6: {} + mathml-tag-names@2.1.3: {} mdast-util-find-and-replace@3.0.1: @@ -17212,6 +17402,8 @@ snapshots: mute-stream@2.0.0: {} + mylas@2.1.13: {} + mz@2.7.0: dependencies: any-promise: 1.3.0 @@ -17284,6 +17476,13 @@ snapshots: dependencies: minimatch: 3.1.2 + node-emoji@2.1.3: + dependencies: + '@sindresorhus/is': 4.6.0 + char-regex: 1.0.2 + emojilib: 2.4.0 + skin-tone: 2.0.0 + node-environment-flags@1.0.6: dependencies: object.getownpropertydescriptors: 2.1.8 @@ -17810,6 +18009,14 @@ snapshots: dependencies: parse-path: 7.0.0 + parse5-htmlparser2-tree-adapter@6.0.1: + dependencies: + parse5: 6.0.1 + + parse5@5.1.1: {} + + parse5@6.0.1: {} + parse5@7.1.2: dependencies: entities: 4.5.0 @@ -17919,6 +18126,10 @@ snapshots: optionalDependencies: fsevents: 2.3.2 + plimit-lit@1.6.1: + dependencies: + queue-lit: 1.5.2 + possible-typed-array-names@1.0.0: {} postcss-import@16.1.0(postcss@8.4.47): @@ -18109,6 +18320,8 @@ snapshots: querystringify@2.2.0: {} + queue-lit@1.5.2: {} + queue-microtask@1.2.3: {} quick-lru@4.0.1: {} @@ -18834,6 +19047,10 @@ snapshots: mrmime: 2.0.0 totalist: 3.0.1 + skin-tone@2.0.0: + dependencies: + unicode-emoji-modifier-base: 1.0.0 + slash@2.0.0: {} slash@3.0.0: {} @@ -19059,7 +19276,7 @@ snapshots: strip-ansi@7.1.0: dependencies: - ansi-regex: 6.0.1 + ansi-regex: 6.1.0 strip-bom@3.0.0: {} @@ -19165,7 +19382,7 @@ snapshots: resolve-from: 5.0.0 string-width: 4.2.3 strip-ansi: 7.1.0 - supports-hyperlinks: 3.0.0 + supports-hyperlinks: 3.1.0 svg-tags: 1.0.0 table: 6.8.2 write-file-atomic: 5.0.1 @@ -19211,7 +19428,7 @@ snapshots: has-flag: 2.0.0 supports-color: 5.5.0 - supports-hyperlinks@3.0.0: + supports-hyperlinks@3.1.0: dependencies: has-flag: 4.0.0 supports-color: 7.2.0 @@ -19379,6 +19596,15 @@ snapshots: ts-interface-checker@0.1.13: {} + tsc-alias@1.8.10: + dependencies: + chokidar: 3.6.0 + commander: 9.5.0 + globby: 11.1.0 + mylas: 2.1.13 + normalize-path: 3.0.0 + plimit-lit: 1.6.1 + tsconfig-paths@3.15.0: dependencies: '@types/json5': 0.0.29 @@ -19499,6 +19725,8 @@ snapshots: dependencies: csstype: 3.1.3 + typescript@5.6.1-rc: {} + typescript@5.6.3: {} ua-parser-js@0.7.37: {} @@ -19519,6 +19747,8 @@ snapshots: unicode-canonical-property-names-ecmascript@2.0.0: {} + unicode-emoji-modifier-base@1.0.0: {} + unicode-match-property-ecmascript@2.0.0: dependencies: unicode-canonical-property-names-ecmascript: 2.0.0 diff --git a/scripts/build.mjs b/scripts/build.mjs index 4310c1638..a3008d8b1 100644 --- a/scripts/build.mjs +++ b/scripts/build.mjs @@ -1,18 +1,24 @@ import childProcess from 'child_process'; -import glob from 'fast-glob'; import path from 'path'; +import { writeFile } from 'fs/promises'; import { promisify } from 'util'; import yargs from 'yargs'; import { getWorkspaceRoot } from './utils.mjs'; const exec = promisify(childProcess.exec); -const validBundles = [ - // build for node using commonJS modules - 'node', - // build with a hardcoded target using ES6 modules - 'stable', -]; +const bundleConfig = { + node: { + moduleType: 'commonjs', + outDirectory: './cjs', + }, + stable: { + moduleType: 'module', + outDirectory: './esm', + }, +}; + +const validBundles = Object.keys(bundleConfig); async function run(argv) { const { bundle, largeFiles, outDir: relativeOutDir, verbose } = argv; @@ -40,28 +46,7 @@ async function run(argv) { '**/*.d.ts', ]; - const topLevelNonIndexFiles = glob - .sync(`*{${extensions.join(',')}}`, { cwd: srcDir, ignore }) - .filter((file) => { - return path.basename(file, path.extname(file)) !== 'index'; - }); - const topLevelPathImportsCanBePackages = topLevelNonIndexFiles.length === 0; - - const outDir = path.resolve( - relativeOutDir, - // We generally support top level path imports e.g. - // 1. `import ArrowDownIcon from '@mui/icons-material/ArrowDown'`. - // 2. `import Typography from '@mui/material/Typography'`. - // The first case resolves to a file while the second case resolves to a package first i.e. a package.json - // This means that only in the second case the bundler can decide whether it uses ES modules or CommonJS modules. - // Different extensions are not viable yet since they require additional bundler config for users and additional transpilation steps in our repo. - // - // TODO v6: Switch to `exports` field. - { - node: topLevelPathImportsCanBePackages ? './node' : './', - stable: topLevelPathImportsCanBePackages ? './' : './esm', - }[bundle], - ); + const outDir = path.resolve(relativeOutDir, bundleConfig[bundle].outDirectory); const babelArgs = [ '--config-file', @@ -91,6 +76,9 @@ async function run(argv) { throw new Error(`'${command}' failed with \n${stderr}`); } + const rootBundlePackageJson = path.join(outDir, 'package.json'); + await writeFile(rootBundlePackageJson, JSON.stringify({ type: bundleConfig[bundle].moduleType })); + if (verbose) { // eslint-disable-next-line no-console console.log(stdout); diff --git a/scripts/copyFiles.mjs b/scripts/copyFiles.mjs index 20bd9d2dd..a59613526 100644 --- a/scripts/copyFiles.mjs +++ b/scripts/copyFiles.mjs @@ -1,7 +1,6 @@ /* eslint-disable no-console */ import path from 'path'; import { - createModulePackages, createPackageFile, includeFileInBuild, prepend, @@ -52,8 +51,6 @@ async function run() { ); await addLicense(packageData); - - await createModulePackages({ from: srcPath, to: buildPath }); } catch (err) { console.error(err); process.exit(1); diff --git a/scripts/copyFilesUtils.mjs b/scripts/copyFilesUtils.mjs index 40b055426..6c4572f21 100644 --- a/scripts/copyFilesUtils.mjs +++ b/scripts/copyFilesUtils.mjs @@ -93,22 +93,43 @@ export async function typescriptCopy({ from, to }) { export async function createPackageFile() { const packageData = await fse.readFile(path.resolve(packagePath, './package.json'), 'utf8'); - const { nyc, scripts, devDependencies, workspaces, ...packageDataOther } = + const { imports, exports, nyc, scripts, devDependencies, workspaces, ...packageDataOther } = JSON.parse(packageData); const newPackageData = { ...packageDataOther, private: false, - ...(packageDataOther.main - ? { - main: fse.existsSync(path.resolve(buildPath, './node/index.js')) - ? './node/index.js' - : './index.js', - module: fse.existsSync(path.resolve(buildPath, './esm/index.js')) - ? './esm/index.js' - : './index.js', - } - : {}), + main: './cjs/index.js', + module: './esm/index.js', + types: 'index', + typesVersions: { + '*': { + index: ['./cjs/index.d.ts'], + '*': ['./cjs/*/index.d.ts'], + }, + }, + exports: { + '.': { + require: { + types: './cjs/index.d.ts', + default: './cjs/index.js', + }, + import: { + types: './esm/index.d.js', + default: './esm/index.js', + }, + }, + './*': { + require: { + types: './cjs/*/index.d.ts', + default: './cjs/*/index.js', + }, + import: { + types: './esm/*/index.d.js', + default: './esm/*/index.js', + }, + }, + }, }; const typeDefinitionsFilePath = path.resolve(buildPath, './index.d.ts'); diff --git a/tsconfig.base.json b/tsconfig.base.json index e5a9ccaee..7cd1b17a6 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -1,10 +1,9 @@ { "compilerOptions": { - "module": "esnext", + "module": "nodenext", "target": "es2020", "lib": ["es2020", "dom"], "jsx": "preserve", - "moduleResolution": "node", "forceConsistentCasingInFileNames": true, "strict": true, "noEmit": true, @@ -14,6 +13,7 @@ "noErrorTruncation": false, "allowJs": true, "skipLibCheck": true, + "allowImportingTsExtensions": true, "paths": { "@base_ui/react": ["./packages/mui-base/src"], "@base_ui/react/*": ["./packages/mui-base/src/*"], diff --git a/vitest.shared.ts b/vitest.shared.mts similarity index 100% rename from vitest.shared.ts rename to vitest.shared.mts diff --git a/vitest.workspace.mts b/vitest.workspace.mts new file mode 100644 index 000000000..305edfd78 --- /dev/null +++ b/vitest.workspace.mts @@ -0,0 +1,3 @@ +import { defineWorkspace } from 'vitest/config'; + +export default defineWorkspace(['packages/*/vitest.config.mts', 'docs/vitest.config.mts']); diff --git a/vitest.workspace.ts b/vitest.workspace.ts deleted file mode 100644 index 5e21bfbb2..000000000 --- a/vitest.workspace.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { defineWorkspace } from 'vitest/config'; - -export default defineWorkspace(['packages/*/vitest.config.ts', 'docs/vitest.config.ts']);