代码之家  ›  专栏  ›  技术社区  ›  wsfuller

Next.js使用polyfills和jQuery包

  •  0
  • wsfuller  · 技术社区  · 2 年前

    有一个特别涉及Next.js的问题 array-flat polyfill 。我需要与旧版本的Chrome兼容,在这个例子中(v60-68)。我正在开发的应用程序使用了一个视频播放器包,该包是使用jQuery3.4构建的。该包使用 $selector).replaceWith(elem) 并且是错误发生的地方。

    $.replaceWith 最终运行:

      var flat = arr.flat ? function(array) {
        return arr.flat.call(array);
      } : function(array) {
        return arr.concat.apply([], array);
      }
    

    问题是不兼容的浏览器将运行 arr.flat.call(array) 因为Next.js polyfill,将在 polyfill-module.js 带有未定义的引用。当进入 node_modules/@next/polyfill-module/src/index.js ,移除阵列平面polyfill,并重建;该应用程序将按预期工作并运行 arr.concant.apply([], array); 正如jQuery所期望的那样。

    所以我正处在如何处理这种情况的十字路口。理想情况下,希望对Next的polyfills保持一些支持,从jQuery迁移是不可能的。有没有一种方法可以共存?例如,Next是否提供了禁用 polyfill-module.js 在特定页面/实例上加载文件?或者有什么建议可以让jQuery在这种特殊情况下按预期运行吗?

    0 回复  |  直到 2 年前
        1
  •  1
  •   wsfuller    2 年前

    我为这个问题找到的解决方案是删除Next.js默认的polyfill array.flat 在较旧的浏览器上,因为它与 jQUery.replaceWith()

    我使用的应用程序 rooks library react-device-detect

    import { useDidMount } from 'rooks';
    import {
      browserVersion,
      isChrome,
      isSafari,
      isFirefox,
    } from 'react-device-detect';
    
    const MyPage: React.FC<PropTypes> = ({ ...props }) => {
    
      useDidMount(() => {
        /*
          Remove NextJS default polyfill for array.flat as it will 
          error using jQuery.replaceWith() which is used in the package 
          we are using. jQuery will handle support for browsers which 
          do not support array.flat. 
        */
    
        //  Stats from https://caniuse.com/?search=array.flat
        const minimumChromeArrayFlatVersion = '69';
        const minimumSafariArrayFlatVersion = '12';
        const minimumFirefoxArrayFlatVersion = '62';
    
        const isChromeCompatible =
          isChrome && browserVersion >= minimumChromeArrayFlatVersion;
        const isSafariCompatible =
          isSafari && browserVersion >= minimumSafariArrayFlatVersion;
        const isFirefoxCompatible =
          isFirefox && browserVersion >= minimumFirefoxArrayFlatVersion;
    
        const isTargetedBrowser = isChrome || isSafari || isFirefox;
        const isBrowserCompatible =
          isChromeCompatible || isSafariCompatible || isFirefoxCompatible;
    
        if (isTargetedBrowser && !isBrowserCompatible) {
          Array.prototype.flat = undefined;
        }
      });
    
      return <div>...</div>;
    }