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.