TypeScript ReferenceError: експорт не визначено


105

Намагаючись реалізувати модуль за офіційним посібником , я отримую це повідомлення про помилку:

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з з в кінці замість export? Це пояснило б повідомлення про помилку, оскільки з s неправильно.
Ігор

Я набираю експорт, а не експорт
Джордж К.

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

Куди це ведеться? На веб-сторінці? На сервері node.js? Вам знадобиться завантажувач модулів у середовищі виконання, в якому нарешті запускається javascript. З прапорців компілятора, якими ви користуєтеся commonjs. Я не такий знайомий з commonjs, але вам потрібно буде встановити commonjs перед тим, як працюватимуть модулі Typescript, або вам потрібно буде перейти на інший завантажувач модулів (наприклад, Requ.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? Я витратив більшу частину години на гуглінг, і не можу знайти ніяких інструкцій, як це зробити. Може хто - то будь ласка , поясніть?
Штурм

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

1
У мене є модуль: amd, а не модуль: commonjs, і у мене є цей рядок у моєму перекладеному .js-файлі.
пабрамс

2
Якщо у вашому tsconfig.json у вас є ціль як ES3 або ES5, тоді typecript автоматично встановить ваш модуль на CommonJS, якщо він не визначений. Видалення модуля недостатньо, замість цього вам потрібно встановити щось інше - див. Typecriptlang.org/docs/handbook/compiler-options.html
Джейк

51

Небагато інших рішень для цього питання

  • Додайте наступний рядок перед іншими посиланнями на Javascript. Це хороший маленький хак.
   <script>var exports = {};</script>
  • Ця проблема виникає з останньою версією TypeScript, цю помилку можна усунути, звернувшись до версії 2.1.6

3
@ChuckLeButt Сподіваюся , що це допомагає stackoverflow.com/questions/19059580 / ...
Venkatesh Muniyandi

3
Ненавиджу, що це працює! І це точно працює. Чи не існує способу змусити TypeScript перетворитись на щось, чого очікує Node? Це навіть Node, який скаржиться? Або це браузер? Я не можу терпіти, не розуміючи, в чому проблема насправді.
skillit zimberg

7

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

і додати до плагінів .babelrc вирішило моє питання.


7

моє рішення - це підсумок всього вище, за допомогою невеликих трюків, які я додав, в основному я додав це до свого html-коду

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

це навіть дозволяє вам використовувати importзамість того, requireякщо ви використовуєте електрон або щось подібне, і це добре працює з typecript 3.5.1, target: es3 -> esnext.


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

це відбувається, якщо під час створення вікна nodeIntegration встановлено значення false, помилка трапиться через те, що ви оновили свій електронний JS або ви переглядаєте застаріле джерело. nodeIntegration була правдою за замовчуванням, тепер вона хибна, тому її потрібно ввімкнути вручну, якщо ви хочете отримати доступ до nodeJS в процесі візуалізації. Див. [Електрон вимагає () не визначено] [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

Що ви маєте на увазі під "Typescript type"? Якщо це цілісний тип, відомий TypeScript - наприклад, число або рядок - ви можете використовувати це відразу. Якщо визначити свої власні типи в модулі, перевірити це: typescriptlang.org/docs/handbook/modules.html
MatX

Я мав на увазі визначення типів зовнішньої бібліотеки, наприклад @ types / jquery від npmjs.com/package/@types/jquery . Щоб зробити змінну $ придатною для використання з мого коду Typescript, я ставлю це до свого коду: import * як $ з "jquery";
BluE

Я націлююсь на es5, чи потрібна мені інша бібліотека, як Requjs, щоб зробити цю роботу?
BluE

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не може бути використаний на все в вашому друкованому.

Помилка питання з’явилася, коли я намагався це зробити, і лише пізніше я виявив, що мені просто потрібно додати створений сценарій 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.

Перевірте порядок виклику необхідних пакетів і завантажте їх у відповідному порядку.

У моєму конкретному випадку (не використовуючи пакет модулів) мені потрібно було завантажити Redux, потім Redux Thunk, потім React Redux. Завантаження React Reduxраніше Redux Thunkне дало б мені exports is not defined.


0

Примітка. Це може бути неприйнятним для відповіді ОП, але я отримував цю помилку, і я вирішував її.

Тож проблема, з якою я стикався, полягала в тому, що я отримував цю помилку, коли отримував бібліотеку '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"]
    }
  }

5
Ласкаво просимо до 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.