Ricerca nel sito web

javascript - Come risolvere l'errore 'require() di ES Module non supportato' durante l'aggiornamento da Angular 12 a 13?


Require() dei moduli ES non supportato durante l'aggiornamento da Angular 12 a 13

Ho aggiornato tutti i miei pacchetti per supportare Angular 13, ho provato a cancellare node_modules, package-lock.json, dist e a eseguire npm install
ma ancora dopo la compilazione in main.js platform-browser viene importato tramite require, il che potrebbe causare questo problema

Versione provata

Versione di Node - 16.20.0

TypeScript - 4.4.3, 4.6.0

L'errore viene visualizzato nella console quando l'app si apre dopo che ng serve ha compilato correttamente

Errore: require() del modulo ES /node_modules/@angular/platform-browser/fesm2015/platform-browser.mjs non supportato. Invece, modifica il require di /node_modules/@angular/platform-browser/fesm2015/platform-browser.mjs in un import() dinamico, che è disponibile in tutti i moduli CommonJS. at __node_internal_captureLargerStackTrace (node:internal/errors:477:5) at new NodeError (node:internal/errors:387:5) at Module.load (node:internal/modules/cjs/loader:1009:11) at Module._load (node:internal/modules/cjs/loader:846:12) at f._load (node:electron/js2c/asar_bundle:2:13330) at o._load (node:electron/js2c/renderer_init:2:3109) at Module.require (node:internal/modules/cjs/loader:1035:19) at require (node:internal/modules/cjs/helpers:102:18) at 7258 (main.js:1:1070126) at r (runtime.js:1:127) at R (main.js:1:2708253) at main.js:1:2708270 at n (runtime.js:1:3008) at main.js:1:57

Package.json:

  "dependencies": {
    "@angular/animations": "~13.4.0",
    "@angular/cdk": "^13.3.9",
    "@angular/common": "13.4.0",
    "@angular/core": "13.4.0",
    "@angular/forms": "~13.4.0",
    "@angular/material": "^13.3.9",
    "@angular/platform-browser": "~13.4.0",
    "@angular/platform-browser-dynamic": "~13.4.0",
    "@angular/router": "~13.4.0",
    "@grpc/grpc-js": "^1.2.12",
    "angular-plotly.js": "^1.8.0",
    "archiver": "^4.0.2",
    "async-waterfall": "^0.1.5",
    "blockly": "^5.20210325.0",
    "bootstrap": "^4.5.2",
    "chokidar": "^3.5.2",
    "crypto-js": "^4.0.0",
    "dom-to-image": "^2.6.0",
    "downloads-folder": "^3.0.1",
    "electron-json-storage": "^4.5.0",
    "electron-log": "^4.4.1",
    "exceljs": "^4.3.0",
    "file-saver": "^2.0.2",
    "form-data": "^4.0.0",
    "google-protobuf": "^3.13.0",
    "http-server": "^0.12.3",
    "jquery": "^3.5.1",
    "lodash": "^4.17.21",
    "masonry-layout": "^4.2.2",
    "moment": "^2.29.1",
    "moment-timezone": "^0.5.32",
    "ng-circle-progress": "^1.5.1",
    "ng-click-outside": "^6.0.0",
    "ngx-filter-pipe": "^2.1.2",
    "plotly.js": "^2.9.0",
    "resize-observer-polyfill": "^1.5.1",
    "rxjs": "^6.5.3",
    "rxjs-compat": "^6.6.3",
    "split2": "^3.2.2",
    "systeminformation": "^5.11.9",
    "tslib": "^2.0.0",
    "yargs": "^17.0.1",
    "zone.js": "~0.11.4"
  },
  "devDependencies": {
    "@angular-builders/custom-webpack": "^13.1.0",
    "@angular-devkit/build-angular": "~13.0.2",
    "@angular/cli": "~13.0.2",
    "@angular/compiler": "~13.4.0",
    "@angular/compiler-cli": "~13.4.0",
    "@angular/language-service": "~13.4.0",
    "@types/crypto-js": "^4.0.1",
    "@types/jasmine": "~3.6.0",
    "@types/jasminewd2": "~2.0.3",
    "@types/lodash": "^4.14.168",
    "@types/node": "^14.14.37",
    "codelyzer": "^6.0.0",
    "electron": "^22.2.1",
    "electron-builder": "^23.1.0",
    "protractor": "~7.0.0",
    "ts-node": "~8.3.0",
    "tslint": "~6.1.0",
    "typescript": "~4.6.4",
    "webpack": "^5.84.1",
    "webpack-node-externals": "^2.5.2"
  }

Risposta n. 1

Sì, abbiamo affrontato questo problema durante l'aggiornamento di Angular dalla versione 12 alla 13 e avevamo "type": "commonjs" presente nel nostro package.json.

Un cambiamento importante effettuato dagli sviluppatori di Angular è che non forniscono più i moduli CommonJS, ma solo i moduli ESM (file MJS). Quindi, se proviamo a caricare pacchetti Angular 13 come core, platform-browser ecc. con la sintassi CommonJS (require('@angular/core')), verrà visualizzato l'errore require() of ES Module not supported.

Abbiamo aggiornato le dipendenze come TypeScript, Node e tutto il resto, reinstallato i moduli di Node e svuotato la cache di npm e Angular più volte, ma nulla ha funzionato per noi.

Nel nostro progetto (Angular + Electron), stavamo usando alcuni dei moduli node (come 'os', 'fs', ecc.) che di solito non sono disponibili nei browser per ovvie ragioni di sicurezza. Quindi stavamo usando un webpack personalizzato per bundlare questi moduli node. Nella configurazione di webpack, possiamo passare l'elenco dei moduli node esterni che devono essere esposti nel browser. Questo elenco di externals includeva anche i pacchetti @angular (In realtà, avevamo inserito tutti i moduli node usando webpack-node-externals nella lista delle dipendenze esterne). Il bundle generato aveva quindi le importazioni commonJS, cioè require() per le dipendenze esterne. Quindi, ci dava l'errore require() of ES Module not supported.

Per impostazione predefinita, l'angular webpack generava solo le importazioni ESM, ma poiché avevamo specificato angular nelle dipendenze esterne, stavamo ottenendo quell'errore. Quindi ci sono rimaste due opzioni

  • Rimuovere i pacchetti Angular dall'elenco degli esterni. Si consiglia di mantenere questo elenco il più piccolo possibile.
  • Configura il builder webpack personalizzato per generare anche importazioni ESM per gli esterni.

Abbiamo optato per la prima opzione e ha funzionato alla perfezione.

Risposta n. 2

RIGUARDO IL PROBLEMA REALE

Prova ad aggiornare a v13.1.4, penso che questo lo risolverà. Ho avuto questo tipo di problema, si è risolto per me.

INFORMAZIONI AGGIUNTIVE

Prima di tutto... NON ELIMINARE package-lock.json. Questo tipo di problemi si verifica nella maggior parte dei casi proprio quando lo elimini continuamente, c'è un lock nel nome per qualcosa che sai, mantiene l'exact, l'albero delle dipendenze perfettamente funzionante, mentre package.json contiene approssimazioni. Ecco perché si genera node_modules con npm ci e non con npm i, perché genererà/rigenererà i node_modules basandosi su package-lock causando errori se non è presente.

Non cancelli mai e poi mai lock.json in un progetto dove hai così tante dipendenze di terze parti. Non si tratta della capacità di rigenerarlo, naturalmente puoi rigenerarlo con npm i, il problema è che non conterrà più lo stesso identico albero delle dipendenze, perché npm i installa i pacchetti basandosi sui criteri di ^ e ~. Questi criteri consentono a npm di installare aggiornamenti dei pacchetti anche se il pacchetto principale non è stato adattato per usare l'aggiornamento.

Per darti un'idea, è qualcosa del genere: Immagina di installare un pacchetto X v.1 che utilizza la dipendenza pacchetto Y v.1.

Ecco, andiamo a cancellare package-lock e usare npm i per rigenerarlo.

Ora risulta che package X ha rilasciato un aggiornamento quindi ora è v.2 e necessita di package Y v.2, quindi npm i li installa a causa del prefisso che ha in package.json.

Ed ecco arrivare la bomba >>> abbiamo anche package C v.1 che in precedenza utilizzava anche package Y v.1 come dipendenza, ma ora ha un'incompatibilità perché package C continua a essere v.1 ma package Y è ora v.2,

Questo significa che in un grande progetto c'è una probabilità molto bassa che il package-lock rigenerato mantenga lo stesso albero delle dipendenze di quello precedente. Potresti risolvere un conflitto cancellandolo, ma probabilmente rovinerai l'intero albero delle dipendenze e non sarai in grado di eseguire il progetto poiché avrai molte discrepanze e incompatibilità tra i pacchetti.

Devi sempre risolvere i problemi dei pacchetti senza eliminare package-lock, è l'ultima opzione se puoi anche chiamarla opzione. Perché non puoi eliminare la versione esatta dell'albero delle dipendenze dove la maggior parte delle cose va bene.

Articoli correlati