Typecript ReferenceError: export không được xác định


105

Đang cố gắng triển khai một mô-đun theo sổ tay chính thức , tôi nhận được thông báo lỗi sau:

Uncaught ReferenceError: xuất không được xác định

tại app.js: 2

Nhưng không nơi nào trong mã của tôi mà tôi đã từng sử dụng tên exports.

Làm thế nào tôi có thể sửa lỗi này?


Các tập tin

app.ts

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

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

mô-đun-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"
    ]
}

Vui lòng sao chép và dán văn bản lỗi vào câu hỏi thay vì sử dụng ảnh chụp màn hình.
Igor

Bạn có chắc là bạn đã không nhập exportsbằng chữ s ở cuối thay vì exportkhông? Điều đó sẽ giải thích thông báo lỗi như với s là sai.
Igor

tôi gõ export không phải là export
George C.

bất kỳ ví dụ nào từ repositorie mà gona hoạt động 10000%
George C.

Điều này đang được chạy ở đâu? Trên một trang web? Trên máy chủ node.js? Bạn sẽ cần một trình tải mô-đun trong môi trường thời gian chạy mà javascript cuối cùng chạy trong. Từ các cờ trình biên dịch, bạn đang sử dụng commonjs. Tôi không quen thuộc với commonjs, nhưng bạn sẽ cần thiết lập commonjs trước khi các mô-đun Typecript hoạt động hoặc bạn sẽ cần thay đổi sang một trình tải mô-đun khác (như request.js) và thiết lập một trình đó.
Mike Wodarczyk

Câu trả lời:


41

BIÊN TẬP:

Câu trả lời này có thể không hoạt động tùy thuộc nếu bạn không nhắm mục tiêu es5nữa, tôi sẽ cố gắng làm cho câu trả lời đầy đủ hơn.

Câu trả lời gốc

Nếu CommonJS không được cài đặt ( định nghĩaexports ), bạn phải xóa dòng này khỏi tsconfig.json:

 "module": "commonjs",

Theo các nhận xét, chỉ điều này có thể không hoạt động với các phiên bản sau của tsc. Nếu đúng như vậy, bạn có thể cài đặt một trình tải mô-đun như CommonJS, SystemJS hoặc RequestJS và sau đó chỉ định điều đó.

Ghi chú:

Nhìn vào main.jstệp của bạn đã tsctạo. Bạn sẽ tìm thấy điều này ở trên cùng:

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

Nó là gốc của thông báo lỗi và sau khi xóa "module": "commonjs",, nó sẽ biến mất.


3
Vâng, tôi đã biên dịch lại tệp .ts của mình và lỗi vẫn tồn tại sau khi nhận xét ra "module": "commonJs",:(
Acidic9

2
Nếu cài đặt CommonJS sẽ làm cho lỗi này biến mất, thì làm thế nào để cài đặt CommonJS? Tôi đã dành phần tốt hơn của một giờ trên Google và tôi không thể tìm thấy bất kỳ hướng dẫn nào về cách làm như vậy. Ai đó có thể vui lòng giải thích?
Sturm

1
@Sturm Câu trả lời của tôi có thể bị nhầm lẫn. CommonJS chỉ là một đặc điểm kỹ thuật. Bạn có thể tìm thấy danh sách (không nhất thiết phải đầy đủ) các triển khai tại đây: en.wikipedia.org/wiki/CommonJS
iFreilicht

1
Tôi có mô-đun: amd, không phải mô-đun: commonjs và tôi có dòng này trong tệp .js đã chuyển của mình.
pabrams

2
Nếu bạn có mục tiêu là ES3 hoặc ES5 trong tsconfig.json của mình thì chỉ định kiểu sẽ tự động đặt mô-đun của bạn thành CommonJS nếu nó không được xác định. Xóa module là không đủ, bạn cần phải thiết lập cái gì khác thay vì - xem typescriptlang.org/docs/handbook/compiler-options.html
Jake

51

Một số giải pháp khác cho vấn đề này

  • Thêm dòng sau trước các tham chiếu khác đến Javascript. Đây là một hack nhỏ tốt đẹp.
   <script>var exports = {};</script>
  • Sự cố này xảy ra với phiên bản TypeScript mới nhất, lỗi này có thể được loại bỏ bằng cách tham khảo phiên bản typecript 2.1.6

3
@ChuckLeButt Hy vọng điều này sẽ giúp stackoverflow.com/questions/19059580/…
Venkatesh Muniyandi

3
Tôi ghét rằng nó hoạt động! Và nó chắc chắn hoạt động. Không có cách nào để TypeScript chuyển hóa thành một thứ mà Node mong đợi? Thậm chí có phải Node đang phàn nàn không? Hay là trình duyệt? Tôi không thể chịu nổi khi không hiểu vấn đề thực sự là gì.
skillit zimberg

7

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

và thêm vào các plugin .babelrc đã giải quyết được câu hỏi của tôi.


7

giải pháp của tôi là tổng hợp của tất cả mọi thứ ở trên với một số thủ thuật nhỏ mà tôi đã thêm, về cơ bản tôi đã thêm điều này vào mã html của mình

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

điều này thậm chí còn cho phép bạn sử dụng importthay vì requirenếu bạn đang sử dụng electron hoặc thứ gì đó, và nó hoạt động tốt với typecript 3.5.1, target: es3 -> esnext.


3
một số tiến bộ ở đây, lỗi vừa được thay đổiapp.js:3 Uncaught ReferenceError: require is not defined
Muhammed Moussa

điều này xảy ra nếu nodeIntegration được đặt thành false khi tạo cửa sổ, lỗi xảy ra do bạn đã cập nhật electronJS của mình hoặc bạn đang theo dõi một nguồn lỗi thời. nodeIntegration theo mặc định là true, bây giờ là false, vì vậy bạn phải bật nó theo cách thủ công nếu bạn muốn truy cập nodeJS trong quá trình kết xuất. Xem [Yêu cầu điện tử () không được xác định] [1] [1]: stackoverflow.com/questions/44391448/…
Hocine Abdellatif

Tôi không sử dụng điện tử, dù sao thì tôi đã giải quyết trong trường hợp của mình bằng cách thêm bưu kiện để tạo thành gói và loại bỏ các cách phức tạp khác
Muhammed Moussa

6

Tôi đã giải quyết vấn đề bằng cách xóa "type": "module"trường khỏi package.json.


5

Tôi đã gặp vấn đề tương tự và đã giải quyết nó bằng cách thêm thư viện " es5 " vào tsconfig.json như thế này:

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

Đối với những người vẫn gặp sự cố này, nếu mục tiêu trình biên dịch của bạn được đặt thành ES6, bạn cần yêu cầu babel bỏ qua chuyển đổi mô-đun. Để làm như vậy, hãy thêm cái này vào .babelrctệp của bạn

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

1
Cảm ơn anh bạn! Tôi đã cố gắng làm việc với cơ sở mã cũ hơn, nó kết xuất tất cả vào toàn cục và các tập lệnh được đưa vào trình duyệt với <script>thẻ. Tôi đã hy vọng sử dụng mô-đun cùng với mã cũ hơn và có vẻ như điều đó là không thể. Điều này ít nhất cho phép tôi sử dụng ES6 và để tôi giải quyết việc xuất khẩu sau.
huggie

2
khi thực hiện việc này, tôi gặp lỗi sau: Sử dụng tùy chọn Babel 5 đã bị loại bỏ: .modules - Sử dụng plugin chuyển đổi mô-đun tương ứng trong pluginstùy chọn. Xem babeljs.io/docs/plugins/#modules
chharvey

5

Điều này được khắc phục bằng cách đặt moduletùy chọn trình biên dịch thành es6:

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

3

Tôi cũng gặp lỗi này. Trong trường hợp của tôi, đó là vì chúng tôi có một câu lệnh nhập kiểu cũ trong dự án TypeScript AngularJS của chúng tôi như sau:

import { IAttributes, IScope } from "angular";

được biên dịch sang JavaScript như thế này:

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

Điều này là cần thiết trong những ngày xưa vì khi đó chúng ta sử dụng IAttributesmã và TypeScript sẽ không biết phải làm gì với nó nếu không. Nhưng sau khi xóa câu lệnh nhập và chuyển đổi IAttributessang ng.IAttributeshai dòng JavaScript đó đã biến mất - và thông báo lỗi cũng vậy.


1
Điều đó sẽ hoạt động như thế nào đối với kiểu Typecript? Tôi phải nhập nó, vì vậy Typescript biên dịch nó.
BluE

Bạn hiểu "Loại chữ cái" là gì? Nếu đó là kiểu liên kết được TypeScript biết - chẳng hạn như số hoặc chuỗi - thì bạn có thể sử dụng nó ngay lập tức. Nếu bạn xác định loại của riêng bạn trong một module, kiểm tra này: typescriptlang.org/docs/handbook/modules.html
mATX

Ý tôi là các định nghĩa kiểu của một thư viện bên ngoài như @ type / jquery từ npmjs.com/package/@types/jquery . Để làm cho biến $ có thể sử dụng được từ trong mã Typecript của mình, tôi đặt nó vào mã của mình: import * as $ from "jquery";
BluE

Tôi đang nhắm mục tiêu es5, tôi có cần một thư viện khác như Requijs để làm cho nó hoạt động không?
BluE

1

Chỉ cần thêm libraryTarget: 'umd', như vậy

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

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


0

Đối với một số dự án ASP.NET importexportcó thể hoàn toàn không được sử dụng trong các bản ghi của bạn.

Lỗi của câu hỏi xuất hiện khi tôi cố gắng làm như vậy và sau đó tôi chỉ phát hiện ra rằng tôi chỉ cần thêm tập lệnh JS đã tạo vào Chế độ xem như sau:

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

0

Hãy thử những gì @iFreilicht đề xuất ở trên. Nếu điều đó không hoạt động sau khi bạn đã cài đặt webpack và tất cả, bạn có thể vừa sao chép cấu hình webpack từ một nơi nào đó trực tuyến và cấu hình ở đó mà bạn muốn đầu ra hỗ trợ CommonJS do nhầm lẫn. Đảm bảo đây không phải là trường hợp trong 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

Gặp sự cố tương tự và đã khắc phục nó bằng cách thay đổi thứ tự tải các gói JS.

Kiểm tra thứ tự mà các gói bạn cần đang được gọi và tải chúng theo thứ tự thích hợp.

Trong trường hợp cụ thể của tôi (không sử dụng gói mô-đun) Redux, sau đó Redux Thunk, tôi cần phải tải React Redux. Tải React Reduxtrước Redux Thunksẽ cho tôi exports is not defined.


0

Lưu ý: Điều này có thể không áp dụng cho câu trả lời của OP, nhưng tôi đã gặp lỗi này và đây là cách tôi giải quyết nó.

Vì vậy, vấn đề mà tôi gặp phải là tôi gặp lỗi này khi tôi truy xuất thư viện 'js' từ một CDN cụ thể.

Điều sai duy nhất mà tôi đã làm là nhập từ cjsthư mục của CDN như sau: https://cdn.jsdelivr.net/npm/@popperjs/core@2.4.0/dist/cjs/popper.min.js

Chú ý dist/cjsphần? Đó là nơi có vấn đề.

Tôi quay lại CDN (jsdelivr) trong trường hợp của mình và điều hướng để tìm umdthư mục. Và tôi có thể tìm một bộ popper.min.jsđó là tập tin chính xác để nhập khẩu: 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
Chào mừng bạn đến với StackOverflow. Vui lòng thêm một số ngữ cảnh vào câu trả lời của bạn hoặc một số giải thích để người dùng có thể hiểu những gì đã được thực hiện. Chỉ đăng một JSON có thể không hữu ích ...
Bruno Monteiro

0

Tôi gặp sự cố tương tự, nhưng thiết lập của tôi yêu cầu một giải pháp khác.

Tôi đang sử dụng create-react-app-rewiredgói có config-overrides.jstệp. Trước đây, tôi đã sử dụng addBabelPresetsnhập (trong override()phương thức) từ customize-cravà quyết định trừu tượng hóa các giá trị đặt trước đó thành một tệp riêng biệt. Thật trùng hợp, điều này đã giải quyết được vấn đề của tôi.

Tôi thêm useBabelRc()vào override()phương pháp trong config-overrides.jsvà tạo ra một babel.config.jstập tin với những điều sau đây:

module.exports = {
    presets: [
        '@babel/preset-react',
        '@babel/preset-env'
    ],
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.