Shopify / shopify-app-template-node

MIT License
869 stars 391 forks source link

[CLI 3.0] Separate backend from frontend #1183

Open wisniewski94 opened 1 year ago

wisniewski94 commented 1 year ago

Issue summary

It should be a good idea to separate backend from frontend. Right now the structure is:

/web
- /frontend
- - package.json (frontend)
- index.js (which is the main file of backend)
- package.json (main)

The issues with that are:

I managed to split it into:

/web
- /frontend
- - package.json
- - shopify.web.toml
- /backend
- - package.json
- - shopify.web.toml
- /extensions (haven't tried but should work too)

But the issue is that I have to import htmlFile from frontend, and I consider it to not be the most elegant solution:

    ...
    const htmlFile = join(
      isProd ? PROD_INDEX_PATH : DEV_INDEX_PATH,
      "../../frontend/index.html",
    );

    return res
      .status(200)
      .set("Content-Type", "text/html")
      .send(readFileSync(htmlFile));
  });
...

I haven't yet figured out how to do it better. It's just a quick test, but I think there are many pros to doing it this way.

ghost commented 1 year ago

hi @wisniewski94 , I am also in favour of this separation. My folder structure is the same as yours and did the same thing as the code you shared. However, I have faced an issue and am not sure if you did as well. After my backend have sent the htmlFile to the frontend via .send(readFileSync(htmlFile)); My ngrok client which was serving my backend express app shows the get requests as follows.

image

my index.html file has the following code:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vite + React + TS</title>
  </head>
  <body>
    <div id="root"></div>
    <script type="module" src="src/main.tsx"></script>
  </body>
</html>

and the two GET requests that has a 404 http status code are due to the link tag and script tag retrieving the individual files. It is trying to retrieve those files relative to the index.js file which is residing in the backend folder. Did you manage to serve the frontend without this issue? Any help is greatly appreciated :)

wisniewski94 commented 1 year ago

@jw-soh Hi, I did not find any issue with my current implementation. Everything loads just fine but I do not load anything from the backend as it violates the whole encapsulation idea, which is: frontend and backend are separate packages that should not import from each other. There's the small exception mentioned in the main post which is index.html :).

Michael-Gibbons commented 1 year ago

I've implemented this in my template OSB, see here http://michaelgibbons.info/OSB/#/

bakura10 commented 1 year ago

Hi :),

I tried, for curiosity, to learn more about how apps are working in 2023. I was also extremely confused by the distinction made between frontend/backend.

I looked at the documentation here: https://shopify.dev/apps/tools/cli/migrate#single-process-or-frontend-process and, in the example written there:

image

The PHP app (which is normally the backend part) is actually considered as the "frontend", while the Polaris app (usually frontend) is actually... the backend part, from Shopify CLI perspective.

This general architecture makes me think that Shopify may have mixed different concepts here (maybe the "frontend" should be called "api"/"entry" and backend "webapp" or something like that. Unless I misunderstood something, not only the architecture is confusing, but also the naming. Or am I missing something obvious here?