diff --git a/.circleci/config.yml b/.circleci/config.yml index 8064ee15db1cea..5eda3afeb7a589 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -60,13 +60,12 @@ default-context: &default-context # key: v1-repo-{{ .Branch }}-{{ .Revision }} commands: - install_js: + setup_corepack: parameters: browsers: type: boolean default: false description: 'Set to true if you intend to any browser (for example with playwright).' - steps: - when: condition: << parameters.browsers >> @@ -89,6 +88,17 @@ commands: node --version pnpm --version + install_js: + parameters: + browsers: + type: boolean + default: false + description: 'Set to true if you intend to any browser (for example with playwright).' + + steps: + - setup_corepack: + browsers: << parameters.browsers >> + - run: name: Resolve React version command: | @@ -472,192 +482,174 @@ jobs: - run: name: Build packages for fixtures command: pnpm lerna run --scope "@mui/*" build + - run: + name: Pack packages + command: pnpm release:pack - persist_to_workspace: - root: packages + root: packed paths: - - '*/build' + - '*' - test_bundling_node-esm: + test_bundling_node_cjs: <<: *default-job - working_directory: /tmp/material-ui/test/bundling/fixtures/node-esm/ + working_directory: /tmp/material-ui/test/bundling/fixtures/node-cjs/ steps: - checkout: path: /tmp/material-ui - attach_workspace: - at: /tmp/material-ui/packages + at: /tmp/material-ui/packed + - setup_corepack - run: - name: Prepare fixture - command: | - node ../../scripts/createFixture node-esm + name: Install dependencies + command: pnpm install --ignore-workspace + - run: + name: Test fixture + command: pnpm start + test_bundling_node_esm: + <<: *default-job + working_directory: /tmp/material-ui/test/bundling/fixtures/node-esm/ + steps: + - checkout: + path: /tmp/material-ui + - attach_workspace: + at: /tmp/material-ui/packed + - setup_corepack - run: name: Install dependencies - command: | - pnpm - node ../../scripts/useBuildFromSource.js . + command: pnpm install --ignore-workspace - run: name: Test fixture - command: | - # TODO: Known failure - set +e - pnpm start - exit 0 - test_bundling_next-webpack4: + # TODO: Known failure + command: pnpm start + test_bundling_next_webpack4: <<: *default-job - working_directory: /tmp/material-ui/test/bundling/fixtures/next-webpack4/ docker: - image: mcr.microsoft.com/playwright:v1.47.2-focal + working_directory: /tmp/material-ui/test/bundling/fixtures/next-webpack4/ steps: - checkout: path: /tmp/material-ui - attach_workspace: - at: /tmp/material-ui/packages - - run: - name: Prepare fixture - command: | - node ../../scripts/createFixture next-webpack4 + at: /tmp/material-ui/packed + - setup_corepack: + browsers: true - run: name: Install dependencies - command: | - pnpm - node ../../scripts/useBuildFromSource.js . + command: pnpm install --ignore-workspace - run: name: Test fixture command: pnpm start - test_bundling_next-webpack5: + test_bundling_next_webpack5: <<: *default-job - working_directory: /tmp/material-ui/test/bundling/fixtures/next-webpack5/ docker: - image: mcr.microsoft.com/playwright:v1.47.2-focal + working_directory: /tmp/material-ui/test/bundling/fixtures/next-webpack5/ steps: - checkout: path: /tmp/material-ui - attach_workspace: - at: /tmp/material-ui/packages - - run: - name: Prepare fixture - command: | - node ../../scripts/createFixture next-webpack5 + at: /tmp/material-ui/packed + - setup_corepack: + browsers: true - run: name: Install dependencies - command: | - pnpm - node ../../scripts/useBuildFromSource.js . + command: pnpm install --ignore-workspace - run: name: Test fixture command: pnpm start - test_bundling_create-react-app: + test_bundling_create_react_app: <<: *default-job - working_directory: /tmp/material-ui/test/bundling/fixtures/create-react-app/ docker: - image: mcr.microsoft.com/playwright:v1.47.2-focal + working_directory: /tmp/material-ui/test/bundling/fixtures/create-react-app/ steps: - checkout: path: /tmp/material-ui - attach_workspace: - at: /tmp/material-ui/packages - - run: - name: Prepare fixture - command: | - node ../../scripts/createFixture create-react-app + at: /tmp/material-ui/packed + - setup_corepack: + browsers: true - run: name: Install dependencies - command: | - pnpm - node ../../scripts/useBuildFromSource.js . + command: pnpm install --ignore-workspace - run: name: Test fixture command: pnpm start test_bundling_snowpack: <<: *default-job - working_directory: /tmp/material-ui/test/bundling/fixtures/snowpack/ docker: - image: mcr.microsoft.com/playwright:v1.47.2-focal + working_directory: /tmp/material-ui/test/bundling/fixtures/snowpack/ steps: - checkout: path: /tmp/material-ui - attach_workspace: - at: /tmp/material-ui/packages - - run: - name: Prepare fixture - command: | - node ../../scripts/createFixture snowpack + at: /tmp/material-ui/packed + - setup_corepack: + browsers: true - run: name: Install dependencies - command: | - pnpm - node ../../scripts/useBuildFromSource.js . + command: pnpm install --ignore-workspace - run: name: Test fixture command: pnpm start test_bundling_vite: <<: *default-job - working_directory: /tmp/material-ui/test/bundling/fixtures/vite/ docker: - image: mcr.microsoft.com/playwright:v1.47.2-focal + working_directory: /tmp/material-ui/test/bundling/fixtures/vite/ steps: - checkout: path: /tmp/material-ui - attach_workspace: - at: /tmp/material-ui/packages - - run: - name: Prepare fixture - command: | - node ../../scripts/createFixture vite + at: /tmp/material-ui/packed + - setup_corepack: + browsers: true - run: name: Install dependencies - command: | - pnpm - node ../../scripts/useBuildFromSource.js . + command: pnpm install --ignore-workspace - run: name: Test fixture command: pnpm start test_bundling_esbuild: <<: *default-job - working_directory: /tmp/material-ui/test/bundling/fixtures/esbuild/ docker: - image: mcr.microsoft.com/playwright:v1.47.2-focal + working_directory: /tmp/material-ui/test/bundling/fixtures/esbuild/ steps: - checkout: path: /tmp/material-ui - attach_workspace: - at: /tmp/material-ui/packages - - run: - name: Prepare fixture - command: | - node ../../scripts/createFixture esbuild + at: /tmp/material-ui/packed + - setup_corepack: + browsers: true - run: name: Install dependencies - command: | - pnpm - node ../../scripts/useBuildFromSource.js . + command: pnpm install --ignore-workspace - run: name: Test fixture - command: | - # TODO: Known failure - set +e - pnpm start - exit 0 + command: pnpm start test_bundling_gatsby: <<: *default-job - working_directory: /tmp/material-ui/test/bundling/fixtures/gatsby/ docker: - image: mcr.microsoft.com/playwright:v1.47.2-focal + environment: + GATSBY_CPU_COUNT: '3' + working_directory: /tmp/material-ui/test/bundling/fixtures/gatsby/ steps: - checkout: path: /tmp/material-ui - attach_workspace: - at: /tmp/material-ui/packages - - run: - name: Prepare fixture - command: | - node ../../scripts/useBuildFromSource.js . - node ../../scripts/createFixture gatsby + at: /tmp/material-ui/packed + - setup_corepack: + browsers: true - run: name: Install dependencies - command: pnpm + command: pnpm install --ignore-workspace - run: name: Test fixture command: pnpm start + test_bundle_size_monitor: <<: *default-job steps: @@ -668,6 +660,7 @@ jobs: command: pnpm danger ci environment: DANGER_COMMAND: prepareBundleSizeReport + - setup_corepack - run: name: build @mui packages command: pnpm lerna run --ignore @mui/icons-material --concurrency 6 --scope "@mui/*" build @@ -807,19 +800,15 @@ workflows: jobs: - test_bundling_prepare: <<: *default-context - - test_bundling_node-esm: + - test_bundling_node_cjs: <<: *default-context requires: - test_bundling_prepare - - test_bundling_next-webpack4: + - test_bundling_node_esm: <<: *default-context requires: - test_bundling_prepare - - test_bundling_next-webpack5: - <<: *default-context - requires: - - test_bundling_prepare - - test_bundling_create-react-app: + - test_bundling_create_react_app: <<: *default-context requires: - test_bundling_prepare @@ -839,6 +828,15 @@ workflows: <<: *default-context requires: - test_bundling_prepare + - test_bundling_next_webpack4: + <<: *default-context + requires: + - test_bundling_prepare + - test_bundling_next_webpack5: + <<: *default-context + requires: + - test_bundling_prepare + profile: when: equal: [profile, << pipeline.parameters.workflow >>] diff --git a/.gitignore b/.gitignore index 605f9c60ddddcc..e0af26ad0d2a0b 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,4 @@ docs/public/static/blog/feed/* .nx/cache .nx/workspace-data screenshots +packed diff --git a/apps/pigment-css-vite-app/src/pages/fixtures/index.tsx b/apps/pigment-css-vite-app/src/pages/fixtures/index.tsx index b646a41333c1ea..4967f9144b2bfe 100644 --- a/apps/pigment-css-vite-app/src/pages/fixtures/index.tsx +++ b/apps/pigment-css-vite-app/src/pages/fixtures/index.tsx @@ -17,9 +17,7 @@ export default function Layout() { ); const demo = new URLSearchParams(location.search).get('demo'); - const fixturesRoutes = (matchedRoute?.route.children ?? []).filter( - (item) => !!item.path && item.path !== 'index.test', - ); + const fixturesRoutes = (matchedRoute?.route.children ?? []).filter((item) => !!item.path); const demosRoutes = (materialUIRoute?.route.children ?? []).filter( (item) => !!item.path && !item.path.includes('react-pagination'), diff --git a/apps/pigment-css-vite-app/vite.config.ts b/apps/pigment-css-vite-app/vite.config.ts index 1aeffb286e54bb..88f1fb06db2f1f 100644 --- a/apps/pigment-css-vite-app/vite.config.ts +++ b/apps/pigment-css-vite-app/vite.config.ts @@ -43,8 +43,10 @@ export default defineConfig({ sourceMap: true, displayName: true, }), - Pages(), splitVendorChunkPlugin(), + Pages({ + exclude: ['**/*.test.*'], + }), nodePolyfills(), ], }); diff --git a/package.json b/package.json index a9369b0369538d..a9a367aca9fa2f 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "release:publish": "pnpm publish --recursive --tag latest", "release:publish:dry-run": "pnpm publish --recursive --tag latest --registry=\"http://localhost:4873/\"", "release:tag": "node scripts/releaseTag.mjs", + "release:pack": "tsx scripts/releasePack.mts", "docs:api": "rimraf --glob ./docs/pages/**/api-docs ./docs/pages/**/api && pnpm docs:api:build", "docs:api:build": "tsx ./scripts/buidApiDocs/index.ts", "docs:build": "pnpm --filter docs build", diff --git a/scripts/releasePack.mts b/scripts/releasePack.mts new file mode 100644 index 00000000000000..7766eb1efc5944 --- /dev/null +++ b/scripts/releasePack.mts @@ -0,0 +1,107 @@ +/* eslint-disable no-console */ +import yargs from 'yargs'; +import { hideBin } from 'yargs/helpers'; +import { $ } from 'execa'; +import * as path from 'path'; +import * as fs from 'fs/promises'; + +interface WorkspaceDefinition { + name: string; + version: string; + path: string; + private: boolean; +} + +interface Manifest { + packages: Record; +} + +interface RunOptions { + packages?: string[]; + outDir: string; + concurrency: number; +} + +async function packWorkspace(workspace: WorkspaceDefinition, outDir: string): Promise { + const packages: Record = {}; + const { stdout: zipFilePath } = await $({ + cwd: workspace.path, + })`pnpm pack --pack-destination ${outDir}`; + packages[workspace.name] = zipFilePath; + return zipFilePath; +} + +async function run({ packages, outDir, concurrency }: RunOptions) { + const allWorkspaces: WorkspaceDefinition[] = await $`pnpm -r ls --depth -1 --json`.then( + (result) => JSON.parse(result.stdout), + ); + const workspacesMap = new Map(allWorkspaces.map((workspace) => [workspace.name, workspace])); + + const publicPackages = allWorkspaces + .filter((workspace) => !workspace.private) + .map((workspace) => workspace.name); + const packagesToPack = packages || publicPackages; + + const workspacesToPack = packagesToPack.map((name) => { + const workspace = workspacesMap.get(name); + if (!workspace) { + throw new Error(`Workspace ${name} not found`); + } + return workspace; + }); + + const absoluteDestination = path.resolve(outDir); + + const workspacesIterator = workspacesToPack.values(); + const manifest: Manifest = { packages: {} }; + const workers = Array.from({ length: concurrency }).map(async () => { + for (const workspace of workspacesIterator) { + /* eslint-disable no-await-in-loop */ + console.log(`packing "${workspace.name}"`); + const zipFilePath = await packWorkspace(workspace, absoluteDestination); + const newName = path.join(absoluteDestination, `${workspace.name}.tgz`); + await fs.mkdir(path.dirname(newName), { recursive: true }); + await fs.rename(zipFilePath, newName); + const relativeZipFilePath = path.relative(absoluteDestination, newName); + manifest.packages[workspace.name] = relativeZipFilePath; + console.log(`packed "${zipFilePath}"`); + /* eslint-enable no-await-in-loop */ + } + }); + + await Promise.all(workers); + + await fs.writeFile( + path.join(absoluteDestination, 'manifest.json'), + JSON.stringify(manifest, null, 2), + ); +} + +yargs(hideBin(process.argv)) + .command( + '$0', + 'Pack workspaces.', + (command) => { + return command + .option('packages', { + describe: 'Workspace Packages to pack, defaults to public packages', + type: 'array', + alias: 'p', + }) + .option('outDir', { + default: './packed', + describe: 'Destination folder', + type: 'string', + }) + .option('concurrency', { + default: 5, + describe: 'Number of concurrent packing processes', + type: 'number', + }); + }, + run, + ) + .help() + .strict(true) + .version(false) + .parse(); diff --git a/scripts/sizeSnapshot/package.json b/scripts/sizeSnapshot/package.json index cdf10486a4b819..5a71c6f3278715 100644 --- a/scripts/sizeSnapshot/package.json +++ b/scripts/sizeSnapshot/package.json @@ -1,6 +1,7 @@ { "name": "size-snapshot", "version": "1.0.0", + "private": true, "description": "Size snapshot of MUI packages", "dependencies": { "@mui/base": "workspace:^", diff --git a/test/bundling/README.md b/test/bundling/README.md index cb57ff507ddaff..4fdd303c23c34d 100644 --- a/test/bundling/README.md +++ b/test/bundling/README.md @@ -7,21 +7,24 @@ The created file might need some manual adjustment since not every edge case is ## Run a fixture +### To test a Pull Request + +1. Checkout branch +1. `pnpm install` +1. `pnpm lerna run build --scope "@mui/*"` +1. `pnpm release:pack` +1. Navigate into the fixture you want to test (where the `package.json` is located) +1. `pnpm install --ignore-workspace` +1. `pnpm start` + +### To test a published npm dist tag + +_For example: `latest` or `next` on npm or a codesandboxci published version_ + 1. Navigate into the fixture you want to test (where the `package.json` is located) -1. Use the node version you want to use (for example `nvm use 14.0.0`) -1. Prepare the package.json - - to test a Pull Request - 1. checkout branch - 1. `pnpm install` - 1. `pnpm lerna run build --scope "@mui/*"` - 1. `cd` to fixture - 1. `pnpm install` - 1. `node ../../scripts/useBuildFromSource.js .` - - to test a published npm dist tag (for example `latest` or `next`) on npm - 1. `cd` to fixture - 1. adjust the dependencies in the package.json accordingly - 1. `pnpm install` -1. `pnpm start` should exit with 0 +1. Adjust `pnpm.overrides` of the `package.json` file to point to the desired version +1. `pnpm install --ignore-workspace` +1. `pnpm start` ### In CI @@ -44,7 +47,7 @@ curl --request POST \ 1. Create a folder in `test/fixtures/bundling` 1. Add the necessary dependencies -1. Re-use the entries for `dependencies` and `resolutions` for `@mui/*` packages from the other fixtures +1. Re-use the entries for `dependencies` and `pnpm.overrides` for `@mui/*` packages from the other fixtures 1. Create a template 1. Write a factory that fills the template in `test/bundling/scripts/createFixture` 1. Add an entry into the `bundling` CircleCI pipeline (`.circleci/config.yml`) diff --git a/test/bundling/fixtures/create-react-app/package.json b/test/bundling/fixtures/create-react-app/package.json index ab22cb818fa310..ef39bc2d2ee037 100644 --- a/test/bundling/fixtures/create-react-app/package.json +++ b/test/bundling/fixtures/create-react-app/package.json @@ -3,6 +3,7 @@ "version": "1.0.0", "license": "MIT", "scripts": { + "prestart": "node ../../scripts/createFixture.js create-react-app", "start": "pnpm cross-env DISABLE_ESLINT_PLUGIN=true SKIP_PREFLIGHT_CHECK=true react-scripts build && concurrently --success first --kill-others \"pnpm server\" \"node testCreateReactAppIntegration\"", "server": "serve -p 5001 -s build" }, @@ -10,13 +11,13 @@ "@emotion/core": "11.0.0", "@emotion/react": "11.10.4", "@emotion/styled": "11.10.4", - "@mui/material": "5.10.5", - "@mui/icons-material": "5.10.3", - "@mui/lab": "5.0.0-alpha.99", - "@mui/styled-engine": "5.10.5", - "@mui/styles": "5.10.3", - "@mui/system": "5.10.5", - "@mui/utils": "5.10.3", + "@mui/material": "workspace:*", + "@mui/icons-material": "workspace:*", + "@mui/lab": "workspace:*", + "@mui/styled-engine": "workspace:*", + "@mui/styles": "workspace:*", + "@mui/system": "workspace:*", + "@mui/utils": "workspace:*", "react": "18.2.0", "react-dom": "18.2.0", "react-scripts": "5.0.1", @@ -39,5 +40,17 @@ "last 1 firefox version", "last 1 safari version" ] + }, + "pnpm": { + "overrides": { + "@mui/base": "file:../../../../packed/@mui/base.tgz", + "@mui/material": "file:../../../../packed/@mui/material.tgz", + "@mui/icons-material": "file:../../../../packed/@mui/icons-material.tgz", + "@mui/lab": "file:../../../../packed/@mui/lab.tgz", + "@mui/styled-engine": "file:../../../../packed/@mui/styled-engine.tgz", + "@mui/styles": "file:../../../../packed/@mui/styles.tgz", + "@mui/system": "file:../../../../packed/@mui/system.tgz", + "@mui/utils": "file:../../../../packed/@mui/utils.tgz" + } } } diff --git a/test/bundling/fixtures/esbuild/package.json b/test/bundling/fixtures/esbuild/package.json index 3d3922a962870b..7e198fc0c39eb7 100644 --- a/test/bundling/fixtures/esbuild/package.json +++ b/test/bundling/fixtures/esbuild/package.json @@ -3,21 +3,22 @@ "version": "1.0.0", "license": "MIT", "scripts": { + "prestart": "node ../../scripts/createFixture.js esbuild", "start": "pnpm build && concurrently --success first --kill-others \"pnpm server\" \"node testEsbuildIntegration\"", - "build": "esbuild esbuild.fixture.js --bundle --outfile=build/esbuild.fixture.js", + "build": "esbuild esbuild.fixture.js --bundle --outfile=build/esbuild.fixture.js --tsconfig=tsconfig.json", "server": "serve -p 5001 -s build" }, "dependencies": { "@emotion/core": "11.0.0", "@emotion/react": "11.10.4", "@emotion/styled": "11.10.4", - "@mui/material": "5.10.5", - "@mui/icons-material": "5.10.3", - "@mui/lab": "5.0.0-alpha.99", - "@mui/styled-engine": "5.10.5", - "@mui/styles": "5.10.3", - "@mui/system": "5.10.5", - "@mui/utils": "5.10.3", + "@mui/material": "workspace:*", + "@mui/icons-material": "workspace:*", + "@mui/lab": "workspace:*", + "@mui/styled-engine": "workspace:*", + "@mui/styles": "workspace:*", + "@mui/system": "workspace:*", + "@mui/utils": "workspace:*", "esbuild": "0.15.7", "react": "18.2.0", "react-dom": "18.2.0", @@ -27,5 +28,17 @@ "concurrently": "7.4.0", "playwright": "1.47.2", "serve": "14.0.1" + }, + "pnpm": { + "overrides": { + "@mui/base": "file:../../../../packed/@mui/base.tgz", + "@mui/material": "file:../../../../packed/@mui/material.tgz", + "@mui/icons-material": "file:../../../../packed/@mui/icons-material.tgz", + "@mui/lab": "file:../../../../packed/@mui/lab.tgz", + "@mui/styled-engine": "file:../../../../packed/@mui/styled-engine.tgz", + "@mui/styles": "file:../../../../packed/@mui/styles.tgz", + "@mui/system": "file:../../../../packed/@mui/system.tgz", + "@mui/utils": "file:../../../../packed/@mui/utils.tgz" + } } } diff --git a/test/bundling/fixtures/esbuild/tsconfig.json b/test/bundling/fixtures/esbuild/tsconfig.json new file mode 100644 index 00000000000000..3b7182f4eaf85f --- /dev/null +++ b/test/bundling/fixtures/esbuild/tsconfig.json @@ -0,0 +1,4 @@ +{ + "compilerOptions": {}, + "exclude": ["node_modules", "build"] +} diff --git a/test/bundling/fixtures/gatsby/.browserslistrc b/test/bundling/fixtures/gatsby/.browserslistrc new file mode 100644 index 00000000000000..cef7bb62dac7f6 --- /dev/null +++ b/test/bundling/fixtures/gatsby/.browserslistrc @@ -0,0 +1,2 @@ +defaults and fully supports es6-module +maintained node versions diff --git a/test/bundling/fixtures/gatsby/package.json b/test/bundling/fixtures/gatsby/package.json index f1250b043d8409..9d96877746dd98 100644 --- a/test/bundling/fixtures/gatsby/package.json +++ b/test/bundling/fixtures/gatsby/package.json @@ -3,20 +3,21 @@ "version": "1.0.0", "license": "MIT", "scripts": { + "prestart": "node ../../scripts/createFixture.js gatsby", "start": "pnpm gatsby build && concurrently --success first --kill-others \"pnpm gatsby serve\" \"node testGatsbyIntegration\"" }, "dependencies": { "@emotion/core": "11.0.0", "@emotion/react": "11.10.4", "@emotion/styled": "11.10.4", - "@mui/material": "5.10.5", - "@mui/icons-material": "5.10.3", - "@mui/lab": "5.0.0-alpha.99", - "@mui/styled-engine": "5.10.5", - "@mui/styles": "5.10.3", - "@mui/system": "5.10.5", - "@mui/utils": "5.10.3", - "gatsby": "4.25.7", + "@mui/material": "workspace:*", + "@mui/icons-material": "workspace:*", + "@mui/lab": "workspace:*", + "@mui/styled-engine": "workspace:*", + "@mui/styles": "workspace:*", + "@mui/system": "workspace:*", + "@mui/utils": "workspace:*", + "gatsby": "5.13.7", "react": "18.2.0", "react-dom": "18.2.0", "react-is": "18.2.0" @@ -24,5 +25,17 @@ "devDependencies": { "concurrently": "7.4.0", "playwright": "1.47.2" + }, + "pnpm": { + "overrides": { + "@mui/base": "file:../../../../packed/@mui/base.tgz", + "@mui/material": "file:../../../../packed/@mui/material.tgz", + "@mui/icons-material": "file:../../../../packed/@mui/icons-material.tgz", + "@mui/lab": "file:../../../../packed/@mui/lab.tgz", + "@mui/styled-engine": "file:../../../../packed/@mui/styled-engine.tgz", + "@mui/styles": "file:../../../../packed/@mui/styles.tgz", + "@mui/system": "file:../../../../packed/@mui/system.tgz", + "@mui/utils": "file:../../../../packed/@mui/utils.tgz" + } } } diff --git a/test/bundling/fixtures/next-webpack4/next.config.js b/test/bundling/fixtures/next-webpack4/next.config.js index af6c7df4649094..2e0d198c8f3565 100644 --- a/test/bundling/fixtures/next-webpack4/next.config.js +++ b/test/bundling/fixtures/next-webpack4/next.config.js @@ -1,3 +1,13 @@ module.exports = { webpack5: false, + eslint: { + ignoreDuringBuilds: true, + }, + webpack(config, { defaultLoaders }) { + config.module.rules.push({ + test: /\/node_modules\/@mui\//, + use: [defaultLoaders.babel], + }); + return config; + }, }; diff --git a/test/bundling/fixtures/next-webpack4/package.json b/test/bundling/fixtures/next-webpack4/package.json index 85c5042066580a..125cafa2f20a40 100644 --- a/test/bundling/fixtures/next-webpack4/package.json +++ b/test/bundling/fixtures/next-webpack4/package.json @@ -3,19 +3,20 @@ "version": "1.0.0", "license": "MIT", "scripts": { - "start": "pnpm next build && concurrently --success first --kill-others \"pnpm next start\" \"node testNextWebpack4Integration\"" + "prestart": "node ../../scripts/createFixture.js next-webpack4", + "start": "NODE_OPTIONS=--openssl-legacy-provider pnpm next build && concurrently --success first --kill-others \"pnpm next start\" \"node testNextWebpack4Integration\"" }, "dependencies": { "@emotion/core": "11.0.0", "@emotion/react": "11.10.4", "@emotion/styled": "11.10.4", - "@mui/material": "5.10.5", - "@mui/icons-material": "5.10.3", - "@mui/lab": "5.0.0-alpha.99", - "@mui/styled-engine": "5.10.5", - "@mui/styles": "5.10.3", - "@mui/system": "5.10.5", - "@mui/utils": "5.10.3", + "@mui/material": "workspace:*", + "@mui/icons-material": "workspace:*", + "@mui/lab": "workspace:*", + "@mui/styled-engine": "workspace:*", + "@mui/styles": "workspace:*", + "@mui/system": "workspace:*", + "@mui/utils": "workspace:*", "next": "11.1.4", "react": "^17.0.2", "react-dom": "^17.0.2", @@ -24,5 +25,17 @@ "devDependencies": { "concurrently": "7.4.0", "playwright": "1.47.2" + }, + "pnpm": { + "overrides": { + "@mui/base": "file:../../../../packed/@mui/base.tgz", + "@mui/material": "file:../../../../packed/@mui/material.tgz", + "@mui/icons-material": "file:../../../../packed/@mui/icons-material.tgz", + "@mui/lab": "file:../../../../packed/@mui/lab.tgz", + "@mui/styled-engine": "file:../../../../packed/@mui/styled-engine.tgz", + "@mui/styles": "file:../../../../packed/@mui/styles.tgz", + "@mui/system": "file:../../../../packed/@mui/system.tgz", + "@mui/utils": "file:../../../../packed/@mui/utils.tgz" + } } } diff --git a/test/bundling/fixtures/next-webpack5/next.config.js b/test/bundling/fixtures/next-webpack5/next.config.js new file mode 100644 index 00000000000000..7d17dcfcfb4d45 --- /dev/null +++ b/test/bundling/fixtures/next-webpack5/next.config.js @@ -0,0 +1,5 @@ +module.exports = { + eslint: { + ignoreDuringBuilds: true, + }, +}; diff --git a/test/bundling/fixtures/next-webpack5/package.json b/test/bundling/fixtures/next-webpack5/package.json index 44edc264933f78..82ef59c0f5a0f2 100644 --- a/test/bundling/fixtures/next-webpack5/package.json +++ b/test/bundling/fixtures/next-webpack5/package.json @@ -9,13 +9,13 @@ "@emotion/core": "11.0.0", "@emotion/react": "11.10.4", "@emotion/styled": "11.10.4", - "@mui/material": "5.10.5", - "@mui/icons-material": "5.10.3", - "@mui/lab": "5.0.0-alpha.99", - "@mui/styled-engine": "5.10.5", - "@mui/styles": "5.10.3", - "@mui/system": "5.10.5", - "@mui/utils": "5.10.3", + "@mui/material": "workspace:*", + "@mui/icons-material": "workspace:*", + "@mui/lab": "workspace:*", + "@mui/styled-engine": "workspace:*", + "@mui/styles": "workspace:*", + "@mui/system": "workspace:*", + "@mui/utils": "workspace:*", "next": "12.3.0", "react": "18.2.0", "react-dom": "18.2.0", @@ -24,5 +24,17 @@ "devDependencies": { "concurrently": "7.4.0", "playwright": "1.47.2" + }, + "pnpm": { + "overrides": { + "@mui/base": "file:../../../../packed/@mui/base.tgz", + "@mui/material": "file:../../../../packed/@mui/material.tgz", + "@mui/icons-material": "file:../../../../packed/@mui/icons-material.tgz", + "@mui/lab": "file:../../../../packed/@mui/lab.tgz", + "@mui/styled-engine": "file:../../../../packed/@mui/styled-engine.tgz", + "@mui/styles": "file:../../../../packed/@mui/styles.tgz", + "@mui/system": "file:../../../../packed/@mui/system.tgz", + "@mui/utils": "file:../../../../packed/@mui/utils.tgz" + } } } diff --git a/test/bundling/fixtures/node-cjs/development.js b/test/bundling/fixtures/node-cjs/development.js new file mode 100644 index 00000000000000..3c51c76266bab2 --- /dev/null +++ b/test/bundling/fixtures/node-cjs/development.js @@ -0,0 +1,5 @@ +import * as ReactIs from 'react-is'; +import Accordion2 from '@mui/material/Accordion'; + +// eslint-disable-next-line no-console +console.assert(ReactIs.isValidElementType(Accordion2)); diff --git a/test/bundling/fixtures/node-cjs/node-cjs.template b/test/bundling/fixtures/node-cjs/node-cjs.template new file mode 100644 index 00000000000000..3444091e6caa5d --- /dev/null +++ b/test/bundling/fixtures/node-cjs/node-cjs.template @@ -0,0 +1,3 @@ +{{{requires}}} + +{{{usage}}} diff --git a/test/bundling/fixtures/node-cjs/package.json b/test/bundling/fixtures/node-cjs/package.json new file mode 100644 index 00000000000000..ed913aababbd3f --- /dev/null +++ b/test/bundling/fixtures/node-cjs/package.json @@ -0,0 +1,35 @@ +{ + "name": "node-esm", + "version": "1.0.0", + "main": "index.js", + "type": "commonjs", + "license": "MIT", + "scripts": { + "prestart": "node ../../scripts/createFixture.js node-cjs", + "start": "node node-cjs.fixture.js" + }, + "dependencies": { + "@emotion/core": "11.0.0", + "@emotion/styled": "11.10.4", + "@mui/material": "workspace:*", + "@mui/icons-material": "workspace:*", + "@mui/lab": "workspace:*", + "@mui/styled-engine": "workspace:*", + "@mui/styles": "workspace:*", + "@mui/system": "workspace:*", + "@mui/utils": "workspace:*", + "react-is": "18.2.0" + }, + "pnpm": { + "overrides": { + "@mui/base": "file:../../../../packed/@mui/base.tgz", + "@mui/material": "file:../../../../packed/@mui/material.tgz", + "@mui/icons-material": "file:../../../../packed/@mui/icons-material.tgz", + "@mui/lab": "file:../../../../packed/@mui/lab.tgz", + "@mui/styled-engine": "file:../../../../packed/@mui/styled-engine.tgz", + "@mui/styles": "file:../../../../packed/@mui/styles.tgz", + "@mui/system": "file:../../../../packed/@mui/system.tgz", + "@mui/utils": "file:../../../../packed/@mui/utils.tgz" + } + } +} diff --git a/test/bundling/fixtures/node-esm/package.json b/test/bundling/fixtures/node-esm/package.json index 2cc5d58eaeded5..8056aa2e7e4d5a 100644 --- a/test/bundling/fixtures/node-esm/package.json +++ b/test/bundling/fixtures/node-esm/package.json @@ -5,18 +5,31 @@ "type": "module", "license": "MIT", "scripts": { + "prestart": "node ../../scripts/createFixture.js node-esm", "start": "node node-esm.fixture.js" }, "dependencies": { "@emotion/core": "11.0.0", "@emotion/styled": "11.10.4", - "@mui/material": "5.10.5", - "@mui/icons-material": "5.10.3", - "@mui/lab": "5.0.0-alpha.99", - "@mui/styled-engine": "5.10.5", - "@mui/styles": "5.10.3", - "@mui/system": "5.10.5", - "@mui/utils": "5.10.3", + "@mui/material": "workspace:*", + "@mui/icons-material": "workspace:*", + "@mui/lab": "workspace:*", + "@mui/styled-engine": "workspace:*", + "@mui/styles": "workspace:*", + "@mui/system": "workspace:*", + "@mui/utils": "workspace:*", "react-is": "18.2.0" + }, + "pnpm": { + "overrides": { + "@mui/base": "file:../../../../packed/@mui/base.tgz", + "@mui/material": "file:../../../../packed/@mui/material.tgz", + "@mui/icons-material": "file:../../../../packed/@mui/icons-material.tgz", + "@mui/lab": "file:../../../../packed/@mui/lab.tgz", + "@mui/styled-engine": "file:../../../../packed/@mui/styled-engine.tgz", + "@mui/styles": "file:../../../../packed/@mui/styles.tgz", + "@mui/system": "file:../../../../packed/@mui/system.tgz", + "@mui/utils": "file:../../../../packed/@mui/utils.tgz" + } } } diff --git a/test/bundling/fixtures/snowpack/package.json b/test/bundling/fixtures/snowpack/package.json index 2d6648545ad5af..69e363dabed378 100644 --- a/test/bundling/fixtures/snowpack/package.json +++ b/test/bundling/fixtures/snowpack/package.json @@ -3,6 +3,7 @@ "version": "1.0.0", "license": "MIT", "scripts": { + "prestart": "node ../../scripts/createFixture.js snowpack", "start": "pnpm snowpack build && concurrently --success first --kill-others \"pnpm server\" \"node testSnowpackIntegration\"", "server": "serve -p 5001 -s build" }, @@ -10,13 +11,13 @@ "@emotion/core": "11.0.0", "@emotion/react": "11.10.4", "@emotion/styled": "11.10.4", - "@mui/material": "5.10.5", - "@mui/icons-material": "5.10.3", - "@mui/lab": "5.0.0-alpha.99", - "@mui/styled-engine": "5.10.5", - "@mui/styles": "5.10.3", - "@mui/system": "5.10.5", - "@mui/utils": "5.10.3", + "@mui/material": "workspace:*", + "@mui/icons-material": "workspace:*", + "@mui/lab": "workspace:*", + "@mui/styled-engine": "workspace:*", + "@mui/styles": "workspace:*", + "@mui/system": "workspace:*", + "@mui/utils": "workspace:*", "snowpack": "3.8.8", "react": "18.2.0", "react-dom": "18.2.0", @@ -26,5 +27,17 @@ "concurrently": "7.4.0", "playwright": "1.47.2", "serve": "14.0.1" + }, + "pnpm": { + "overrides": { + "@mui/base": "file:../../../../packed/@mui/base.tgz", + "@mui/material": "file:../../../../packed/@mui/material.tgz", + "@mui/icons-material": "file:../../../../packed/@mui/icons-material.tgz", + "@mui/lab": "file:../../../../packed/@mui/lab.tgz", + "@mui/styled-engine": "file:../../../../packed/@mui/styled-engine.tgz", + "@mui/styles": "file:../../../../packed/@mui/styles.tgz", + "@mui/system": "file:../../../../packed/@mui/system.tgz", + "@mui/utils": "file:../../../../packed/@mui/utils.tgz" + } } } diff --git a/test/bundling/fixtures/vite/package.json b/test/bundling/fixtures/vite/package.json index e745bd9aad5673..b1bd0fa9b86064 100644 --- a/test/bundling/fixtures/vite/package.json +++ b/test/bundling/fixtures/vite/package.json @@ -3,6 +3,7 @@ "version": "1.0.0", "license": "MIT", "scripts": { + "prestart": "node ../../scripts/createFixture.js vite", "start": "pnpm vite build && concurrently --success first --kill-others \"pnpm server\" \"node testViteIntegration\"", "server": "serve -p 5001 -s build" }, @@ -10,13 +11,13 @@ "@emotion/core": "11.0.0", "@emotion/react": "11.10.4", "@emotion/styled": "11.10.4", - "@mui/material": "5.10.5", - "@mui/icons-material": "5.10.3", - "@mui/lab": "5.0.0-alpha.99", - "@mui/styled-engine": "5.10.5", - "@mui/styles": "5.10.3", - "@mui/system": "5.10.5", - "@mui/utils": "5.10.3", + "@mui/material": "workspace:*", + "@mui/icons-material": "workspace:*", + "@mui/lab": "workspace:*", + "@mui/styled-engine": "workspace:*", + "@mui/styles": "workspace:*", + "@mui/system": "workspace:*", + "@mui/utils": "workspace:*", "react": "18.2.0", "react-dom": "18.2.0", "react-is": "18.2.0", @@ -26,5 +27,17 @@ "concurrently": "7.4.0", "playwright": "1.47.2", "serve": "14.0.1" + }, + "pnpm": { + "overrides": { + "@mui/base": "file:../../../../packed/@mui/base.tgz", + "@mui/material": "file:../../../../packed/@mui/material.tgz", + "@mui/icons-material": "file:../../../../packed/@mui/icons-material.tgz", + "@mui/lab": "file:../../../../packed/@mui/lab.tgz", + "@mui/styled-engine": "file:../../../../packed/@mui/styled-engine.tgz", + "@mui/styles": "file:../../../../packed/@mui/styles.tgz", + "@mui/system": "file:../../../../packed/@mui/system.tgz", + "@mui/utils": "file:../../../../packed/@mui/utils.tgz" + } } } diff --git a/test/bundling/scripts/createFixture.js b/test/bundling/scripts/createFixture.js index 3a5b98ba908f72..7ceeaf15966f3c 100644 --- a/test/bundling/scripts/createFixture.js +++ b/test/bundling/scripts/createFixture.js @@ -33,6 +33,19 @@ async function writeNodeESMFixture(context) { await writeFromTemplate(destinationPath, templateSource, fixtureTemplateValues); } +/** + * @param {FixtureContext} context + */ +async function writeNodeCJSFixture(context) { + const { fixtureUrl, fixtureTemplateValues } = context; + const destinationPath = new URL('./node-cjs.fixture.js', fixtureUrl); + const templateSource = await fs.readFile(new URL('node-cjs.template', fixtureUrl), { + encoding: 'utf8', + }); + + await writeFromTemplate(destinationPath, templateSource, fixtureTemplateValues); +} + /** * @param {FixtureContext} context */ @@ -118,10 +131,27 @@ async function readFixtureTemplateValues(fileUrl) { const importsMatch = code.match(/\/\/ #region imports(.+?)\/\/ #endregion/s); const [imports] = importsMatch; + const lines = imports.split(/\n+/).filter((line) => { + const trimmed = line.trim(); + return trimmed && !trimmed.startsWith('//') && !trimmed.startsWith('/*'); + }); + const requires = lines + .map((line) => { + const [, specifier, module] = /import (.*) from ['"](.*)['"]/.exec(line); + if (specifier.startsWith('*')) { + return `const ${specifier.replace('* as ', '')} = require('${module}')`; + } + if (specifier.startsWith('{')) { + return `const ${specifier.replace(' as ', ': ')} = require('${module}')`; + } + return `const { default: ${specifier} } = require('${module}')`; + }) + .join('\n'); + const usageMatch = code.match(/\/\/ #region usage(.+?)\/\/ #endregion/s); const [usage] = usageMatch; - return { imports, usage }; + return { imports, usage, requires }; } function resolveFixtureUrl(fixtureName) { @@ -144,6 +174,12 @@ async function run(context) { ); switch (fixture) { + case 'node-cjs': + await writeNodeCJSFixture({ + fixtureUrl: resolveFixtureUrl('node-cjs'), + fixtureTemplateValues, + }); + break; case 'node-esm': await writeNodeESMFixture({ fixtureUrl: resolveFixtureUrl('node-esm'), diff --git a/test/bundling/scripts/useBuildFromSource.js b/test/bundling/scripts/useBuildFromSource.js deleted file mode 100644 index 20d5b8f4358306..00000000000000 --- a/test/bundling/scripts/useBuildFromSource.js +++ /dev/null @@ -1,96 +0,0 @@ -// Only use built-in modules because this script runs pre-install. -import { promises as fs } from 'fs'; -import { URL } from 'url'; - -/** - * node 12 compatible implementation of cp -r - * @param {URL} sourceDirectory - * @param {URL} targetDirectory - */ -async function copyDirectory(sourceDirectory, targetDirectory) { - await fs.mkdir(targetDirectory, { recursive: true }); - - const sourceFiles = await fs.readdir(sourceDirectory, { withFileTypes: true }); - await Promise.all( - sourceFiles.map(async (sourceFileEntry) => { - let copyMethod; - let sourceFileUrlInput; - if (sourceFileEntry.isDirectory()) { - sourceFileUrlInput = `./${sourceFileEntry.name}/`; - copyMethod = copyDirectory; - } else { - sourceFileUrlInput = `./${sourceFileEntry.name}`; - copyMethod = fs.copyFile; - } - await copyMethod( - new URL(sourceFileUrlInput, sourceDirectory), - new URL(sourceFileUrlInput, targetDirectory), - ); - }), - ); -} - -/** - * node 12 compatible implementation of rm -rf - * @param {string} directory - */ -async function rmRecursiveForce(directory) { - const files = await fs.readdir(directory); - await Promise.all( - files.map(async (fileBasename) => { - const fileName = new URL(fileBasename, directory); - - const fileStats = await fs.stat(fileName); - if (fileStats.isDirectory()) { - await rmRecursiveForce(fileName); - } else { - await fs.unlink(fileName, { force: true }); - } - }), - ); - - await fs.rmdir(directory); -} - -async function run(context) { - const { fixturePath } = context; - if (fixturePath === undefined) { - throw new Error( - `Usage: ${process.argv[1]} [distTag]\n distTag: An npm tag e.g. 'npm:next' or 'npm:latest'. Omit the use the built packages from source.`, - ); - } - const cwdUrl = new URL(`${process.cwd()}/`, 'file://'); - const fixtureUrl = new URL(`./${fixturePath}/`, cwdUrl); - - const workspaceRoot = new URL('../../../', import.meta.url); - await Promise.all( - [ - 'material', - 'icons-material', - 'lab', - 'private-theming', - 'styled-engine', - 'styles', - 'system', - 'types', - 'base', - 'utils', - ].map(async (muiPackageName) => { - // clean copy - try { - await rmRecursiveForce(new URL(`./node_modules/@mui/${muiPackageName}/`, fixtureUrl)); - } catch (error) { - // already exists - } - await copyDirectory( - new URL(`./packages/mui${`-${muiPackageName}`}/build/`, workspaceRoot), - new URL(`./node_modules/@mui/${muiPackageName}/`, fixtureUrl), - ); - }), - ); -} - -run({ fixturePath: process.argv[2] }).catch((error) => { - console.error(error); - process.exit(1); -});