google-wallet / pass-converter

Tool to convert passes for different wallet apps from one format to another
Apache License 2.0
206 stars 29 forks source link

ERR_REQUIRE_ESM with strip-json-comments module #35

Closed pandafour closed 2 months ago

pandafour commented 2 months ago

Apologies in advance if this isn't the right way to report this. However, while trying to run this as a node.js app on a web server I kept receiving the following error message...

const stripJsonComments = require('strip-json-comments');
                          ^
Error [ERR_REQUIRE_ESM]: require() of ES Module /public_html/wp-content/plugins/tickera-wallet-passes/pass-converter/node_modules/strip-json-comments/index.js from /public_html/wp-content/plugins/tickera-wallet-passes/pass-converter/config.js not supported.
Instead change the require of index.js in /public_html/wp-content/plugins/tickera-wallet-passes/pass-converter/config.js to a dynamic import() which is available in all CommonJS modules.
    at Object.<anonymous> (/public_html/wp-content/plugins/tickera-wallet-passes/pass-converter/config.js:17:27)
    at Object.<anonymous> (/public_html/wp-content/plugins/tickera-wallet-passes/pass-converter/pass/index.js:27:16)
    at Object.<anonymous> (/public_html/wp-content/plugins/tickera-wallet-passes/pass-converter/app.js:20:14) {
  code: 'ERR_REQUIRE_ESM'
}

In case anyone else comes across this, I was able to fix it by using jsonc-parser instead of strip-json-comments since it is CommonJS-compatible. I also removed strip-json-trailing-commas sincejsonc-parser can handle JSON with comments and doesn't require stripping trailing commas separately. Not sure this is a proper fix or not, but it worked for me at least.

Change the config.js file to be:

const { parse } = require('jsonc-parser');
const fs = require('fs');
const path = require('path');

// The Proxy wrapper ensures config is lazily loaded, so we can redefine
// PASS_CONVERTER_CONFIG_PATH at runtime, which we do in the tests.
module.exports = new Proxy(
  {},
  {
    get(target, prop, receiver) {
      if (this._config === undefined) {
        const configPath = process.env.PASS_CONVERTER_CONFIG_PATH || path.resolve(__dirname, 'config.json');
        const configContent = fs.readFileSync(configPath, 'utf8'); // Ensure content is a string
        // Parse the JSON content with comments handled by jsonc-parser
        this._config = parse(configContent);
        // Most of the entries default to empty strings, but code may expect them to be
        // undefined since they were originally env vars, so filter these out to retain the behavior.
        this._config = Object.fromEntries(Object.entries(this._config).filter(([key, value]) => value !== ''));
      }
      return this._config[prop];
    },
  },
);

Change the package.json file to be:

{
  "dependencies": {
    "@google-cloud/storage": "^6.12.0",
    "adm-zip": "^0.5.10",
    "airlines-iata-codes": "^1.0.1",
    "apn": "^1.6.2",
    "axios": "^1.3.1",
    "chrono-node": "^2.6.4",
    "express": "^4.18.2",
    "express-fileupload": "^1.4.0",
    "fix-esm": "^1.0.0",
    "google-auth-library": "^9.0.0",
    "jsonwebtoken": "^9.0.1",
    "jsonc-parser": "^3.0.0",
    "nanoid": "^3.3.6",
    "node-cache": "^5.1.2",
    "node-fetch": "^3.3.2",
    "open": "^8.4.2",
    "sqlite3": "^5.1.6",
    "strip-comments": "^2.0.1",
    "tinycolor2": "^1.6.0",
    "typeorm": "^0.3.17"
  },
  "scripts": {
    "test": "jest"
  },
  "devDependencies": {
    "jest": "^27.5.1",
    "prettier": "2.7.1"
  }
}
pandafour commented 2 months ago

Fix reported above.