Cú pháp: Không thể sử dụng câu lệnh nhập bên ngoài mô-đun


53

Tôi đã có một dự án ApolloServer gây rắc rối cho tôi, vì vậy tôi nghĩ rằng tôi có thể cập nhật nó và gặp vấn đề khi sử dụng Babel mới nhất. "Index.js" của tôi là:

require('dotenv').config()
import {startServer} from './server'
startServer()

Và khi tôi chạy nó, tôi gặp lỗi "SyntaxError: Không thể sử dụng câu lệnh nhập bên ngoài một mô-đun". Đầu tiên tôi đã thử làm mọi thứ để thuyết phục TPTB * rằng đây là một mô-đun (không thành công). Vì vậy, tôi đã thay đổi "nhập" thành "yêu cầu" và điều này đã hoạt động.

Nhưng bây giờ tôi có khoảng hai chục "nhập" trong các tệp khác cho tôi cùng một lỗi.

* Tôi chắc chắn gốc rễ của vấn đề của tôi là tôi thậm chí không chắc những gì phàn nàn về vấn đề này. Tôi giả sử đó là Babel 7 (vì tôi đến từ Babel 6 và tôi phải thay đổi các cài đặt trước) nhưng tôi không chắc chắn 100%.

Hầu hết những gì tôi tìm thấy cho các giải pháp dường như không áp dụng cho Node thẳng. Giống như cái này ở đây:

Nhập mô-đun ES6 cho "Uncaught SyntaxError: Định danh không mong đợi"

Nói rằng nó đã được giải quyết bằng cách thêm "type = module" nhưng điều này thường đi vào HTML, trong đó tôi không có. Tôi cũng đã thử sử dụng các cài đặt trước cũ của dự án của mình:

"presets": ["es2015", "stage-2"],
"plugins": []

Nhưng điều đó lại gây ra cho tôi một lỗi khác: "Lỗi: Các tệp Plugin / Preset không được phép xuất các đối tượng, chỉ có các chức năng."

CẬP NHẬT: Đây là những phụ thuộc mà tôi bắt đầu với:

"dependencies": {
"@babel/polyfill": "^7.6.0",
"apollo-link-error": "^1.1.12",
"apollo-link-http": "^1.5.16",
"apollo-server": "^2.9.6",
"babel-preset-es2015": "^6.24.1",

1
Xin chào, có cùng một vấn đề ngay bây giờ. Bạn cũng có thể chia sẻ phụ thuộc của bạn? Thậm chí có thể là một khác biệt trước và sau khi cập nhật của bạn. Tôi có thể kiểm tra lại để xem liệu chúng tôi có thể tìm thấy các gói tương tự có thể gây rắc rối không.
lynx

Tôi chỉ thay thế tất cả "nhập khẩu" bằng "yêu cầu" và tất cả đều ổn. Ngốc nhưng không đáng để cố gắng tìm ra nó ngay bây giờ. Tôi sẽ cập nhật bản gốc với phụ thuộc, mặc dù. Nếu bạn nhận được bất kỳ khách hàng tiềm năng nào, tôi sẽ kiểm tra chúng dựa trên mã gốc của tôi.
dùng3810626

1
Cú pháp CommonJS (Yêu cầu và module.exports) là định dạng ban đầu cho nút và webpack cũng hỗ trợ nó, nhưng cú pháp mô-đun ES6 (xuất, nhập) là cách mới hơn và bây giờ nút và webpack hỗ trợ nó. Tôi đọc rằng nút đó hỗ trợ nhập ngay bây giờ nhưng rất nhiều hướng dẫn hiển thị yêu cầu công cụ nút thuần mà sử dụng cú pháp đó cho nút tốt hơn.
Ted Fitzpatrick

1
Cuối cùng, đối với tôi con đường để đi dường như này: github.com/vuejs/vue-jest/issues/134#issuecomment-461755061 Setting preset trong jest.config.jsđể 'ts-jest/presets/js-with-ts'- vẫn có một số vấn đề khác nhưng điều này giải quyết được cái lớn. ..... uh yea, vấn đề của tôi là thử nghiệm liên quan ... các bản dựng bình thường vẫn ổn
lynx

Lynx, Thú vị. Không sử dụng Jest, bản thân tôi. Ted, thật thú vị. OK, tôi sẽ không đổ mồ hôi.
dùng3810626

Câu trả lời:


50

Cập nhật 2020 (Nút 13.2.0+)

Xác minh rằng bạn đã cài đặt phiên bản Node mới nhất. Các --experimental-modulescờ không còn cần thiết. Đơn giản chỉ cần làm một trong những điều sau đây :

  • Thêm vào "type": "module"cha mẹ gần nhất package.json. Với điều này, tất cả .js.mjscác tệp được hiểu là các mô-đun ES. Bạn có thể diễn giải các tệp riêng lẻ dưới dạng CommonJS bằng cách sử dụng .cjstiện ích mở rộng.

HOẶC LÀ

  • Tên tập tin rõ ràng với .mjsphần mở rộng. Tất cả các tệp khác, chẳng hạn như .jssẽ được hiểu là CommonJS, là mặc định nếu typekhông được xác định trong package.json.

Nếu tôi sử dụng điều này, sau đó thay đổi đường dẫn để bao gồm "js" cho tệp được yêu cầu, sau đó thay đổi định dạng của câu lệnh xuất trong tệp được yêu cầu, sau đó lấy tất cả các câu lệnh "yêu cầu" mà tôi đã thay đổi từ "nhập khẩu". bây giờ "yêu cầu" chưa được biết, điều này sẽ hoạt động, vì vậy tôi sẽ chấp nhận câu trả lời này.
dùng3810626

2
Đây thực sự không phải là một lựa chọn nếu vấn đề nằm dưới node_modules / phải không? Bất kỳ ý tưởng làm thế nào để khắc phục trong trường hợp đó?
Trent Bing

18

Theo tài liệu chính thức ( https://nodejs.org/api/esm.html#esm_code_import_code_statements ):

báo cáo nhập khẩu chỉ được phép trong các mô-đun ES. Để biết chức năng tương tự trong CommonJS, hãy xem import ().

Để làm cho Node xử lý tệp của bạn dưới dạng mô-đun ES, bạn cần ( https://nodejs.org/api/esm.html#esm_en bật ):

  • thêm "loại": "mô-đun" vào pack.json
  • thêm cờ "--experimental-mô-đun" vào lệnh gọi nút

6

Tôi đã có cùng một vấn đề và sau đây đã khắc phục nó (sử dụng nút 12.13.1):

  • Thay đổi phần mở rộng tệp .js thành .mjs
  • Thêm cờ --experimental-mô-đun khi chạy ứng dụng của bạn.
  • Tùy chọn: thêm "loại": "mô-đun" trong gói.json của bạn

thêm thông tin: https://nodejs.org/api/esm.html


0

Tôi đã gặp vấn đề này trong một dự án API Express còn non trẻ.

Mã máy chủ vi phạm trong src/server/server.js:

import express from 'express';
import {initialDonationItems, initialExpenditureItems} from "./DemoData";

const server = express();

server.get('/api/expenditures', (req, res) => {
  res.type('json');
  res.send(initialExpenditureItems);
});

server.get('/api/donations', (req, res) => {
  res.type('json');
  res.send(initialDonationItems);
});

server.listen(4242, () => console.log('Server is running...'));

Đây là sự phụ thuộc của tôi:

{
  "name": "contributor-api",
  "version": "0.0.1",
  "description": "A Node backend to provide storage services",
  "scripts": {
    "dev-server": "nodemon --exec babel-node src/server/server.js --ignore dist/",
    "test": "jest tests"
  },
  "license": "ISC",
  "dependencies": {
    "@babel/core": "^7.9.6",
    "@babel/node": "^7.8.7",
    "babel-loader": "^8.1.0",
    "express": "^4.17.1",
    "mysql2": "^2.1.0",
    "sequelize": "^5.21.7",
    "sequelize-cli": "^5.5.1"
  },
  "devDependencies": {
    "jest": "^25.5.4",
    "nodemon": "^2.0.3"
  }
}

Và đây là người chạy đã ném lỗi:

nodemon --exec babel-node src/server/server.js --ignore dist

Điều này thật khó chịu, vì tôi đã có một dự án Express tương tự hoạt động tốt.

Giải pháp trước tiên là thêm sự phụ thuộc này:

npm install @babel/preset-env

Và sau đó kết nối nó bằng cách sử dụng một babel.config.jstrong dự án gốc:

module.exports = {
  presets: ['@babel/preset-env'],
};

Tôi không hoàn toàn hiểu được lý do tại sao điều này hoạt động, nhưng tôi đã sao chép nó từ một nguồn có thẩm quyền , vì vậy tôi rất vui khi được gắn bó với nó.


Vâng, vấn đề của tôi là mã có một loạt các cài đặt trước và tôi không bao giờ có thể hoàn toàn đạt được sự cân bằng của những thứ tôi muốn so với những thứ tôi không muốn / thứ đó đã phá vỡ.
dùng3810626

Tôi đã cố gắng giải quyết các sự cố về JS khó hiểu cả ngày Đến đó ...:-)
dừng lại

1
Chúc may mắn! Đó là một khu rừng ở ngoài đó! (Ý tôi là, theo nghĩa đen, hệ sinh thái JS là một khu rừng ...)
user3810626

-2
  1. Tôi gặp vấn đề tương tự khi tôi bắt đầu sử dụng babel ... Nhưng sau đó, tôi đã có một giải pháp ... Cho đến nay tôi vẫn không gặp vấn đề gì nữa ... Hiện tại, Node v12.14.1, "@ babel / node" : "^ 7.8.4", tôi sử dụng nút babel và nút để thực thi (nút cũng tốt ..)
  2. pack.json: "start": "gật đầu --exec babel-node server.js" debug ":" babel-node debug server.js "!! lưu ý: server.js là tệp nhập của tôi, bạn có thể sử dụng tệp của bạn.
  3. launch.json Khi bạn gỡ lỗi, bạn cũng cần định cấu hình tệp launch.json của mình "runtimeExecutable": "$ {workspaceRoot} /node_modules/.bin/babel-node" !! lưu ý: cộng với runtimeExecutable vào cấu hình.
  4. Tất nhiên, với nút babel, thông thường bạn cũng cần và chỉnh sửa một tệp khác, chẳng hạn như tệp babel.config.js / .babelrc

-2

Giải pháp của tôi là bao gồm đường dẫn nút babel trong khi chạy gật đầu như sau:

nodemon node_modules/.bin/babel-node index.js

bạn có thể thêm vào tập lệnh pack.json của mình dưới dạng:

debug: nodemon node_modules/.bin/babel-node index.js

LƯU Ý: Tệp mục nhập của tôi là index.js thay thế nó bằng tệp nhập của bạn (nhiều tệp có app.js / server.js).

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.