meggsimum / geoserver-node-client

Node.js client for GeoServer REST API
BSD 2-Clause "Simplified" License
51 stars 16 forks source link

node-fetch v3 is an ESM-only and throw error ERR_REQUIRE_ESM #226

Open cesco69 opened 4 months ago

cesco69 commented 4 months ago

Hi, I'm on Node.js 20 with typescript, when try to use geoserver-node-client I see this error into the console

Error [ERR_REQUIRE_ESM]: require() of ES Module \node-fetch@3.3.2\node_modules\node-fetch\src\index.js from \geoserver-node-client@1.4.2\node_modules\geoserver-node-client\dist\src\layer.js not supported.
Instead change the require of index.js in \geoserver-node-client@1.4.2\node_modules\geoserver-node-client\dist\src\layer.js to a dynamic import() which is available in all CommonJS modules.
    at Object.<anonymous> (\geoserver-node-client@1.4.2\node_modules\geoserver-node-client\dist\src\layer.js:12:41) {
  code: 'ERR_REQUIRE_ESM'
}

From the node-fetch package readme:

node-fetch is an ESM-only module - you are not able to import it with require. We recommend you stay on v2 which is built with CommonJS unless you use ESM yourself. We will continue to publish critical bug fixes for it.

If you want to require it, then downgrade to v2.

The other option you have is to use async import('node-fetch'), eg.:

  /**
   * Get the GeoServer version.
   *
   * @throws Error if request fails
   *
   * @returns {Object} The version of GeoServer
   */
  async getVersion () {
    const url = this.url + 'about/version.json';
    const response = await (await import('node-fetch')).default(url, {
      credentials: 'include',
      method: 'GET',
      headers: {
        Authorization: this.auth
      }
    });

    if (!response.ok) {
      const geoServerResponse = await getGeoServerResponseText(response);
      throw new GeoServerResponseError(null, geoServerResponse);
    }
    return response.json();
  }

or use CommonJS https://github.com/node-fetch/node-fetch?tab=readme-ov-file#commonjs eg.:

const fetch = (...args) => import('node-fetch').then(({default: fetch}) => fetch(...args));

The workaround for use latest geoserver-node-client is install old node-fetch 2.6.8:

npm i node-fetch@2.6.8
chrismayer commented 3 months ago

Hi @cesco69 , thanks for your issue, your analysis and your workarounds :+1: Do you think this is only TypeScript related? Not really, or what do you think?

I have to dig a bit to fully understand whats going on and think what could be the best solution for this. I'll come back to this...