Nhận xuất mã thông báo bất ngờ


220

Tôi đang cố chạy một số mã ES6 trong dự án của mình nhưng tôi gặp phải lỗi xuất mã thông báo không mong muốn.

export class MyClass {
  constructor() {
    console.log("es6");
  }
}

5
không có đủ thông tin về môi trường hoặc cấu hình của bạn để cung cấp bất kỳ trợ giúp nào. Lỗi này cho thấy rằng webpack hoặc babel không hoạt động chính xác, như exportchỉ có trong ES6 và các mô-đun đó là những gì cung cấp hỗ trợ ES6.
Claies

24
Bạn nên sử dụng module.exports = MyClass, khôngexport class MyClass
onmyway133

Câu trả lời:


249

Bạn đang sử dụng cú pháp Mô-đun ES6.

Điều này có nghĩa là môi trường của bạn (ví dụ: node.js) phải hỗ trợ cú pháp Mô-đun ES6.

NodeJS sử dụng cú pháp Mô-đun CommonJS ( module.exports) chứ không phải cú pháp mô-đun ES6 ( exporttừ khóa).

Giải pháp:

  • Sử dụng babelgói npm để dịch mã ES6 của bạn sang commonjsmục tiêu

hoặc là

  • Tái cấu trúc với cú pháp CommonJS.

Ví dụ về cú pháp CommonJS là (từ flaviocopes.com/commonjs/ ):

  • exports.uppercase = str => str.toUpperCase()
  • exports.a = 1

15
Khi nào nodejs sẽ hỗ trợ importhữu cơ? Tôi nghĩ v10.0.0 sẽ có nó nhưng dường như không.
chovy

4
Hỗ trợ thử nghiệm @chovy có sẵn với cờ "--experimental-mô-đun". Các tập tin cần phải có phần mở rộng .mjs
Giovanni P.

1
Tôi đang gặp lỗi này khi sử dụng Chrome 66 với sự hỗ trợ riêng cho các mô-đun.
Tom Russell

BTW: lưu ý rằng trong khi các mô-đun hỗ trợ node10 / node12 phía sau cờ, họ không hỗ trợ nó trong chế độ REPL - tuy nhiên, nó được hỗ trợ trong chế độ eval trong nút12 .
jakub.g

2
Đối với một người vẫn chưa rõ về Cú pháp của CommonJs. vui lòng kiểm tra liên kết này, có thể giúp một chút. flaviocopes.com/commonjs
LT

142

Trong trường hợp bạn gặp lỗi này, nó cũng có thể liên quan đến cách bạn đưa tệp javascript vào trang html của bạn. Khi tải các mô-đun, bạn phải khai báo rõ ràng các tệp như vậy. Dưới đây là một ví dụ:

//module.js:
function foo(){
   return "foo";
}

var bar = "bar";

export { foo, bar };

Khi bạn bao gồm tập lệnh như thế này:

<script src="module.js"></script>

Bạn sẽ nhận được lỗi:

Uncaught SyntaxError: Xuất khẩu mã thông báo bất ngờ

Bạn cần bao gồm tệp với thuộc tính loại được đặt thành "mô-đun":

<script type="module" src="module.js"></script>

Và sau đó nó sẽ hoạt động như mong đợi và bạn đã sẵn sàng nhập mô-đun của mình vào một mô-đun khác:

import { foo, bar } from  "./module.js";

console.log( foo() );
console.log( bar );

37
Không giống như câu trả lời "được đánh giá cao nhất", điều này thực sự giải quyết được vấn đề và giải thích lý do tại sao nó xảy ra mà không gợi ý rằng lựa chọn duy nhất là tận dụng phương thức CommonJS, phương thức APM hoặc để dịch mã của chúng tôi ... Đây cũng là một ngoại lệ theo tiêu chuẩn w3c nơi typedự kiến ​​là loại mime hợp lệ (còn gọi là loại phương tiện), vì vậy đây là một phát hiện bất ngờ. Cảm ơn!
Shaun Wilson

4
Điều này sửa lỗi nhưng sau đó tôi nhận được "Mã thông báo bất ngờ {" trên dòng lệnh nhập trong Chrome 67 với tập lệnh là nội tuyến, ví dụ: <script> nhập ... </ script>
PandaWood

1
@PandaWood Bạn phải sử dụng <script type="module">import ...</script>, khi bạn nhập từ mô-đun. Tôi đã thử nghiệm nó trong phiên bản gần đây của Chromium.
Vladimir S.

Điều này đã khắc phục sự cố của tôi :)
user3651476

Pure JS (ES6) đã hỗ trợ nhập và điều này giải thích chính xác lý do tại sao tôi gặp điều này
Eric

15

Theo quan điểm của tôi

Xuất khẩu

ES6

myClass.js

export class MyClass1 {
}
export class MyClass2 {
}

other.js

import { MyClass1, MyClass2 } from './myClass';

Thay thế CommonJS

myClass.js

class MyClass1 {
}
class MyClass2 {
}
module.exports = { MyClass1, MyClass2 }
// or
// exports = { MyClass1, MyClass2 };

other.js

const { MyClass1, MyClass2 } = require('./myClass');

Xuất mặc định

ES6

myClass.js

export default class MyClass {
}

other.js

import MyClass from './myClass';

Thay thế CommonJS

myClass.js

module.exports = class MyClass1 {
}

other.js

const MyClass = require('./myClass');

Hi vọng điêu nay co ich


Đối với ví dụ Xuất mặc định ES6, bạn đã viết "xuất mặc định", nhưng nó phải là "xuất mặc định".
IAM_AL_X

@IAM_AL_X Cảm ơn bạn đã nắm bắt :-)
Barnstokkr

10

Để sử dụng ES6 thêm babel-preset-env

và trong .babelrc:

{
  "presets": ["@babel/preset-env"]
}

Trả lời cập nhật nhờ bình luận @ Afghanistanbari để áp dụng babel 7.


8
Câu hỏi của anh không phải về việc giải thích babel. Vậy tại sao phải trả lời một cái gì đó không cần thiết mà có thể gây nhầm lẫn khác?
Jalal

7
@monsto câu hỏi này đã được babeltác giả gắn thẻ . Trong khi câu trả lời của Phil Ricketts làm rõ vấn đề, điều này tốt, thì câu trả lời này là một giải pháp trực tiếp cho vấn đề của tác giả.
boycy

"@ babel / preset-env"
ghanbari

6

Không cần sử dụng Babel tại thời điểm này (JS đã trở nên rất mạnh mẽ) khi bạn chỉ cần sử dụng xuất khẩu mô-đun JavaScript mặc định. Kiểm tra hướng dẫn đầy đủ

Message.js

module.exports = 'Hello world';

app.js

var msg = require('./Messages.js');

console.log(msg); // Hello World

2
Làm thế nào bạn sẽ xuất một lớp sau đó?
Sherwin Ablaña Dapito

1
Tôi đang xóa câu trả lời của tôi vì câu hỏi trên thực tế là dành cho ES6 chứ không phải CommonJS được sử dụng bởi NodeJS. Vui lòng kiểm tra ở trên để có câu trả lời.
Alvin Konda

@ SherwinAblañaDapito module.exports = class MyClass {} hoạt động
Marian Klühspies

3

Cài đặt các gói babel @babel/core@babel/presetsẽ chuyển ES6 thành mục tiêu chung vì nút js không hiểu trực tiếp các mục tiêu ES6

npm install --save-dev @babel/core @babel/preset-env

Sau đó, bạn cần tạo một tệp cấu hình có tên .babelrctrong thư mục gốc của dự án của bạn và thêm mã này vào đó

{ "presets": ["@babel/preset-env"] }


Tôi cũng cần cài đặt @ babel / register, nếu không tôi vẫn sẽ nhận được "SyntaxError: Không thể sử dụng câu lệnh nhập bên ngoài một mô-đun"
phân tử

3

Tôi đã sửa lỗi này bằng cách tạo một tệp điểm như thế nào.

// index.js
require = require('esm')(module)
module.exports = require('./app.js')

và bất kỳ tệp nào tôi đã nhập bên trong app.jsvà ngoài hoạt động với imports/exports bây giờ bạn chỉ cần chạy nó nhưnode index.js

Lưu ý: nếu app.jssử dụng export default, điều này trở thành require('./app.js').defaultkhi sử dụng tệp điểm nhập cảnh.


1
Câu trả lời tốt nhất cho các dự án đơn giản không cần babel, webpack, bưu kiện, v.v ... Tôi đã sử dụng trong dự án monorepo với đơn giản / máy chủ nhanh cho dự án. Làm việc như một bùa mê ...
mattdlockyer

-3

Sử dụng cú pháp ES6 không hoạt động trong nút, thật không may, bạn phải có babel rõ ràng để làm cho trình biên dịch hiểu cú pháp như xuất hoặc nhập.

npm install babel-cli --save

Bây giờ chúng ta cần tạo tệp .babelrc, trong tệp babelrc, chúng ta sẽ đặt babel sử dụng cài đặt sẵn es2015 mà chúng ta đã cài đặt làm cài đặt sẵn khi biên dịch sang ES5.

Tại thư mục gốc của ứng dụng, chúng tôi sẽ tạo tệp .babelrc. $ npm cài đặt babel-preset-es2015 --save

Tại thư mục gốc của ứng dụng, chúng tôi sẽ tạo tệp .babelrc.

{  "presets": ["es2015"] }

Hy vọng nó hoạt động ... :)

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.