element-react
element-react copied to clipboard
SSR problems
Description
Hello,
I was trying to use ElementUI with react-express-views
and when I'm trying to use Button (or any other component) I get an error
Reproduce Steps
- Set up express server with
express-react-views
const express = require('express');
const consoleUtil = require('../util/consoleUtil.js');
const app = express();
app.set('views', __dirname + '/views');
app.set('view-engine', 'jsx');
app.engine('jsx', require('express-react-views').createEngine());
const router = express.Router();
app.use('/', router);
router.get('/', (req, res, next) => {
res.render('main/test.jsx', {
test: 'test text',
title: 'test title'
});
});
app.listen(8080, () => {
consoleUtil.log('Webserver running...')
});
- Make
test.jsx
template inviews
folder
const React = require('react');
const ElementUI = require('element-react');
class TestLayout extends React.Component {
render() {
return (
<html>
<head>
</head>
<body>
<ElementUI.Button>
Hello
</ElementUI.Button>
</body>
</html>
);
}
}
module.exports = TestLayout;
- Run the server and go to
localhost:8080
Error Trace (if possible)
ReferenceError: document is not defined
at Object.<anonymous> (/home/jas777/Venom/node_modules/element-react/dist/npm/es5/src/table/TableHeader.js:45:17)
at Module._compile (internal/modules/cjs/loader.js:654:30)
at Module._extensions..js (internal/modules/cjs/loader.js:665:10)
at Object.require.extensions.(anonymous function) [as .js] (/home/jas777/Venom/node_modules/babel-register/lib/node.js:152:7)
at Module.load (internal/modules/cjs/loader.js:566:32)
at tryModuleLoad (internal/modules/cjs/loader.js:506:12)
at Function.Module._load (internal/modules/cjs/loader.js:498:3)
at Module.require (internal/modules/cjs/loader.js:598:17)
at require (internal/modules/cjs/helpers.js:11:18)
at Object.<anonymous> (/home/jas777/Venom/node_modules/element-react/dist/npm/es5/src/table/Table.js:37:20)
Solution
No idea
Additional Information
Any additional information, configuration or data that might be necessary to reproduce the issue.
same problem here
Me too
this issue is still present in 1.4.33 :/
edit: I was able to overcome this issue by loading this problematic component dynamically using [loadable components](smooth-code/loadable-components: React code splitting ... - GitHub https://github.com/smooth-code/loadable-components)
this however doesn't solve this issue if you need to render anything from element-react on server...
Just use wrapper of some sort:
use it like this:
import { Table, Pagination, Loading } from './wrapper'
this will only import the modules you need and also, remove all the others during the build
with tree-shaking
so the final package size will be much less.
The code needs refactoring, but it works.
Just add the required components in the wrapper
file.
wrapper.jsx
import React from 'react'
const SSR = () => <div>SSR</div>
let Alert = SSR
let Button = SSR
let Card = SSR
let Layout = SSR
let Loading = SSR
let Message = SSR
let MessageBox = SSR
let Notification = SSR
let Radio = SSR
let Dialog = SSR
let Rate = SSR
let Progress = SSR
let Badge = SSR
let Tabs = SSR
let Tree = SSR
let Input = SSR
let Icon = SSR
let Menu = SSR
let Steps = SSR
let Breadcrumb = SSR
let Tooltip = SSR
let InputNumber = SSR
let Checkbox = SSR
let Slider = SSR
let Table = SSR
let Switch = SSR
let Form = SSR
let Upload = SSR
let Tag = SSR
let Select = SSR
let Dropdown = SSR
let Popover = SSR
let Pagination = SSR
let AutoComplete = SSR
let TimeSelect = SSR
let TimePicker = SSR
let TimeRangePicker = SSR
let DatePicker = SSR
let DateRangePicker = SSR
let Carousel = SSR
let Collapse = SSR
let ColorPicker = SSR
let Cascader = SSR
let Transfer = SSR
// required
if (typeof window !== `undefined`) {
Loading = require('element-react/dist/npm/es6/src/loading').default
Table = require('element-react/dist/npm/es6/src/table').default
Pagination = require('element-react/dist/npm/es6/src/pagination').default
}
export {
Alert,
Button,
Card,
Layout,
Loading,
Message,
MessageBox,
Notification,
Radio,
Dialog,
Rate,
Progress,
Badge,
Tabs,
Tree,
Input,
Icon,
Menu,
Steps,
Breadcrumb,
Tooltip,
InputNumber,
Checkbox,
Slider,
Table,
Switch,
Form,
Upload,
Tag,
Select,
Dropdown,
Popover,
Pagination,
AutoComplete,
TimeSelect,
TimePicker,
TimeRangePicker,
DatePicker,
DateRangePicker,
Carousel,
Collapse,
ColorPicker,
Cascader,
Transfer
}
Cheers @n8tb1t Ended up using a similar solution together with loadable to work with Gatsby.
Button = loadable((): any => import("element-react/dist/npm/es6/src/button"))
This did give me import issues when testing with Jest. However, managed to get around it by setting the moduleNameMapper
to load element-react
instead
moduleNameMapper: {
"src/components/wrapper": "element-react",
}