Module Resolution

πŸ‘¨β€πŸ’Ό Great! Now our server is all configured to create 'use client' module references to properly separate our client and server code. And our client is configured to resolve those references to the client code necessary to run in the browser and make the components stateful and interactive!
If you check out the RSC payload now, you'll notice that the client component is now referenced in the RSC payload:
2:"$Sreact.suspense"
1:{"name":"App","env":"Server","owner":null}
0:D"$1"
4:{"name":"SearchResultsFallback","env":"Server","owner":"$1"}
3:D"$4"
3:[["$","li","0",{"children":["$","a",null,{"href":"#","children":[["$","img",null,{"src":"/img/fallback-ship.png","alt":"loading"},"$4"],"... loading"]},"$4"]},"$4"],["$","li","1",{"children":["$","a",null,{"href":"#","children":[["$","img",null,{"src":"/img/fallback-ship.png","alt":"loading"},"$4"],"... loading"]},"$4"]},"$4"],["$","li","2",{"children":["$","a",null,{"href":"#","children":[["$","img",null,{"src":"/img/fallback-ship.png","alt":"loading"},"$4"],"... loading"]},"$4"]},"$4"],["$","li","3",{"children":["$","a",null,{"href":"#","children":[["$","img",null,{"src":"/img/fallback-ship.png","alt":"loading"},"$4"],"... loading"]},"$4"]},"$4"],["$","li","4",{"children":["$","a",null,{"href":"#","children":[["$","img",null,{"src":"/img/fallback-ship.png","alt":"loading"},"$4"],"... loading"]},"$4"]},"$4"],["$","li","5",{"children":["$","a",null,{"href":"#","children":[["$","img",null,{"src":"/img/fallback-ship.png","alt":"loading"},"$4"],"... loading"]},"$4"]},"$4"],["$","li","6",{"children":["$","a",null,{"href":"#","children":[["$","img",null,{"src":"/img/fallback-ship.png","alt":"loading"},"$4"],"... loading"]},"$4"]},"$4"],["$","li","7",{"children":["$","a",null,{"href":"#","children":[["$","img",null,{"src":"/img/fallback-ship.png","alt":"loading"},"$4"],"... loading"]},"$4"]},"$4"],["$","li","8",{"children":["$","a",null,{"href":"#","children":[["$","img",null,{"src":"/img/fallback-ship.png","alt":"loading"},"$4"],"... loading"]},"$4"]},"$4"],["$","li","9",{"children":["$","a",null,{"href":"#","children":[["$","img",null,{"src":"/img/fallback-ship.png","alt":"loading"},"$4"],"... loading"]},"$4"]},"$4"],["$","li","10",{"children":["$","a",null,{"href":"#","children":[["$","img",null,{"src":"/img/fallback-ship.png","alt":"loading"},"$4"],"... loading"]},"$4"]},"$4"],["$","li","11",{"children":["$","a",null,{"href":"#","children":[["$","img",null,{"src":"/img/fallback-ship.png","alt":"loading"},"$4"],"... loading"]},"$4"]},"$4"]]
6:{"name":"SearchResults","env":"Server","owner":"$1"}
5:D"$6"
8:{"name":"ShipFallback","env":"Server","owner":"$1"}
7:D"$8"
7:["$","div",null,{"className":"ship-info","children":[["$","div",null,{"className":"ship-info__img-wrapper","children":["$","img",null,{"src":"/img/ships/ec7a3f950f99f.webp?size=200","alt":"ec7a3f950f99f"},"$8"]},"$8"],["$","section",null,{"children":["$","h2",null,{"children":"Loading..."},"$8"]},"$8"],["$","div",null,{"children":["Top Speed: XX"," ",["$","small",null,{"children":"lyh"},"$8"]]},"$8"],["$","section",null,{"children":["$","ul",null,{"children":[["$","li","0",{"children":[["$","label",null,{"children":"loading"},"$8"],":"," ",["$","span",null,{"children":["XX ",["$","small",null,{"children":"(loading)"},"$8"]]},"$8"]]},"$8"],["$","li","1",{"children":[["$","label",null,{"children":"loading"},"$8"],":"," ",["$","span",null,{"children":["XX ",["$","small",null,{"children":"(loading)"},"$8"]]},"$8"]]},"$8"],["$","li","2",{"children":[["$","label",null,{"children":"loading"},"$8"],":"," ",["$","span",null,{"children":["XX ",["$","small",null,{"children":"(loading)"},"$8"]]},"$8"]]},"$8"]]},"$8"]},"$8"]]},"$8"]
a:{"name":"ShipDetails","env":"Server","owner":"$1"}
9:D"$a"
0:["$","div",null,{"className":"app","children":[["$","div",null,{"className":"search","children":[["$","form",null,{"children":["$","input",null,{"name":"search","placeholder":"Filter ships...","type":"search","defaultValue":"","autoFocus":true},"$1"]},"$1"],["$","ul",null,{"children":["$","$2",null,{"fallback":"$3","children":"$L5"},"$1"]},"$1"]]},"$1"],["$","div",null,{"className":"details","children":["$","$2",null,{"fallback":"$7","children":"$L9"},"$1"]},"$1"]]},"$1"]
b:I["/edit-text.js","EditableText"]
9:["$","div",null,{"className":"ship-info","children":[["$","div",null,{"className":"ship-info__img-wrapper","children":["$","img",null,{"src":"/img/ships/ec7a3f950f99f.webp?size=200","alt":"Scout Ship"},null]},null],["$","section",null,{"children":["$","h2",null,{"children":["$","$Lb","ec7a3f950f99f",{"shipId":"ec7a3f950f99f","initialValue":"Scout Ship"},null]},null]},null],["$","div",null,{"children":["Top Speed: ",11," ",["$","small",null,{"children":"lyh"},null]]},null],["$","section",null,{"children":["$","p",null,{"children":"NOTE: This ship is not equipped with any weapons."},null]},null]]},null]
5:[["$","li","Infinity Drifter",{"children":["$","a",null,{"href":"/bc4cbadf89bd3","style":{"fontWeight":"normal"},"children":[["$","img",null,{"src":"/img/ships/bc4cbadf89bd3.webp?size=20","alt":"Infinity Drifter"},null],"Infinity Drifter"]},null]},null],["$","li","Star Hopper",{"children":["$","a",null,{"href":"/3ba8aa65ffe6c","style":{"fontWeight":"normal"},"children":[["$","img",null,{"src":"/img/ships/3ba8aa65ffe6c.webp?size=20","alt":"Star Hopper"},null],"Star Hopper"]},null]},null],["$","li","Galaxy Cruiser",{"children":["$","a",null,{"href":"/ab267a5984523","style":{"fontWeight":"normal"},"children":[["$","img",null,{"src":"/img/ships/ab267a5984523.webp?size=20","alt":"Galaxy Cruiser"},null],"Galaxy Cruiser"]},null]},null],["$","li","Planet Hopper",{"children":["$","a",null,{"href":"/d3b8aa65ffe6c","style":{"fontWeight":"normal"},"children":[["$","img",null,{"src":"/img/ships/d3b8aa65ffe6c.webp?size=20","alt":"Planet Hopper"},null],"Planet Hopper"]},null]},null],["$","li","Space Taxi",{"children":["$","a",null,{"href":"/1ff1991efe029","style":{"fontWeight":"normal"},"children":[["$","img",null,{"src":"/img/ships/1ff1991efe029.webp?size=20","alt":"Space Taxi"},null],"Space Taxi"]},null]},null],["$","li","Star Destroyer",{"children":["$","a",null,{"href":"/f3d9a88e1c234","style":{"fontWeight":"normal"},"children":[["$","img",null,{"src":"/img/ships/f3d9a88e1c234.webp?size=20","alt":"Star Destroyer"},null],"Star Destroyer"]},null]},null],["$","li","Interceptor",{"children":["$","a",null,{"href":"/cb03cc4e5717e","style":{"fontWeight":"normal"},"children":[["$","img",null,{"src":"/img/ships/cb03cc4e5717e.webp?size=20","alt":"Interceptor"},null],"Interceptor"]},null]},null],["$","li","Stealth Cruiser",{"children":["$","a",null,{"href":"/6c86fca8b9086","style":{"fontWeight":"normal"},"children":[["$","img",null,{"src":"/img/ships/6c86fca8b9086.webp?size=20","alt":"Stealth Cruiser"},null],"Stealth Cruiser"]},null]},null],["$","li","Battleship",{"children":["$","a",null,{"href":"/fdc13cb488bf1","style":{"fontWeight":"normal"},"children":[["$","img",null,{"src":"/img/ships/fdc13cb488bf1.webp?size=20","alt":"Battleship"},null],"Battleship"]},null]},null],["$","li","Dreadnought",{"children":["$","a",null,{"href":"/d486d48b82b81","style":{"fontWeight":"normal"},"children":[["$","img",null,{"src":"/img/ships/d486d48b82b81.webp?size=20","alt":"Dreadnought"},null],"Dreadnought"]},null]},null],["$","li","Cruiser",{"children":["$","a",null,{"href":"/cfd10fcd2de6c","style":{"fontWeight":"normal"},"children":[["$","img",null,{"src":"/img/ships/cfd10fcd2de6c.webp?size=20","alt":"Cruiser"},null],"Cruiser"]},null]},null],["$","li","Frigate",{"children":["$","a",null,{"href":"/e92cefe4f6727","style":{"fontWeight":"normal"},"children":[["$","img",null,{"src":"/img/ships/e92cefe4f6727.webp?size=20","alt":"Frigate"},null],"Frigate"]},null]},null],["$","li","Scout Ship",{"children":["$","a",null,{"href":"/ec7a3f950f99f","style":{"fontWeight":"bold"},"children":[["$","img",null,{"src":"/img/ships/ec7a3f950f99f.webp?size=20","alt":"Scout Ship"},null],"Scout Ship"]},null]},null]]
What's so cool about this is it allows us to have composition across the wire. We can compose our client and server code together!
A common question at this point is "do I need to add 'use client' to every module I want in the client." The answer is no! You only need to add 'use client' to the top-level module that you want to run in the client. Think of 'use client' as a <script> tag in the browser. It's the entry point to your client code (you can have many such entries). 'use client' is a way to create a boundry between the server and client code.
For a handy visualization, check out this animation.
πŸ§β€β™‚οΈ Now that we support client components, I'm going to add a bunch to the codebase for our image optimizations and things. I'm also going to prep some stuff for the new Router you're building next. Feel free to check out the diff if you want to see what I'm going to do.