gatsbyjs / gatsby

The best React-based framework with performance, scalability and security built in.
https://www.gatsbyjs.com
MIT License
55.24k stars 10.32k forks source link

Gatsby's Use Of Polyfills and the 'Missing Resources for x' error #12399

Closed Undistraction closed 5 years ago

Undistraction commented 5 years ago

Description

I've just been through the incredibly painful process of getting a Gatsby site working in IE 11 and thought it was worth writing up the problems I faced due to Gatsby's current architecture.

We were receiving an error for every page in IE:

Can't find resource for ...

There was no other error. The pages loaded fine in all the other browsers we tested, so my hunch was that Gatsby was swallowing some kind of IE-specific error.

After a lot of digging I eventually tracked the point of failure to Gatsby's loader, specifically, this line.

.catch(() => {
   failed = true
})

Inspecting the value passed to the catch I could see that the error was related to something that needed to be polyfilled. The problem here being that Gatsby was swallowing this useful error and giving me nothing to help me pinpoint the issue. The resource wasn't missing - it was just erroring when the Loader tried to fetch it. It would make a lot of sense to error here with a more useful message, passing on the specific error that the loader had encountered.

This leads me on to the second issue. Gatsby uses babel-preset-env to handle polyfills, and by default useBuiltIns is set to usage. This sounds great on the surface, but masks what I would consider to be a big problem. If any third-party modules need polyfilling, it seems that Gatsby will not add the Polyfills they need. It will add polyfill imports to project-based code, but will not add imports to non-project-based code. This means if a third-part module was published with useBuiltIns set to entry, it appears that Gatsby will not include the expected babel-polyfill import and replace with the necessary polyfill imports. This means that if a third-party library needs a polyfill that hasn't been supplied due usage within the gatsby project, then this polyfill will not be included. In my case it was a dependency of another dependency.

Combined with the first issue, this was nightmarishly hard to debug.

I'd also suggest adding a section to the browser support docs that makes it clear that Gatsby's declared browser support is only for production builds. I spent a good deal of time trying to debug IE locally before realising that Gatsby doesn't support IE11 when running in development. I eventually found the docs for Gatsby's default babel preset which explained this, but I think these need to be much more prominent. To anyone encountering a similar issue, the only fix I've found is to manually include the entire babel-polyfill using:

// gatsby-browser.js

require('babel-polyfill')

exports.onClientEntry = () => {
  // Without this function body the import will not be picked up.
}

This is far from ideal as this includes a tonne of extra polyfills we don't need, but it at least fixes the problem in the short term.

I guess another option would be to switch Gatsby from using usage to entry so that the import will be replaced by only required polyfills. That appears to be possible by overriding Gatsby's default babel config.

The above is true as of "gatsby": "2.1.22"

KyleAMathews commented 5 years ago

Hey, sorry you had so much trouble :-( this is definitely something we should fix.

The problem I believe isn't Babel but the fact that we don't transpile node_modules. Which means that any code there which should be polyfilling, Babel doesn't see so doesn't add the polyfills.

DSchau commented 5 years ago

First of all - thanks for writing this up! We appreciate it, and as @KyleAMathews said, we're bummed to hear about the pain points you've been experiencing.

Let's dive into some of your points in a bit more detail, though!

Inspecting the value passed to the catch I could see that the error was related to something that needed to be polyfilled. The problem here being that Gatsby was swallowing this useful error and giving me nothing to help me pinpoint the issue. The resource wasn't missing - it was just erroring when the Loader tried to fetch it. It would make a lot of sense to error here with a more useful message, passing on the specific error that the loader had encountered.

Would you be interested in PRing a change for logging the error? I think this is a pretty non-intrusive change that will be impactful for a lot of users testing in e.g. IE 11.

If any third-party modules need polyfilling, it seems that Gatsby will not add the Polyfills they need. It will add polyfill imports to project-based code, but will not add imports to non-project-based code

This is correct, yeah. One thing we've considered is transpiling node_modules, but there are trade-offs there as well, primarily related to performance and possible redundancy. I believe create-react-app does this starting in v2, so it's certainly something we should investigate.

As @KyleAMathews notes though, babel-preset-env is only able to operate on userland code, e.g. your src/ directory. We'd need to start transpiling node_modules for the usage setting to be most valuable.

Finally:

I spent a good deal of time trying to debug IE locally before realising that Gatsby doesn't support IE11 when running in development

Would you happen to have any more info on what failed? I'd imagine we can include some polyfills in development only so that we can avoid this. We actually already do something similar here

In effect - we can absolutely harden our support for IE 11. We have some low-hanging fruit that can be PR'd to improve upon the development experience and alert of issues early. Longer term - transpiling node_modules may be a good solution for more of these issues.

Thanks for opening this!

Undistraction commented 5 years ago

Just one of those things. The fact Gatsby was building without error, then swallowing the runtime error was what made it really horrible to debug, so I think that would be a useful fix.

In the short term what would you think the best approach is to involve including the whole of babel-polyfill just to cover node modules that need to be polyfilled? Do you think that overriding Gatsby's default Babel config and using entry instead is the best approach?

DSchau commented 5 years ago

In the short term what would you think the best approach is to involve including the whole of babel-polyfill just to cover node modules that need to be polyfilled?

Do you mean for your particular use case, or globally? I can chime in on #12409 with some more thoughts.

Undistraction commented 5 years ago

@DSchau Sorry. Think we overlapped there.

Would you be interested in PRing a change for logging the error? I think this is a pretty non-intrusive > change that will be impactful for a lot of users testing in e.g. IE 11.

Yes of course. I'll try and make some time this week.

Would you happen to have any more info on what failed? I'd imagine we can include some polyfills in > development only so that we can avoid this. We actually already do something similar here

My understanding from the docs for babel-preset-gatsby is that Gatsby conciously doesn't support IE in development. It says of its default targets:

defaults to { "browsers": ["last 4 versions", "safari >= 7", "ie >= 9"] } in production and { "browsers": ["last 2 versions", "not ie <= 11", "not android 4.4.3"] } in development when targeting the browser.

So in terms of polyfilling userland code, I guess the solution is to support the same in development as in production, or at least provide a simple way to add this support.

Do you mean for your particular use case, or globally? I can chime in on #12409 with some more thoughts.

Would be great to hear your thoughts for the best way to handle this in my case. I definitely have multiple node_modules that need to be polyfilled. Not sure what the best approach there is. Is it to include babel-polyfill and override Gatsby's default babel config to make sure it uses entries so that it includes all polyfills for the specified range?

DSchau commented 5 years ago

I definitely have multiple node_modules that need to be polyfilled

The quickest here is to just conditionally enable transpilation on those modules, with a plugin like gatsby-plugin-compile-es6-modules.

You'd use it like so in gatsby-config.js:

module.exports = {
  plugins: [
    {
      resolve: `gatsby-plugin-compile-es6-packages`,
      options: {
        modules: [
          'module-1',
          'module-2',
          'module-you-get-the-idea'
        ]
      }
    }
  ]
}
Undistraction commented 5 years ago

@DSchau Thanks. That looks like a good option. Guess the problem there is how easy it would be for a new module that needs polyfilling to slip in as a dependency or sub-dependency without being added to the list.

DSchau commented 5 years ago

@Undistraction I suppose that will just require a little due diligence in ensuring that doesn't happen! You could probably automate the check with a CI task and some type of traversal of code you depend upon.

Is this happening fairly frequently? More specifically--which packages does this seem to be occurring in?

Undistraction commented 5 years ago

@DSchau Yep. That's a fair point. There were a few places I found it was happening. I was using Formik which in turn uses Yup. Yup uses methods on Set that need to be polyfilled for IE11. I was also using our own packages from NPM (from a monorepo). They are all transpiled with babel (with modules left as ES6 so Gatsby can use Tree Shaking). They use a few features that need to be polyfilled.

Undistraction commented 5 years ago

This is what I ended up doing:

I opted not to use gatsby-plugin-compile-es6-packages as I don't think this approach scales. It might if the only modules that were causing problems were top level dependencies, but given that it could be a module deep in the dependency tree that needs polyfilling, I feel this is an ineffective solution. I was also concerned with potential side-effects by transpiling third-party libraries.

I chose to go with using 'entry' instead because I can be sure that they correct polyfills will be present for my chosen browser range, regardless of whether those polyfills are needed within my gatsby project. The other option is to include the whole polyfill, but that will add ~100kb to your project.

  1. Create a .babelrc at the root of your gatsby project. This is based on gatsby's babel-preset-gatsby, however I couldn't get gatsby to recognise either babel.config.js or babelrc.js so I had to use a JSON format. Note that I've set debug to true for babel-preset-env which will output a lot of useful information including a list of which transforms are being applied and which polyfills have been used to replace your import '@babel/polyfill' :
    
    {
    "env": {
    "test": {
      "presets": [
        "@babel/preset-env",
        {
          "loose": true,
          "modules": "commonjs",
          "useBuiltIns": "entry",
          "targets": { "browsers": [">0.25%", "not dead"] }
        }
      ]
    }
    },
    "presets": [
    "babel-preset-gatsby",
    [
      "@babel/preset-env",
      {
        "debug": true,
        "loose": true,
        "modules": false,
        "useBuiltIns": "entry",
        "targets": { "browsers": [">0.25%", "not dead"] }
      }
    ]
    ],
    "plugins": [
    [
      "@babel/plugin-proposal-class-properties",
      {
        "loose": true
      }
    ],
    "babel-plugin-macros",
    "@babel/plugin-syntax-dynamic-import",
    [
      "@babel/plugin-transform-runtime",
      {
        "helpers": true,
        "regenerator": true
      }
    ]
    ]
    }

2. Add the following to `gatsby-browser.js` in the root of your gatsby project. Note that _you must use ES6 imports_ otherwise the polyfill will not be picked up.

import '@babel/polyfill'

// eslint-disable-next-line import/prefer-default-export export const onClientEntry = () => { // Without this function body the import will not be picked up. }



That should get things working. I'm not going to close this as I believe Gatsby's current approach is not the right one. It makes it very easy to end up with a broken site in some browsers just to make a relatively small size gain through using 'usage' instead of 'entry'. Personally I see this as a poor tradeoff, and most importantly an unexpected issue and one that is hard to debug.
DSchau commented 5 years ago

This is based on gatsby's babel-preset-gatsby, however I couldn't get gatsby to recognise either babel.config.js or babelrc.js

Did you try .babelrc.js? If that doesn't work--that's a bit concerning. If .babelrc works, though, then the .js variant should as well.

I was also concerned with potential side-effects by transpiling third-party libraries

You see our concern with us transpiling node_modules globally, then! Generally - I think this is pretty safe, but I see your point.

I'm not going to close this as I believe Gatsby's current approach is not the right one

Kinda agree with this. I think smart defaults but also allowing these defaults to be customized is the right approach. I like your idea in #12409 in re: to this.

Do you think a reasonable solution is to implement a PR that satisfies #12409 and improved documentation, here?

Undistraction commented 5 years ago

You see our concern with us transpiring node_modules globally, then! Generally - I think this is pretty safe, but I see your point.

I completely see your concern. I'm absolutely not being down on you guys. It's a tricky problem to solve, and getting into transpiling third party modules is a big thing and one that will bring its own batch of obscure issues.

Do you think a reasonable solution is to implement a PR that satisfies #12409 and improved documentation, here?

I think that would be helpful yes.

Undistraction commented 5 years ago

@DSchau I've created a repro showing the issue using 'entry' here: https://github.com/gatsbyjs/gatsby/issues/12640

dustinhorton commented 5 years ago

I'm experiencing this error but unsure which modules need transpilling—any tips on how to identify them?

arnars commented 5 years ago

@dustinhorton which error exactly?

I had the most luck with just uncommenting a lot of stuff, and then do gatsby build > gatsby serve (delete .cache and public before) and run in browserstack.

"serve": "rm -rf .cache ; rm -rf public ; gatsby build; gatsby serve"
dustinhorton commented 5 years ago

@arnars Error: Missing resources for <path>

arnars commented 5 years ago

@dustinhorton and others that come across this thread:

I have created a gist where I share my experiences when getting Gatsby to work with IE. https://gist.github.com/arnars/2bb1d81fc0955d57fe88a8348695f594

If you have any solutions that are not mentioned already, please feel free to share them.

hugo-marques-m3 commented 5 years ago

@dustinhorton and others that come across this thread:

I have created a gist where I share my experiences when getting Gatsby to work with IE. https://gist.github.com/arnars/2bb1d81fc0955d57fe88a8348695f594

If you have any solutions that are not mentioned already, please feel free to share them.

@arnars You're my hero. I needed to do this https://gist.github.com/arnars/2bb1d81fc0955d57fe88a8348695f594#include-babelpolyfill-in-your-webpackconfig but I thought it wasn't possible anymore. Thanks a lot.

StevenElberger commented 5 years ago

We're experiencing the missing resources error on all browsers, not just IE so this probably isn't just about polyfills. Any ideas on what else could cause this issue?

DSchau commented 5 years ago

@StevenElberger could you share a reproduction and/or the URL of the application?

StevenElberger commented 5 years ago

@DSchau we're seeing it happen on https://ritual.com/ but are having trouble reproducing this locally.

DSchau commented 5 years ago

Possibly some non-transpiled code is making its way into the browser and breaking builds (e.g. on older browsers without support for e.g. arrow functions).

Are you able to validate in those browsers? Or provide a certain browser that this happens in?

StevenElberger commented 5 years ago

I did see it reproduced with the latest Chrome version (73.0.3683.86).

List of browsers we're seeing this happen in:

Screen Shot 2019-04-04 at 3 06 34 PM
kristojorg commented 5 years ago

@StevenElberger I'm also seeing similar errors across multiple browsers, mobile safari being the most frequent. I can't reproduce locally and when I visit through simulator I'm getting no errors, so trying to figure out what this could be related to.

A day ago I disabled gatsby-plugin-offline and added gatsby-plugin-remove-serviceworker, and I haven't seen an error since. That was the only thing I could think of that might make certain loads fail and others not on any given browser.

smakosh commented 5 years ago

Workaround: https://github.com/gatsbyjs/gatsby/issues/13410#issuecomment-486306784

Undistraction commented 5 years ago

For anyone needing a quick fix, I found that the only solution that worked in all cases was to create a local plugin that adds all polyfills manually in its gatsby-browser.js. I then added that plugin as the very first plugin in gatsby-config.js.

This is pretty ugly, but it works in multiple cases where this error occurs and other solutions fail.

Note that it is not enough to put this in your project's gatsby-browser.js as that is loaded after any of your plugin's gatsby-browser.js files. There are some very confusing cases where loading polyfills after the import of a library that needs them can be problematic (react and react-dom I'm looking at you).

Also note that your local plugins are not transpiled by Gatsby so using entry as a way of autopopulating your polyfills won't work (unless you set up your own build step).

Here is mygatsby-browser.js for the default settings, obviously yours will need to be specific to your browser matrix. You can toggle babel-preset-env into debug mode and set it to entry, and it will output all the polyfills it is adding to the console.

import 'core-js/modules/es6.array.copy-within' // { "android":"4.4.3", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.array.fill' // { "android":"4.4.3", "ie":"11" }
import 'core-js/modules/es6.array.find' // { "android":"4.4.3", "ie":"11" }
import 'core-js/modules/es6.array.find-index' // { "android":"4.4.3", "ie":"11" }
import 'core-js/modules/es6.array.from' // { "android":"4.4.3", "chrome":"49", "ie":"11", "ios":"8" }
import 'core-js/modules/es7.array.includes' // { "android":"4.4.3", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.array.iterator' // { "android":"4.4.3", "ie":"11" }
import 'core-js/modules/es6.array.of' // { "android":"4.4.3", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.array.sort' // { "android":"4.4.3", "chrome":"49", "ios":"8" }
import 'core-js/modules/es6.array.species' // { "android":"4.4.3", "chrome":"49", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.date.to-json' // { "ios":"8" }
import 'core-js/modules/es6.date.to-primitive' // { "android":"4.4.3", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.function.has-instance' // { "android":"4.4.3", "chrome":"49", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.function.name' // { "ie":"11" }
import 'core-js/modules/es6.map' // { "android":"4.4.3", "chrome":"49", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.math.acosh' // { "android":"4.4.3", "ie":"11" }
import 'core-js/modules/es6.math.asinh' // { "android":"4.4.3", "ie":"11" }
import 'core-js/modules/es6.math.atanh' // { "android":"4.4.3", "ie":"11" }
import 'core-js/modules/es6.math.cbrt' // { "android":"4.4.3", "ie":"11" }
import 'core-js/modules/es6.math.clz32' // { "android":"4.4.3", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.math.cosh' // { "android":"4.4.3", "ie":"11" }
import 'core-js/modules/es6.math.expm1' // { "android":"4.4.3", "ie":"11" }
import 'core-js/modules/es6.math.fround' // { "android":"4.4.3", "ie":"11" }
import 'core-js/modules/es6.math.hypot' // { "android":"4.4.3", "ie":"11" }
import 'core-js/modules/es6.math.imul' // { "ie":"11" }
import 'core-js/modules/es6.math.log1p' // { "android":"4.4.3", "ie":"11" }
import 'core-js/modules/es6.math.log10' // { "android":"4.4.3", "ie":"11" }
import 'core-js/modules/es6.math.log2' // { "android":"4.4.3", "ie":"11" }
import 'core-js/modules/es6.math.sign' // { "android":"4.4.3", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.math.sinh' // { "android":"4.4.3", "ie":"11" }
import 'core-js/modules/es6.math.tanh' // { "android":"4.4.3", "ie":"11" }
import 'core-js/modules/es6.math.trunc' // { "android":"4.4.3", "ie":"11" }
import 'core-js/modules/es6.number.constructor' // { "android":"4.4.3", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.number.epsilon' // { "android":"4.4.3", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.number.is-finite' // { "ie":"11", "ios":"8", "opera":"57" }
import 'core-js/modules/es6.number.is-integer' // { "android":"4.4.3", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.number.is-nan' // { "ie":"11", "ios":"8", "opera":"57" }
import 'core-js/modules/es6.number.is-safe-integer' // { "android":"4.4.3", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.number.max-safe-integer' // { "android":"4.4.3", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.number.min-safe-integer' // { "android":"4.4.3", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.number.parse-float' // { "android":"4.4.3", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.number.parse-int' // { "android":"4.4.3", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.object.assign' // { "android":"4.4.3", "ie":"11", "ios":"8" }
import 'core-js/modules/es7.object.define-getter' // { "android":"4.4.3", "chrome":"49", "ie":"11", "ios":"8" }
import 'core-js/modules/es7.object.define-setter' // { "android":"4.4.3", "chrome":"49", "ie":"11", "ios":"8" }
import 'core-js/modules/es7.object.entries' // { "android":"4.4.3", "chrome":"49", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.object.freeze' // { "android":"4.4.3", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.object.get-own-property-descriptor' // { "android":"4.4.3", "ie":"11", "ios":"8" }
import 'core-js/modules/es7.object.get-own-property-descriptors' // { "android":"4.4.3", "chrome":"49", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.object.get-own-property-names' // { "android":"4.4.3", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.object.get-prototype-of' // { "android":"4.4.3", "ie":"11", "ios":"8" }
import 'core-js/modules/es7.object.lookup-getter' // { "android":"4.4.3", "chrome":"49", "edge":"17", "ie":"11", "ios":"8" }
import 'core-js/modules/es7.object.lookup-setter' // { "android":"4.4.3", "chrome":"49", "edge":"17", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.object.prevent-extensions' // { "android":"4.4.3", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.object.is' // { "ie":"11", "ios":"8", "opera":"57" }
import 'core-js/modules/es6.object.is-frozen' // { "android":"4.4.3", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.object.is-sealed' // { "android":"4.4.3", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.object.is-extensible' // { "android":"4.4.3", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.object.keys' // { "android":"4.4.3", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.object.seal' // { "android":"4.4.3", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.object.set-prototype-of' // { "android":"4.4.3", "ios":"8" }
import 'core-js/modules/es7.object.values' // { "android":"4.4.3", "chrome":"49", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.promise' // { "android":"4.4.3", "chrome":"49", "ie":"11", "ios":"8" }
import 'core-js/modules/es7.promise.finally' // { "android":"4.4.3", "chrome":"49", "edge":"17", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.reflect.apply' // { "android":"4.4.3", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.reflect.construct' // { "android":"4.4.3", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.reflect.define-property' // { "android":"4.4.3", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.reflect.delete-property' // { "android":"4.4.3", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.reflect.get' // { "android":"4.4.3", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.reflect.get-own-property-descriptor' // { "android":"4.4.3", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.reflect.get-prototype-of' // { "android":"4.4.3", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.reflect.has' // { "android":"4.4.3", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.reflect.is-extensible' // { "android":"4.4.3", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.reflect.own-keys' // { "android":"4.4.3", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.reflect.prevent-extensions' // { "android":"4.4.3", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.reflect.set' // { "android":"4.4.3", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.reflect.set-prototype-of' // { "android":"4.4.3", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.regexp.constructor' // { "android":"4.4.3", "chrome":"49", "edge":"17", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.regexp.flags' // { "android":"4.4.3", "edge":"17", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.regexp.match' // { "android":"4.4.3", "chrome":"49", "edge":"17", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.regexp.replace' // { "android":"4.4.3", "chrome":"49", "edge":"17", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.regexp.split' // { "android":"4.4.3", "chrome":"49", "edge":"17", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.regexp.search' // { "android":"4.4.3", "chrome":"49", "edge":"17", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.regexp.to-string' // { "android":"4.4.3", "chrome":"49", "edge":"17", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.set' // { "android":"4.4.3", "chrome":"49", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.symbol' // { "android":"4.4.3", "chrome":"49", "edge":"17", "ie":"11", "ios":"8" }
import 'core-js/modules/es7.symbol.async-iterator' // { "android":"4.4.3", "chrome":"49", "edge":"17", "ie":"11", "ios":"8", "safari":"11.1" }
import 'core-js/modules/es6.string.anchor' // { "ie":"11", "opera":"57" }
import 'core-js/modules/es6.string.big' // { "ie":"11", "opera":"57" }
import 'core-js/modules/es6.string.blink' // { "ie":"11", "opera":"57" }
import 'core-js/modules/es6.string.bold' // { "ie":"11", "opera":"57" }
import 'core-js/modules/es6.string.code-point-at' // { "android":"4.4.3", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.string.ends-with' // { "android":"4.4.3", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.string.fixed' // { "ie":"11", "opera":"57" }
import 'core-js/modules/es6.string.fontcolor' // { "ie":"11", "opera":"57" }
import 'core-js/modules/es6.string.fontsize' // { "ie":"11", "opera":"57" }
import 'core-js/modules/es6.string.from-code-point' // { "android":"4.4.3", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.string.includes' // { "android":"4.4.3", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.string.italics' // { "ie":"11", "opera":"57" }
import 'core-js/modules/es6.string.iterator' // { "android":"4.4.3", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.string.link' // { "ie":"11", "opera":"57" }
import 'core-js/modules/es7.string.pad-start' // { "android":"4.4.3", "chrome":"49", "ie":"11", "ios":"8" }
import 'core-js/modules/es7.string.pad-end' // { "android":"4.4.3", "chrome":"49", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.string.raw' // { "android":"4.4.3", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.string.repeat' // { "android":"4.4.3", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.string.small' // { "ie":"11", "opera":"57" }
import 'core-js/modules/es6.string.starts-with' // { "android":"4.4.3", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.string.strike' // { "ie":"11", "opera":"57" }
import 'core-js/modules/es6.string.sub' // { "ie":"11", "opera":"57" }
import 'core-js/modules/es6.string.sup' // { "ie":"11", "opera":"57" }
import 'core-js/modules/es6.typed.array-buffer' // { "android":"4.4.3", "chrome":"49", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.typed.int8-array' // { "android":"4.4.3", "chrome":"49", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.typed.uint8-array' // { "android":"4.4.3", "chrome":"49", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.typed.uint8-clamped-array' // { "android":"4.4.3", "chrome":"49", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.typed.int16-array' // { "android":"4.4.3", "chrome":"49", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.typed.uint16-array' // { "android":"4.4.3", "chrome":"49", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.typed.int32-array' // { "android":"4.4.3", "chrome":"49", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.typed.uint32-array' // { "android":"4.4.3", "chrome":"49", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.typed.float32-array' // { "android":"4.4.3", "chrome":"49", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.typed.float64-array' // { "android":"4.4.3", "chrome":"49", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.weak-map' // { "android":"4.4.3", "chrome":"49", "ie":"11", "ios":"8" }
import 'core-js/modules/es6.weak-set' // { "android":"4.4.3", "chrome":"49", "ie":"11", "ios":"8" }
import 'core-js/modules/web.timers' // { "android":"4.4.3", "chrome":"49", "edge":"17", "firefox":"64", "ie":"11", "ios":"8", "opera":"57", "safari":"11.1" }
import 'core-js/modules/web.immediate' // { "android":"4.4.3", "chrome":"49", "edge":"17", "firefox":"64", "ie":"11", "ios":"8", "opera":"57", "safari":"11.1" }
import 'core-js/modules/web.dom.iterable' // { "android":"4.4.3", "chrome":"49", "edge":"17", "firefox":"64", "ie":"11", "ios":"8", "opera":"57", "safari":"11.1" }

// eslint-disable-next-line import/prefer-default-export
export const onClientEntry = () => {
  // Without this function body the import will not be picked up.
}
jackhair commented 5 years ago

@Undistraction Does this solution not work just importing core-js as a whole?

Undistraction commented 5 years ago

@jackhair that would work, but you'd be including every polyfill provided by core-js in your build. With this approach you're only including the ones for your supported browsers which can be a big saving.

realgt commented 5 years ago

I originally fixed this issue with https://github.com/gatsbyjs/gatsby/issues/12399#issuecomment-473231797 but the 'Missing resources' errors popped back up after pulling in react-spring. Ultimately what worked for me was not needing to setup my own local plugin, but just adding a dependency to gatsby-plugin-compile-es6-packages and listing the modules needing transpiling there:

    {
      resolve: `gatsby-plugin-compile-es6-packages`,
      options: {
        modules: [
          `react-spring`, 
          `react-hot-loader`
        ]
      }
    }
dustinhorton commented 5 years ago

I wouldn't think you'd need react-hot-loader since that should only be used in dev?

Wish there was an easy way to figure out what to feed gatsby-plugin-compile-es6-packages…I've resorted to tossing in all my third -party deps.

jackhair commented 5 years ago

@dustinhorton Did throwing all your third-party deps into gatsby-plugin-compile-es6-packages resolve the issue of Missing Resources for you?

dustinhorton commented 5 years ago

@jackhair I haven't deployed yet—I'll report back when I can.

realgt commented 5 years ago

I wouldn't think you'd need react-hot-loader since that should only be used in dev?

Wish there was an easy way to figure out what to feed gatsby-plugin-compile-es6-packages…I've resorted to tossing in all my third -party deps.

right, but wanted IE passing first on my local dev

what i did was check IE console for errors, clicked into the offending line, and scrolled up until i saw what module was throwing them. wash and repeat.

gatsbot[bot] commented 5 years ago

Hiya!

This issue has gone quiet. Spooky quiet. 👻

We get a lot of issues, so we currently close issues after 30 days of inactivity. It’s been at least 20 days since the last update here.

If we missed this issue or if you want to keep it open, please reply here. You can also add the label "not stale" to keep this issue open!

As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request. Check out gatsby.dev/contributefor more information about opening PRs, triaging issues, and contributing!

Thanks for being a part of the Gatsby community! 💪💜

dustinhorton commented 5 years ago

still just hoping for a larger contributor to provide a path—i'd be happy to spend some time adding to the docs but don't want to mislead users.

wardpeet commented 5 years ago

https://github.com/gatsbyjs/gatsby/pull/14111 should fix polyfills for all dependencies so you don't need gatsby-plugin-compile-es6-packages anymore. I appreciate if you could test this and let me know of any bugs.

hugo-marques-m3 commented 5 years ago

14111 should fix polyfills for all dependencies so you don't need gatsby-plugin-compile-es6-packages anymore. I appreciate if you could test this and let me know of any bugs.

That sounds awesome @wardpeet. If I understand that correctly, that would solve the local packages polyfills issues. But will it allow us to include the polyfills that we want to include because one of our included scripts requires and uses it immediately on page load (polyfills that can't be added through gatsby-browser because it needs them before that runs)?

I guess we will just need to import the polyfills in the code and it would add them, right?

wardpeet commented 5 years ago

From gatsby@2.11.0 you don't have to do anything. We use @babel/preset-env to look for polyfills automatically based on your browserlist config (we have one by default, so don't worry if you haven't got one). That should be all, note that we only do this on production builds.

I'll close, please re-open if the issue hasn't got solved.

Undistraction commented 5 years ago

@wardpeet This is great news. Sorry I missed your original post.

Just to be absolutely clear, does this mean that if a package somewhere deep in the dependency tree needs a polyfill for the browserlist config configured for Gatsby, Gatsby will now inject the appropriate polyfill into that dependency's code?

Undistraction commented 5 years ago

@wardpeet This is great news. Thank you, and sorry I missed your original post.

Just to be absolutely clear, does this mean that if a package somewhere deep in the dependency tree needs a polyfill for the browserlist config configured for Gatsby, Gatsby will now inject the appropriate polyfill into that dependency's code?

Also, is there any way to enable this in development? We use browserstack to check dev builds as we work.

wardpeet commented 5 years ago

Just to be absolutely clear, does this mean that if a package somewhere deep in the dependency tree needs a polyfill for the browserlist config configured for Gatsby, Gatsby will now inject the appropriate polyfill into that dependency's code?

Yes, everything is ran by babel so everything get compiled into compatible sources. (if not, please let me know :smile:)

Also, is there any way to enable this in development? We use browserstack to check dev builds as we work.

I haven't really tested this but something along the lines of this should work in gatsby-node.js

exports.onCreateWebpackConfig = ({ actions, loaders, stage, getConfig }) => {
  if (stage !== 'develop') {
    return;
  }
  const config = getConfig()
  const originalJsRule = loaders.js();

  config.module.rules = [
    // Omit the default rule where test === '\.jsx?$'
    ...config.module.rules.filter(
      rule => String(rule.test).includes('js|mjs|jsx')
    ),

    // Recreate it with custom exclude filter
    {
      ...originalJsRule,
      exclude: new RegExp(originalJsRule.exclude.source.replace('|node_modules', ''))
    },
  ]

  // This will completely replace the webpack config with the modified object.
  actions.replaceWebpackConfig(config)
}

More info on this topic can be found https://www.gatsbyjs.org/docs/add-custom-webpack-config/

Undistraction commented 5 years ago

That's great. Thank you again. I'm assuming you opted to make this production only for performance reasons?

wardpeet commented 5 years ago

Yes, transpiling node_modules can get expensive depending on how many you have and how big they are. We want develop to be super fast. With modern builds we might re-iterate on this again.

Undistraction commented 5 years ago

Thanks for answering my questions.

dustinhorton commented 5 years ago

@wardpeet have you had a chance to look closer at getting your node_module polyfilling working in dev? trying to test locally in IE 11 with the above and no dice unfortunately.