Search code examples
reactjslaravelviteshopify-app

Uncaught ReferenceError: require is not defined [Shopify PHP-React Browser issue]


I've create a Shopify app using PHP template and react front-end template and it works fine on local with all the code. However, the issue comes when I change the app environment to 'production'. I understand that on changing environment to production the entry point changes to public and public/index.html is accessed. Inside which I find the following code:

<!DOCTYPE html> 
<html lang="en"> 
    <head> 
        <meta charset="UTF-8" />
        <!-- Ensures that the UI is properly scaled in the Shopify Mobile app -->
        <meta name="viewport" content="width=device-width, initial-scale=1">
        
        
        <script type="module" crossorigin src="/assets/index-c9af863b.js"></script>
        <link rel="stylesheet" href="/assets/index-f14d2172.css">
    </head> 
    <body> 
        <div id="app"><!--index.jsx injects App.jsx here--></div>
    </body> 
</html>

on npm run build, vite builds the js files and that's when the issue occurs. When index.html is accessed it throws "Uncaught ReferenceError: require is not defined" error at the following line:

var wb = require("react")

Even though I have not used require anywhere and it's a fresh Shopify template for PHP. It seems like some other dependency is causing the issue or there is some issue with vite build.

Package.json file:

{
  "name": "shopify-frontend-template-react",
  "version": "1.0.0",
  "private": true,
  "license": "UNLICENSED",
  "scripts": {
    "build": "vite build",
    "dev": "vite",
    "coverage": "vitest run --coverage"
  },
  "type": "module",
  "engines": {
    "node": ">= 12.16"
  },
  "stylelint": {
    "extends": "@shopify/stylelint-polaris"
  },
  "dependencies": {
    "@formatjs/intl-locale": "^3.3.2",
    "@formatjs/intl-localematcher": "^0.4.0",
    "@formatjs/intl-pluralrules": "^5.2.4",
    "@shopify/app-bridge": "^3.7.7",
    "@shopify/app-bridge-react": "^3.7.7",
    "@shopify/i18next-shopify": "^0.2.3",
    "@shopify/polaris": "^10.49.1",
    "@vitejs/plugin-react": "1.2.0",
    "i18next": "^23.1.0",
    "i18next-resources-to-backend": "^1.1.4",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-i18next": "^13.0.0",
    "react-query": "^3.34.19",
    "react-router-dom": "^6.3.0",
    "vite": "^4.3.9"
  },
  "devDependencies": {
    "@shopify/stylelint-polaris": "^12.0.0",
    "history": "^5.3.0",
    "jsdom": "^19.0.0",
    "prettier": "^2.6.0",
    "stylelint": "^15.6.1",
    "vi-fetch": "^0.6.1"
  }
}

The following things I have already tried:

  • Add/Remove "type" from Package.json
  • Change vite.config.js -> vite.config.mjs
  • Import React from 'react' in Index.jsx file
  • Tried building app using react-app and react-app-rewired

The templates I have tried with:

However, I have not found any solution for this issue.


Solution

  • I was able to resolve this issue:

    There are other ways to call in dependency in JavaScript aside from the require() method. In fact, we can instruct Vite to “transform” statements like require which are not browser friendly, to browser friendly declaration during its asset building.

    To do this, we can revise the vite.config.js ( in the shopify-php template’s case, found in web/frontend/vite.config.js ) to add this “build” instruction through “transformMixedEsModules”. See the below updated function

    export default defineConfig({
      root: dirname(fileURLToPath(import.meta.url)),
      plugins: [react()],
      define: {
        "process.env.SHOPIFY_API_KEY": JSON.stringify(process.env.SHOPIFY_API_KEY),
      },
      resolve: {
        preserveSymlinks: true,
      },
      server: {
        host: "localhost",
        port: process.env.FRONTEND_PORT,
        hmr: hmrConfig,
        proxy: {
          "^/(\\?.*)?$": proxyOptions,
          "^/api(/|(\\?.*)?$)": proxyOptions,
        },
      },
      build: {
        commonjsOptions: {
          transformMixedEsModules: true
        }
      },
    });