Plan ESM migration for Azure Functions Node.js Worker
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 5/5
- Tempo stimato
- Più di una settimana
- Idoneità per principianti
- 30/100
- Tipo di issue
- Refactoring
- Chiarezza
- Abbastanza chiara
- Stato di attività
- Tranquilla
- Stack tecnologico
- node.js, typescript, webpack
- Ambito
- backend, build-system
Direzione di ricerca
Inizia leggendo nodejsWorker.js e loadScriptFile.ts, quindi esamina l'attuale generazione dei proto e la configurazione di webpack. Esamina le issue correlate #791 e #804 e identifica i controlli di compatibilità necessari per le applicazioni cliente CJS ed ESM. Il lavoro sarà considerato completato quando sarà concordato un piano di migrazione circoscritto, con fasi, modifiche alle dipendenze e criteri di convalida.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Summary
The Node.js ecosystem is steadily moving toward ES Modules (ESM) as the default module system. Several key dependencies of the Azure Functions Node.js Worker have already shipped ESM-only major versions, and Node.js itself is on a path to make ESM the default. The Worker currently uses CommonJS throughout, which will become increasingly difficult to maintain.
Key Insight: Worker ESM migration does NOT break customer code
The Worker loads customer code via dynamic import() or require() based on the customer's own package.json "type" field and file extension (.mjs/.cjs). See loadScriptFile.ts:
if (isESModule(filePath, packageJson)) {
script = await eval('import(fileUrl.href)'); // ESM customer code
} else {
script = require(filePath); // CJS customer code
}
The Worker's internal module system and the customer's module system are independent. Node.js supports CJS and ESM coexisting in the same process. Therefore:
| Layer | Current | After Worker ESM migration |
|---|---|---|
| Worker (internal) | CJS | ESM |
| @azure/functions library | Dual (CJS + ESM) | Maintain dual support |
| Customer code | CJS or ESM (user choice) | No change |
This means:
- Worker can safely migrate to ESM-only internally — it is not exposed to customers
@azure/functionslibrary should maintain dual CJS/ESM support in the current major version (4.x)- Library 5.x can go ESM-only with sufficient migration period (keep 4.x CJS support for 1+ year)
Ecosystem Facts
Node.js: ESM as default is in progress
- Node.js TSC discussed making
--default-type=modulethe default (nodejs/TSC#1445) - Node.js 22.7.0+ can auto-detect module format (
require()of ESM modules) - Node.js 26.0.0 (released May 2026) removed
--experimental-default-typeand--experimental-transform-types, continuing the trend toward ESM-first - PR to mark CommonJS as legacy in Node.js docs: nodejs/node#57460
- npm CLI issue to default
npm init --type=module: npm/cli#8159 - Node.js continues to support CommonJS but is shifting it to opt-in rather than opt-out
Key npm packages going ESM-only
Several packages in the Worker's dependency chain have shipped ESM-only versions:
- long@5 (ESM-only): Required by
@grpc/proto-loader >= 0.7.9andprotobufjs >= 8.0 - chalk@5, ora@6, globby@13, got@13, node-fetch@3, execa@6: Popular utilities that dropped CommonJS in major versions
- sindresorhus ecosystem: One of the largest package authors, ESM-only since 2021
protobufjs 8.x: ESM migration pressure on gRPC stack
protobufjs 8.0 depends on long@5 (ESM-only). This blocks upgrading:
@grpc/proto-loader >= 0.7.9requireslong@5@grpc/[email protected]requiresprotobufjs ^7.5.3(still v7, butlong@5)- The Worker's proto generation script uses
pbjs -w commonjs, which would need to change to-w es6
Current Worker State
- Worker entry point (
nodejsWorker.js) usesrequire() - Proto generation uses
pbjs -w commonjsoutput format - webpack bundles everything into CommonJS (
libraryTarget: 'commonjs2') - All source files use CommonJS
require()/module.exports @grpc/[email protected]and@grpc/[email protected]are pinned to avoidlong@5
Migration Strategy
Phase 1: Worker internal ESM migration (no customer impact)
- Migrate Worker source from CommonJS to ESM (TypeScript with ESM output)
- Update proto generation from
pbjs -w commonjstopbjs -w es6 - Update webpack config (
libraryTarget) or switch to ESM-compatible bundler - Bump
@grpc/proto-loaderto 0.8.x and@grpc/grpc-jsto latest - Upgrade
protobufjsto 8.x,protobufjs-clito 2.x,longto v5 - Validation: E2E test with both CJS and ESM customer function apps to confirm backward compatibility
- Target: Can be done as a focused effort with comprehensive testing
Phase 2: Library dual support (current 4.x)
- Ensure
@azure/functions4.x continues to provide dual CJS/ESM exports - Validate that ESM Worker + CJS library + CJS customer code works end-to-end
- Validate that ESM Worker + ESM library + ESM customer code works end-to-end
Phase 3: Library ESM-only (future 5.x, customer impact)
- Release
@azure/functions5.x as ESM-only - Maintain
@azure/functions4.x with CJS support for at least 1 year after 5.x release - Provide clear migration documentation for customers
- Announce timeline well in advance
- This is the only phase that impacts customers
Related Issues and PRs
- #791 - Add ESM support for @azure/functions-core virtual module (open PR)
- #804 - protobufjs bump blocked protobufjs 8.x due to ESM-only
long@5(merged) - #803 - protobufjs vulnerability fix (closed)
- #344 - Add support for ES Modules (closed)
- #531 - Respect package.json type: module for ESM Functions (closed)
- #104 - Add ES6 Style Exports (open, 2018)
- nodejs/TSC#1445 - When to make --default-type=module the Node.js default
- nodejs/node#57460 - Mark CommonJS as legacy in docs
- Lingua principale
- TypeScript
- Stelle
- 110
- Fork
- 52
- Metriche di merge delle PR
- Nessuna PR unita negli ultimi 30g
Preparare l'ambiente
Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di Azure/azure-functions-nodejs-worker
-
Handle valid prerelease Node.js versions without failing worker initializationForse già presa @TsuyoshiUshio l’ha presa 71 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 74/100
-
area:nodejs-functions dependencies engineering tests
Difficoltà 5/5 Più di una settimana Idoneità per principianti 35/100
-
Specialization race: double startApp() with stale require cache leaves worker on default v3 model with all functions unloadableForse già presa @swapnil-nagar l’ha presa 76 giorni fa. Aperta
Difficoltà 5/5 Più di una settimana Idoneità per principianti 30/100
Azure/azure-functions-nodejs-worker#838 · 1 commento ·
-
c-ares DNS misconfiguration on Windows Consumption causes mongodb+srv:// and dns.resolve*() failuresAperta
Difficoltà 4/5 3-5 giorni Idoneità per principianti 64/100
Azure/azure-functions-nodejs-worker#830 · 1 commento ·
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 48/100
Tutte le issue di Azure/azure-functions-nodejs-worker
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
transitmatters/shutdown-tracker#155 ·
I maintainer di solito rispondono entro 2 giorni
-
Popping out a single panel leaves its always render overlay in the main window, blocking clicksApertabug triaged
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
I maintainer di solito rispondono entro 1 giorno
-
"Claude Code request is missing its initial user message" when the prompt starts with an image pathAperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 84/100
earendil-works/pi-claude-code#31 ·
I maintainer di solito rispondono entro 8 giorni
-
bug pending triage
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 92/100
privatenumber/cleye#48 ·