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
8 changes: 6 additions & 2 deletions scripts/sizeSnapshot/create.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// @ts-check

const path = require('path');
const os = require('os');
const fse = require('fs-extra');
Expand All @@ -23,9 +25,11 @@ async function getWebpackSizes(webpackEnvironment) {

const entries = await getWebpackEntries();

const uniqueEntries = new Set(entries);

const sizeArrays = await Promise.all(
entries.map((entry, index) =>
worker.run({ entry, webpackEnvironment, index, total: entries.length }),
Array.from(uniqueEntries, (entry, index) =>
worker.run({ entry, webpackEnvironment, index, total: uniqueEntries.size }),
),
);

Expand Down
154 changes: 54 additions & 100 deletions scripts/sizeSnapshot/webpack.config.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// @ts-check

const path = require('path');
const CompressionPlugin = require('compression-webpack-plugin');
const glob = require('fast-glob');
Expand All @@ -6,128 +8,70 @@ const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');

const workspaceRoot = path.join(__dirname, '..', '..');

/**
* @typedef {object} WebpackEntry
* @property {string} import
* @property {string} [importName]
*
* @typedef {object} Environment
* @property {boolean} analyze
* @property {boolean} accurateBundles
*/

/**
*
* @returns {Promise<WebpackEntry[]>}
*/
async function getWebpackEntries() {
const materialPackagePath = path.join(workspaceRoot, 'packages/mui-material/build');
const materialComponents = (await glob(path.join(materialPackagePath, '([A-Z])*/index.js'))).map(
(componentPath) => {
const componentName = path.basename(path.dirname(componentPath));
let entryName = componentName;
// adjust for legacy names
if (componentName === 'Paper') {
entryName = '@material-ui/core/Paper.esm';
} else if (componentName === 'TextareaAutosize') {
entryName = '@material-ui/core/Textarea';
}

return {
id: entryName,
import: `@mui/material/${componentName}`,
};
return `@mui/material/${componentName}`;
},
);

const labPackagePath = path.join(workspaceRoot, 'packages/mui-lab/build');
const labComponents = (await glob(path.join(labPackagePath, '([A-Z])*/index.js'))).map(
(componentPath) => {
const componentName = path.basename(path.dirname(componentPath));

return {
id: componentName,
import: `@mui/lab/${componentName}`,
};
},
);

const joyPackagePath = path.join(workspaceRoot, 'packages/mui-joy/build');
const joyComponents = (await glob(path.join(joyPackagePath, '([A-Z])*/index.js'))).map(
(componentPath) => {
const componentName = path.basename(path.dirname(componentPath));

return {
id: `@mui/joy/${componentName}`,
import: `@mui/joy/${componentName}`,
};
return `@mui/lab/${componentName}`;
},
);

return [
{
// WARNING: Changing the name will break tracking of bundle size over time
// If the name of the package changes, rename its display name in https://github.com/eps1lon/mui-contributor-dashboard/blob/main/src/pages/SizeComparison.tsx
id: '@material-ui/core',
import: '@mui/material',
},
'@mui/material',
...materialComponents,
{
id: '@material-ui/lab',
import: '@mui/lab',
},
'@mui/lab',
...labComponents,
{
id: '@material-ui/styles',
import: '@mui/styles',
},
{
id: '@material-ui/private-theming',
import: '@mui/private-theming',
},
{
id: '@material-ui/system',
import: '@mui/system',
},
{
id: 'createBox',
import: '@mui/system/createBox',
},
{
id: 'createStyled',
import: '@mui/system/createStyled',
},
{
id: '@material-ui/core/styles/createTheme',
importName: 'createTheme',
import: '@mui/material/styles',
},
{
id: 'colorManipulator',
import: '@mui/system/colorManipulator',
},
{
id: 'useAutocomplete',
import: '@mui/lab/useAutocomplete',
},
{
id: '@material-ui/core/useMediaQuery',
import: '@mui/material/useMediaQuery',
},
{
id: '@material-ui/core/useScrollTrigger',
import: '@mui/material/useScrollTrigger',
},
{
id: '@material-ui/utils',
import: '@mui/utils',
},
// TODO: Requires webpack v5
// Resolution of webpack/acorn to 7.x is blocked by nextjs (https://github.com/vercel/next.js/issues/11947)
// {
// id: '@material-ui/core.modern',
// webpack: true,
// path: path.join(path.relative(workspaceRoot, materialPackagePath), 'modern/index.js'),
// },
{
id: '@mui/joy',
import: '@mui/joy',
},
...joyComponents,
'@mui/styles',
'@mui/private-theming',
'@mui/system',
'@mui/system/createBox',
'@mui/system/createStyled',
'@mui/material/styles#createTheme',
'@mui/system/colorManipulator',
'@mui/lab/useAutocomplete',
'@mui/material/useMediaQuery',
'@mui/material/useScrollTrigger',
'@mui/utils',
];
}

/**
*
* @param {WebpackEntry} entry
* @param {Environment} environment
* @returns
*/
function createWebpackConfig(entry, environment) {
const analyzerMode = environment.analyze ? 'static' : 'disabled';
const concatenateModules = !environment.accurateBundles;

const importNames = entry.importName ? `{ ${entry.importName} as foo }` : '* as foo';
const entryName = entry;
const [importSrc, importName] = entryName.split('#');

const importSpec = importName ? `{ ${importName} as foo }` : '* as foo';

/**
* @type {import('webpack').Configuration}
Expand All @@ -142,6 +86,14 @@ function createWebpackConfig(entry, environment) {
minimizer: [
new TerserPlugin({
test: /\.m?js(\?.*)?$/i,
// Avoid creating LICENSE.txt files for each module
// See https://github.com/webpack-contrib/terser-webpack-plugin#remove-comments
terserOptions: {
format: {
comments: false,
},
},
extractComments: false,
}),
],
},
Expand All @@ -156,15 +108,17 @@ function createWebpackConfig(entry, environment) {
path: path.join(__dirname, 'build'),
},
plugins: [
new CompressionPlugin(),
new CompressionPlugin({
filename: '[path][base][fragment].gz',
}),
new BundleAnalyzerPlugin({
analyzerMode,
// We create a report for each bundle so around 120 reports.
// Opening them all is spam.
// If opened with `webpack --config . --analyze` it'll still open one new tab though.
openAnalyzer: false,
// '[name].html' not supported: https://github.com/webpack-contrib/webpack-bundle-analyzer/issues/12
reportFilename: `${entry.id}.html`,
reportFilename: `${importSrc}.html`,
}),
],
// A context to the current dir, which has a node_modules folder with workspace dependencies
Expand All @@ -173,7 +127,7 @@ function createWebpackConfig(entry, environment) {
// This format is a data: url combined with inline matchResource to obtain a virtual entry.
// See https://github.com/webpack/webpack/issues/6437#issuecomment-874466638
// See https://webpack.js.org/api/loaders/#inline-matchresource
[entry.id]: `./index.js!=!data:text/javascript,import ${importNames} from '${entry.import}';console.log(foo);`,
[entryName]: `./index.js!=!data:text/javascript,import ${importSpec} from '${importSrc}';console.log(foo);`,
},
// TODO: 'browserslist:modern'
// See https://github.com/webpack/webpack/issues/14203
Expand Down
Loading