Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

1.8K
Views
Comprender esModuleInterop en el archivo tsconfig

Estaba revisando el archivo .tsconfig de alguien y allí vi --esModuleInterop

Este es su archivo .tsconfig

 { "compilerOptions": { "moduleResolution": "node", "target": "es6", "module": "commonjs", "lib": ["esnext"], "strict": true, "sourceMap": true, "declaration": true, "esModuleInterop": true, "allowSyntheticDefaultImports": true, "experimentalDecorators": true, "emitDecoratorMetadata": true, "declarationDir": "./dist", "outDir": "./dist", "typeRoots": ["node_modules/@types"] }, "include": ["src/**/*.ts"], "exclude": ["node_modues"] }

Aquí, mi pregunta principal es qué es "esModuleInterop": true, y "allowSyntheticDefaultImports": true, . Sé que dependen del "module": "commonjs", . ¿Puede alguien tratar de explicarlo en el mejor lenguaje humano posible?

Los documentos oficiales para los estados allowSyntheticDefaultImports

Permitir importaciones predeterminadas desde módulos sin exportación predeterminada. Esto no afecta la emisión del código, solo la verificación de tipos.

¿Que significa eso? Si no hay ningún valor predeterminado de exportación, creo que el único caso de uso del valor predeterminado de importación sería inicializar algo. ¿Como un soltero?

La siguiente pregunta/respuesta tampoco tiene sentido. ¿Hay alguna manera de usar --esModuleInterop en tsconfig en lugar de que sea una bandera?

Y --esModuleInterop definición en la página del compilador

Emita los ayudantes __importStar y __importDefault para la compatibilidad con el ecosistema babel en tiempo de ejecución y habilite --allowSyntheticDefaultImports para la compatibilidad con el sistema de tipos.

También me pareció difícil de entender/comprender

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

esModuleInterop genera los ayudantes descritos en los documentos. Mirando el código generado, podemos ver exactamente lo que hacen:

 //ts import React from 'react' //js var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); var react_1 = __importDefault(require("react"));

__importDefault : si el módulo no es un módulo es, lo que devuelve require se convierte en el valor predeterminado. Esto significa que si usa la importación predeterminada en un módulo commonjs , todo el módulo es en realidad el predeterminado.

__importStar se describe mejor en este PR :

TypeScript trata una importación de espacio de nombres (es decir, import * as foo from "foo" ) como equivalente a const foo = require("foo") . Las cosas son simples aquí, pero no funcionan si el objeto principal que se importa es un primitivo o un valor con firmas de llamada/construcción. ECMAScript básicamente dice que un registro de espacio de nombres es un objeto simple.

Babel primero requiere en el módulo y busca una propiedad llamada __esModule . Si __esModule se establece en true , el comportamiento es el mismo que el de TypeScript, pero de lo contrario, sintetiza un registro de espacio de nombres donde:

  1. Todas las propiedades se extraen del módulo requerido y se ponen a disposición como importaciones con nombre.
  2. El módulo requerido originalmente está disponible como una importación predeterminada.

Entonces obtenemos esto:

 // ts import * as React from 'react' // emitted js var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; result["default"] = mod; return result; }; Object.defineProperty(exports, "__esModule", { value: true }); var React = __importStar(require("react"));

allowSyntheticDefaultImports es el compañero de todo esto, establecer esto en falso no cambiará los ayudantes emitidos (ambos seguirán teniendo el mismo aspecto). Pero generará un error de mecanografiado si está utilizando la importación predeterminada para un módulo commonjs. Entonces, esta import React from 'react' generará el error Module '".../node_modules/@types/react/index"' has no default export. si allowSyntheticDefaultImports es false .

over 4 years ago · Santiago Trujillo Report

0

Planteamiento del problema

El problema ocurre cuando queremos importar el módulo CommonJS al código base del módulo ES6.

Antes de estas banderas, teníamos que importar módulos CommonJS con la importación de estrella ( * as something ):

 // node_modules/moment/index.js exports = moment
 // index.ts file in our app import * as moment from 'moment' moment(); // not compliant with es6 module spec // transpiled js (simplified): const moment = require("moment"); moment();

Podemos ver que * era de alguna manera equivalente a la variable exports . Funcionó bien, pero no cumplía con las especificaciones de los módulos es6. En especificaciones, el registro de espacio de nombres en la importación de estrellas ( moment en nuestro caso) puede ser solo un objeto simple, no invocable ( moment() no está permitido).

Solución

Con la bandera esModuleInterop podemos importar módulos CommonJS de acuerdo con las especificaciones de los módulos es6 . Ahora nuestro código de importación se ve así:

 // index.ts file in our app import moment from 'moment' moment(); // compliant with es6 module spec // transpiled js with esModuleInterop (simplified): const moment = __importDefault(require('moment')); moment.default();

Funciona y es perfectamente válido con las especificaciones de los módulos es6, porque el moment no es un espacio de nombres de la importación de estrellas, es una importación predeterminada.

pero como funciona? Como puede ver, debido a que hicimos una importación predeterminada, llamamos a la propiedad default en un objeto de moment . Pero no declaramos una propiedad default en el objeto de exports en la biblioteca de momentos. La clave es la función __importDefault . Asigna módulo ( exports ) a la propiedad default para módulos CommonJS:

 var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; };

Como puede ver, importamos los módulos es6 tal como están, pero los módulos CommonJS están envueltos en un objeto con la clave default . Esto hace posible importar valores predeterminados en módulos CommonJS.

__importStar hace un trabajo similar: devuelve esModules intactos, pero traduce los módulos CommonJS en módulos con una propiedad default :

 // index.ts file in our app import * as moment from 'moment' // transpiled js with esModuleInterop (simplified): const moment = __importStar(require("moment")); // note that "moment" is now uncallable - ts will report error!
 var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; result["default"] = mod; return result; };

Importaciones sintéticas

¿Y qué pasa con allowSyntheticDefaultImports ? ¿Para qué sirve? Ahora los documentos deberían ser claros:

Allow default imports from modules with no default export. This does not affect code emit, just typechecking.

En la escritura de moment , no tenemos una exportación predeterminada especificada, y no deberíamos tenerla, porque solo está disponible con la esModuleInterop . Por lo tanto, allowSyntheticDefaultImports no informará un error si queremos importar el valor predeterminado de un módulo de terceros que no tiene una exportación predeterminada.

over 4 years ago · Santiago Trujillo Report

0

En mi caso (estoy usando un proyecto mecanografiado en VS2019 y reacciono v16.13.xx) tuve que reemplazar

 import React from 'react';

con

 declare var require: any var React = require('react');

Y funcionó

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!