javascriptnode.jsparse-server

How to make parse-server detect I'm using ESM now?


I want to use ESM instead of CommonJS in my Node.js server is used to run ParseServer (version 6.4.0). I adapt my code. However, Parse-Server doesn't detect that I'm using ECM now and is throwing the following error:

require() of ES Module ../main.js from ../node_modules/parse-server/lib/ParseServer.js not supported.
Instead change the require of main.js in ../node_modules/parse-server/lib/ParseServer.js to a dynamic import() which is available in all CommonJS modules.

I found a solution by forcing the use of ESM via my npm start command : npm_package_type=module node app.js

But that's not a viable solution, as it should work from scratch.

To switch to ESM, I change theses line in my package.json :

  "type": "module",
  "engines": {
    "node": ">=16"
  },

I also use import/export in all my files. What should I also do to make parse-server aware I'm now in ECM?

Looking into parseServer code, it crashes here:

   if (process.env.npm_package_type === 'module' || ((_json = json) === null || _json === void 0 ? void 0 : _json.type) === 'module') {
            await import(path.resolve(process.cwd(), cloud));
          } else {
            require(path.resolve(process.cwd(), cloud));
          }

It crashes because it goes into the require part which is not allow for ESM instead of the import part. It only works when I change my npm start command and force it.


Solution

  • I eventually found a solution using this link that @SuatKarabacak suggested.

    To make it works, I have to create a async function in my main.js then export it as a default. It look like:

    const cloud = async function() {
        await import("./file.js"); // it contains cloud functions
        /**
         * parse bindings
         * @type {ParseClass}
         */
        const ParseClass = (await import("./ParseClass.js"))["default"];
    
        Parse.Object.registerSubclass("ParseClass", ParseClass);
    }
    
    export default cloud;
    

    Then in my index.js, I imported it:

    import cloud from "./cloud/main.js";
    

    and I use it directly in the config object of ParseServer

    new ParseServer({
    cloud,
    ...
    });
    

    I don't test if my classes have issues and I'll let you know if that's the case but my cloud functions work.