gatsbyjs / gatsby

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

Horizontal-Page-Progress - Error Static html build #10175

Closed dorukde closed 5 years ago

dorukde commented 5 years ago

Description

intro: I am quite new to JS + React + Gatsby and happened to meet Gatsby through a 'React for Designers' course. The course content was quite good overall, but not up-do-date for sure. So, I started with Gatsby v1, and everything works fine (tried to migrate to v2 and found it to be an overkill at this stage when having errors - maybe later). I updated gatsby version, and things still work. So, I left it as it is (using old layout index.js & structure)

I am trying to have a horizontal progress bar that shows the vertical-scroll progression (similar to medium.com, and many other sites. I lost myself in the wild world of npm libraries and found 'horizontal-page-progress' to be working. I have 2 different headers and one of them displays the horizontal-page-progress. Whenever I 'gatsby develop' things work, but 'gatsby build' is a sad story.

Steps to reproduce

link to project: https://github.com/dorukde/ux-portfolio

Step 1: On 'about.js' Page, I added the lines

import HorizontalPageProgress from 'react-horizontal-page-progress' and <HorizontalPageProgress height="10px" backgroundColor="#00ff99" /> under the div 'HeroAbout2'

Expected result

I see the progress bar working at times and I sometimes get nothing after 'gatsby develop' and re-run it, and voila... However, I cannot build and see any result.

Actual result

The error message is as follows:

Error Building static HTML for pages failed

See our docs page on debugging HTML builds for help https://goo.gl/yL9lND

  342 | module.exports = function(list, options) {
  343 |     if (typeof DEBUG !== "undefined" && DEBUG) {
> 344 |         if (typeof document !== "object") throw new Error("The style-loader cannot be used in a non-browser environment");
      | ^
  345 |     }
  346 | 
  347 |     options = options || {};

  WebpackError: The style-loader cannot be used in a non-browser environment

  - index.js:344 module.exports.module.exports [as exports]
    ~/react-horizontal-page-progress/build/index.js:344:1

  - index.js:85 Object.<anonymous>
    ~/react-horizontal-page-progress/build/index.js:85:1

  - index.js:21 __webpack_require__
    ~/react-horizontal-page-progress/build/index.js:21:1

  - index.js:124 Object.<anonymous>
    ~/react-horizontal-page-progress/build/index.js:124:1

  - index.js:21 __webpack_require__
    ~/react-horizontal-page-progress/build/index.js:21:1

  - index.js:67 
    ~/react-horizontal-page-progress/build/index.js:67:1

  - index.js:70 Object.exports.__esModule
    ~/react-horizontal-page-progress/build/index.js:70:1

  - about.js:8 Object.exports.__esModule
    src/pages/about.js:8:1

Environment


  System:
    OS: macOS 10.14.1
    CPU: (8) x64 Intel(R) Core(TM) i7-4870HQ CPU @ 2.50GHz
    Shell: 3.2.57 - /bin/bash
  Binaries:
    Node: 10.11.0 - /usr/local/bin/node
    npm: 6.4.1 - /usr/local/bin/npm
  Browsers:
    Chrome: 70.0.3538.110
    Firefox: 63.0.3
    Safari: 12.0.1
  npmPackages:
    gatsby: ^1.9.277 => 1.9.277 
    gatsby-link: ^1.6.46 => 1.6.46 
    gatsby-plugin-layout: ^1.0.9 => 1.0.9 
    gatsby-plugin-page-load-delay: ^0.1.2 => 0.1.2 
    gatsby-plugin-page-transitions: ^1.0.7 => 1.0.7 
    gatsby-plugin-react-helmet: ^2.0.11 => 2.0.11 
  npmGlobalPackages:
    gatsby-cli: 2.4.5
dorukde commented 5 years ago

I have made the leap and spent several beginner-hours to migrate everything I did on v1 to v2, hoping to find my way around. Here is the current situation on the ux-portfolio_v2 folder:

  1. I tested and used a differently-behaving scroll progress, it works this time on 'develop gatsby' (behaves strangely but fixable from .js itself).

  2. gatsby-plugin-page-transitions has crushed my 'gatsby build' - The plugin "gatsby-plugin-page-transitions@1.0.7" is exporting a variable named "replaceHistory" which isn't an API. This is surprising, as the structure is v2 is built considering this behaviour. Is there anybody who has solved this for full-screen transitions on layout.js ?

  3. Gatsby v2 will also require me re-think about using two different sets of header.js (or header.css) files, which requires other tweaks.

Anybody has found a way around this?

So, at this stage I could not solve my problem, but we know v2 comes without scroll-progress problem, but with a big problem about page-transitions.

dorukde commented 5 years ago

It look like I am talking to myself, which is fine for documentation purposes at least. Here we go with the log:

'react-momentum' seems to work with Gatsby v1 for scroll-progression, with the need of workarounds (adding more props, changing behaviour, etc.) for my specific project. Some comments about v2:

  1. The documentation seems to provide solutions for google-analytics (with a dead-link)
  2. The gatsby-page-transition plug-in page seems to provide solutions for v2, which is not supported. If I knew about these, I would not spend several learning-hours to migrate to v2.
  3. The presumption of changing behaviour for 'dynamic layouts' might not be beneficial for many users. My previous case involved a location based if-else logic for 2 different headers, wrapped around an animation. The differences of headers were not that simple either (involving different states and animations, etc.). A workaround with Gatsby styled-components plug-in would be neat (at least in the documentation for pure-beginners like me).
jonniebigodes commented 5 years ago

@dorukde No you're not talking to yourself. I've been keeping one eye on your issue while responding to other people. Probably tonight or tomorrow afternoon my time, i'll clone your repo, check the code and then help you with providing with a answer to your issue either via the plugin you are using or an alternative.

dorukde commented 5 years ago

@jonniebigodes I have progressed a bit more (thanks to Lekoarts on Discord chat) and have managed to keep v1 behaviour of the layout to v2 and maintain the page-transition animations using another library. So, after having reached the same stage, the problem still persists.

I could not manage to find a working scroll-reader for Gatsby. Horizontal scroll works on 'develop' but gives several errorrs, same with another package i found on npm.

This is the new repo (v2) that has the migrated v1, but without the scroll-slider Test_v2

dorukde commented 5 years ago

@jonniebigodes

I will need to find a way to implement the scroll-progression slider the best way possible (with my newbie skillset). I have tried many libraries but they either do not work at all, or do not work on Safari.

Following a jQuery tutorial about this seems easy to implement, but since I know very little about react-dom & babel, I feel confused looking at js files in relevant node_modules folders to fix problems (either with webpack or .window).

Considering the dependencies, do you think implementing this would be possible on Gatsby, or what the ideal approach should be?

https://codepen.io/masakiando/pen/bRmRXa

dorukde commented 5 years ago

Ok, finally sorted this out. I missed the 'rect' (needed some sleep). It looks ugly but it works. I have no clue how to turn this into a plug-in, but I will add an explainer here on how I solved it, in case other newbies want to implement.

dorukde commented 5 years ago

I was having trouble rendering Nothing renders as soon as I include that in the render. I will get a build and see it on Netlify soon.

I found that I was missing a very simple thing.

I guess we can close the issue. Thanks @jonniebigodes @dantehemerson I guess the previous problem was related with 'window.XXX' or webpack dependency issue. I will test the builds on different browsers too, but initial test was fine.

jonniebigodes commented 5 years ago

Sorry i wasn't much more of a help. But before we close this issue, some closing words that might help you out in the future. While using gatsby and ssr ( Server Side Rendering), in your component ManageScrollBar, i would recomend the following change to prevent issues that could arise further down the line.

import React, { Component } from 'react'
import PropTypes from 'prop-types'
import '../components/scroll.css'

class ScrollBar extends Component {
  render() {
    const { width, height } = this.props
    return (
      <div
        className="scrollbar"
        style={{
          border: 'solid 1px lightgray',
          height,
          backgroundColor: '#f4f6f9',
        }}
      >
        <div
          className="scrollbar"
          id="hoge"
          style={{
            width: `${width}%`,
            height,
            backgroundColor: '#40aa94',
          }}
        />
      </div>
    )
  }
}
ScrollBar.propTypes = {
  width: PropTypes.number.isRequired,
  height: PropTypes.numberisRequired,
}

ScrollBar.defaultProps = {
  height: 10,
  width: 0,
}

class ManageScrollBar extends Component {
  constructor(props) {
    super(props)
    this.state = {
      scrollY: 0,
      scrollBarRate: 0,
    }
    this.ScrollRateCalculation = this.ScrollRateCalculation.bind(this)
  }

  ScrollRateCalculation() {
    const innerHeight = window.innerHeight //A
    const scrollMax = Math.ceil(window.outerHeight - innerHeight)
    const scrollY =
      document.documentElement.scrollTop || document.body.scrollTop
    const scrollRate = parseInt((scrollY / scrollMax) * 100, 10)
    this.setState({
      scrollY: scrollY,
      scrollBarRate: scrollRate,
    })
  }

  componentDidMount() {
      // sanity check to see if the window object is accessible
      // as you don't have access to it in ssr(server side rendering) 
      // and will make you scratch your head and wonder why react will spit out errors left and right and prevent the component rendering
      if (typeof window !== 'undefined') {
          this.ScrollRateCalculation()
          document.addEventListener('scroll', this.ScrollRateCalculation)
          window.addEventListener('hashchange', this.ScrollRateCalculation)
          document.addEventListener('click', this.ScrollRateCalculation)
      }

  }
  // make sure to remove the listener
  // when the component is not mounted anymore
  // you don't need it, no need for lingering stuff
  componentWillUnmount() {
    if (typeof window !== 'undefined') {
      window.removeEventListener('resize', this.ScrollRateCalculation)
    }
  }

  render() {
    const {scrollBarRate}= this.state // destructuring is your new best friend, learn it, love it, breath it xD.
    return (
      <div>
        <ScrollBar className="scrollbar" width={scrollBarRate} />
      </div>
    )
  }
}

class Scroller extends Component {
  render() {
    return (
      <div>
        <ManageScrollBar />
      </div>
    )
  }
}

export default Scroller

Making this small adjustment, that sanity check, will help you solve some issues you might have in the future for the reason i stated above. Also and if you don't mind i'll leave this issue open a bit longer, at least until you check if it's all alright and up and running in Netlify. Thanks for using Gatsby 👍

dorukde commented 5 years ago

@jonniebigodes

It works here (need to have a very small window-size though). https://doruk2.netlify.com/app2/

I will be playing with it here and then call it for about page soon. As soon as I am done with the portfolio, I will be going back to refresh JS & increase React knowledge, and get back to this component and make it even smoother and bulletproof.

Thanks a lot!

jonniebigodes commented 5 years ago

No problem. Once again sorry i wasn't more of a help, and once more thanks for using gatsby 👍