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

[build error] skipping server-sided rendering for a react component using react-router (Spectacle) #401

Closed
kwangkim opened this issue Aug 21, 2016 · 9 comments

Comments

@kwangkim
Copy link

I am adding a spectacle presentation as a js file.
It works very well with develop mode.
But I got an error when I built it.

Failed at generating HTML                                                                   

/Users/devkwang/dev/gatsby/slide/node_modules/gatsby/dist/bin/cli.js:52                     
      throw err;                                                                            
      ^                                                                                     
Error: Error: Minified exception occurred; use the non-minified dev environment for the full
 error message and additional helpful warnings.                                             
    at Object.invariant [as default] (render-page.js:20674:16)                              
    at createHashHistory (render-page.js:20990:130)                                         
    at Object.defineProperty.value (render-page.js:85078:48)                                
    at __webpack_require__ (render-page.js:30:30)                                           
    at Object.defineProperty.value (render-page.js:84870:20)                                
    at __webpack_require__ (render-page.js:30:30)                                           
    at Object.defineProperty.value (render-page.js:48672:19)                                
    at __webpack_require__ (render-page.js:30:30)                                           
    at Object.defineProperty.value (render-page.js:48355:19)                                
    at __webpack_require__ (render-page.js:30:30)    

I think spectacle does not allow server-side rendering since it uses hashHistory.
Is there anyway to skip server-side rendering to avoid above problem?

@KyleAMathews
Copy link
Contributor

Is there some way you could add Spectacle in "componentDidMount"?
On Sun, Aug 21, 2016 at 10:55 AM kwangkim notifications@github.com wrote:

I am adding a spectacle presentation as a js file.
It works very well with develop mode.
But I got an error when I built it.

Failed at generating HTML

/Users/devkwang/dev/gatsby/slide/node_modules/gatsby/dist/bin/cli.js:52
throw err;
^
Error: Error: Minified exception occurred; use the non-minified dev environment for the full
error message and additional helpful warnings.
at Object.invariant as default
at createHashHistory (render-page.js:20990:130)
at Object.defineProperty.value (render-page.js:85078:48)
at webpack_require (render-page.js:30:30)
at Object.defineProperty.value (render-page.js:84870:20)
at webpack_require (render-page.js:30:30)
at Object.defineProperty.value (render-page.js:48672:19)
at webpack_require (render-page.js:30:30)
at Object.defineProperty.value (render-page.js:48355:19)
at webpack_require (render-page.js:30:30)

I think spectacle does not allow server-side rendering since it uses
hashHistory.
Is there anyway to skip server-side rendering to avoid above problem?


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
#401, or mute the thread
https://github.com/notifications/unsubscribe-auth/AAEVhyH_BJ9g-GTxs5bKjtANp9hninTHks5qiJELgaJpZM4JpWS1
.

@KyleAMathews
Copy link
Contributor

Also a more convoluted way is to render the presentation in its own react
root.
On Sun, Aug 21, 2016 at 10:57 AM Kyle Mathews mathews.kyle@gmail.com
wrote:

Is there some way you could add Spectacle in "componentDidMount"?
On Sun, Aug 21, 2016 at 10:55 AM kwangkim notifications@github.com
wrote:

I am adding a spectacle presentation as a js file.
It works very well with develop mode.
But I got an error when I built it.

Failed at generating HTML

/Users/devkwang/dev/gatsby/slide/node_modules/gatsby/dist/bin/cli.js:52
throw err;
^
Error: Error: Minified exception occurred; use the non-minified dev environment for the full
error message and additional helpful warnings.
at Object.invariant as default
at createHashHistory (render-page.js:20990:130)
at Object.defineProperty.value (render-page.js:85078:48)
at webpack_require (render-page.js:30:30)
at Object.defineProperty.value (render-page.js:84870:20)
at webpack_require (render-page.js:30:30)
at Object.defineProperty.value (render-page.js:48672:19)
at webpack_require (render-page.js:30:30)
at Object.defineProperty.value (render-page.js:48355:19)
at webpack_require (render-page.js:30:30)

I think spectacle does not allow server-side rendering since it uses
hashHistory.
Is there anyway to skip server-side rendering to avoid above problem?


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
#401, or mute the thread
https://github.com/notifications/unsubscribe-auth/AAEVhyH_BJ9g-GTxs5bKjtANp9hninTHks5qiJELgaJpZM4JpWS1
.

@kwangkim
Copy link
Author

Unfortunately, it does not work.
By adding import {Spectacle} from 'spectacle' , I got same error.

import React from 'react'
import DocumentTitle from 'react-document-title'
import { config } from 'config'
import {Spectacle} from 'spectacle' //error!

export default class ReactComponent extends React.Component {
  constructor() {
    super()
  }
  render() {
    return (
      <DocumentTitle title={`${config.siteTitle} | React.js components`}>
      </DocumentTitle>
    )
  }
}

I am making a lecture note (presentation) site which includes many presentations.

@KyleAMathews
Copy link
Contributor

Try require.ensure. This is a more advanced technique but basically it let's you load code on demand. Wrapping the require of spectacle in this should ensure the code that's dying on the server isn't loaded until the client. Would be very interested to see if this works out.

You can read more about it here https://webpack.github.io/docs/code-splitting.html

Gatsby will be using it soonish to split code on larger sites #10

Try something like:

let Spectacle
export default class ReactComponent extends React.Component {
  componentDidMount () {
    require.ensure([], function(require) {
      { Spectacle } = require("spectacle");
    });
  }

  render () {
    if (Spectacle) {
      return (
        <Spectacle />
      )
    } else {
      return (
        <div />
      )
    }
  }
}

@kwangkim
Copy link
Author

It works very well with a minor modification.

import React from 'react'
import DocumentTitle from 'react-document-title'
import { config } from 'config'
let MySlide ;
export default class ReactComponent extends React.Component {
  constructor () {
    super()
    this.state = { mount : false } //To rerender
  }
  componentDidMount () {
    //require.ensure([], function(require) {
       MySlide = require("../client/myslide.js");
    //});
    this.setState( { mount : true }); //To rerender.
  }
  render () {
    if (MySlide !== undefined ) {
      return (
        <MySlide/>
      )
    } else {
      return (
        null
      )
    }
  }
}

require.ensure did not work with develop and build command I also added a dummy state to re-render.

Error: ReferenceError: window is not defined                                                
    at Object.assign.i (render-page.js:13:37)                                               
    at render-page.js:104:10                                                                
    at webpackUniversalModuleDefinition (render-page.js:3:20)                               
    at render-page.js:10:3                                                                  
    at ContextifyScript.Script.runInContext (vm.js:35:29)                                   
    at ContextifyScript.Script.runInNewContext (vm.js:41:15)                                
    at module.exports (/Users/devkwang/dev/gatsby/slide/node_modules/eval/eval.js:62:12)    
    at Compiler.<anonymous> (/Users/devkwang/dev/gatsby/slide/node_modules/static-site-gener
ator-webpack-plugin/index.js:31:20)                                                         
    at Compiler.applyPluginsAsync (/Users/devkwang/dev/gatsby/slide/node_modules/tapable/lib
/Tapable.js:71:13)                                                                          
    at Compiler.emitAssets (/Users/devkwang/dev/gatsby/slide/node_modules/webpack/lib/Compil
er.js:226:7) 

If I find a better way, I will post it later.
Thank you very much for your advise.

@KyleAMathews
Copy link
Contributor

Great! Please do post if you make any more improvements.

Closing this issue for now...

@cescoferraro
Copy link

Use the react-async-component and defer the loading for the client only

@kripod
Copy link
Contributor

kripod commented Oct 21, 2017

Is there a better solution since the release of Gatsby v1? I think there should be a way to exclude specific pages from the server-side rendering process. Modifying the createPage API could provide a solution, I guess...

@aprilmintacpineda
Copy link

I'm getting this error on build with react-router. I tried:

import { GatsbyNode } from 'gatsby';

export const onCreateWebpackConfig: GatsbyNode['onCreateWebpackConfig'] =
  ({ stage, loaders, actions }) => {
    if (stage === 'build-html') {
      actions.setWebpackConfig({
        module: {
          rules: [
            {
              test: /react-router/,
              use: loaders.null()
            }
          ]
        }
      });
    }
  };

but now I'm getting:

Building static HTML failed for path "/[...]/"

See our docs page for more info on this error: https://gatsby.dev/debug-html


  60 |       var before;
  61 |
> 62 |       if (_this.tags.length === 0) {
     | ^
  63 |         if (_this.insertionPoint) {
  64 |           before = _this.insertionPoint.nextSibling;
  65 |         } else if (_this.prepend) {


  WebpackError: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got:
   undefined.

  - emotion-sheet.esm.js:62
    [@internal]/[@emotion]/sheet/dist/emotion-sheet.esm.js:62:1

  - emotion-sheet.esm.js:63
    [@internal]/[@emotion]/sheet/dist/emotion-sheet.esm.js:63:1

  - emotion-sheet.esm.js:66
    [@internal]/[@emotion]/sheet/dist/emotion-sheet.esm.js:66:1

  - emotion-sheet.esm.js:65
    [@internal]/[@emotion]/sheet/dist/emotion-sheet.esm.js:65:11

  - emotion-sheet.esm.js:63
    [@internal]/[@emotion]/sheet/dist/emotion-sheet.esm.js:63:1

  - useAutocomplete.js:15
    [@internal]/[@mui]/base/useAutocomplete/useAutocomplete.js:15:1

  - emotion-sheet.esm.js:63
    [@internal]/[@emotion]/sheet/dist/emotion-sheet.esm.js:63:1

  - emotion-sheet.esm.js:55
    [@internal]/[@emotion]/sheet/dist/emotion-sheet.esm.js:55:1

  - emotion-sheet.esm.js:57
    [@internal]/[@emotion]/sheet/dist/emotion-sheet.esm.js:57:1

  - emotion-sheet.esm.js:63
    [@internal]/[@emotion]/sheet/dist/emotion-sheet.esm.js:63:1

  - emotion-sheet.esm.js:66
    [@internal]/[@emotion]/sheet/dist/emotion-sheet.esm.js:66:1

  - emotion-sheet.esm.js:65
    [@internal]/[@emotion]/sheet/dist/emotion-sheet.esm.js:65:11

  - emotion-sheet.esm.js:63
    [@internal]/[@emotion]/sheet/dist/emotion-sheet.esm.js:63:1

  - useAutocomplete.js:15
    [@internal]/[@mui]/base/useAutocomplete/useAutocomplete.js:15:1

  - emotion-sheet.esm.js:63
    [@internal]/[@emotion]/sheet/dist/emotion-sheet.esm.js:63:1

  - emotion-sheet.esm.js:57
    [@internal]/[@emotion]/sheet/dist/emotion-sheet.esm.js:57:1

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

No branches or pull requests

5 participants