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
I haven't tested Webpack 4 yet. Thanks for reporting!
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.
@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()
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()
{ 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' ] }
}
],
}
]
},
} )
@neoziro Hello!
Do you have any news?
@artemxgruden no, I am sorry I don't see what could be the problem.
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()
};
@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' ] }
}
],
}
]
},
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.
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
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
You have to load components server-side using getLoadableState. Please follow the README for more documentation.
@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"
@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 }
@neoziro Please add support for new getDerivedStateFromProps react 16.3 method
https://reactjs.org/docs/react-component.html#static-getderivedstatefromprops to next version
@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]' ){
...
}
@artemxgruden I do not understand the last one. Can you describe it completely in a different issue?