What if NextJS was just... Rust ft Perseus and Sycamore

What if NextJS was just... Rust ft Perseus and Sycamore


What if NextJS was just... Rust ft Perseus and Sycamore

https://framesurge.sh/perseus/en-US/

https://sycamore-rs.netlify.app/


Content

0.259 -> Welcome back to Let's Code!
1.614 -> Today, we're gonna go a
2.811 -> level up from Sycamore
4.446 -> and talk about Perseus. Perseus
6.679 -> is that higher level meta
8.314 -> framework on top of Sycamore's
10.004 -> reactive bindings. So you
11.68 -> can think of Sycamore
12.838 -> as the core library with
14.874 -> the reactivity and with the
17.029 -> ability to render to Html.
19.399 -> And you can think of
20.076 -> Per as the higher level
22.229 -> tooling, the scale wall validate,
24.66 -> the server side rendering and
26.294 -> hydrate on the client. But
28.501 -> not just the hydrate functionality,
31.133 -> rather the additional functionality and
33.804 -> framework built ins that make
35.239 -> that work seamlessly. Through your
37.37 -> entire application through multiple routes
39.05 -> and multiple pages. Before we
40.69 -> get directly into Perseus, however,
42.93 -> I wanna take a look
44.024 -> at what it looks like
45.223 -> in Sycamore to do
46.222 -> a couple of the things
47.301 -> that Perseus is doing for
48.54 -> us so that we have
49.658 -> something to compare to from
51.457 -> the raw binding that S
53.055 -> gives us to the high
54.27 -> level metaphor framework that Perseus
55.75 -> is. So here we've got
56.91 -> an example of hydration We've
59.15 -> gotten index as usual the
61.124 -> cargo tom with the dependencies
62.882 -> and the main dot that
64.001 -> has our entire application in
65.239 -> it. Now, a curious thing
66.678 -> about this example is that
67.876 -> it includes the pre rendered
69.93 -> or server side rendered at
71.17 -> Html in the index dot
72.73 -> Html file here. So when
74.45 -> we look in the main
75.13 -> dot, you can see that
76.65 -> there's a render to string
77.984 -> much like react or other
79.223 -> frameworks have a render to
80.541 -> string that accepts a view
82.418 -> that, of course accepts the
83.536 -> context as usual or the
84.695 -> scope and also our application
86.943 -> and renders that to a
87.94 -> string and then logs it
88.737 -> out to the console. If
90.013 -> we look at the console,
91.886 -> we can see that Html
93.561 -> output So this render to
95.053 -> string is actually running anywhere
97.131 -> we run this in this
98.169 -> case in the browser. But
99.608 -> that's just a function call
101.525 -> to show us that the
103.098 -> rendered string does indeed output
104.776 -> what's in the index dot
106.015 -> html file. So if you're
107.533 -> expecting this to be a
108.452 -> full, like, running server and
110.983 -> client, this is not that.
112.298 -> This is just an index
113.653 -> dot Html file with some
115.765 -> Html that was rendered out
117.359 -> and copied into that file.
118.89 -> And then we also call
120.53 -> Ci more And you can
122.05 -> see that second isn't a
123.53 -> lot different than what we
124.49 -> pass to render the string.
126.063 -> Because our app isn't really
127.259 -> doing anything special. We're not
128.934 -> passing in any extra data
130.369 -> dependencies or doing anything that
133.119 -> would require this. If we
135.008 -> look at the index dot
136.203 -> Html, you can see that
137.439 -> there are data attributes specifically
139.909 -> data h k. That include
143.034 -> numeric tree is what I'll
144.113 -> call it. So it's... The
145.591 -> root here is one. And
147.309 -> then if we go down
148.827 -> the list of items, the
150.586 -> Ids change. Now I believe
152.317 -> what's happening is that everything
153.872 -> that is a root element
155.587 -> is getting the root of
157.022 -> one for the Id. So
158.338 -> you'll see one dot on
159.335 -> this paragraph tag inside of
160.531 -> the body you'll see b
161.863 -> r on the... On the
163.22 -> brake tag inside of the
164.217 -> body. And you'll see one
165.494 -> dot two on this brake
166.572 -> tag that's also at the
167.769 -> root. But something like this
169.245 -> d that has additional children
171.256 -> inside of it, will get
172.373 -> the Id too as the
173.81 -> rude Id. And as far
174.968 -> as I can tell, this
175.886 -> occurs because it passes basically
179.333 -> first when assigning these Ids.
181.287 -> So it'll get all the
182.484 -> top level stuff and then
183.761 -> it'll start back at the
184.718 -> top and then it'll go
185.715 -> through the next layer or
187.57 -> all of the ones that
188.17 -> have children and assign those
189.57 -> Ids and then as you
190.85 -> go down that list, the
193.01 -> second Id increments So two
195.224 -> things interesting here, there are
196.662 -> Ids for all of our
197.541 -> elements and there are these
200.258 -> Html comments. Now I believe
201.936 -> that these html comments are
203.946 -> significant. Although I have not
205.501 -> confirmed that, because this reminds
208.529 -> me of the way that
209.645 -> react used to do things.
210.522 -> It was ids and then
212.132 -> it was things like comments,
213.609 -> and they just need a
214.687 -> way to mark different places
216.802 -> in the dom to re
218.998 -> attach to on the client
220.115 -> side. So this all works.
221.37 -> It adds tracks, resets. You've
225.53 -> got a paragraph here that
226.89 -> is not hydrated. So if
228.704 -> we go in and I
230.939 -> can find the disabled Javascript
232.694 -> button and we refresh the
234.969 -> client side only stuff disappears.
237.059 -> But the paragraph that is
238.216 -> not hydrated, which will be
239.972 -> inside of four point zero,
241.01 -> I believe, yeah. Right here.
242.406 -> Is not rendered. Notice that
243.963 -> we still have the five
244.761 -> zero zero d because it's
246.172 -> still in the end in
247.807 -> the Html, but the client
249.761 -> side content inside of it
251.395 -> has not rendered. And we
252.552 -> do see one of those
253.748 -> Html comments here. Sort of
255.958 -> indicating that there's a gap.
257.156 -> So we can re enable
257.995 -> Javascript and we see the
259.913 -> client come back and the
261.311 -> client element show up in
262.11 -> the dom. And this is
263.122 -> all well and good, but
263.879 -> I find the way that
265.034 -> it actually is den denoted
267.265 -> in the code, very interesting.
269.216 -> So We have our app
270.588 -> component, which has the same
271.705 -> function signature in S war
273.222 -> as we've been used to.
275.257 -> We have a view as
276.335 -> the return value, which we've
278.011 -> seen before. And then we
279.382 -> have the S web, no
281.177 -> hydrate and Ci more web,
282.653 -> no Ss sr components. So
285.285 -> this component or any of
286.521 -> the children of this component
287.717 -> won't render on the server
288.93 -> or won't be Ss. So
290.29 -> if we do a render
291.13 -> string, these won't be rendered
292.81 -> and in this case, these
294.13 -> will only be rendered on
295.17 -> the server. Now I don't
296.502 -> know how similar the functionality
298.655 -> that is indicated here is
300.25 -> to something like back server
301.685 -> components, but we'll get into
303.12 -> a little bit more of
303.958 -> that in a second. So
305.449 -> Tl r is s has
307.926 -> server side rendering. S has
309.923 -> client side hydration. S has
312.855 -> components that can render on
314.055 -> the server or the client
315.575 -> exclusively, and all of that
317.095 -> works without touching Perseus at
319.055 -> all. But you would have
320.668 -> to set up your own
321.665 -> server because Ci war doesn't
323.86 -> come with say a web
325.455 -> server kind of thing for
326.812 -> you to attach to. Another
328.662 -> example I found particularly in
330.098 -> lightning is this example here
332.251 -> that I had just his
333.647 -> page visit counter. So if
334.963 -> we refresh this, you can
336.04 -> see it flash right there
337.196 -> for a second. And if
338.21 -> I throttle the network to
339.53 -> slow 3g g, we should
341.17 -> be able to see it
342.61 -> happen a lot slower. So
344.05 -> we're seeing loading and then
345.33 -> we're seeing total visits pop
346.77 -> in. So I'll take that
347.864 -> t off, so I don't
349.022 -> forget leave it enabled for
350.661 -> my normal web browsing front
352.379 -> my normal web browsing. And
353.937 -> if we take a look
354.656 -> at the example here, I
356.589 -> find the example, super interesting.
358.227 -> So this is the example
359.546 -> of basically suspense if you
361.983 -> will. In like a react
364.5 -> term. In our world in
366.912 -> S world, all this means
368.709 -> is that we've got an
369.428 -> a component and we're using
371.186 -> this suspense str to or
373.638 -> the suspense component to fall
375.396 -> back to something else. So
376.875 -> we've got our fall back
377.794 -> specified here. Our fall back
379.112 -> is another component. So it's
380.551 -> another view basically. In this
382.203 -> case, we just have loading.
383.479 -> It could be as far
384.516 -> as I can tell anything.
385.991 -> And then we've got the
386.589 -> business count for when whatever
388.822 -> thing is happening inside of
390.098 -> this business component. Is done.
392.19 -> So in this case, we
393.83 -> have our regular component attribute
395.31 -> macro and all we need
396.59 -> to do to make this
397.95 -> an a component something that
399.59 -> will fetch basically on render
401.882 -> is call it an async
403.081 -> function. Once it's an async
404.679 -> function, the function signature changes
407.076 -> a little bit. We have
408.849 -> anonymous lifetime specified here for
410.883 -> scope, but otherwise, it's the
412.319 -> same function signature that we've
413.636 -> been used to with all
414.673 -> the other ci stuff. The
416.363 -> interesting part being, of course
417.839 -> that we can just run
419.116 -> any async code in here
420.632 -> in this case it's fetch
421.669 -> visits passed with an Id,
423.72 -> which just makes a request
424.92 -> to be rick w and
426.28 -> gets back some Json, which
428.04 -> is d serial decentralized into
429.2 -> a visits str, which we
430.88 -> can see up here as
431.52 -> just a value. So we
432.933 -> fetch visits, we await it,
434.688 -> and then we un or
435.805 -> default. So in this case,
437.64 -> if this function failed, we
440.009 -> would get that default value
441.008 -> of total visits zero because
443.165 -> zero is the default value
444.404 -> for a number. And we
445.283 -> just got a component to
446.002 -> render it. And all we
447.36 -> did was have this async
449.575 -> function just sitting here inside
451.535 -> of our async component, and
453.055 -> it kind of just pauses
454.215 -> for a second, falls back
456.135 -> and then renders. To me,
457.549 -> this is a really elegant
459.027 -> way of encoding this. We
461.904 -> haven't quite gotten to the
463.542 -> full suspense for in the
464.741 -> Javascript ecosystem. And since we
467.229 -> have these async functions in
468.942 -> rust, I really like this
470.575 -> approach for that use case
472.607 -> specifically. But all of that
474.138 -> together brings us to Perseus.
476.655 -> Now we didn't cover a
477.414 -> couple of things in s.
478.493 -> We didn't cover the second
479.451 -> war router, for example, because
481.463 -> Per has its own router.
483.379 -> And if we check the
484.497 -> documentation, there is quite a
486.293 -> bit of documentation here. Even
488.488 -> more when you consider that
490.7 -> this documentation that I'm scrolling
492.62 -> through on the side here
493.7 -> is on top of all
494.94 -> of the Sycamore documentation.
496.62 -> So Perseus is definitely a
498.993 -> framework built on top of
500.47 -> S. Perseus in their introduction
502.705 -> goes over a number of
504.301 -> different features that they support
505.539 -> a number of different rendering
506.816 -> paradigm from server side rendered
509.026 -> to static site generation to
511.381 -> how you implement caching if
512.618 -> you decide to run this
513.456 -> as a server, because if
514.813 -> you run this as a
515.532 -> server, you do then have
517.264 -> to worry about cashing the
518.662 -> actual results. And they say,
520.699 -> and I believe them from
521.778 -> what I've seen that they
523.855 -> support sort of a wider
525.785 -> breadth of these rendering options,
528.257 -> than pretty much any other
529.971 -> framework that currently exists. Including
532.683 -> the ones in Javascript. I
534.094 -> think it's worth going over
535.253 -> those in a separate video
536.451 -> though, so we'll have a
537.809 -> video on rendering strategies in
539.367 -> Per most likely. Today will
541.578 -> be covering the Perseus hello
543.014 -> world. So Perseus itself has
545.327 -> a Cli that they suggest
547.799 -> that you download to build
549.673 -> Per applications. I believe I
552.122 -> read somewhere that they they
553.399 -> do actually make it clear
554.316 -> that you could do this
555.474 -> without the Cli, but the
556.87 -> Cli is just something that
558.586 -> they officially support and suggest
560.836 -> that you use. The only
562.074 -> dependencies that you strictly need
563.67 -> to build a Perseus app
564.748 -> are Perseus itself and S
566.544 -> more? I'm not sure how
569.552 -> specifically these versions correlate. So
572.622 -> for something... In other frameworks
574.775 -> in the Javascript ecosystem, for
576.331 -> example, it can be common
577.806 -> to lock a major version
579.698 -> of a framework like next
581.335 -> to gasp beer or whatever.
582.693 -> To a specific version, a
584.091 -> major version of the underlying
586.223 -> framework react, but Perseus and
588.62 -> ci more both aren't at
590.298 -> one point zero yet. So
592.456 -> it may be that we
594.269 -> need to spend a little
595.068 -> bit more time tracking these
596.706 -> dependencies to make sure that
597.625 -> they stay in sync or
598.904 -> at least compatible. It is
600.542 -> interesting that the documentation specifies
603.234 -> rust twenty eighteen for Perseus
605.389 -> and that they specify six
606.945 -> zero dot seven. Because I
608.422 -> know that Si more currently
609.978 -> is on zero dot eight.
611.709 -> And S zero dot eight,
613.904 -> I believe only supports rest
615.501 -> edition twenty twenty one at
616.818 -> this point. So this hello
618.215 -> world example might be a
619.332 -> little bit behind but that
621.104 -> shouldn't materially affect what we're
622.781 -> going through today. They do
623.98 -> have a note here that
625.697 -> like the examples in S
627.415 -> war. In the past it's
628.507 -> been common to require an
630.062 -> index dot Html. But Perseus
632.974 -> now these days includes a
634.569 -> default index dot Html. So
636.044 -> you don't actually need to
637.041 -> stick one. In your application
638.89 -> if you don't want one.
640.007 -> And in fact, elsewhere in
641.522 -> the documentation, they let you
643.236 -> use Sycamore to generate
645.149 -> that index dot Html. Or
647.318 -> S morris Html generation capabilities,
650.232 -> which is kinda nice. I
651.19 -> like that a lot. So
652.108 -> this is our Perseus app.
653.505 -> We pull in Html Perseus
655.181 -> app template. And we use
656.673 -> the Perseus main macro to
659.306 -> sort of generate the root
660.743 -> of our application. In this
662.179 -> case, we call this function
663.216 -> name, but it can be
664.19 -> called anything because I believe
665.71 -> Per main will rewrite this
667.23 -> name. And the function signature
668.87 -> here looks very similar to
670.19 -> the s function signature. It's
672.524 -> the generic g that we
674.324 -> had before that has to
675.725 -> implement the Html trait. But
677.165 -> in this case, we're returning
678.165 -> a Perseus app with that
679.938 -> generic rather than a s
682.292 -> more view or something like
683.33 -> that. So the Perseus app
684.806 -> has a builder pattern that
686.043 -> we can use. So we
686.802 -> per us new then we
688.134 -> can add as many templates
689.413 -> as we want to. Templates
691.85 -> we'll probably get into more
692.929 -> when we talk about different
694.168 -> methods of rendering the different
696.125 -> ways to build a Perseus
697.94 -> application, but you can basically
699.46 -> think of them as, like
701.1 -> the templates for the pages
702.34 -> that you are going to
702.94 -> render out. In which case,
704.834 -> the template here makes a
705.792 -> lot sense because you've got
707.548 -> a paragraph that says hello
708.785 -> world. So if we go
709.703 -> do this ourselves, we do
710.82 -> cargo news let's call it
712.257 -> Per test. See the end
713.99 -> of that directory and open
715.47 -> a s code instance. I'm
716.95 -> going to completely swap out
718.79 -> the cargo dot and use
721.03 -> just what they gave me
722.23 -> to use. Minimize the counter
724.565 -> example that we had up
725.605 -> before as well since we
726.964 -> don't need to look at
727.605 -> that anymore. So we've got
728.805 -> our dependencies here. We've got
730.324 -> p at zero dot three
731.764 -> dot six. With the hydrate
733.457 -> feature, we got Sycamore
734.735 -> at zero dot seven. I've
736.172 -> got an extension in Vs
737.17 -> code telling me that we
738.208 -> could upgrade two zero dot
739.326 -> h dot two, but I'm
740.204 -> not going to do that
741.202 -> because the tutorial doesn't say
743.095 -> that that's okay yet. So
744.575 -> I can test that out.
746.215 -> Then, of course, in main
747.015 -> dot r, we have to
748.175 -> throw in our template. So
749.335 -> in this case, we don't
750.455 -> only need the Perseus Cli,
752.43 -> we also need W pack
754.03 -> installed. So I'm gonna cargo
755.31 -> install both of them. And
756.59 -> while that happens, I'm going
757.71 -> to fix a stake that
759.364 -> I made, this needs to
760.283 -> be l dot r s,
761.641 -> not main dot r s.
763.079 -> So it told me that
763.679 -> W pack failed because I
765.037 -> already have w back installed.
767.53 -> I'm just gonna leave it
768.29 -> like that and hope that
769.53 -> the version that I have
770.37 -> works. Let me use Perseus
772.09 -> serve instead of trunk serve.
774.384 -> And we can see in
776.258 -> parallel we're getting generating your
777.734 -> app, building your app to
778.93 -> w and building server. So
780.845 -> I believe generating your app
782.24 -> is the static site generation.
784.568 -> Building out to w is
786.043 -> building the client side w
787.398 -> bundle. And then bundle building
789.152 -> server would be building the
790.945 -> server side binary that we
792.101 -> would run. And, of course,
793.194 -> if we open this on
795.111 -> what is effectively local host
796.27 -> eighty eighty, we will see
797.907 -> hello world, which is our
799.505 -> template. Let's change this to
801.037 -> Hello Youtube and see if
802.154 -> it just automatically updates. So
804.27 -> you do need to run
805.946 -> with Perseus dash w to
807.861 -> watch your files so if
808.913 -> I wanted to change hello
810.586 -> world hello Youtube and save
812.259 -> it, that would have to
813.852 -> be with the dash w
815.366 -> flag. And then it is
817.136 -> not refreshing the page. I
818.533 -> have to refresh the page
819.65 -> manually. Although I thought I
821.326 -> saw something about live reload
822.962 -> in the docs. And yeah,
824.375 -> there is. On the left
825.055 -> hand side here, you can
825.855 -> see live reloading. So we'll
827.415 -> have to set that up.
828.535 -> I wonder why that's not
829.575 -> the default. So something that's
830.894 -> super interesting is that we
832.014 -> get this dot Perseus folder
833.829 -> this dot folder in the
835.662 -> name of the framework like
836.938 -> dot next or dot gasp
838.851 -> b or got cash or
840.326 -> whatever it is. Is pretty
841.881 -> common. There usually needs to
843.571 -> be a place for files
845.844 -> to be output. That can
847.24 -> then be used to run
848.596 -> a server or cert files
850.67 -> from disk or something like
852.065 -> that. So this is a
853.079 -> very very common pattern. But
855.079 -> it does usually end up
856.24 -> just being an additional caching
857.8 -> directory. So we can see
858.959 -> in here a bunch of,
859.759 -> like, generated cargo Tunnels. We
861.814 -> can see a lived dot
862.574 -> r in the root. We
864.494 -> can see the builder is
865.334 -> a project, the disc is
867.054 -> a bunch of static files.
868.709 -> In this case, it's the
869.868 -> index dot Html and stuff
871.067 -> like that. But just be
872.226 -> aware that that folder is
873.664 -> there. So they have a
876.181 -> Faq question in this tutorial
878.474 -> Why do I need to
879.113 -> c? Why do we need
880.032 -> per? And it's because that
882.069 -> directory is generating a bunch
884.346 -> of different projects. That then
886.4 -> get built in certain ways
888.08 -> and the Cli controls that
890.64 -> larger process. So it's not
892.839 -> just a cargo build or
894.415 -> a trunk serve. It is
896.575 -> generating and building multiple different,
898.575 -> like, rust projects effectively. It
900.55 -> does say the library reload
901.75 -> server should be running. So
903.51 -> I'm gonna do this again
904.75 -> and see if it pulls
906.07 -> down the new files. It
908.244 -> does say reloading, but it
909.882 -> never actually reload the page.
912.68 -> So maybe there's a bug
913.679 -> in it right now or
914.917 -> maybe there's an issue with
916.196 -> the browser I'm using. Let
918.049 -> me do this. To rule
920.287 -> out any shenanigans with arc
922.604 -> because I have had issues
923.763 -> with arc before on cashing
925.72 -> certain things. Gonna do Youtube
927.73 -> third and save that, which
929.445 -> also didn't work in chrome.
931.12 -> So there's something off about
932.396 -> the live reload because I
934.151 -> believe this is actually generated
936.519 -> So if I reload this,
937.953 -> then we get hello Youtube
939.667 -> third. And it says the
940.902 -> library load server is connected,
942.257 -> but it isn't actually running.
944.384 -> So... Or it isn't actually
945.82 -> working for me. But all
947.895 -> that said, I'm sure that
949.851 -> that is either user error
951.646 -> on my part or a
953.694 -> small bug that can be
954.61 -> easily fixed. So that's an
956.124 -> intro to Perseus There is
957.798 -> a lot to go over
959.312 -> here. So that's why this
961.123 -> video was exceptionally long. I
963.161 -> I think it will be
964.04 -> anyway. I haven't actually edited
965.319 -> it yet, obviously. But we've
967.316 -> got the server side rendering,
968.675 -> the static generation, the live
971.602 -> reload functionality we just saw
972.758 -> the client side Was bundle.
974.592 -> There's a couple of other
976.187 -> build techniques, like data imagination,
978.955 -> that I'm looking forward to
980.795 -> exploring, it seems like Perseus
982.795 -> adds quite a bit on
984.035 -> top of Stick more. So
985.315 -> you would probably not used
987.126 -> to come more by itself.
988.883 -> Although you could. I think
990.799 -> we've explored sick more enough
992.276 -> to note that if you
993.713 -> were building a client side
995.803 -> application that was pretty simple,
997.556 -> you could just use more
998.871 -> by itself to build that
1000.027 -> client side application. But once
1002.259 -> you get to the level
1004.429 -> of needing to do server
1005.827 -> side rendering or needing anything
1007.665 -> fancy like stale while validate
1010.302 -> or dealing with that caching
1012.42 -> or wanting multiple different rendering
1014.989 -> strategies between server side, static,
1017.622 -> and other techniques, then you
1019.138 -> would reach for Perseus. Fairly
1020.868 -> quickly. So I hope you
1021.944 -> enjoyed that video. There probably
1023.299 -> will be more Perseus content
1025.132 -> coming soon. And then on
1026.528 -> top of all of that,
1027.444 -> there's this interesting page that
1029.175 -> only has one plugin at
1030.335 -> the moment, but it's the
1031.895 -> size optimizations plugin and potentially,
1035.095 -> there could be reasons to
1036.615 -> write our own plug. So
1038.388 -> hopefully, we'll be able to
1040.026 -> upgrade second more to zero
1040.985 -> dot eight soon, and we'll
1042.423 -> continue with Perseus. I hope
1043.702 -> you have a great day.

Source: https://www.youtube.com/watch?v=-9zQgLwKJdU