diff --git a/core/audits/byte-efficiency/legacy-javascript.js b/core/audits/byte-efficiency/legacy-javascript.js index df5e023b8cf9..f870062d7ec3 100644 --- a/core/audits/byte-efficiency/legacy-javascript.js +++ b/core/audits/byte-efficiency/legacy-javascript.js @@ -152,6 +152,12 @@ class LegacyJavascript extends ByteEfficiencyAudit { // Object.defineProperty(String.prototype, 'startsWith' expression += `|defineProperty\\(${object || 'window'},\\s?${qt(property)}`; + // es-shims + // no(Object,{entries:r},{entries:function + if (object) { + expression += `|\\(${object},\\s*{${property}:.*},\\s*{${property}`; + } + // core-js if (object) { const objectWithoutPrototype = object.replace('.prototype', ''); @@ -234,6 +240,9 @@ class LegacyJavascript extends ByteEfficiencyAudit { ]; for (const [name, coreJs2Module] of coreJsPolyfills) { + // es-shims follows a pattern for its packages. + // Tack it onto the corejs size estimation, as it is likely close in size. + const esShimModule = name.toLowerCase(); data.push({ name, modules: [ @@ -243,6 +252,7 @@ class LegacyJavascript extends ByteEfficiencyAudit { .replace('es6.', 'es.') .replace('es7.', 'es.') .replace('typed.', 'typed-array.'), + esShimModule, ], corejs: true, }); @@ -333,8 +343,9 @@ class LegacyJavascript extends ByteEfficiencyAudit { // Skip if the pattern matching found a match for this polyfill. if (matches.some(m => m.name === name)) continue; - const source = bundle.rawMap.sources.find(source => - modules.some(module => source.endsWith(`${module}.js`))); + const source = bundle.rawMap.sources.find(source => modules.some(module => { + return source.endsWith(`/${module}.js`) || source.includes(`node_modules/${module}/`); + })); if (!source) continue; const mapping = bundle.map.mappings().find(m => m.sourceURL === source); diff --git a/core/test/audits/byte-efficiency/legacy-javascript-test.js b/core/test/audits/byte-efficiency/legacy-javascript-test.js index c1d7d8259fb2..6903b896138d 100644 --- a/core/test/audits/byte-efficiency/legacy-javascript-test.js +++ b/core/test/audits/byte-efficiency/legacy-javascript-test.js @@ -176,6 +176,9 @@ describe('LegacyJavaScript audit', () => { 'Object.defineProperty(String.prototype, "repeat", function() {})', '$export($export.S,"Object",{values:function values(t){return i(t)}})', 'String.raw = function() {}', + // es-shims (object.entries) + 'no(Object,{entries:r},{entries:function', + 'no(Array.prototype,{find:r},{find:function', // Currently are no polyfills that declare a class. Maybe in the future. // 'Object.defineProperty(window, \'WeakMap\', function() {})', // 'WeakMap = function() {}', @@ -255,7 +258,11 @@ describe('LegacyJavaScript audit', () => { it('detects non-corejs modules from source maps', async () => { const map = { - sources: ['node_modules/focus-visible/dist/focus-visible.js'], + sources: [ + 'node_modules/focus-visible/dist/focus-visible.js', + 'node_modules/array.prototype.find/index.js', + 'node_modules/object.entries/index.js', + ], mappings: 'blah', }; const script = { @@ -266,13 +273,22 @@ describe('LegacyJavaScript audit', () => { const result = await getResult([script]); expect(result.items).toHaveLength(1); + expect(result.items[0].subItems.items).toHaveLength(3); expect(result.items[0].subItems.items).toMatchObject([ { signal: 'focus-visible', location: {line: 0, column: 0}, }, + { + signal: 'Array.prototype.find', + location: {line: 0, column: 0}, + }, + { + signal: 'Object.entries', + location: {line: 0, column: 0}, + }, ]); - expect(result.items[0].wastedBytes).toBe(3000); + expect(result.items[0].wastedBytes).toBe(38062); }); });