添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

It seems that all of this is broken in Nuxt 2.0 . At a minimum I'm looking to polyfill enough to get IE 11 working. Here's what I've tried:

Using vendor as I used to

Removing build.babel allowed the build process to work:

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

But I think build.vendor is just ignored now, so this seems to do nothing.

Using polyfill.io

I tried adding:

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

to my head, along with:

render: {
  resourceHints: false,

to disable the preload hints (I'm unsure if this matters). This results in a page which looks correct - polyfill.min.js is loaded before all other scripts. Somehow, when I test on ie11, Object.entries is undefined and the page explodes.

@Aldarund thanks - I tried that as well. I can see (via build -a) that core-js is included, but I still see the same errors when testing. I wonder if core-js just isn't being hoisted properly in the build. But even if that were true, I don't understand why polyfill.io would fail. – David Weldon Sep 24, 2018 at 18:40 @Imre_G I believe the polyfill is actually being included, and it works fine in a simple app. Once packages are included (in my case @nuxtjs/apollo), then it seems to break. When I have an update from the nuxt devs, I'll post my findings here. – David Weldon Sep 26, 2018 at 17:00

Here are the steps I took to upgrade to nuxt 2.2.0, and get my app working on IE 11 with the necessary polyfills. Your experience may differ, depending on which packages you have installed.

Step 1

Remove build.vendor and build.babel from nuxt.config.js.

build.vendor is deprecated. I tried to tweak build.babel, as the nuxt docs indicate it defaults to using vue-app. I think it's actually using babel-preset-env. This, along with other tools, depends on browserslist, which has some rational defaults. I didn't change my browserslist config, but you could by following their docs.

Step 2

Upgrade or replace any modules causing build issues. When I upgraded, @nuxtjs/apollo had a transpilation problem via one of its dependencies. This has since been resolved, however I ended up switching to vue-apollo + apollo-boost as it was a better fit for my project.

Step 3

Add polyfills for any extra features core-js doesn't provide, but that your target browsers need. You should be able to determine these based on any exceptions thrown in the console while testing on your targets.

I used polyfill.io by adding the following to 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 },
  

Note: I've included body: true which moves the script out of the head section of your page. It will, however, be inserted before any of your application code.

Note: IntersectionObserver is recommended for link prefetching.

You can create a similar URL by using the builder. Note that once you select a feature, the builder will automatically select default, which is (as far as I can tell) functionally equivalent to the polyfills that ship with core-js. Because core-js isn't currently optional (you're going to ship it anyway), it makes sense not to include the default set from polyfill.io.

For an in-depth discussion of polyfills and why polyfill.io is probably a good idea, see this post. The short version is that it loads only the stuff the client actually needs based on the browser's UA.

Finally, you'll need to test your app to see which additional features (if any) are needed for successful execution in a given browser. You may need to repeat this process several times until all of the errors go away. Make sure to test on multiple pages, as not all of your page bundles will have the same requirements.

Conclusion

While some aspects of the above are application-specific, hopefully this can help move you in the right direction. The most important takeaway is that there's no one solution to this - you'll still need to test in your target browsers to verify that the code executes.

@Merc This is a high priority issue for me. As I learn more, I'll be sure to add it here. – David Weldon Nov 16, 2018 at 23:45 @Merc I've added some improvements based on continued experimentation. Please read the latest version of step 3 in my answer. – David Weldon Feb 5, 2019 at 19:09

I tried all the above approaches and nothing at all worked. However, I found that I could get my code to work with IE11 by creating a plugin and adding it to nuxt.config.js as follows:

// nuxt.config.js

  plugins: [
    { src: '~/plugins/polyfills', mode: 'client' },

// plugins/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'

I removed any special babel config. That's all it took. I know this means my code will always run the polyfills, but there are no 3rd party dependencies (polyfill.io for example). You may edit the list of required polyfills as needed. Hope this helps someone!

  • It supports feature detection before loading any polyfill
  • Is compatible with polyfill.io polyfills.
  • Does not include the polyfills in default bundles.
  • Lazy loads polyfills only if needed
  • Delays Nuxt initialization if and only if polyfills are required.
  • npm install nuxt-polyfill
    

    Add the module to your 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',
    

    Disclaimer: I made it.

    For anyone using this options, I needed enter a detect method (in my case for Array.from: detect: () => !Array.from) for it to work, otherwise it wasn't loaded at all I think, or it assumed the native implementation was there on the server side so it didn't include it on the client side. – Lumocra Apr 29, 2019 at 14:58 @Lumocra Could you share your whole solution ? We cannot seem to be able to make it work for Array.from – Scriptodude May 1, 2019 at 19:34 @Lumocra @Scriptodude If you do not supply a detect function, the polyfill will always be included and ran. But keep in mind that this happens when the first plugins start to run. So you need to make sure you only use the polyfill in default exported functions of plugins, computed properties or methods of components, any getter, mutation or action of vuex stores, etc. You can't just use it in the global path of the script because it's not polyfilled at that time. – Tim May 3, 2019 at 6:42 @Scriptodude In nuxt.config.js: polyfill: { features: [ ..., { require: 'array-from', detect: () => !Array.from }, ... ] }, – Lumocra May 7, 2019 at 12:10 But I still have to manually add each polyfill? It can't detect which are needed based on the features in my code? – Oli Jan 7, 2020 at 22:16

    I am using nuxt 2.x, and the fix is quite simple, you just need to add transpile in nuxt.config.js

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

    Thanks for contributing an answer to Stack Overflow!

    • Please be sure to answer the question. Provide details and share your research!

    But avoid

    • Asking for help, clarification, or responding to other answers.
    • Making statements based on opinion; back them up with references or personal experience.

    To learn more, see our tips on writing great answers.