Hmm, good point. I have my webpack project set up for tree shaking (as far as I understand at least, sideEffects = false
and in webpack config usedExports: true, minimize: true,
), and testing it out I now understand it even less lol. Across my different pages using babylon.js (viewer on 2, core on the third), with most being a common bundle:
Importing the entire library as you mention, I’m getting a bundled size of 4.59 MiB 4.84 MiB 4.6 MiB
. It also seems to contain two levels of @babylonjs/core for some reason, although as far as I can tell each of those contains slightly different things.
Now if I use the more specific imports like:
import { Engine } from "@babylonjs/core/Engines/engine";
import { Scene } from "@babylonjs/core/scene";
import { ArcRotateCamera } from "@babylonjs/core/Cameras/arcRotateCamera";
[etc.]
the bundle size actually goes up for some reason. The difference is very small but it is there: 4.64 MiB 4.88 MiB 4.64 MiB
This leaves me with absolutely no clue what’s going on - my assumption was that, with tree shaking supposedly enabled for both, importing the entire library would end up larger than just importing specifically the classes I use, but the opposite (although marginally) seems to be true…
full webpack config because why not
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
module.exports = {
entry: {
home: './src/home.js',
class: './src/class/class.js',
'ar-viewer': './src/ar-viewer/ar-viewer.js',
'model-viewer': './src/model-viewer/model-viewer.js',
create: './src/create/create.js'
},
output: {
filename: (pathData) => {
const name = pathData.chunk.name;
if (name === 'home') return 'home.bundle.js';
return `${name}/[name].bundle.js`;
},
chunkFilename: (pathData) => {
const name = pathData.chunk.name;
if (name.startsWith('home')) return '[name].bundle.js';
return `${name}/[name].bundle.js`;
},
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
},
plugins: [
new BundleAnalyzerPlugin(),
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
filename: 'index.html',
template: './src/index.html',
chunks: ['home']
}),
new HtmlWebpackPlugin({
filename: 'class/index.html',
template: './src/class/index.html',
chunks: ['class']
}),
new HtmlWebpackPlugin({
filename: 'model-viewer/index.html',
template: './src/model-viewer/index.html',
chunks: ['model-viewer']
}),
new HtmlWebpackPlugin({
filename: 'ar-viewer/index.html',
template: './src/ar-viewer/index.html',
chunks: ['ar-viewer']
}),
new HtmlWebpackPlugin({
filename: 'create/index.html',
template: './src/create/index.html',
chunks: ['create']
}),
new CopyWebpackPlugin({
patterns: [
{ from: '**/*.css', to: '[path][name][ext]', context: 'src' },
{ from: 'src/res', to: 'res' }
]
})
],
optimization: {
splitChunks: {
cacheGroups: {
default: false,
vendors: false,
common: {
name: 'common',
chunks: 'all',
minChunks: 2,
priority: 30,
reuseExistingChunk: true,
enforce: true,
},
homeVendors: {
test: /[\\/]node_modules[\\/]/,
name: 'homeVendors',
chunks: (chunk) => chunk.name === 'home',
priority: 20,
enforce: true,
},
classVendors: {
test: /[\\/]node_modules[\\/]/,
name: 'classVendors',
chunks: (chunk) => chunk.name === 'class',
priority: 20,
enforce: true,
},
modelViewerVendors: {
test: /[\\/]node_modules[\\/]/,
name: 'model-viewer-vendors',
chunks: (chunk) => chunk.name === 'model-viewer',
priority: 20,
enforce: true,
},
arViewerVendors: {
test: /[\\/]node_modules[\\/]/,
name: 'ar-viewer-vendors',
chunks: (chunk) => chunk.name === 'ar-viewer',
priority: 20,
enforce: true,
},
createVendors: {
test: /[\\/]node_modules[\\/]/,
name: 'create-vendors',
chunks: (chunk) => chunk.name === 'create',
priority: 20,
enforce: true,
}
}
},
usedExports: true,
minimize: true,
minimizer: [
'...',
new CssMinimizerPlugin()
]
},
performance: {
hints: 'warning',
maxAssetSize: 512000,
maxEntrypointSize: 512000,
assetFilter: function (assetFilename) {
// Only provide performance hints for JS and CSS files
return /\.(js|css)$/.test(assetFilename);
}
}
};