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

ssr not working with webpack 4.0.0-beta1 #46

Closed
artemxgruden opened this issue Feb 14, 2018 · 17 comments
Closed

ssr not working with webpack 4.0.0-beta1 #46

artemxgruden opened this issue Feb 14, 2018 · 17 comments

Comments

@artemxgruden
Copy link

artemxgruden commented Feb 14, 2018

export const Layout = loadable( () => import( / webpackChunkName: "main.layout" / './components/layouts/container.mjs' ) )

first error:
loadable-components: modules entry is missing, your are probably missing loadable-components/babel

then I set in webpack server config:

module: {
    rules: [
      {
        test: /\.(js|mjs)$/,
        use: [
          { 
            loader: 'babel-loader', 
            options: { plugins: [  'loadable-components/babel', 'dynamic-import-node' ] }
          }
        ],
        exclude: /node_modules/
      }
    ]
  },

then another error:
Error: Cannot find module './components/layouts/container.mjs'

"devDependencies": {
    "babel-core": "^6.26.0",
    "babel-loader": "^7.1.2",
    "babel-plugin-dynamic-import-node": "^1.2.0",
    "webpack": "^4.0.0-beta.1",
    "webpack-cli": "^2.0.4",
    "webpack-node-externals": "^1.6.0"
  },
"dependencies": {
    "loadable-components": "^1.1.1",
    "prop-types": "^15.6.0",
    "react": "^16.2.0",
    "react-dom": "^16.2.0",
    "react-redux": "^5.0.6",
    "redux": "^4.0.0-beta.1",
    "styled-components": "^3.1.6"
  }

but all works with webpack 3.10.0

@gregberge
Copy link
Owner

I haven't tested Webpack 4 yet. Thanks for reporting!

@gregberge gregberge added the bug label Feb 15, 2018
@gregberge
Copy link
Owner

I tested it with Webpack 4 and it works, anyway it still in beta and loadable-components is not Webpack dependent so it should not be impacted. I hope your issue will be solved soon.

@artemxgruden
Copy link
Author

artemxgruden commented Feb 21, 2018

@neoziro
the problem appears when I use files with .mjs extensions ( webpack 4 parse them in a special way )

file c1.js

import { Component, createElement } from 'react'
export default props => createElement( 'p', {}, 'hello' )

file main.js

import { createElement } from 'react'
import loadable from 'loadable-components'
import { getLoadableState } from 'loadable-components/server'

const View = loadable( () => import( /* webpackChunkName: "main.view" */ './c1.js' ) )

const main = async () => {
  try {
    const loadableState = await getLoadableState( createElement( View ) )
    console.log( loadableState )

  } catch ( error ) {
    console.error( error )

  }
}

main()

output: DeferredState { tree: { children: [ [Object] ] } } - ok

file main.mjs

import * as React from 'react'
const createElement = React.default.createElement

import * as LoadableComponents from 'loadable-components'
const loadable = LoadableComponents.default.default

import * as LoadableComponentsServer from 'loadable-components/server'
const getLoadableState = LoadableComponentsServer.default.getLoadableState

const View = loadable( () => import( /* webpackChunkName: "main.view" */ './c1.js' ) )

const main = async () => {
  try {
    const loadableState = await getLoadableState( createElement( View ) )
    console.log( loadableState )

  } catch ( error ) {
    console.error( error )

  }
}

main()

which gives me

{ Error: loadable-components: modules entry is missing, your are probably missing `loadable-components/babel`
    at /Users/artemxgruden/projectsm2/node-views-provider-template/node_modules/loadable-components/dist/loadable-components.server.cjs.js:153:17
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:160:7)
    at Function.Module.runMain (module.js:703:11)
    at startup (bootstrap_node.js:190:16)
    at bootstrap_node.js:662:3 queryErrors: [ [Circular] ] }

my webpack 4 configuration for server:

const nodeExternals = require( 'webpack-node-externals' )

module.exports = ( { NODE_ENV, PORT, VIEW_TYPE, DATA_PROVIDER }, webpack, joinPath ) => ( {
  target: 'node',
  externals: [ nodeExternals() ],
  node: {
    __dirname: true
  },
  entry: {
    main: joinPath( `./unbundled/server/main.mjs` ),
    // main: joinPath( `./unbundled/server/main.js` ),
  },
  output: {
    path: joinPath( `./bundled/server/` ),
    filename: '[name].js',
  },
  resolve: {
    modules: [
      'node_modules',
      joinPath( './unbundled/' ),
    ],
    extensions: [ '.mjs', '.js', '.json' ],
  },
  devtool: 'source-map',
  optimization: {
    splitChunks: {
      chunks: 'all'
    }
  },
  plugins: [
    new webpack.DefinePlugin( {
      'process.env': {
        'NODE_ENV': JSON.stringify( NODE_ENV ),
        'PORT': JSON.stringify( PORT ),
        'RUNNING_ENV': JSON.stringify( 'SERVER' ),
        'DATA_PROVIDER': JSON.stringify( DATA_PROVIDER ),
        'VIEW_TYPE': JSON.stringify( VIEW_TYPE ) 
      }
    } ),
  ],

  module: {
    rules: [
      {
        test: /\.(js|mjs)$/,
        use: [
          { 
            loader: 'babel-loader', 
            options: { plugins: [  'loadable-components/babel' ] }
          }
        ],
      }
    ]
  },
} )

@gregberge gregberge reopened this Feb 21, 2018
@artemxgruden
Copy link
Author

@neoziro Hello!
Do you have any news?

@gregberge
Copy link
Owner

@artemxgruden no, I am sorry I don't see what could be the problem.

@jcardella
Copy link

Here's a link to a test project - https://github.com/gcardella/react-universal so you can understand the problem better.

src/server/render.js has the call to ${loadableState.getScriptTag()}

See comments in the webpack.server.config.js. I am not able to load components using ssr due to the error below:

Error on server:

 Error: Cannot find module "function (){return t("../home/Home")}".
0|server   |     at n (/Users/gcardella/Documents/projects/joe-website/dist/0.server.js:1:132)
0|server   |     at /Users/gcardella/Documents/projects/joe-website/dist/server.js:1:5008
0|server   |     at <anonymous>

webpack.server.config.js:

const nodeExternals = require('webpack-node-externals');
const path = require('path');

const srcPath = path.resolve(__dirname, 'src');
const distPath = path.resolve(__dirname, 'dist');

module.exports = {
  context: srcPath,
  entry: './server/index.js',
  output: {
    path: distPath,
    filename: 'server.js',
    publicPath: '/assets/'
  },
  target: 'node',
  node: {
    __dirname: false,
    __filename: false,
  },
  resolve: {
    modules: ['node_modules', 'src'],
    extensions: ['*', '.js', '.json']
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /(node_modules)/,
        loader: 'babel-loader',
        options: {
          presets: [
            ['env', {
              targets: {
                node: 8
              }
            }]
          ],
          /*  if I remove 'babel-plugin-dynamic-import-node', the page loads, the ssr code is there in view source, but I get an error in the client console: Uncaught Error: loadable-components state not found. You have a problem server-side. Please verify that you have called `loadableState.getScriptTag()` server-side. */
/* If I leave the babel-plugin-dynamic-import-node, the no pages load because of a server error: 
   Error: Cannot find module "function (){return t("../home/Home")}".  --- the contents of t("..") are the current route.
*/
          plugins: [ 'loadable-components/babel', 'babel-plugin-dynamic-import-node' ] 
        }
      },
      // ...
    ]
  },
  externals: nodeExternals()
};

@artemxgruden
Copy link
Author

artemxgruden commented Mar 21, 2018

@jcardella please check

@neoziro thank you, I have no problems with node 9.8.0, since node 9.6.0 has support dynamic import feature

module versions:
"webpack": "^4.1.1",
"webpack-cli": "^2.0.12",
"loadable-components": "^1.1.1",

I have no webpack configuration for server, only for client
and for client I have no babel-loader in module section of webpack configuration

module: {
    rules: [
      {
        test: /\.(js|mjs)$/,
        use: [
          { 
            loader: 'babel-loader', 
            options: { plugins: [  'loadable-components/babel' ] }
          }
        ],
      }
    ]
  },

@jcardella
Copy link

jcardella commented Mar 21, 2018

I have node -v 9.9.0 ... I don't think the problem is with loadable-components. I think the problem is with loadable-components/babel or babel-plugin-dynamic-import-node not being webpack 4 ready? If I rollback webpack to ver 3.x and loadable-components to ver 0.2.0, everything works without errors.

@gregberge
Copy link
Owner

babel-plugin-dynamic-import-node should not be used with Webpack.

For Webpack: only loadable-components/babel.
For Node: loadable-components/babel + babel-plugin-dynamic-import-node

@artemxgruden
Copy link
Author

artemxgruden commented Mar 29, 2018

hi @neoziro still not working when get ssr markup from node without webpack bundling
node version 9.10
loadable-components versions 1.1.1

c1.mjs

import * as React from 'react'
const createElement = React.default.createElement
export default props => createElement( 'p', {}, 'hello' )

main.mjs

// import initializeProvider from './initializeProvider.mjs'
// initializeProvider()

import * as React from 'react'
const createElement = React.default.createElement
const Component = React.default.Component

import * as ReactDOMServer from 'react-dom/server'
const renderToNodeStream = ReactDOMServer.default.renderToNodeStream
const renderToString = ReactDOMServer.default.renderToString
const renderToStaticMarkup = ReactDOMServer.default.renderToStaticMarkup
import * as LoadableComponentsServer from 'loadable-components/server'
const getLoadableState = LoadableComponentsServer.default.getLoadableState

import * as LoadableComponents from 'loadable-components'
const loadable = LoadableComponents.default.default

import c1 from './c1.mjs'
const c1l = loadable( () => import( /* webpackChunkName: "c1" */ './c1.mjs' ) )

console.info( c1l )
console.info( 'markup', renderToStaticMarkup( createElement( c1 ) ) )
console.info( 'markupl', renderToStaticMarkup( createElement( c1l ) ) )

log

{ [Function: LoadableComponent]
  load: [Function: load],
  Component: null,
  loadingPromise: null,
  '@@loadable-components/loadable': [Function] }
markup <p>hello</p>
markupl

markup is empty string

@gregberge
Copy link
Owner

You have to load components server-side using getLoadableState. Please follow the README for more documentation.

@artemxgruden
Copy link
Author

@neoziro thank you, my mistake

main.mjs now

import * as React from 'react'
const createElement = React.default.createElement
const Component = React.default.Component

import * as ReactDOMServer from 'react-dom/server'
const renderToNodeStream = ReactDOMServer.default.renderToNodeStream
const renderToString = ReactDOMServer.default.renderToString
const renderToStaticMarkup = ReactDOMServer.default.renderToStaticMarkup
import * as LoadableComponentsServer from 'loadable-components/server'
const getLoadableState = LoadableComponentsServer.default.getLoadableState

import * as LoadableComponents from 'loadable-components'
const loadable = LoadableComponents.default.default

const c1l = loadable( () => import( /* webpackChunkName: "c1" */ './c1.mjs' ), {
  modules: [ './c1.mjs' ],
} )

const main = async () => {
  const composition = createElement( c1l )
  getLoadableState( composition ).then( app => {
    console.info( 'markup', renderToString( composition ) )
  } ).catch( e => {
    console.log( e )
  } )

}

main()

webpack 4 config for node server

const nodeExternals = require( 'webpack-node-externals' )

module.exports = ( { NODE_ENV, PORT, VIEW_TYPE, MACHINE }, webpack, joinPath ) => ( {
  target: 'node',
  externals: [ nodeExternals( {
    whitelist: [
     
    ],
  } ) ],
  node: {
    __dirname: true
  },
  entry: {
    main: joinPath( `./unbundled/server/main.mjs` ),
  },
  output: {
    path: joinPath( `./bundled/server/` ),
    filename: '[name].js',
  },
  resolve: {
    modules: [
      'node_modules',
      joinPath( './unbundled/' )
    ],
    extensions: [ '.mjs', '.js', '.json' ],
  },
  devtool: 'source-map',
  optimization: {
    splitChunks: {
      chunks: 'all'
    }
  },
  plugins: [
    new webpack.DefinePlugin( {
      'process.env': {
        'NODE_ENV': JSON.stringify( NODE_ENV ),
        'PORT': JSON.stringify( PORT ),
        'RUNNING_ENV': JSON.stringify( 'SERVER' ),
        'MACHINE': JSON.stringify( MACHINE ),
        'VIEW_TYPE': JSON.stringify( VIEW_TYPE ) 
      }
    } ),
  ],

  module: {
    rules: [
      {
        test: /\.(js|mjs)$/,
        use: [
          { 
            loader: 'babel-loader', 
            options: { plugins: [ 'loadable-components/babel' ] },
          }
        ],
      }
    ]
  },
 
} )

"webpack": "^4.2.0",
"webpack-cli": "^2.0.13",
"babel-core": "^6.26.0",
"babel-loader": "^7.1.4"

@artemxgruden
Copy link
Author

@neoziro but I have error when running main.mjs without webpack bundling

Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object.
    in LoadableComponent
{ Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
    at invariant (/Users/artemxgruden/projectsm/cvz-nvp/node_modules/fbjs/lib/invariant.js:42:15)
    at ReactDOMServerRenderer.render (/Users/artemxgruden/projectsm/cvz-nvp/node_modules/react-dom/cjs/react-dom-server.node.development.js:2482:7)
    at ReactDOMServerRenderer.read (/Users/artemxgruden/projectsm/cvz-nvp/node_modules/react-dom/cjs/react-dom-server.node.development.js:2312:19)
    at renderToString (/Users/artemxgruden/projectsm/cvz-nvp/node_modules/react-dom/cjs/react-dom-server.node.development.js:2684:25)
    at getLoadableState.then.app (file:///Users/artemxgruden/projectsm/cvz-nvp/functions/unbundled/server/main.mjs:25:29)
    at <anonymous> name: 'Invariant Violation', framesToPop: 1 }

@artemxgruden
Copy link
Author

artemxgruden commented Mar 30, 2018

@neoziro Please add support for new getDerivedStateFromProps react 16.3 method
https://reactjs.org/docs/react-component.html#static-getderivedstatefromprops to next version

@artemxgruden
Copy link
Author

artemxgruden commented Mar 30, 2018

@neoziro Please up static methods of wrapped components.
I have my own lib, and I added such fix especially for using with loadable-components:

c - ƒ LoadableComponent()

if ( c && c.Component && c.Component.preloadDataState && Object.prototype.toString.call( c.Component.preloadDataState === '[object AsyncFunction]' ){
...
}

@gregberge
Copy link
Owner

@artemxgruden I do not understand the last one. Can you describe it completely in a different issue?

@artemxgruden
Copy link
Author

@neoziro #58

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

3 participants