![Cover image for Writing a React SSR app in Deno](https://media.dev.to/cdn-cgi/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F2ihewnvzcyn1yk28hwx6.png)
As featured in Open JS World 2020 by Ryan Dahl.
Deno v1 has shipped and is causing a real buzz in the JavaScript community.
For those that have...
For further actions, you may consider blocking this person and/or reporting abuse
[notecomm@localhost react]$ deno run --allow-net ./server.tsx
error: TS2345 [ERROR]: Argument of type 'string | URL' is not assignable to parameter of type 'string'.
Type 'URL' is not assignable to type 'string'.
return new URL(url).pathname
~~~
at deno.land/std@0.59.0/path/win32.ts...
TS2345 [ERROR]: Argument of type 'string | URL' is not assignable to parameter of type 'string'.
Type 'URL' is not assignable to type 'string'.
return new URL(url).pathname;
~~~
at deno.land/std@0.59.0/path/posix.ts...
TS2345 [ERROR]: Argument of type 'string | URL' is not assignable to parameter of type 'string'.
Type 'URL' is not assignable to type 'string'.
return new URL(url).pathname
~~~
at deno.land/std@0.58.0/path/win32.ts...
TS2345 [ERROR]: Argument of type 'string | URL' is not assignable to parameter of type 'string'.
Type 'URL' is not assignable to type 'string'.
return new URL(url).pathname;
~~~
at deno.land/std@0.58.0/path/posix.ts...
TS2345 [ERROR]: Argument of type 'ParsedURL' is not assignable to parameter of type 'string'.
const loc = encodeUrl(new URL(originalUrl).toString());
~~~~~~~~~~~
at deno.land/x/opine@0.14.0/src/middl...
Found 5 errors.
github.com/apiel/adka/issues/1
on deps.ts change
export { opine } from "deno.land/x/opine@0.19.1/mod.ts"; to
export { opine } from "deno.land/x/opine@0.19.1/mod.ts"; or
export { opine } from "deno.land/x/opine@main/mod.ts";
Ah yes! Thanks for pointing this out.
Unfortunately the release of Deno 1.2.0 brought about some breaking changes meaning it no longer works with several std libraries pre 0.61.0
I will try to update this blog post to list the latest versions to use - unfortunately with the pace Deno is moving blog post become outdated very quickly 😂
I get 27
TS1205
errors using latest Deno:Errors:
Found 27 errors.
Hey Christos 👋
This article was written back in May when Deno was on a much earlier version than
1.5.4
! May I recommend you have a look at all of the Deno modules you import in thedeps.ts
to ensure you are using the latest version which (hopefully!) works for the version of Deno you are running.For example, Opine's current latest version is
0.25.0
, so updating to that may solve your issues 😄 (REF: github.com/asos-craigmorten/opine)Let us know if upgrading modules works out for you!
I've had wrong
react-dom
16.3.1
instead od16.13.1
and now that I've updated it and alsoopine
to latest0.25.0
I get hooks error:even after doing Deno reload using:
I understand that this article and example source code was written for an older Dyno version, but I believe it’s kind of useless if it’s not updated for the latest version and that’s not even a major version, it’s a minor version with some obvious breaking changes.
Having new to Deno developers installing an old version is not convenient.
Anyway, thanks for your time.
Hi Christos, I'm sorry you felt my article was useless 😕
Over the past year, with every minor version of Deno there has been almost always a breaking change (even with just minor version upgrades), which has made it difficult to keep every demo and article up to date, and working with the latest versions, as this can take a lot of time.
I haven't and wouldn't ever recommend people use an older version 🙂 but I hope people come to expect that an old article might not work with a newer version after so many breaking changes 😅
If you find issues with any articles, what can be really useful for me (and all writers!) is if you are able to overcome the issues and leave comments on how to fix them - then the writer can easily update the article when they have time, or if not, at least others can read the comment and see the solution!
For now anyway, I have updated the article to work for Deno 1.5.4 (the latest). Please let me know if you have any further issues! I will always try to respond (eventually)! 😄
Best of luck with your Deno journey!
Thank you Craig for making some time to update this article.
I didn't mean to offend you by saying the article is "useless", it just does not provide much value for begginers and new to Deno developers.
I have my own blog (lytrax.io) that I have many outdated articles and also many outdated answers in Stack Overflow and every single article has value; it's value just declines in time because it gets outdated and sometimes not even working with new versions.
Now for the updated version, I still get React hooks error in
server.tsx
line 29 where(ReactDOMServer as any).renderToString
tries to render the<App/>
component:I tried to run this using Windows 10 and also macOS Catalina and getting the exact same error on both systems. I have created a Github repo here github.com/clytras/deno-react-ssr to make it easy test the code on different environments.
What am I doing wrong?
Again thanks for replying and updating the article! 👍
Curious...! I'll check out your repo and see what I've missed 😄 Had it working locally when did the rewrite so maybe something lost in translation somewhere! 😅
Update:
So I ran the following:
Opened up
http://localhost:3000
on both Firefox and Chrome (for MacOS) and could see the app running as intended without any console errors!Firefox:
Chrome:
When you have run your updated application, have you checked to see if the old version of the application has been stopped! I commonly use port 3000 for apps and find all the time that I'm wondering why one app isn't right when I have a forked version running in a different window! (E.g.
lsof -ti tcp:3000
)Otherwise, rather unhelpfully / frustratingly(!) your setup works on my machine! (MacOS Mojave 10.14.6)
If you don't make any progress debugging, can you try out the React example on the Opine repo (REF: github.com/asos-craigmorten/opine/...) - if that doesn't work we can get an issue raised and start debugging properly!
Very strange!
It's not the port, I just tried a different free port (
17123
) and getting the same error and I don't get anything when I runlsof -ti tcp:3000
on macOS Catalina (10.15.7).Here is the screenshot of the console and the error:
And Windows terminal screenshot:
How can I debug this?
I also cloned opine and tried to run the example using
deno run --allow-net --allow-read --unstable ./examples/react/server.tsx
and I got an other error about invalid imports that are using thev
infront of versions:And this again for both Windows and macOS!
Does opine server running on your machine with Deno 1.5.4 without any modifications?
Hi Craig, thanks for the nice tutorial!
Launching the example with a today updated deno installation (deno 1.0.2, v8 8.4.300, typescript 3.9.2) fails with following errors:
I'm unfortunatelly not an expert in deno. Do you have already an idea to solve these problems?
Really sorry about that! I may have missed something when copying snippets from IDE to blog post! Alternatively it may be the Deno version - I tested this with Deno 1.0.0, and I know the newer versions broke some dependencies with type errors (namely the EVT Deno library had issues with v1.0.1 at one point!) - I’ll take a look when I can next, make fixes, and get back to you as soon as possible :)
In the meantime, you can try and see if it’s a Deno version by downgrading Deno to v1.0.0 - there instructions on how to install specific versions here: github.com/denoland/deno_install#i... (I’ll test myself as well!)
I can confirm this code, including:
Appears to be broken for versions >= 1.0.1, so there must have been an accidental breaking change in Deno?
For now, the code should work fine on v1.0.0 (just tested) and I'll look to get it updated to be compatible with these latest versions of Deno :)
Further to my last comment, the easiest way to change to a specific version of Deno is to use the
upgrade
command:Edit:
I have found the relevant issues, and they should hopefully be resolved by the Deno team in the next Deno release. In the meantime I have updated the article to provide guidance on how to set Deno version to 1.0.0, added links to the issues and will look to update the code samples to support v1.0.1 and v1.0.2.
Edit 2:
Code and article updated to support Deno v1.0.2 🦕 🥳. Unfortunately Deno v1.0.1 support won't be possible due to a bug in the Deno core.
Upgrade to Deno v1.0.2 using the
upgrade
command:Thanks a lot!
With deno 1.0.2 I do still get
Cannot find module 'https://dev.jspm.io/react@16.13.1' or its corresponding type declarations
Oh no! 😢I’ll take another look - the underlying problem (as far as I know) is a bug in Deno which will be released in 1.0.3, check out github.com/denoland/deno/issues/5772
For now I believe v1.0.0 should be fine, so can downgrade in the meantime to get started.
Another open issue is that the unstable Import Map feature of Deno doesn’t play nicely with React atm - see github.com/denoland/deno/issues/5815
Off the top of my head, one thing to try is to use the Deno Types hint:
Will test again myself and get back to you!
Ok, I am able to reproduce! Here are the steps that I took:
a. Ran the Deno
upgrade
command to change to v1.0.2:b. Checked that I was definitely testing on Deno v1.0.2
c. Cleared my Deno cache in case I had managed to get the module previously and cache it:
And then deleting everything inside the directories listed for
Remote modules cache
andTypeScript compiler cache
.d. Created an
app.tsx
andserver.tsx
as per this article.e. Ran the following command:
And voila, errors:
In this instance, adding the
@deno-types
directive (though a good thing to do to get the React types) does nothing to solve the issue because Deno has the current bug that it's typescript compiler ignores all.tsx
and.jsx
files (see github.com/denoland/deno/pull/5785) and they are exactly the extensions we've been using!Unfortunately neither Deno nor Typescript have a particularly great solution to this problem 😞 but there are 2 workarounds that you can use for now until v1.0.3 is released (if can find more then please comment!):
a. Use
// @ts-ignore
comments above each top-level React import statement. For exampleThough I prefer option 2 (which I will use to update this blog post):
b. Create a
dep.ts
(note the.ts
extension will mean that Deno v1.0.2 will compile it despite the bug). We will then import all of our dependencies into this file, and re-export them for use in ourapp.tsx
andserver.tsx
:You can then run
deno run --allow-net --reload ./server.tsx
and it should start the application 🥳 🎉Let me know how you get on!
Edit: Blog post all updated! Thanks so much for providing the feedback - articles become so much more useful to everyone through comments and pointing out bugs! I've certainly learned things 😄
Great tutorial, able to get it running within few minutes!
I'm new to JS world, have not used nodejs, and directly learning deno. I wanted to convert this little react js, and in the process learn deno & react :
github.com/anborg/react-pwa
Can someone help me to convert the above node to deno - to make it well organized source/subcomponent staticpage/images etc.
I am looking for an example deno-react project that is structurally similar e.g src/index.js, /public_html/index.html, writing into div "root" instead of rewriting "body", react subcomponents in separate subfolders etc.
Hey @anborg ! 👋
Wow, I'd say a PWA React app is a reasonably complex thing! 😲
I have an example of how you can write an MVC like setup in another post including static CSS and EJS templates.
I've not seen any particularly complex examples of React + Deno - if you google there are a few examples / videos that use a mixture of Node and Deno for the desired effect. If you find any awesome examples then please do share!
I would be happy to create a more complex example React application which has some sub-components, uses static CSS etc. and tutorial to go with it - would that be useful?
I’ve put together a quick example of using SSR React with suspense, static CSS and sub-components here —> github.com/asos-craigmorten/opine/...
I plan to write up a new post about it over the next couple of days.
@craig Thanks for the SSR. Would be great to have a CSR (client side rendering) React & Deno example, with a structured project so it can be used as a template to write maintainable production quality code.
Hey sure, thanks for the suggestion. CSR would be very similar to the example, but instead of performing a server-side
renderToString
(here github.com/asos-craigmorten/opine/...) you would just not bother! Instead effectively setting the content of the React root (here github.com/asos-craigmorten/opine/...) as empty.Finally instead of hydrating the content in your client-side script (here github.com/asos-craigmorten/opine/...), you would just use the
reactDOM.render()
method to create your app completely on the client. 🎉For this particular example you could then likely refactor a couple of things such as the
isServer
prop that is used in this example to manage the fact that React Suspense is yet supported server-side.Yes a simple react + deno + calling some weservice (e.g elasticsearch), subcompoenents, css etc. would serve as a production quality template!
Great stuff, very promising!
Is there any way to import css/less module?
Unfortunately CSS Modules etc. aren't there yet with Deno as they generally require a bundler to make them work.
You are able to use static CSS easily, see here for an example of how you can server static CSS.
I've also got a post on how to write a more complex app using static CSS here.
Fingers crossed tooling for things like CSS modules will be developed by the community shortly!
you can try Aleph.js, a react framework in deno, with built-in css/less support, or import sass with plugin.
Hi Craig, nice tutorial!
I would suggest using denon, like nodemon but for deno, to ease the development process of this kind of apps.