ReferenceError do Typescript: as exportações não estão definidas


105

Ao tentar implementar um módulo seguindo o manual oficial , recebo esta mensagem de erro:

ReferenceError não capturado: as exportações não estão definidas

em app.js: 2

Mas em nenhum lugar do meu código eu uso o nome exports.

Como posso consertar isso?


arquivos

app.ts

let a = 2;
let b:number = 3;

import Person = require ('./mods/module-1');

módulo-1.t

 export class Person {
  constructor(){
    console.log('Person Class');
  }
}
export default Person;

tsconfig.json

{
   "compilerOptions": {
        "module": "commonjs",
        "target": "es5",
        "noImplicitAny": false,
        "sourceMap": true,
        "outDir": "scripts/"
    },
    "exclude": [
        "node_modules"
    ]
}

Copie e cole o texto do erro na pergunta em vez de usar capturas de tela.
Igor

Tem certeza de que não digitou exportscom um s no final em vez de export? Isso explicaria a mensagem de erro, pois s está errado.
Igor

eu digito exportação, não exportação
George C.

qualquer exemplo de repositório que funcionará 10000%
George C.

Onde isso está sendo executado? Em uma página da web? Em um servidor node.js? Você precisará de um carregador de módulo no ambiente de tempo de execução em que o javascript finalmente é executado. Dos sinalizadores do compilador, você está usando commonjs. Não estou tão familiarizado com commonjs, mas você precisará configurar o commonjs antes que os módulos do Typescript funcionem ou você precisará mudar para outro carregador de módulo (como require.js) e configurá-lo.
Mike Wodarczyk

Respostas:


41

EDITAR:

Esta resposta pode não funcionar, dependendo se você não estiver es5mais segmentando , tentarei tornar a resposta mais completa.

Resposta Original

Se o CommonJS não estiver instalado (o que defineexports ), você deve remover esta linha de tsconfig.json:

 "module": "commonjs",

De acordo com os comentários, isso sozinho pode não funcionar com versões posteriores do tsc. Se for esse o caso, você pode instalar um carregador de módulo como CommonJS, SystemJS ou RequireJS e, em seguida, especificar isso.

Nota:

Olhe para o main.jsarquivo que tscgerou. Você encontrará isso no topo:

Object.defineProperty(exports, "__esModule", { value: true });

É a raiz da mensagem de erro e, após a remoção "module": "commonjs",, desaparecerá.


3
Sim, recompilei meu arquivo .ts e o erro ainda existe depois de comentar "module": "commonJs",:(
Acidic9 de

2
Se a instalação do CommonJS fará com que esse erro desapareça, como alguém realmente instalará o CommonJS? Passei quase uma hora pesquisando no Google e não consigo encontrar nenhuma instrução sobre como fazer isso. Pode alguém por favor explicar?
Sturm

1
@Sturm Minha resposta pode ter uma formulação confusa. CommonJS é apenas uma especificação. Você pode encontrar uma lista (não necessariamente exaustiva) de implementações aqui: en.wikipedia.org/wiki/CommonJS
iFreilicht

1
Eu tenho o módulo: amd, não o módulo: commonjs, e tenho esta linha no meu arquivo .js transpilado.
pabrams

2
Se você tiver destino como ES3 ou ES5 em seu tsconfig.json, o typescript configurará automaticamente seu módulo para CommonJS se não estiver definido. Remover o módulo não é suficiente, você precisa definir outra coisa - consulte typescriptlang.org/docs/handbook/compiler-options.html
Jake

51

Algumas outras soluções para este problema

  • Adicione a seguinte linha antes de outras referências a Javascript. Este é um pequeno hack agradável.
   <script>var exports = {};</script>
  • Esse problema ocorre com a versão mais recente do TypeScript, esse erro pode ser eliminado consultando a versão 2.1.6 do typescript

3
@ChuckLeButt Espero que isso ajude stackoverflow.com/questions/19059580/…
Venkatesh Muniyandi

3
Eu odeio que isso funcione! E definitivamente funciona. Não há uma maneira de fazer com que o TypeScript transpile em algo que o Node espera? É mesmo Node que está reclamando? Ou é o navegador? Não suporto não entender qual é realmente o problema.
skillit zimberg

7

npm install @babel/plugin-transform-modules-commonjs

e adicionar aos plug-ins .babelrc resolveu minha dúvida.


7

minha solução é uma soma de tudo acima com pequenos truques que adicionei, basicamente adicionei isso ao meu código html

<script>var exports = {"__esModule": true};</script>
<script src="js/file.js"></script>

isso até permite que você use em importvez de requirese estiver usando elétron ou algo assim, e funciona bem com o texto datilografado 3.5.1, alvo: es3 -> esnext.


3
algum progresso aqui, o erro apenas mudou para serapp.js:3 Uncaught ReferenceError: require is not defined
Muhammed Moussa

isso acontece se nodeIntegration for definido como false ao criar a janela, o erro acontece porque você atualizou seu electronJS ou está seguindo uma fonte desatualizada. nodeIntegration era true por padrão, agora é false, então você deve habilitá-lo manualmente se quiser acessar nodeJS no processo de renderização. Veja [Electron require () is not defined] [1] [1]: stackoverflow.com/questions/44391448/…
Hocine Abdellatif

Não estou usando o elétron, de qualquer forma resolvi no meu caso adicionando pacote para fazer pacotes e removendo outras maneiras complicadas
Muhammed Moussa


5

Eu tive o mesmo problema e resolvi adicionando a biblioteca " es5 " ao tsconfig.json assim:

{
    "compilerOptions": {
        "target": "es5", //defines what sort of code ts generates, es5 because it's what most browsers currently UNDERSTANDS.
        "module": "commonjs",
        "moduleResolution": "node",
        "sourceMap": true,
        "emitDecoratorMetadata": true, //for angular to be able to use metadata we specify in our components.
        "experimentalDecorators": true, //angular needs decorators like @Component, @Injectable, etc.
        "removeComments": false,
        "noImplicitAny": false,
        "lib": [
            "es2016",
            "dom",
            "es5"
        ]
    }
}

5

Para as pessoas que ainda têm esse problema, se o destino do compilador estiver definido como ES6, você precisará dizer ao babel para pular a transformação do módulo. Para fazer isso, adicione isso ao seu .babelrcarquivo

{
  "presets": [ ["env", {"modules": false} ]]
}

1
Obrigado cara! Tenho tentado trabalhar com uma base de código mais antiga que despeja tudo em global e os scripts são incluídos no navegador com a <script>tag. Eu esperava usar o módulo junto com o código mais antigo e parece que não é possível. Isso me permite pelo menos usar o ES6 e lidar com a exportação mais tarde.
abraço de

2
ao fazer isso, obtive o seguinte erro: Usando a opção removida do Babel 5: .modules - Use o plug-in de transformação do módulo correspondente na pluginsopção. Confira babeljs.io/docs/plugins/#modules
chharvey

5

Isso é corrigido definindo a moduleopção do compilador para es6:

{
  "compilerOptions": {     
    "module": "es6",
    "target": "es5",    
  }
}

3

Eu também tive esse mesmo erro. No meu caso, foi porque tínhamos uma instrução de importação antiquada em nosso projeto TypeScript AngularJS como esta:

import { IAttributes, IScope } from "angular";

que foi compilado para JavaScript assim:

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

Isso era necessário nos velhos tempos porque então IAttributesusávamos no código e o TypeScript não saberia o que fazer com ele de outra forma. Mas depois de remover a instrução de importação e converter IAttributespara ng.IAttributesessas duas linhas de JavaScript, desapareceu - e também a mensagem de erro.


1
Como isso funcionaria para um tipo de texto datilografado? Eu tenho que importá-lo, então o Typescript o compila.
BluE

O que você quer dizer com "tipo de texto datilografado"? Se for um tipo inteiro conhecido pelo TypeScript - como número ou string - você pode usá-lo imediatamente. Se você definir seus próprios tipos em um módulo, verifique isto: typescriptlang.org/docs/handbook/modules.html
MatX

Eu quis dizer as definições de tipo de uma biblioteca externa como @ types / jquery de npmjs.com/package/@types/jquery . Para tornar a variável $ utilizável de dentro do meu código Typescript, coloquei isso no meu código: import * as $ from "jquery";
BluE

Meu objetivo é o es5. Preciso de outra biblioteca como a requirejs para fazer isso funcionar?
BluE

1

Basta adicionar libraryTarget: 'umd', assim

const webpackConfig = {
  output: {
    libraryTarget: 'umd' // Fix: "Uncaught ReferenceError: exports is not defined".
  }
};

module.exports = webpackConfig; // Export all custom Webpack configs.

1

para mim, remover "esModuleInterop": truedo tsconfig.json funcionou.


0

Para alguns projetos ASP.NET importe exportnão podem ser usados ​​em seus scripts de tipo.

O erro da pergunta apareceu quando tentei fazer isso e só descobri mais tarde que só precisava adicionar o script JS gerado ao View assim:

<script src="~/scripts/js/[GENERATED_FILE].Index.js" asp-append-version="true"></script>

0

Experimente o que @iFreilicht sugeriu acima. Se isso não funcionou depois de instalar o webpack e tudo, você pode ter apenas copiado uma configuração do webpack de algum lugar online e configurado lá que deseja que a saída suporte CommonJS por engano. Certifique-se de que este não seja o caso em webpack.config.js:

module.exports = {
  mode: process.env.NODE_ENV || "development",
  entry: { 
    index: "./src/js/index.ts"
  },
  ...
  ...
  output: {
    libraryTarget: 'commonjs',         <==== DELETE THIS LINE
    path: path.join(__dirname, 'build'),
    filename: "[name].bundle.js"
  }
};

0

Tive o mesmo problema e resolvi alterando a ordem de carregamento dos pacotes JS.

Verifique a ordem em que os pacotes de que você precisa estão sendo chamados e carregue-os na ordem apropriada.

No meu caso específico (não usando o módulo bundler) Eu precisava de carga Redux, em seguida Redux Thunk, então React Redux. Carregando React Reduxantes Redux Thunkme daria exports is not defined.


0

Nota: Isso pode não ser aplicável para a resposta de OP, mas eu estava recebendo este erro e foi assim que resolvi.

Portanto, o problema que eu estava enfrentando era que recebia esse erro quando recuperava uma biblioteca 'js' de um CDN específico.

A única coisa errada que eu estava fazendo era importar do cjsdiretório do CDN assim: https://cdn.jsdelivr.net/npm/@popperjs/core@2.4.0/dist/cjs/popper.min.js

Observe a dist/cjsparte? É aí que estava o problema.

Voltei para o CDN (jsdelivr) no meu caso e naveguei até encontrar a umdpasta. E eu poderia encontrar um outro conjunto de popper.min.jsque era o arquivo correto para importação: https://cdn.jsdelivr.net/npm/@popperjs/core@2.4.0/dist/umd/popper.min.js.


0
  {
    "compileOnSave": false,
    "compilerOptions": {
      "baseUrl": "./",
      "outDir": "./dist",
      "sourceMap": true,
      "declaration": false,
      "module": "esnext",
      "moduleResolution": "node",
      "emitDecoratorMetadata": true,
      "experimentalDecorators": true,
      "target": "es5",
      "typeRoots": ["node_modules/@types"],
      "lib": ["es2018", "dom"]
    }
  }

5
Bem-vindo ao StackOverflow. Adicione algum contexto à sua resposta ou explicação para que o usuário possa entender o que foi feito. Apenas postar um JSON pode não ser tão útil ...
Bruno Monteiro

0

Eu tive o mesmo problema, mas minha configuração exigia uma solução diferente.

Estou usando o create-react-app-rewiredpacote com um config-overrides.jsarquivo. Anteriormente, eu estava usando a addBabelPresetsimportação (no override()método) de customize-crae decidi abstrair essas predefinições em um arquivo separado. Coincidentemente, isso resolveu meu problema.

Eu adicionei useBabelRc()ao override()método em config-overrides.jse criei um babel.config.jsarquivo com o seguinte:

module.exports = {
    presets: [
        '@babel/preset-react',
        '@babel/preset-env'
    ],
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.