如何为Nuxt 2.0添加polyfill?

24
在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工作。这是我尝试过的:

像我以前一样使用vendor

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

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

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

使用polyfill.io

我尝试添加:

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

到我的头部,连同:

render: {
  resourceHints: false,
},
禁用 preload 提示(我不确定这是否重要)。这会导致页面看起来正确 - polyfill.min.js 在所有其他脚本之前加载。但是,在我在 IE11 上进行测试时,Object.entries 未定义,页面崩溃了。

尝试完全从构建配置中移除 Babel。它应该自动工作。 - Aldarund
@Aldarund 谢谢 - 我也尝试了那个方法。我可以看到(通过build -a),core-js已经被包含了,但是在测试时仍然出现相同的错误。我想知道 core-js 是否没有在构建中正确提升。但即使是这样,我也不明白为什么 polyfill.io 会失败。 - David Weldon
你不能只是在插件中要求polyfill吗? - Imre_G
@Imre_G 我相信 polyfill 实际上已经被包含了,并且在一个简单的应用程序中它可以正常工作。一旦包被包含进来(在我的情况下是 @nuxtjs/apollo),那么它似乎就会出问题。当我从 nuxt 开发人员那里得到更新时,我会在这里发布我的发现。 - David Weldon
4个回答

28

以下是我升级到nuxt 2.2.0 并在IE 11上使用必要的polyfills让我的应用程序正常工作所采取的步骤。您的经验可能因安装的软件包而异。

第一步

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

build.vendor已被弃用。 我尝试调整build.babel,因为nuxt文档指示它默认使用 vue-app。我认为它实际上使用的是babel-preset-env。 这与其他工具一起依赖于browserslist,后者具有一些合理的默认值。我没有更改浏览器列表配置,但您可以按照其文档进行更改。

第二步

升级或替换任何导致构建问题的模块。当我升级时,@nuxtjs/apollo由于其一个依赖项的转译问题而导致构建失败。然而这个问题已经被解决,但最终我选择了vue-apollo+ apollo-boost,因为它更适合我的项目。

第三步

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

我使用了polyfill.io,将以下内容添加到nuxt.config.js中:

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

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

注意:我已经包含了body: true,这会将脚本从页面的部分移出。然而,它将会被插入到你的应用程序代码之前

注意: 推荐使用IntersectionObserver进行链接预取

你可以使用构建器创建类似的URL。请注意,一旦选择了一个功能,构建器将自动选择默认值default,这在功能上(据我所知)与随core-js一起提供的填充功能相当。因为core-js目前不可选(你无论如何都要发布它),所以最好不要包括来自polyfill.iodefault集合。

关于填充和为什么polyfill.io可能是一个好主意的深入讨论,请参见这篇文章。简短的版本是,它仅加载客户端实际需要的基于浏览器UA的内容。

最后,你需要测试你的应用程序,以查看在特定浏览器中是否需要任何其他功能。你可能需要重复这个过程几次,直到所有的错误都消失为止。请确保在多个页面上进行测试,因为不是所有的页面包都具有相同的要求。

结论

虽然上述内容的一些方面是特定于应用程序的,但希望这可以帮助你走向正确的方向。最重要的是,没有一个解决方案可以适用于所有情况 - 你仍然需要在目标浏览器中进行测试,以验证代码是否被执行。


感谢您详细的解释。希望核心团队能尽快解决这个问题。 - Johan
1
@Merc 这对我来说是一个高优先级的问题。随着我学到更多,我一定会在这里添加它。 - David Weldon
@Merc 我根据持续的实验添加了一些改进。请阅读我回答中步骤3的最新版本。 - David Weldon

9
我尝试了以上所有方法,但都无法起作用。然而,我发现通过创建一个插件并将其添加到nuxt.config.js中,可以使我的代码在IE11上运行,如下所示: // nuxt.config.js
  plugins: [
    { src: '~/plugins/polyfills', mode: 'client' },
  ],

// 插件 / 兼容补丁.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配置,只需要这样做。我知道这意味着我的代码将始终运行polyfills,但没有第三方依赖项(例如polyfill.io)。您可以根据需要编辑所需的polyfill列表。希望这能帮助到某人!


1
这是我认为最好的解决方案。谢谢! - DJDJ

8

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

  • 它支持在加载任何polyfill之前进行功能检测
  • polyfill.io polyfills兼容。
  • 不会将polyfills包含在默认捆绑包中。
  • 仅在需要时延迟加载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',
    ]
}

免责声明:该内容由我个人制作。


1
对于使用这些选项的任何人,我需要输入一个检测方法(在我的情况下是针对Array.from:detect: () => !Array.from),否则它根本不会加载,我认为,或者它假定服务器端存在本地实现,因此在客户端上没有包含它。 - Lumocra
1
@Lumocra,你能分享一下你的整个解决方案吗?我们似乎无法让Array.from正常工作。 - Scriptodude
1
在 nuxt.config.js 中:polyfill: { features: [ ..., { require: 'array-from', detect: () => !Array.from }, ... ] }, - Lumocra
但我仍然需要手动添加每个 polyfill 吗?它不能根据我的代码中的功能检测出哪些是必需的吗? - Oli
@Tim,你能分享一个使用nuxt-polyfill和polyfill.io捆绑包而不是URL的示例吗? - menepet
显示剩余2条评论

0

我正在使用 nuxt 2.x,修复方法非常简单,只需要在 nuxt.config.js 中添加 transpile 即可。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接