123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- // Keep in sync with next.js polyfills file : https://github.com/vercel/next.js/blob/master/packages/next-polyfill-nomodule/src/index.js
- const NEXT_POLYFILLED_FEATURES = [
- 'Array.prototype.@@iterator',
- 'Array.prototype.copyWithin',
- 'Array.prototype.fill',
- 'Array.prototype.find',
- 'Array.prototype.findIndex',
- 'Array.prototype.flatMap',
- 'Array.prototype.flat',
- 'Array.from',
- 'Array.prototype.includes',
- 'Array.of',
- 'Function.prototype.name',
- 'fetch',
- 'Map',
- 'Number.EPSILON',
- 'Number.Epsilon',
- 'Number.isFinite',
- 'Number.isNaN',
- 'Number.isInteger',
- 'Number.isSafeInteger',
- 'Number.MAX_SAFE_INTEGER',
- 'Number.MIN_SAFE_INTEGER',
- 'Number.parseFloat',
- 'Number.parseInt',
- 'Object.assign',
- 'Object.entries',
- 'Object.fromEntries',
- 'Object.getOwnPropertyDescriptor',
- 'Object.getOwnPropertyDescriptors',
- 'Object.is',
- 'Object.keys',
- 'Object.values',
- 'Reflect',
- 'Set',
- 'Symbol',
- 'Symbol.asyncIterator',
- 'String.prototype.codePointAt',
- 'String.prototype.endsWith',
- 'String.fromCodePoint',
- 'String.prototype.includes',
- 'String.prototype.@@iterator',
- 'String.prototype.padEnd',
- 'String.prototype.padStart',
- 'String.prototype.repeat',
- 'String.raw',
- 'String.prototype.startsWith',
- 'String.prototype.trimEnd',
- 'String.prototype.trimStart',
- 'URL',
- 'URL.prototype.toJSON',
- 'URLSearchParams',
- 'WeakMap',
- 'WeakSet',
- 'Promise',
- 'Promise.prototype.finally',
- 'es2015', // Should be covered by babel-preset-env instead.
- 'es2016', // contains polyfilled 'Array.prototype.includes', 'String.prototype.padEnd' and 'String.prototype.padStart'
- 'es2017', // contains polyfilled 'Object.entries', 'Object.getOwnPropertyDescriptors', 'Object.values', 'String.prototype.padEnd' and 'String.prototype.padStart'
- 'es2018', // contains polyfilled 'Promise.prototype.finally' and ''Symbol.asyncIterator'
- 'es2019', // Contains polyfilled 'Object.fromEntries' and polyfilled 'Array.prototype.flat', 'Array.prototype.flatMap', 'String.prototype.trimEnd' and 'String.prototype.trimStart'
- 'es5', // Should be covered by babel-preset-env instead.
- 'es6', // Should be covered by babel-preset-env instead.
- 'es7', // contains polyfilled 'Array.prototype.includes', 'String.prototype.padEnd' and 'String.prototype.padStart'
- ]
- const url = 'https://nextjs.org/docs/messages/no-unwanted-polyfillio'
- //------------------------------------------------------------------------------
- // Rule Definition
- //------------------------------------------------------------------------------
- module.exports = {
- meta: {
- docs: {
- description: 'Prevent duplicate polyfills from Polyfill.io.',
- category: 'HTML',
- recommended: true,
- url,
- },
- type: 'problem',
- schema: [],
- },
- create: function (context) {
- let scriptImport = null
- return {
- ImportDeclaration(node) {
- if (node.source && node.source.value === 'next/script') {
- scriptImport = node.specifiers[0].local.name
- }
- },
- JSXOpeningElement(node) {
- if (
- node.name &&
- node.name.name !== 'script' &&
- node.name.name !== scriptImport
- ) {
- return
- }
- if (node.attributes.length === 0) {
- return
- }
- const srcNode = node.attributes.find(
- (attr) => attr.type === 'JSXAttribute' && attr.name.name === 'src'
- )
- if (!srcNode || srcNode.value.type !== 'Literal') {
- return
- }
- const src = srcNode.value.value
- if (
- src.startsWith('https://cdn.polyfill.io/v2/') ||
- src.startsWith('https://polyfill.io/v3/')
- ) {
- const featureQueryString = new URL(src).searchParams.get('features')
- const featuresRequested = (featureQueryString || '').split(',')
- const unwantedFeatures = featuresRequested.filter((feature) =>
- NEXT_POLYFILLED_FEATURES.includes(feature)
- )
- if (unwantedFeatures.length > 0) {
- context.report({
- node,
- message: `No duplicate polyfills from Polyfill.io are allowed. ${unwantedFeatures.join(
- ', '
- )} ${
- unwantedFeatures.length > 1 ? 'are' : 'is'
- } already shipped with Next.js. See: ${url}`,
- })
- }
- }
- },
- }
- },
- }
|