Shopify / shopify-app-template-remix

327 stars 137 forks source link

Incompatibility with 3.x.x and sst v2 #844

Open theoldfather opened 5 days ago

theoldfather commented 5 days ago

Getting this nasty error when I try to updates @shopify/shopify-app-remix from 2.8.2 to 3.x.x. I am running sst v2 (2.43.7) with RemixSite set to build with node 20.x : runtime: "nodejs20.x"

Would love to upgrade so I can get the latest APIs from shopify, but seems like there use of new attributes is causing problems.

Error: There was a problem bundling the SSR function for the "ServerFunction" Site.
Expected ";" but found "with"
node_modules/@shopify/shopify-app-remix/dist/esm/react/components/AppProvider/AppProvider.mjs
3 │ import englishI18n from '@shopify/polaris/locales/en.json' with { type: 'json' };

Trace: Error: There was a problem bundling the SSR function for the "ServerFunction" Site.
Expected ";" but found "with"
node_modules/@shopify/shopify-app-remix/dist/esm/react/components/AppProvider/AppProvider.mjs
3 │ import englishI18n from '@shopify/polaris/locales/en.json' with { type: 'json' };
    at SsrFunction.buildAssetFromHandler (file:///ssd2/Projects/sst-app/node_modules/sst/constructs/SsrFunction.js:225:19)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async file:///ssd2/Projects/sst-app/node_modules/sst/constructs/SsrFunction.js:65:19
    at process.<anonymous> (file:///ssd2/Projects/sst-app/node_modules/sst/cli/sst.js:58:21)
    at process.emit (node:events:531:35)
    at process.emit (node:domain:488:12)
    at process._fatalException (node:internal/process/execution:178:25)
    at processPromiseRejections (node:internal/process/promises:289:13)
    at process.processTicksAndRejections (node:internal/process/task_queues:96:32)
lizkenyon commented 5 days ago

Hi there 👋

This is most likely an issue with the Node version. In Node 22 removed import assertions, and replaced them with import attributes, but they were only patched into specific older node versions.

Can you try one of these Node versions

 "node": "^18.20 || ^20.10 || >=21.0.0"
theoldfather commented 5 days ago

This is my engine config and my local build version is Node v21.7.3.

"engines": {
    "node": "^20.10 || >=21.0.0"
  },

So far my very hacky and unsatisfying work around is to use a vite plugin:

// vite-import-assertion-plugin.ts
import { transformAsync } from '@babel/core';
import { Plugin } from 'vite';

export default function importAssertionPlugin(): Plugin {
  return {
    name: 'vite-plugin-import-assertion',
    async transform(code: string, id: string): Promise<string | undefined> {
      if (id.includes('node_modules') || !id.endsWith('.mjs')) {
        return undefined;
      }

      const result = await transformAsync(code, {
        filename: id,
        plugins: [
          ['@babel/plugin-syntax-import-assertions'],
        ],
        presets: [
          ['@babel/preset-env', { targets: { node: 'current' } }],
        ],
      });

      return result?.code ?? undefined;
    },
  };
}
// vite.config.ts
...
import importAssertionPlugin from './vite-import-assertion-plugin';
...
plugins: [
    importAssertionPlugin(),
    remix({
      ignoredRouteFiles: ["**/.*"],

    }),
    tsconfigPaths(),
  ],
...

// stacks/stacks.ts
const site = new RemixSite(stack, "site", {
...
      nodejs: {
            esbuild: {
              external: ["@aws-sdk/*"],
              loader: {
                '.json': 'json',
              },
              plugins:[
                {
                  name: 'import-assertion',
                  setup(build) {
                    build.onLoad({ filter: /\.mjs$/ }, async (args) => {
                      const fs = require('fs');
                      let contents = await fs.promises.readFile(args.path, 'utf8');
                      contents = contents.replace(/import .+ from .+ with { type: 'json' };/g, (match) => {
                        return match.replace(' with { type: \'json\' }', '');
                      });
                      return { contents, loader: 'js' };
                    });
                  },
                }
              ]
            },
          },
....
lizkenyon commented 5 days ago

Thank you for the update. And glad to hear you found a workaround for now.

If you are able to provide a minimal repo to reproduce this, as well as the Node versions you are using, we may be able to look into this further to see if there is a better solution for your use case.