Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gatsby-remark-autolink-headers: SSR assumes let keyword is available #21058

Closed
ivan-aksamentov opened this issue Jan 30, 2020 · 0 comments · Fixed by #21083
Closed

gatsby-remark-autolink-headers: SSR assumes let keyword is available #21058

ivan-aksamentov opened this issue Jan 30, 2020 · 0 comments · Fixed by #21083

Comments

@ivan-aksamentov
Copy link
Contributor

ivan-aksamentov commented Jan 30, 2020

I opened PR with a fix here:
#21083

Description

I initially encountered this error while porting https://nextstrain.org to IE:
nextstrain/nextstrain.org#113

When gatsby-remark-autolink-headers is enabled, Internet Explorer 10-11 will fail with

SCRIPT1004: Expected ';' 

pointing to the line 6 in the snippet below:

    document.addEventListener("DOMContentLoaded", function(event) {
      var hash = window.decodeURI(location.hash.replace('#', ''))
      if (hash !== '') {
        var element = document.getElementById(hash)
        if (element) {
/* line 6: */  let scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
          let clientTop = document.documentElement.clientTop || document.body.clientTop || 0
          var offset = element.getBoundingClientRect().top + scrollTop - clientTop
          // Wait for the browser to finish rendering before scrolling.
          setTimeout((function() {
            window.scrollTo(0, offset - 0)
          }), 0)
        }
      }

As you see, the code contains let keyword and is not properly transpiled (Or, also, you know, not minimized and whatnot ;) )

The snippet comes from a string hardcoded in packages/gatsby-remark-autolink-headers/src/gatsby-ssr.js:

const script = `
document.addEventListener("DOMContentLoaded", function(event) {
var hash = window.decodeURI(location.hash.replace('#', ''))
if (hash !== '') {
var element = document.getElementById(hash)
if (element) {
let scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
let clientTop = document.documentElement.clientTop || document.body.clientTop || 0
var offset = element.getBoundingClientRect().top + scrollTop - clientTop
// Wait for the browser to finish rendering before scrolling.
setTimeout((function() {
window.scrollTo(0, offset - ${offsetY})
}), 0)
}
}
})
`

Note that the browser version does not contain let:
Note that the browser version does contain let too, but is transpiled correctly into var. Here is the source:

const getTargetOffset = hash => {
const id = window.decodeURI(hash.replace(`#`, ``))
if (id !== ``) {
const element = document.getElementById(id)
if (element) {
let scrollTop =
window.pageYOffset ||
document.documentElement.scrollTop ||
document.body.scrollTop
let clientTop =
document.documentElement.clientTop || document.body.clientTop || 0
return (
element.getBoundingClientRect().top + scrollTop - clientTop - offsetY
)
}
}
return null
}

Steps to reproduce

Open Gatsby-generated HTML with Internet Explorer (any version) or any other browser that does not support let keyword.

Expected result

There should be no errors in console and page should be rendered in the browser.

Actual result

There is an error in console and page is not rendered in the browser.

Environment

  System:
    OS: Linux 5.3 Ubuntu 18.04.3 LTS (Bionic Beaver)
    CPU: does not matter
    Shell: does not matter
  Binaries:
    Node: 12.14.1 - ~/.nvm/versions/node/default/bin/node
    Yarn: 1.21.1 - ~/.nvm/versions/node/default/bin/yarn
    npm: 6.13.7 - ~/.nvm/versions/node/default/bin/npm
  Languages:
    Python: 2.7.17 - /home/ia/.pyenv/shims/python
  npmPackages:
    gatsby: ^2.18.21 => 2.18.21
    gatsby-plugin-catch-links: ^2.1.24 => 2.1.24
    gatsby-plugin-feed: ^2.3.26 => 2.3.26
    gatsby-plugin-google-analytics: ^2.1.32 => 2.1.32
    gatsby-plugin-google-fonts: ^1.0.1 => 1.0.1
    gatsby-plugin-manifest: ^2.2.37 => 2.2.37
    gatsby-plugin-nprogress: ^2.1.18 => 2.1.18
    gatsby-plugin-offline: ^3.0.31 => 3.0.31
    gatsby-plugin-react-helmet: ^3.1.21 => 3.1.21
    gatsby-plugin-sharp: ^2.3.13 => 2.3.13
    gatsby-plugin-sitemap: ^2.2.25 => 2.2.25
    gatsby-plugin-styled-components: ^3.1.17 => 3.1.17
    gatsby-plugin-twitter: ^2.1.18 => 2.1.18
    gatsby-remark-autolink-headers: ^2.1.23 => 2.1.23
    gatsby-remark-copy-linked-files: ^2.1.36 => 2.1.36
    gatsby-remark-images: ^3.1.42 => 3.1.42
    gatsby-remark-prismjs: ^3.3.30 => 3.3.30
    gatsby-remark-responsive-iframe: ^2.2.31 => 2.2.31
    gatsby-remark-smartypants: ^2.1.20 => 2.1.20
    gatsby-source-filesystem: ^2.1.46 => 2.1.46
    gatsby-transformer-remark: ^2.6.48 => 2.6.48

gatsbybot pushed a commit that referenced this issue Jan 31, 2020
…21083)

* fix(gatsby-remark-autolink-headers): remove hardcoded "let" keyword

This resolves #21058

In `gatsby-remark-autolink-headers`, this code snippet https://github.com/gatsbyjs/gatsby/blob/5e7ccd13f79e54036869a72e423bf7cf4ab486af/packages/gatsby-remark-autolink-headers/src/gatsby-ssr.js#L51-L67
contains 2 instances of hardcoded "let" keyword, which  is being rendered into the HTML without transpilation. This makes the script crash in old browsers, such as IE (all versions).

This commit replaces "let" to "var". Care should be taken because this is an unsafe transformation, due to var scope hoisting. My initial tests show that everything is good.

I initially encountered this error while porting https://nextstrain.org to IE: nextstrain/nextstrain.org#113

This fix should help scientists researching 2019-nCoV outbreak (some of them still use Internet Explorer)

* fix(gatsby-remark-autolink-headers): add a comment explaining "let" keyword removal

#21058
#21083
ehowey pushed a commit to ehowey/gatsby that referenced this issue Jan 31, 2020
…atsbyjs#21083)

* fix(gatsby-remark-autolink-headers): remove hardcoded "let" keyword

This resolves gatsbyjs#21058

In `gatsby-remark-autolink-headers`, this code snippet https://github.com/gatsbyjs/gatsby/blob/5e7ccd13f79e54036869a72e423bf7cf4ab486af/packages/gatsby-remark-autolink-headers/src/gatsby-ssr.js#L51-L67
contains 2 instances of hardcoded "let" keyword, which  is being rendered into the HTML without transpilation. This makes the script crash in old browsers, such as IE (all versions).

This commit replaces "let" to "var". Care should be taken because this is an unsafe transformation, due to var scope hoisting. My initial tests show that everything is good.

I initially encountered this error while porting https://nextstrain.org to IE: nextstrain/nextstrain.org#113

This fix should help scientists researching 2019-nCoV outbreak (some of them still use Internet Explorer)

* fix(gatsby-remark-autolink-headers): add a comment explaining "let" keyword removal

gatsbyjs#21058
gatsbyjs#21083
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant