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

Getting better at control of what runs on the server. #116

Closed
marshallswain opened this issue Jan 28, 2016 · 7 comments
Closed

Getting better at control of what runs on the server. #116

marshallswain opened this issue Jan 28, 2016 · 7 comments

Comments

@marshallswain
Copy link
Member

As was noted in this issue, it's not really simple to control what code runs on the server without setting up checks for attributes or methods that don't exist on the server as you run into them. So, how do we help each other become better SSR developers? SSR definitely seems to work fine with the majority of the code it encounters. Maybe I'm just unlucky and I'm running into this more often because I like to play with sockets. Really, the only two scenarios I've encountered so far are

Are there other issues that developers using SSR are running into besides these ones? A section in the docs on "Things to know when working with SSR" would be nice to have so that experienced devs can help the newcomers.

Maybe as a backup option for flow control we can inject global utility functions into the page that help control what runs on the server? Functions like onClient() that should evaluate to false on the server and true on the client, or onServer() that would do the opposite. They could at least be useful for troubleshooting an app that won't load in SSR. The downside with these functions would be when you want to run your code in a location that doesn't support SSR, like as an iOS app. They'd have to be shimmed in or removed.

I think ideally we would find each problem area and make it work great (no errors that stop rendering) without modifying our code. Based on what I saw with the noop() shim for socket.io on the server, I think we've already been trying to do this.

What are some other ideas that would help people more easily use SSR?

@marshallswain
Copy link
Member Author

How to know you're in node:

{}.toString.call(process) === '[object process]'

@marshallswain
Copy link
Member Author

In the documentation, we can show how to use this module to prevent code from running on the server:
https://github.com/iliakan/detect-node/blob/master/index.js

We might be able to create an example shim for some API to show users how to do it, then gather a collection of them from the community and link to them in the docs when we know about them.

@DesignByOnyx
Copy link

Dealing with SSR in a "polymorphic" fashion is indeed an art and you have
to write code while being aware of the environments in which its running. I
think it's easy enough to polyfill and noop certain known functionality
such as localStorage, web workers (maybe), matchMedia, and other stuff. But
you cant fix everything, especially 3rd party modules. I would like to
contribute to this "list for newcomers" as ssr not as easy as one might be
led to believe with some quick demos. I think it would make a great blog
post series.

Another big consideration is when doing ssr where the app mounts onto the
ssr'd dom as opposed to replacing it - the app reuses the dom sent by the
server and no mutations actually take place during the initial "mount".
This is how react works, and the state of the ssr'd content must match
exactly the state of the app during initial mount in the client. I
personally like this behavior for both performance and disciplinary
reasons, but it does require discipline for it to work. I would love to
talk about these things and am prepared to give examples.

https://github.com/iliakan/detect-node/blob/master/index.js


Reply to this email directly or view it on GitHub
#116 (comment).

@marshallswain
Copy link
Member Author

Here's a good one for localStorage on the server:
https://www.npmjs.com/package/localstorage-memory

@marshallswain
Copy link
Member Author

@matthewp or @justinbmeyer Could we make donejs develop set the process.env.NODE_ENV to develop so we could do something like this:

import isNode from 'detect-node';

var hostname;
if(isNode){
  if(process.env.NODE_ENV === 'development'){
    hostname = 'localhost';
  } else {
    hostname = <production-host-name>
  }
}

@matthewp
Copy link
Contributor

matthewp commented Feb 6, 2016

Sounds reasonable to me, by the way env is already set on your appState, if you have access to it you can check state.attr('env.NODE_ENV')

@matthewp
Copy link
Contributor

Moved this to donejs/done-serve#4

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