Alpha preview: Converting a import-mapped React app to use esbuild with JSX in Rails 7

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in the last video i showed how you can use react with this new import mapped approach to javascript in rails through the html library that makes it possible to write react without jsx but i wanted to take a opportunity here to show that you can also go the other way from here you can start with this import map approach that's going to be the default in rail 7 and then if you run into issues concerns or annoyances with that setup it's quite easy to go from here to a fully node transpiler bundler setup and we'll make a simple conversion like that today and i'll also show you a new feature of the import map setup in rails with the new command line interface for dealing with javascript dependencies on the cdn so let's start by just setting up our basic skeleton this is again running on the rails main pr for import map actually that's not true we've merged that pr this is now on rails main and using the latest development uh import map gems and turbo and stimulus and so forth but let's have a look at setting up the same kind of controller that we used in the other video that just gave us a components index that we can show a react component on so i'll start by running the generator to create a new controller here called components and it's going to have an index action and let's have a look at setting up the div that we need for showing our react component in it it is going to be an id and we're going to call it clock because we're going to use that same clock component that we used in the other video but before we get started on that we have to add all the libraries we're going to use and this is where i'll show you the new import map bin stop which is a way of interacting with your import map which if we have a quick look at that just has the default stuff in it right now it has the hot wire libraries and it mounts the controller but for this example we're going to use react so we need to add the react libraries the react frameworks to this as well as htm to show the initial setup so let's have a look at that and we're going to run this new import map command that's added by the import map gem now and we can run pin to say we want to pin these libraries or these frameworks from the javascript cdn that this is backed by by default which is jspm you can use other backers like jsdeliver and unpackaged as well but let's just add these three uh libraries and frameworks and then have a look and see what that generates for us so what this command does it actually calls out to a web service running on jspm that will resolve these three package names and give us the most recent version of all of them as well as the dependencies that are needed to to make them go and those dependencies might differ from um the cdn to cdn some cdns package up more into single bundles and others uh let the dependencies kind of float on their own but here you can see we've pinned a total of five packages and if we jump back to have a look at the import map you can see that these five packages have been mapped now as you can see this is a file you can hand edit but you can actually also manipulate this file through the import map not just by pinning but you can unpin things so let's say we wanted to remove html for example we weren't going to use that anymore boom that's gone let's say we wanted to update one of the pins that we have for example the version of react that was mapped by default was 1702 let's say we wanted uh one back 1701 running the pin command again will update both the pin and the dependencies that go with it so now you see the react is 1701 and reactdom was 1702 but the dependency i think that was yeah object assign also follows that and we'll automatically update that in the file in line and as i said you don't have to use jspm you can also use another javascript cdn so if we first start by unpinning react and then we'll pin it again from another cdn from js deliver where you'll see that that cdn actually packages things a little differently it doesn't split out object design into its own package so if we jump back in here you can see that react is packaged from jsdeliver you should probably use just a single uh cdn if you can get away with it that's just a single ssl handshake and setup so we will unpin um a react i can actually we can just pin react and then rely on the default being gspn so now we have react react dom and oh we actually also needed htm back before we can proceed one more thing we're going to add here is we're going to add a new pin all which is essentially a glob from a new directory called components mount that under components um and then let's create that so here we're gonna have our components and the one component we're gonna put in there is this clock um this is the same example that i've been using in the other video i'm gonna paste in the converted to htm setup example this was the same example we were using one of the previous videos i haven't changed anything here as you can see this uses htm instead of jsx to set things up and then we actually also need to have that react dom render call so now we have a component set up and we can include that component here um we're actually not going to use stimulus for this we can just import the components clock and as you can see here we're using a bear identifier not this and the bear identifier is the one that works with the import map setup it's the one that's going to be defined here let's actually just remove stimulus as well here because then i'll show you what this produces which is another feature of the import map command is that you can show the json that'll be produced in the import map script tag that'll be included on the page and as you can see here we have the components clock mounted and it'll mount it to this directory under the asset pipeline okay i think we actually have all the bits that we need uh let me see did i add the clock there yes i did we should be able to start our server now and then have a look at that setup yes we're going to rest oh i forgot that we need to set up the route so we're going to mount this on root and let's have a look at that okay we have the components we have our hello world clock that's being rendered this is being rendered through the import map setup this is exactly as we've done already in the previous videos except perhaps a little nicer now with the import map bin stop that we can use but let's assume that we can't deal with html we want our jsx so we'll convert this to using a more traditional setup you could just slot in the webpack or gem here to do that but i'm actually going to use another example using es build because es build is a neat new super fast bundler for javascript and it's very easy to use it together with rails actually piggybacking off the existing asset pipeline to do so and i'll show you how to do that so the first thing we need to do is we need to create a package json file that's going to have our dependencies and everything set up but let me just start by having a name and the fact that it's private and then we'll add our dependencies through npm so let's jump over to the command line here and we're going to add react react dom which is the same things as we were just using and then also turbo rails because we had that on the input map setup and then we're going to add es build and these packages are just going to install and add it themselves to to the package json file that we had and then in this package.json file we're going to add a couple of scripts we're going to add scripts for building and for watching using um es belt so as you can see here we're running es build because we already installed that it's going to produce a bundle where the entry point is the same entry point as we were using for the import map and we'll have to adjust that a little bit to make it work for yes build rather than the input map setup and then we will actually do an output file to put this inside the asset pipeline because then we can refer to it both in development and in production and we'll get the right stamping and digesting of the file in production this is a really neat way of not even needing an explicit integration for es build to be able to use it so now we have that set up and now we need to convert our um javascript to be able to use this setup and the first thing we have to do is we have to get away from these bare identifiers for the components that we have locally also we're not setting this up anymore so we're going to import this clock but the clock that we have right now we have that as a as a js file so let's actually add a jsx version and we could be explicit about requiring that and then we can have them side by side so you can see the difference um i'm gonna do the jsx version here and that jsx version is just going to be the vanilla version as you would find it on the react site i'm going to paste that in you see let's compare them back to back here in the input map version we needed to do this little html dance we imported htm as well we bind it to h and then we use that down here instead of gsx in the gsx version there's no htm and we're just rendering the jsx directly without modification um the second thing we have to do is we have to remove the import map tags from the um layout because we're no longer using the input map approach and then what we're going to do instead is we're just going to do a totally standard javascript include for application and we're also going to do let it be tracked by turbo and then we have to remember also to defer such that this javascript is not run before we've rendered the dom because our component relies on the div id clock so i think this is actually it we should be able to start es build now and um see if we can build so the first thing we can do is just run the build command that we had set up and as you can see pretty quick 46 milliseconds of course there's not a lot to this application but even very large applications built very quickly with es build now we can see this build output here actually if we have a look in here and you can see all the stuff that es build puts together to include react and the react dom and blah blah blah to get our clock component set up oh yeah actually it also has turbo in there now you can do two things with this you can either check in this artifact which makes things a little easier on the deployment side now you don't need a special step to build with es belt or you can cook in the es build command as part of your deployment script whatever works for you it doesn't really matter um but what we're going to do here is we're going to set it up and instead of doing a build we're going to do a watch so we can make changes and we're going to start another console here that will run our rail server and let's see if we actually got everything configured correctly um go back here the funny thing is of course you can't tell that this is not running off the import map version that's the whole point is that this was exactly the same but if we take a look under the network tab here and we see to reload we'll see now we have only a single script we have that script that was compiled by es belt with all the stuff that i just showed you in it instead of having the individual layers as we would with the import map version so this is essentially it this is how little it takes to jump from an import mapped setup to an es build traditional setup so i think this makes a big difference in calming someone down who might think that oh if i'm starting on the import map approach what if i later want to do jsx or i want to do something else where um i need to use a bundling tool well you just make these very simple changes as we've seen in the [Music] application.js file that we had set up it's actually a very little difference i mean this is of course also just a dumb example but the difference is between that and that and then having the jsx component uh versus having the um import map version so that's it i'm continuing to work on this stuff but we are rapidly progressing towards a rails 7 alpha that you can play with as a gem but you can obviously already use this and play with it off the rails main line there's still a lot of development going on on the import map rails gem and the other gems that go with this but we are improving it making it better this setup with the javascript cdns in particular i think is something that is really appealing i know that a fair number of people have some instinctual reactions to javascript cdn so can i trust them are they going to be fast enough are they going to be reliable and i think those fears will dissipate as this starts rolling out as people more people start using this in production in fact we are working on and have a running version of hey that has been set up on import maps is using the javascript cdn that is jspm and we're going to launch that very shortly have a big story about how we've done that the performance impact and improvements in several ways and certainly the improvement in the development experience where we don't have any of the build steps set up but as i showed if we should come to regret that for hey for whatever reason it would be a very small jump to turn the same javascript back into a built transpiled output with a single file so that's it i hope you enjoyed this and i will hopefully have more good stuff to show you soon
Info
Channel: David Heinemeier Hansson
Views: 4,824
Rating: undefined out of 5
Keywords:
Id: Chiu-0EVW3g
Channel Id: undefined
Length: 16min 39sec (999 seconds)
Published: Wed Sep 01 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.