Skip to content

Commit 043becf

Browse files
feat: Reducing the agent chunk count (#637)
1 parent 5dca741 commit 043becf

File tree

7 files changed

+308
-117
lines changed

7 files changed

+308
-117
lines changed

src/features/session_replay/aggregate/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,12 +173,14 @@ export class Aggregate extends AggregateBase {
173173
}
174174

175175
try {
176+
// Do not change the webpackChunkName or it will break the webpack nrba-chunking plugin
176177
recorder = (await import(/* webpackChunkName: "recorder" */'rrweb')).record
177178
} catch (err) {
178179
return this.abort()
179180
}
180181

181182
try {
183+
// Do not change the webpackChunkName or it will break the webpack nrba-chunking plugin
182184
const { gzipSync, strToU8 } = await import(/* webpackChunkName: "compressor" */'fflate')
183185
gzipper = gzipSync
184186
u8 = strToU8

tools/webpack/configs/common.mjs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import webpack from 'webpack'
22
import TerserPlugin from 'terser-webpack-plugin'
3+
import NRBAChunkingPlugin from '../plugins/nrba-chunking/index.mjs'
34

45
/**
56
* @typedef {import('../index.mjs').WebpackBuildOptions} WebpackBuildOptions
@@ -10,8 +11,9 @@ import TerserPlugin from 'terser-webpack-plugin'
1011
* builds.
1112
* @param {WebpackBuildOptions} env Build variables passed into the webpack cli
1213
* using --env foo=bar --env biz=baz
14+
* @param {string} asyncChunkName Partial name to use for the loader's async chunk
1315
*/
14-
export default (env) => {
16+
export default (env, asyncChunkName) => {
1517
return {
1618
devtool: false,
1719
mode: env.SUBVERSION === 'PROD' ? 'production' : 'development',
@@ -28,7 +30,14 @@ export default (env) => {
2830
}
2931
})],
3032
flagIncludedChunks: true,
31-
mergeDuplicateChunks: true
33+
mergeDuplicateChunks: true,
34+
splitChunks: {
35+
chunks: 'async',
36+
cacheGroups: {
37+
defaultVendors: false,
38+
default: false
39+
}
40+
}
3241
},
3342
output: {
3443
filename: (pathData) => {
@@ -51,6 +60,9 @@ export default (env) => {
5160
filename: '[file].map[query]',
5261
moduleFilenameTemplate: 'nr-browser-agent://[namespace]/[resource-path]?[loaders]',
5362
publicPath: env.PUBLIC_PATH
63+
}),
64+
new NRBAChunkingPlugin({
65+
asyncChunkName
5466
})
5567
]
5668
}

tools/webpack/configs/polyfills.mjs

Lines changed: 102 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import path from 'path'
2+
import webpack from 'webpack'
23
import { merge } from 'webpack-merge'
34
import commonConfig from './common.mjs'
45
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer'
@@ -14,47 +15,112 @@ import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer'
1415
* using --env foo=bar --env biz=baz
1516
*/
1617
export default (env) => {
17-
return merge(commonConfig(env), {
18-
target: 'browserslist:ie >= 11',
19-
entry: {
20-
'nr-loader-rum-polyfills': path.resolve(env.paths.src, 'cdn/polyfills/lite.js'),
21-
'nr-loader-rum-polyfills.min': path.resolve(env.paths.src, 'cdn/polyfills/lite.js'),
22-
'nr-loader-full-polyfills': path.resolve(env.paths.src, 'cdn/polyfills/pro.js'),
23-
'nr-loader-full-polyfills.min': path.resolve(env.paths.src, 'cdn/polyfills/pro.js'),
24-
'nr-loader-spa-polyfills': path.resolve(env.paths.src, 'cdn/polyfills/spa.js'),
25-
'nr-loader-spa-polyfills.min': path.resolve(env.paths.src, 'cdn/polyfills/spa.js'),
26-
'nr-polyfills.min': path.resolve(env.paths.src, 'cdn/polyfills.js')
18+
const entryGroups = [
19+
{
20+
asyncChunkName: 'nr-rum-polyfills',
21+
entry: {
22+
'nr-loader-rum-polyfills': path.join(env.paths.src, 'cdn/polyfills/lite.js'),
23+
'nr-loader-rum-polyfills.min': path.join(env.paths.src, 'cdn/polyfills/lite.js')
24+
},
25+
plugins: [
26+
new webpack.IgnorePlugin({
27+
checkResource: (resource, context) => {
28+
if (context.match(/features\/utils/) && resource.indexOf('aggregate') > -1) {
29+
// Only allow page_view_event, page_view_timing, and metrics features
30+
return !resource.match(/page_view_event\/aggregate|page_view_timing\/aggregate|metrics\/aggregate/)
31+
}
32+
33+
return false
34+
}
35+
})
36+
]
2737
},
28-
output: {
29-
chunkFilename: env.SUBVERSION === 'PROD' ? `[name].[chunkhash:8]-es5${env.PATH_VERSION}.min.js` : `[name]-es5${env.PATH_VERSION}.js`
38+
{
39+
asyncChunkName: 'nr-full-polyfills',
40+
entry: {
41+
'nr-loader-full-polyfills': path.join(env.paths.src, 'cdn/polyfills/pro.js'),
42+
'nr-loader-full-polyfills.min': path.join(env.paths.src, 'cdn/polyfills/pro.js')
43+
},
44+
plugins: [
45+
new webpack.IgnorePlugin({
46+
checkResource: (resource, context) => {
47+
if (context.match(/features\/utils/) && resource.indexOf('aggregate') > -1) {
48+
// Allow all features except spa and session_replay
49+
return resource.match(/spa\/aggregate|session_replay\/aggregate/)
50+
}
51+
52+
return false
53+
}
54+
})
55+
]
3056
},
31-
module: {
32-
rules: [
33-
{
34-
test: /\.js$/,
35-
exclude: /(node_modules)/,
36-
use: {
37-
loader: 'babel-loader',
38-
options: {
39-
envName: 'webpack-ie11'
57+
{
58+
asyncChunkName: 'nr-spa-polyfills',
59+
entry: {
60+
'nr-loader-spa-polyfills': path.join(env.paths.src, 'cdn/polyfills/spa.js'),
61+
'nr-loader-spa-polyfills.min': path.join(env.paths.src, 'cdn/polyfills/spa.js')
62+
},
63+
plugins: [
64+
new webpack.IgnorePlugin({
65+
checkResource: (resource, context) => {
66+
if (context.match(/features\/utils/) && resource.indexOf('aggregate') > -1) {
67+
// Do not allow session_replay feature
68+
return resource.match(/session_replay\/aggregate/)
4069
}
70+
71+
return false
4172
}
42-
}
73+
})
4374
]
4475
},
45-
plugins: [
46-
new BundleAnalyzerPlugin({
47-
analyzerMode: 'static',
48-
openAnalyzer: false,
49-
defaultSizes: 'stat',
50-
reportFilename: `polyfills${env.PATH_VERSION}.stats.html`
51-
}),
52-
new BundleAnalyzerPlugin({
53-
analyzerMode: 'json',
54-
openAnalyzer: false,
55-
defaultSizes: 'stat',
56-
reportFilename: `polyfills${env.PATH_VERSION}.stats.json`
57-
})
58-
]
76+
{
77+
asyncChunkName: 'nr-polyfills',
78+
entry: {
79+
'nr-polyfills.min': path.resolve(env.paths.src, 'cdn/polyfills.js')
80+
},
81+
plugins: [
82+
new webpack.optimize.LimitChunkCountPlugin({
83+
maxChunks: 1
84+
})
85+
]
86+
}
87+
]
88+
89+
return entryGroups.map(entryGroup => {
90+
return merge(commonConfig(env, entryGroup.asyncChunkName), {
91+
target: 'browserslist:ie >= 11',
92+
entry: entryGroup.entry,
93+
output: {
94+
chunkFilename: env.SUBVERSION === 'PROD' ? `[name].[chunkhash:8]-es5${env.PATH_VERSION}.min.js` : `[name]-es5${env.PATH_VERSION}.js`
95+
},
96+
module: {
97+
rules: [
98+
{
99+
test: /\.js$/,
100+
exclude: /(node_modules)/,
101+
use: {
102+
loader: 'babel-loader',
103+
options: {
104+
envName: 'webpack-ie11'
105+
}
106+
}
107+
}
108+
]
109+
},
110+
plugins: [
111+
new BundleAnalyzerPlugin({
112+
analyzerMode: 'static',
113+
openAnalyzer: false,
114+
defaultSizes: 'stat',
115+
reportFilename: `${entryGroup.asyncChunkName}${env.PATH_VERSION}.stats.html`
116+
}),
117+
new BundleAnalyzerPlugin({
118+
analyzerMode: 'json',
119+
openAnalyzer: false,
120+
defaultSizes: 'stat',
121+
reportFilename: `${entryGroup.asyncChunkName}${env.PATH_VERSION}.stats.json`
122+
})
123+
]
124+
})
59125
})
60126
}

tools/webpack/configs/standard.mjs

Lines changed: 114 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import path from 'path'
2+
import webpack from 'webpack'
23
import { merge } from 'webpack-merge'
34
import commonConfig from './common.mjs'
45
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer'
@@ -14,57 +15,122 @@ import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer'
1415
* using --env foo=bar --env biz=baz
1516
*/
1617
export default (env) => {
17-
return merge(commonConfig(env), {
18-
target: 'web',
19-
entry: {
20-
'nr-loader-rum': path.join(env.paths.src, 'cdn/lite.js'),
21-
'nr-loader-rum.min': path.join(env.paths.src, 'cdn/lite.js'),
22-
'nr-loader-full': path.join(env.paths.src, 'cdn/pro.js'),
23-
'nr-loader-full.min': path.join(env.paths.src, 'cdn/pro.js'),
24-
'nr-loader-spa': path.join(env.paths.src, 'cdn/spa.js'),
25-
'nr-loader-spa.min': path.join(env.paths.src, 'cdn/spa.js'),
26-
...(env.SUBVERSION !== 'PROD' && { 'nr-loader-experimental': path.resolve(env.paths.src, 'cdn/experimental.js') }),
27-
...(env.SUBVERSION !== 'PROD' && { 'nr-loader-experimental.min': path.resolve(env.paths.src, 'cdn/experimental.js') })
18+
const entryGroups = [
19+
{
20+
asyncChunkName: 'nr-rum',
21+
entry: {
22+
'nr-loader-rum': path.join(env.paths.src, 'cdn/lite.js'),
23+
'nr-loader-rum.min': path.join(env.paths.src, 'cdn/lite.js')
24+
},
25+
plugins: [
26+
new webpack.IgnorePlugin({
27+
checkResource: (resource, context) => {
28+
if (context.match(/features\/utils/) && resource.indexOf('aggregate') > -1) {
29+
// Only allow page_view_event, page_view_timing, and metrics features
30+
return !resource.match(/page_view_event\/aggregate|page_view_timing\/aggregate|metrics\/aggregate/)
31+
}
32+
33+
return false
34+
}
35+
})
36+
]
37+
},
38+
{
39+
asyncChunkName: 'nr-full',
40+
entry: {
41+
'nr-loader-full': path.join(env.paths.src, 'cdn/pro.js'),
42+
'nr-loader-full.min': path.join(env.paths.src, 'cdn/pro.js')
43+
},
44+
plugins: [
45+
new webpack.IgnorePlugin({
46+
checkResource: (resource, context) => {
47+
if (context.match(/features\/utils/) && resource.indexOf('aggregate') > -1) {
48+
// Allow all features except spa and session_replay
49+
return resource.match(/spa\/aggregate|session_replay\/aggregate/)
50+
}
51+
52+
return false
53+
}
54+
})
55+
]
2856
},
29-
module: {
30-
rules: [
31-
{
32-
test: /\.js$/,
33-
exclude: /(node_modules)/,
34-
use: (env.coverage || 'false').toLowerCase() === 'true'
35-
? [
36-
{ loader: './tools/webpack/loaders/istanbul/index.mjs' },
37-
{
38-
loader: 'babel-loader',
39-
options: {
40-
envName: 'webpack'
57+
{
58+
asyncChunkName: 'nr-spa',
59+
entry: {
60+
'nr-loader-spa': path.join(env.paths.src, 'cdn/spa.js'),
61+
'nr-loader-spa.min': path.join(env.paths.src, 'cdn/spa.js')
62+
},
63+
plugins: [
64+
new webpack.IgnorePlugin({
65+
checkResource: (resource, context) => {
66+
if (context.match(/features\/utils/) && resource.indexOf('aggregate') > -1) {
67+
// Do not allow session_replay feature
68+
return resource.match(/session_replay\/aggregate/)
69+
}
70+
71+
return false
72+
}
73+
})
74+
]
75+
}
76+
]
77+
78+
if (env.SUBVERSION !== 'PROD') {
79+
entryGroups.push({
80+
asyncChunkName: 'nr-experimental',
81+
entry: {
82+
'nr-loader-experimental': path.join(env.paths.src, 'cdn/experimental.js'),
83+
'nr-loader-experimental.min': path.join(env.paths.src, 'cdn/experimental.js')
84+
},
85+
plugins: []
86+
})
87+
}
88+
89+
return entryGroups.map(entryGroup => {
90+
return merge(commonConfig(env, entryGroup.asyncChunkName), {
91+
target: 'web',
92+
entry: entryGroup.entry,
93+
module: {
94+
rules: [
95+
{
96+
test: /\.js$/,
97+
exclude: /(node_modules)/,
98+
use: (env.coverage || 'false').toLowerCase() === 'true'
99+
? [
100+
{ loader: './tools/webpack/loaders/istanbul/index.mjs' },
101+
{
102+
loader: 'babel-loader',
103+
options: {
104+
envName: 'webpack'
105+
}
41106
}
42-
}
43-
]
44-
: [
45-
{
46-
loader: 'babel-loader',
47-
options: {
48-
envName: 'webpack'
107+
]
108+
: [
109+
{
110+
loader: 'babel-loader',
111+
options: {
112+
envName: 'webpack'
113+
}
49114
}
50-
}
51-
]
52-
}
115+
]
116+
}
117+
]
118+
},
119+
plugins: [
120+
...entryGroup.plugins,
121+
new BundleAnalyzerPlugin({
122+
analyzerMode: 'static',
123+
openAnalyzer: false,
124+
defaultSizes: 'stat',
125+
reportFilename: `${entryGroup.asyncChunkName}-standard${env.PATH_VERSION}.stats.html`
126+
}),
127+
new BundleAnalyzerPlugin({
128+
analyzerMode: 'json',
129+
openAnalyzer: false,
130+
defaultSizes: 'stat',
131+
reportFilename: `${entryGroup.asyncChunkName}-standard${env.PATH_VERSION}.stats.json`
132+
})
53133
]
54-
},
55-
plugins: [
56-
new BundleAnalyzerPlugin({
57-
analyzerMode: 'static',
58-
openAnalyzer: false,
59-
defaultSizes: 'stat',
60-
reportFilename: `standard${env.PATH_VERSION}.stats.html`
61-
}),
62-
new BundleAnalyzerPlugin({
63-
analyzerMode: 'json',
64-
openAnalyzer: false,
65-
defaultSizes: 'stat',
66-
reportFilename: `standard${env.PATH_VERSION}.stats.json`
67-
})
68-
]
134+
})
69135
})
70136
}

0 commit comments

Comments
 (0)