How to include ESM dependencies in Netlify functions?

Please help!

My build/bundle successfully but the function errors when it’s run.

Request from ::1: POST /.netlify/functions/esm-muxter
Error importing Turboship: /Users/loi/Desktop/work/turboship/turboship/.netlify/functions-serve/esm-muxter/netlify/functions/esm-muxter/Turboship/Turboship.js:1

import chalk from 'chalk'
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at internalCompileFunction (node:internal/vm:73:18)
    at wrapSafe (node:internal/modules/cjs/loader:1178:20)
    at Module._compile (node:internal/modules/cjs/loader:1220:27)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1310:10)
    at Module.load (node:internal/modules/cjs/loader:1119:32)
    at Function.Module._load (node:internal/modules/cjs/loader:960:12)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/translators:169:29)
    at ModuleJob.run (node:internal/modules/esm/module_job:194:25)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
  1. I have a ESM Netlify function(esm-muxter).
  2. It’s defined using ESM syntax & netlify.toml config [functions] value of “node_bundler=esbuild”
  3. I’ve included dependency files locally which I need for the function to run(ESM).
  4. When I bundle the function, the entry file is parsed to CJS but the dependency files are not
  5. Errors throw when function is invoked complaining “import statements cannot be used in CJS…” etc.
  6. These are coming from my dependency files.

My questions are

  • How can I make “netlify functions:build” recursively parse my ESM to CJS like it does the entry file?
  • Or how can I make “netlify functions:build” respect my configuration choice(ESM) so that the dependency files work correctly?

Correct me if I’m wrong. I think that the function should maintain ESM syntax(from the netlify.toml config). However I see

  • The functions package.json is type: commonjs. The package.json inside of ./.netlify/functions-server/…/…/package.json
  • Entrypoint file is parsed to Cjs format…
"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// lots more...

The site is
https://turboship.netlify.app



Thanks for your help in advance~!

ESM works without any extra hassle. It usually just works. If it doesn’t, we’d need a reproduction repo. I currently have the working on several of my projects, an example right here: lambda-network-interfaces/netlify/functions/get.js at main · Hrishikesh-K/lambda-network-interfaces (github.com)