5.2.1 CRA.2.1+SSR+Typescript throws the following error
{ Invariant Violation: loadable: SSR requires@loadable/babel, please install it
at invariant (/Users/example-project/node_modules/@loadable/component/dist/loadable.cjs.js:13:15)
at new InnerLoadable (/Users/example-project/node_modules/@loadable/component/dist/loadable.cjs.js:131:9)
at processChild (/Users/example-project/node_modules/react-dom/cjs/react-dom-server.node.development.js:2748:14)
at resolve (/Users/example-project/node_modules/react-dom/cjs/react-dom-server.node.development.js:2714:5)
at ReactDOMServerRenderer.render (/Users/example-project/node_modules/react-dom/cjs/react-dom-server.node.development.js:3098:22)
at ReactDOMServerRenderer.read (/Users/example-project/node_modules/react-dom/cjs/react-dom-server.node.development.js:3057:29)
at renderToStaticMarkup (/Users/example-project/node_modules/react-dom/cjs/react-dom-server.node.development.js:3539:27)
at process (/Users/example-project/node_modules/react-apollo/react-apollo.umd.js:129:24) framesToPop: 1, name: 'Invariant Violation' }
Steps to reproduce the behavior:
https://github.com/followbl/loadable-components/tree/bug-ssr-loadable
in the examples SSR repo of loadable-components
yarn && yarn run build:web && yarn run build:server
At a minimum it should say the correct plugin to install @loadable/babel-plugin...however, even with the plugin installed, I'm still running in to the above error. If you comment out the loadable components in loadable-components/examples/server-side-rendering/src/client/routes.tsx and load the vanilla ones, it works fine. This very well could be an issue you in ts-loader or my tsconfig...but I have spent over a day on this bug and cannot think of what else might be causing this
https://github.com/followbl/loadable-components/tree/bug-ssr-loadable
yarn && yarn run build:web && yarn run build:server
one thing I should note, it's swallowing the error in the example repo, but I can verifiably reproduce the error in the production project we're currently utilizing this in.
Hello @followbl, I tried to run your project but without any success. The page "http://localhost:3006" is hanging forever and does not respond. You configuration is very complicated and I think I would not be able to help you. I can guide you to try to find a way to solve your problem:
Try to run Babel on your files, the error you are experiencing means that @loadable/babel-plugin does not run on your files.
Also be careful of using import loadable from '@loadable/component', it relies on loadable exactly like styled for emotion and styled-components.
@neoziro you're comments above have helped me continue my debugging. thank you 馃
So I've verified that it is indeed running through the @loadable/babel-plugin and I've narrowed it down to the fact that the hanging is froom the node stream not completing. It's hanging in both...
extractor.collectChunk and ChunkExtractorManager which I'm guessing are one in the same. looking in to why it...
@neoziro so I can now 100% reproduce it.
It has to do with my files containing @loadable/component imports that moved from .js to .tsx...simply just swapping out these file extensions works completely. Do you by chance know of anyone that's utilizing a TS + loadable-components SSR setup in production (or anywhere). I would love to share/compare tsconfig.json with them to see what I'm missing. Here's the one we're running in production.
tsconfig.base.json
{
"compilerOptions": {
"target": "es6",
"sourceMap": true,
"module": "commonjs",
"lib": [
"es5",
"es2015.promise",
"es6",
"es7",
"esnext",
"dom"
],
"baseUrl": ".",
"paths": {
"shared/*": ["./shared/*"],
"src/*": ["src/*"]
},
"noEmit": true,
"strict": true,
"noImplicitAny": false,
"resolveJsonModule": true,
"esModuleInterop": true,
"outDir": "./dist",
"typeRoots": [
"node_modules/@types"
],
"allowJs": true,
"checkJs": true,
"skipLibCheck": true,
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"moduleResolution": "node",
"isolatedModules": true
},
"exclude": [
"node_modules",
"./dist",
"./build",
"./**/*.spec.ts",
"./**/*.test.ts"
]
}
SSR Module tsconfig.json
{
"extends": "../tsconfig.base.json",
"compilerOptions": {
"baseUrl": ".",
"module": "commonjs",
"outDir": "./dist",
"jsx": "react" ,
"paths": {
"shared/*": ["../shared/*"],
"ssr/*": ["../ssr/*"],
"src/*": ["../src/*"]
}
}
}
Personally I don't know people running it, I don't use TypeScript. Help is welcome!
The common approach is combine ts and babel - first apply ts-loader, then - babel-loader. Or awesome-typescript-loader with useBabel enabled.
Be sure to _preserve_ JS, JSX and module system, to give babel code it's expecting to have.
tsconfig.json
{
"jsx": "preserve",
"target": "es2016",
"module": "esnext",
"moduleResolution": "node"
}
The TypeScript will do one job, and babel - another, helping each other.
@theKashey thanks for the response. yea, I'm positive it's something surrounding what you're talking about. I tried a few config adjustments and could not make it work. Our node SSR server has to have "jsx": "react" set for it to work..
TO BE CLEAR: I 100% know I'm doing something wrong here, I just don't know how to fix it.
If you or anyone has a full typescript + ssr + webpack example working I would LOVE 馃樆 to take a look. Until then I think we're gonna roll with any files that have loadable in them with no typings. Sad, but it ain't the worst since we pretty much use loadable in only a couple files outside of our main router which is ALL loadable 馃帀
Don't hesitate to contribute to the website to add document TypeScript usage.
@neoziro as soon as I have a working solution I will gladly update a fully working TypeScript example. Thanks for loadable-components and your attentiveness to users of this OSS 馃憤
@followbl Did you find a solution or any sort of workaround?
@usamakamran1 unfortunately I did not.
However, fortunately enough because code splitting is commonly done in a separate file, I just put the loadable function in a *.js file like so and it worked perfectly
import React from 'react';
import loadable from '@loadable/component';
const ViewError = loadable(() => import(/* webpackChunkName: "ViewError" */ './container'), {
fallback: <div />,
});
export default ViewError;
Don't hesitate to use babel and ts together
// webpack conf
...
module: {
rules: [
{
test: /\.tsx?$/,
exclude: /node_modules/,
use: [
'babel-loader', // <------------
'ts-loader'
],
},
{
test: /\.js$/,
use: {
loader: 'babel-loader',
}
},
...
// tsconfig.json
{
"compilerOptions": {
...
"module": "esnext", // <--------
"jsx": "preserve", // (actually - optional, but better let TS produce "proper" ES6+JSX code)
....
}
}
Using ts-loader and babel-loader together in webpack worked for me. Had to change the current build process for my project but certainly worth it.
I think the issue is solved now, we have a lot of configuration examples.
Most helpful comment
@neoziro as soon as I have a working solution I will gladly update a fully working TypeScript example. Thanks for loadable-components and your attentiveness to users of this OSS 馃憤