solidjs / solid

A declarative, efficient, and flexible JavaScript library for building user interfaces.
https://solidjs.com
MIT License
32.05k stars 914 forks source link

Browser error when importing 'cross-fetch' in example Solid SSR project #420

Closed zejji closed 3 years ago

zejji commented 3 years ago

I would like to use full server-side rendering for SEO reasons, so I've set up the 'solid-ssr' example projects and these work great. I've been focusing on the 'async' example as this obviously serves the page fully pre-rendered.

However, as soon as I modify the simulated fetches in Profile/index.js and replace them with real fetches (using the cross-fetch library), I run into an issue.

Specifically, it works fine on the server, but in the browser I get the following error:

image

I've never used rollup before, but the searching I have done so far indicates it might be rollup configuration issue. Would you be able to cast any light on this? (Naturally, in practice virtually all projects are likely to need to fetch data from an API.)

My Profile/index.js is modified as follows - all other files are unchanged from the solid-ssr examples:

import { createResource, lazy } from "solid-js";
import fetch from "cross-fetch";

const Profile = lazy(() => import("./Profile"));

const fetchJSON = query => fetch(query).then(r => r.json());

// this component lazy loads data and code in parallel
export default () => {
  const [user] = createResource("user", () => {
      // fetch some data from the Pokemon API
      console.log("LOAD USER");
      return fetchJSON('https://pokeapi.co/api/v2/berry/1/')
        .then((res) => { return { firstName: res.name, lastName: res.name }; });
    }),
    [info] = createResource(
      () => user() && "userinfo",
      () => {
        // cascading data loading
        console.log("LOAD INFO");
        return fetchJSON('https://pokeapi.co/api/v2/berry/2/')
          .then((res) => { return [res.firmness.name, res.item.name, res.natural_gift_type.name];});
      },
      []
    );

  return <Profile user={user()} info={info()} />;
};

Update: just to note that it works fine if I replace import fetch from "cross-fetch"; with const fetch = (typeof window === 'undefined') ? require("node-fetch") : window.fetch;, although this is obviously a bit dirty!

ryansolid commented 3 years ago

Yes it looks like something is importing stream which isn't present in the browser.

This repo has same example with real data fetching and maybe can serve as a better example. https://github.com/ryansolid/solid-ssr-workbench

zejji commented 3 years ago

Thanks @ryansolid - that works as expected. I'll take a deep dive and look at the differences. Looking forward to seeing how the SSR feature develops - I'm quite excited to see how the performance of a .NET 6 backend and Solid with async SSR combine 😃

ryansolid commented 3 years ago

@zejji Any more action to take here. Or should close it?

zejji commented 3 years ago

@ryansolid - Would it be worth removing the example SSR project from the main Solid repo and instead linking to the Solid SSR workbench project somewhere in the documentation (maybe in a separate "SSR" documentation page), with some minimal setup instructions?

In any case, it would probably avoid confusion if the code is kept in one place. Other than that I think this issue can be closed.

zejji commented 3 years ago

Obviously if the upcoming starter kit is set up for isomorphic rendering out of the box, this issue will become moot. Definitely looking forward to it! I think making things as easy to use as, for example, SvelteKit will massively help with wider adoption of SolidJS.

ryansolid commented 3 years ago

Yeah that is exactly what SolidStart is. I have some vision differences from SvelteKit so I still have work to do. Mostly in how routing is handled (more like Remix Run, watched the video recently and nice to validate we were on similar page), and how API endpoints are handled. Stuff is sort of working with Node, SSG, and Cloudflare but I have a lot of rough edges to iron out.