TypeScript ReferenceError: экспорт не определен


106

Попытка реализовать модуль по официальному справочнику , я получаю следующее сообщение об ошибке:

Uncaught ReferenceError: экспорт не определен

в app.js: 2

Но нигде в моем коде я никогда не использую имя exports .

Как я могу это исправить?


Файлы

app.ts

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

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

модуль-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"
    ]
}

Скопируйте и вставьте текст ошибки в вопрос вместо использования снимков экрана.
Игорь

Вы уверены, что не набирали exportsс буквой s в конце вместо export? Это объяснило бы сообщение об ошибке, поскольку с s неверно.
Игорь


любой пример из репозитория, который будет работать на 10000%
Джордж К.

Где это запускается? На веб-странице? На сервере node.js? Вам понадобится загрузчик модулей в среде выполнения, в которой, наконец, будет работать javascript. Из флагов компилятора вы используете commonjs. Я не так хорошо знаком с commonjs, но вам нужно будет настроить commonjs, прежде чем модули Typescript будут работать, или вам нужно будет перейти на другой загрузчик модулей (например, require.js) и настроить его.
Майк Водарчик

Ответы:


41

РЕДАКТИРОВАТЬ:

Этот ответ может не сработать, если вы не нацеливаетесь es5 , я постараюсь сделать ответ более полным.

Оригинальный ответ

Если CommonJS не установлен ( что определяетexports ), вам необходимо удалить эту строку из своего tsconfig.json:

 "module": "commonjs",

Согласно комментариям, это само по себе может не работать с более поздними версиями tsc. Если это так, вы можете установить загрузчик модулей, например CommonJS, SystemJS или RequireJS, а затем указать это.

Примечание:

Посмотрите на созданный вами main.jsфайл tsc. Вы найдете это на самом верху:

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

Это корень сообщения об ошибке, и после удаления "module": "commonjs",он исчезнет.


3
Да, я перекомпилировал свой файл .ts, и после комментария ошибка все еще существует "module": "commonJs",:(
Acidic9,

2
Если установка CommonJS устранит эту ошибку, то как на самом деле установить CommonJS? Я потратил большую часть часа на поиск в Google и не могу найти никаких инструкций, как это сделать. Может кто - то пожалуйста , объясните?
Sturm

1
@Sturm Мой ответ может быть запутанным. CommonJS - это всего лишь спецификация. Вы можете найти (не обязательно исчерпывающий) список реализаций здесь: en.wikipedia.org/wiki/CommonJS
iFreilicht

1
У меня есть module: amd, а не module: commonjs, и у меня есть эта строка в моем транспилированном файле .js.
pabrams 05

2
Если у вас есть цель как ES3 или ES5 в вашем tsconfig.json, тогда typescript автоматически установит ваш модуль на CommonJS, если он не определен. Удаление модуля недостаточно, вам нужно вместо этого установить что-то другое - см. Typescriptlang.org/docs/handbook/compiler-options.html
Jake

52

Несколько других решений для этой проблемы

  • Добавьте следующую строку перед другими ссылками на Javascript. Это хороший маленький прием.
   <script>var exports = {};</script>
  • Эта проблема возникает с последней версией TypeScript, эту ошибку можно устранить, обратившись к typescript версии 2.1.6.

3
@ChuckLeButt Надеюсь, это поможет stackoverflow.com/questions/19059580/…
Венкатеш Муниянди

3
Ненавижу, что это работает! И это определенно работает. Разве нет способа заставить TypeScript преобразовать в то, что ожидает Node? Это даже Node жалуется? Или это браузер? Я терпеть не могу не понимать, в чем на самом деле проблема.
Skillit Zimberg

9

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

и добавление в плагины .babelrc разрешило мой вопрос.



7

мое решение - это сумма всего вышеперечисленного с небольшими хитростями, которые я добавил, в основном я добавил это в свой html-код

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

это даже позволяет вам использовать importвместо этого, requireесли вы используете электрон или что-то в этом роде, и он отлично работает с машинописным текстом 3.5.1, target: es3 -> esnext.


3
некоторый прогресс здесь, ошибка просто изменилась наapp.js:3 Uncaught ReferenceError: require is not defined
Мухаммед Мусса

это происходит, если для nodeIntegration установлено значение false при создании окна, ошибка возникает из-за того, что вы обновили свой electronicJS или следите за устаревшим источником. По умолчанию nodeIntegration было true, теперь false, поэтому вам нужно включить его вручную, если вы хотите получить доступ к nodeJS в процессе рендеринга. См. [Electron require () не определен] [1] [1]: stackoverflow.com/questions/44391448/…
Hocine Abdellatif

Я не использую электрон, в любом случае я решил в своем случае, добавив посылку для создания связки и удалил другие хитрые способы
Мухаммед Мусса,

5

У меня была такая же проблема , и решить ее , добавив « ES5 » библиотеку tsconfig.json , как это:

{
    "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

Для людей, которые все еще сталкиваются с этой проблемой, если ваш целевой компилятор установлен на ES6, вам нужно указать babel, чтобы он пропустил преобразование модуля. Для этого добавьте это в свой .babelrcфайл

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

1
Спасибо чувак! Я пытался работать со старой базой кода, которая выгружает все в глобальный, а скрипты включаются в браузер с <script>тегом. Я надеялся использовать модуль вместе со старым кодом, и похоже, что это невозможно. Это, по крайней мере, позволяет мне использовать ES6 и позволяет мне заниматься экспортом позже.
huggie

2
при этом я получил следующую ошибку: Использование удаленной опции Babel 5: .modules - Используйте соответствующий плагин преобразования модуля в pluginsопции. Проверьте babeljs.io/docs/plugins/#modules
chharvey

5

Это исправлено установкой параметра moduleкомпилятора на es6:

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

3

У меня тоже была такая же ошибка. В моем случае это произошло из-за того, что в нашем проекте TypeScript AngularJS был устаревший оператор импорта, например:

import { IAttributes, IScope } from "angular";

который был скомпилирован в JavaScript следующим образом:

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

Это было необходимо в старые времена, потому что мы тогда использовали IAttributesкод, и TypeScript не знал бы, что с ним делать в противном случае. Но после удаления оператора импорта и преобразования IAttributesв ng.IAttributesэти две строки JavaScript исчезли, как и сообщение об ошибке.


1
Как это будет работать для типа Typescript? Мне нужно импортировать его, поэтому Typescript его компилирует.
BluE 08

Что вы подразумеваете под «типографским шрифтом»? Если это целочисленный тип, известный TypeScript, например число или строка, то вы можете использовать его сразу. Если вы определяете свои собственные типы в модуле, проверьте это: typescriptlang.org/docs/handbook/modules.html
MatX

Я имел в виду определения типов внешней библиотеки типа @ types / jquery из npmjs.com/package/@types/jquery . Чтобы сделать переменную $ доступной для использования в моем коде Typescript, я поместил это в свой код: import * as $ from "jquery";
BluE 08

Я нацелен на es5, нужна ли мне еще одна библиотека, например requirejs, для этой работы?
BluE 08

1

Просто добавь libraryTarget: 'umd'вот так

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

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


0

Для некоторых проектов ASP.NET importиexport может вообще не использоваться в ваших TypeScript.

Ошибка вопроса появилась, когда я попытался это сделать, и только позже я обнаружил, что мне просто нужно добавить сгенерированный скрипт JS в представление следующим образом:

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

0

Попробуйте то, что предложил @iFreilicht выше. Если это не сработало после того, как вы установили веб-пакет и все такое, возможно, вы просто скопировали конфигурацию веб-пакета из Интернета и настроили там, что вы хотите, чтобы вывод по ошибке поддерживал CommonJS. Убедитесь, что это не так 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

Была такая же проблема и исправлена ​​путем изменения порядка загрузки пакетов JS.

Проверьте порядок, в котором вызываются нужные вам пакеты, и загрузите их в соответствующем порядке.

В моем конкретном случае (без использования модуля Bundler) мне нужно нагрузки Redux, затем Redux Thunk, затем React Redux. Погрузка React Reduxраньше Redux Thunkдала бы мне exports is not defined.


0

Примечание: это может быть неприменимо для ответа OP, но я получал эту ошибку, и вот как я ее решил.

Итак, проблема, с которой я столкнулся, заключалась в том, что я получал эту ошибку, когда извлекал библиотеку js из определенного CDN.

Единственное, что я делал неправильно, это импортировал из cjsкаталога CDN следующим образом: https://cdn.jsdelivr.net/npm/@popperjs/core@2.4.0/dist/cjs/popper.min.js

Заметили dist/cjsдеталь? Вот где была проблема.

Я вернулся к CDN (jsdelivr) в моем случае и нашел umdпапку. И я мог бы найти еще один набор из popper.min.jsкоторых был правильный файл для импорта: 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"]
    }
  }

6
Добро пожаловать в StackOverflow. Добавьте контекст к вашему ответу или объяснение, чтобы пользователь мог понять, что было сделано. Только публикация JSON может быть не такой полезной ...
Бруно Монтейро,

0

У меня была такая же проблема, но для моей настройки требовалось другое решение.

Пользуюсь create-react-app-rewiredпакетом с config-overrides.jsфайлом. Раньше я использовал addBabelPresetsимпорт (в override()методе) из customize-craи решил абстрагировать эти пресеты в отдельный файл. По совпадению, это решило мою проблему.

Я добавил useBabelRc()в override()метод config-overrides.jsи создал babel.config.jsфайл со следующим:

module.exports = {
    presets: [
        '@babel/preset-react',
        '@babel/preset-env'
    ],
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.