如何将 polyfill 添加到 nuxt 2.0?

Posted

技术标签:

【中文标题】如何将 polyfill 添加到 nuxt 2.0?【英文标题】:How to add a polyfill to nuxt 2.0? 【发布时间】:2019-02-26 09:09:23 【问题描述】:

在 Nuxt 1.4.2 中,我的 nuxt.config.js 中有以下内容:

build: 
  vendor: ['babel-polyfill'],
  babel: 
    presets: [
      ['vue-app', 
        useBuiltIns: true,
        targets:  ie: 11, uglify: true ,
      ,
      ],
    ],
  ,
,

似乎所有这些都在 Nuxt 2.0 中被破坏了。至少我正在寻找足以让 IE 11 工作的 polyfill。这是我尝试过的:

像以前一样使用供应商

删除build.babel 允许构建过程工作:

build: 
  vendor: ['babel-polyfill'],
,

但我认为 build.vendor 现在只是被忽略了,所以这似乎没有任何作用。

使用 polyfill.io

我尝试添加:

script: [
   src: 'https://cdn.polyfill.io/v2/polyfill.min.js' ,
],

致我的head,以及:

render: 
  resourceHints: false,
,

禁用preload 提示(我不确定这是否重要)。这会产生一个看起来正确的页面 - polyfill.min.js 在所有其他脚本之前加载。不知何故,当我在 ie11 上测试时,Object.entries 未定义,页面爆炸了。

【问题讨论】:

尝试从构建配置中删除 babel。它应该自动工作 @Aldarund 谢谢 - 我也试过了。我可以看到(通过 build -a)包含 core-js,但在测试时我仍然看到相同的错误。我想知道core-js 是否在构建中没有被正确提升。但即使这是真的,我也不明白为什么polyfill.io 会失败。 你不能只需要插件中的 polyfil 吗? @Imre_G 我相信 polyfill 实际上已包含在内,它在一个简单的应用程序中运行良好。一旦包含了软件包(在我的情况下为@nuxtjs/apollo),它似乎就坏了。当我从 nuxt 开发人员那里得到更新时,我会在这里发布我的发现。 【参考方案1】:

以下是我升级到 nuxt 2.2.0 并使用必要的 polyfill 让我的应用在 IE 11 上运行的步骤。您的体验可能会有所不同,具体取决于您安装的软件包。

第 1 步

nuxt.config.js 中删除build.vendorbuild.babel

build.vendor 已弃用。我尝试调整build.babel,因为nuxt docs 表明它默认使用vue-app。我认为它实际上是在使用babel-preset-env。这与其他工具一起取决于browserslist,它有一些合理的defaults。我没有更改浏览器列表配置,但您可以关注他们的docs。

第 2 步

升级或替换任何导致构建问题的模块。当我升级时,@nuxtjs/apollo 通过其依赖项之一遇到了转译问题。这一直是resolved,但我最终切换到vue-apollo + apollo-boost,因为它更适合我的项目。

第 3 步

core-js 未提供但目标浏览器需要的任何额外功能添加 polyfill。在测试目标时,您应该能够根据控制台中抛出的任何异常来确定这些。

我通过将以下内容添加到nuxt.config.js 来使用polyfill.io:

const features = [
  'fetch',
  'Object.entries',
  'IntersectionObserver',
].join('%2C');

head: 
  script: [
     src: `https://polyfill.io/v3/polyfill.min.js?features=$features`, body: true ,
  ],
,

注意:我已包含body: true,它将脚本移出页面的head 部分。但是,它将被插入之前您的任何应用程序代码。

注意: IntersectionObserver 推荐用于link prefetching。

您可以使用builder 创建一个类似的网址。请注意,一旦您选择了一个特性,构建器将自动选择 default,它(据我所知)在功能上等同于 core-js 附带的 polyfill。因为core-js 目前不是可选的(无论如何你都要发布它),所以不包含来自polyfill.iodefault 集是有意义的。

有关 polyfill 的深入讨论以及为什么 polyfill.io 可能是一个好主意,请参阅 this post。简短的版本是它仅根据浏览器的 UA 加载客户端实际需要的内容。

最后,您需要测试您的应用以查看在给定浏览器中成功执行需要哪些附加功能(如果有)。您可能需要多次重复此过程,直到所有错误都消失。确保在多个页面上进行测试,因为并非所有页面包都具有相同的要求。

结论

虽然上述某些方面是特定于应用程序的,但希望这可以帮助您朝着正确的方向前进。最重要的一点是没有唯一的解决方案 - 您仍然需要在目标浏览器中进行测试以验证代码是否执行。

【讨论】:

感谢您的详细解释。希望核心团队尽快解决这个问题 @Merc 这对我来说是一个高优先级的问题。随着我了解更多,我一定会在此处添加。 @Merc 我在不断试验的基础上添加了一些改进。请阅读我的回答中步骤 3 的最新版本。【参考方案2】:

您也可以使用nuxt-polyfill 模块。

它支持特征检测 在加载任何polyfill之前 与polyfill.io polyfill 兼容。 默认包中不包含 polyfill。 仅在需要时才延迟加载 polyfills 当且仅当需要 polyfill 时才延迟 Nuxt 初始化。
npm install nuxt-polyfill

将模块添加到您的 nuxt.config.js:

export default 

    // Configure polyfills:
    polyfill: 
        features: [
            /* 
                Feature without detect:

                Note: 
                  This is not recommended for most polyfills
                  because the polyfill will always be loaded, parsed and executed.
            */
            
                require: 'url-polyfill' // NPM package or require path of file
            ,

            /* 
                Feature with detect:

                Detection is better because the polyfill will not be 
                loaded, parsed and executed if it's not necessary.
            */
            
                require: 'intersection-observer',
                detect: () => 'IntersectionObserver' in window,
            ,

            /*
                Feature with detect & install:

                Some polyfills require a installation step
                Hence you could supply a install function which accepts the require result
            */
            
                require: 'smoothscroll-polyfill',

                // Detection found in source: https://github.com/iamdustan/smoothscroll/blob/master/src/smoothscroll.js
                detect: () => 'scrollBehavior' in document.documentElement.style && window.__forceSmoothScrollPolyfill__ !== true,

                // Optional install function called client side after the package is required:
                install: (smoothscroll) => smoothscroll.polyfill()
            
        ]
    ,

    // Add it to the modules section:
    modules: [
        'nuxt-polyfill',
    ]

免责声明:我做到了。

【讨论】:

对于使用此选项的任何人,我需要输入一个检测方法(在我的情况下为 Array.from:detect: () => !Array.from)才能工作,否则我认为它根本没有加载,或者它假设本机实现在服务器端,所以它没有在客户端包含它。 @Lumocra 你能分享你的整个解决方案吗?我们似乎无法使其适用于Array.from @Lumocra @Scriptodude 如果你不提供检测功能,polyfill 将始终被包含并运行。但请记住,这发生在第一个插件开始运行时。所以你需要确保你只使用插件的default exported functions、组件的computed propertiesmethods、vuex商店的任何getter, mutation or action等中的polyfill。你不能只在全局路径中使用它脚本,因为当时它还没有填充。 @Scriptodude 在 nuxt.config.js 中:polyfill: features: [ ..., require: 'array-from', detect: () => !Array.from , ... ] , 但是我还是要手动添加每个polyfill?它无法根据我的代码中的功能检测到需要哪些?【参考方案3】:

我尝试了上述所有方法,但没有任何效果。但是,我发现我可以通过创建一个插件并将其添加到 nuxt.config.js 中来让我的代码与 IE11 一起使用,如下所示:

// nuxt.config.js

  plugins: [
     src: '~/plugins/polyfills', mode: 'client' ,
  ],

// 插件/polyfills.js

import 'core-js/fn/object/entries'
import 'core-js/fn/array/includes'
import 'core-js/fn/array/find'
import 'core-js/fn/array/from'
import 'core-js/es6/promise'
import 'core-js/fn/object/assign'
import 'core-js/es6/symbol'
import 'whatwg-fetch'

我删除了任何特殊的 babel 配置。这就是全部。我知道这意味着我的代码将始终运行 polyfill,但没有第 3 方依赖项(例如 polyfill.io)。您可以根据需要编辑所需的 polyfill 列表。希望这对某人有帮助!

【讨论】:

这是最好的解决方案,IMO。谢谢!【参考方案4】:

我用的是nuxt 2.x,修复很简单,你只需要在nuxt.config.js中添加transpile

build:  transpile: ['vue-cli-plugin-apollo'] 

【讨论】:

以上是关于如何将 polyfill 添加到 nuxt 2.0?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 Naver Analytics 添加到 Nuxt.js SPA 应用程序?

如何将 vue3-openlayers 插件添加到 nuxt

如何使用 Nuxt Js 将数据属性添加到脚本标签?

在 Nuxt.js 中发送每个请求时,如何将对象添加到 apollo 上的数据?

如何将 Firebase Firestore 数据添加到 s-s-r Nuxt Apps Vuex Store

如何在 vercel zeit 上使用 Tailwindcss 2.0 部署 nuxt.js 项目