element-react icon indicating copy to clipboard operation
element-react copied to clipboard

SSR problems

Open jas777 opened this issue 5 years ago • 5 comments

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

  1. 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...')
});
  1. Make test.jsx template in views 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;
  1. 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.

jas777 avatar Nov 14 '18 16:11 jas777

same problem here

luisaddor avatar Nov 21 '18 21:11 luisaddor

Me too

tlecreate avatar Feb 27 '19 21:02 tlecreate

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...

ondrejrohon avatar Jul 12 '19 14:07 ondrejrohon

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
}

n8tb1t avatar Jul 13 '19 21:07 n8tb1t

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",
}

Jezfx avatar Sep 25 '19 11:09 Jezfx