Node.js - SyntaxError: неожиданный импорт маркера
Я не понимаю, что не так. Узел v5.6.0 NPM v3.10.6
Код:
function (exports, require, module, __filename, __dirname) {
import express from 'express'
};
Ошибка:
SyntaxError: Unexpected token import
at exports.runInThisContext (vm.js:53:16)
at Module._compile (module.js:387:25)
at Object.Module._extensions..js (module.js:422:10)
at Module.load (module.js:357:32)
at Function.Module._load (module.js:314:12)
at Function.Module.runMain (module.js:447:10)
at startup (node.js:140:18)
at node.js:1001:3
Ответы
Ответ 1
Обновление: в узле 9 он включен за флагом и использует расширение .mjs
.
node --experimental-modules my-app.mjs
Хотя import
действительно является частью ES6, он, к сожалению, еще не поддерживается в NodeJS по умолчанию и только недавно получил поддержку в браузерах.
Смотрите таблицу сравнения браузеров на MDN и эту проблему с узлом.
От Джеймса М Снелла Обновление на модулях ES6 в Node.js (февраль 2017):
Работа продолжается, но это займет некоторое время - в настоящее время мы рассматриваем как минимум год.
Пока поддержка не появится изначально, вам нужно будет продолжать использовать классические операторы require
:
const express = require("express");
Если вы действительно хотите использовать новые функции ES6/7 в NodeJS, вы можете скомпилировать его с помощью Babel. Вот пример сервера.
Ответ 2
К сожалению, Node.js пока не поддерживает ES6 import
.
Чтобы выполнить то, что вы пытаетесь сделать (импортируйте модуль Express), этого кода должно быть достаточно
var express = require("express");
Кроме того, убедитесь, что у вас установлен Express, выполнив
$ npm install express
Дополнительную информацию об обучении Node.js см. в Node.js Docs.
Ответ 3
Ошибка: SyntaxError: Неожиданный импорт токена или SyntaxError: Неожиданный экспорт токена
Решение: измените все ваши импорты как пример
const express = require('express');
const webpack = require('webpack');
const path = require('path');
const config = require('../webpack.config.dev');
const open = require('open');
Ответ 4
Как уже упоминалось в других ответах, Node JS в настоящее время не поддерживает импорт ES6
(На данный момент читайте ОБНОВЛЕНИЕ 2)
Включить импорт ES6 в узле js обеспечивает решение этой проблемы. Я устал от этого, и это сработало для меня.
Запустите команду:
npm install babel-register babel-preset-env --save-dev
Теперь вам нужно создать новый файл (config.js) и добавить в него следующий код.
require('babel-register')({
presets: [ 'env' ]
})
// Import the rest of our application.
module.exports = require('./your_server_file.js')
Теперь вы можете писать операторы импорта без ошибок.
Надеюсь, это поможет.
EDIT:
Вам нужно запустить новый файл, который вы создали с кодом выше. В моем случае это был config.js
. Поэтому я должен бежать:
node config.js
ОБНОВЛЕНИЕ 2:
Экспериментируя, я нашел одно простое решение этой проблемы.
Создайте файл .babelrc
в корне вашего проекта.
Добавьте следующее (и любые другие предварительные настройки Babel, которые вам нужны, можно добавить в этот файл):
{
"presets": ["env"]
}
Установите babel-preset-env
с помощью команды npm install babel-preset-env --save
, а затем установите babel-cli
с помощью команды npm install babel-cli -g --save
Теперь перейдите в папку, где находится ваш сервер или индексный файл, и запустите, используя: babel-узел fileName.js
Или вы можете запустить, используя npm start
, добавив следующий код в ваш файл package.json
:
"scripts": {
"start": "babel-node src/index.js"
}
Ответ 5
Если вы до сих пор не можете использовать "импорт", вот как я справился: просто переведите его в дружественный узел. Пример:
import { parse } from 'node-html-parser';
Такой же как:
const parse = require('node-html-parser').parse;
Ответ 6
если вы можете использовать "babel", попробуйте добавить скрипты сборки в package.json(- presets = es2015), как показано ниже. он делает для прекомпиляции код импорта для es2015
"build": "babel server --out-dir build --presets=es2015 && webpack"
Ответ 7
В предложении Babel 7 вы можете добавить зависимости от разработчиков
npm i -D @babel/core @babel/preset-env @babel/register
и добавьте .babelrc в корень
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"node": "current"
}
}
]
]
}
и добавьте в файл .js
require("@babel/register")
или если вы запустите его в cli, вы можете использовать хук require как -r @babel/register, ex.
$node -r @babel/register executeMyFileWithESModules.js
Ответ 8
Начиная с Node.js v12 (и теперь он, вероятно, довольно стабилен, но все еще помечен как "экспериментальный"), у вас есть несколько вариантов использования ESM (E CMA S cript M odules) в Node.js (для файлов есть третий способ оценки строк), вот что говорится в документации:
Флаг --experimental-modules
можно использовать для включения поддержки модулей ECMAScript (ES-модулей).
После включения Node.js будет обрабатывать следующие элементы как модули ES, когда они передаются на node
в качестве начального ввода или когда на них ссылаются операторы import
в коде модуля ES:
-
Файлы, оканчивающиеся на .mjs
.
-
Файлы, оканчивающиеся на .js
, или файлы без расширений, если ближайший родительский файл package.json
содержит поле верхнего уровня "type"
со значением "module"
.
-
Строки, передаваемые в качестве аргумента --eval
или --print
, или --print
на node
через STDIN
с флагом --input-type=module
.
Node.js будет обрабатывать как CommonJS все другие формы ввода, такие как файлы .js
где ближайший родительский файл package.json
не содержит поля "type"
top" верхнего уровня, или строковый ввод без флага --input-type
. Это поведение для сохранения обратной совместимости. Однако теперь, когда Node.js поддерживает как модули CommonJS, так и ES, лучше по возможности быть явным. Node.js будет обрабатывать следующее как CommonJS, когда передается node
в качестве начального ввода или когда на него ссылаются операторы import
в коде модуля ES:
-
Файлы, оканчивающиеся на .cjs
.
-
Файлы, оканчивающиеся на .js
, или файлы без расширений, если ближайший родительский файл package.json
содержит поле верхнего уровня "type"
со значением "commonjs"
.
-
Строки передаются в качестве аргумента --eval
или --eval
или --print
на node
через STDIN
с флагом --input-type=commonjs
.
Ответ 9
В моем случае это был файл .babelrc
, и он должен содержать что-то вроде этого:
{
"presets": ["es2015-node5", "stage-3"],
"plugins": []
}
Ответ 10
Когда я начинал с Express, всегда хотел, чтобы решение использовало импорт, а не требовал
const express = require("express");
// to
import express from "express"
Много раз прохожу эту строчку: - Unfortunately, Node.js does not support ES6 import yet.
Теперь, чтобы помочь другим, я создаю два новых решения здесь
1) esm: -
Исключительно простой, не требующий больших затрат, загрузчик модулей ECMAScript.
пусть заставит это работать
yarn add esm / npm install esm
создайте start.js или используйте свое пространство имен
require = require("esm")(module/*, options*/)
// Import the rest of our application.
module.exports = require('./src/server.js')
// where server.js is express server start file
Измените свой package.josn
путь прохождения start.js
"scripts": {
"start": "node start.js",
"start:dev": "nodemon start.js",
},
"dependencies": {
+ "esm": "^3.2.25",
},
"devDependencies": {
+ "nodemon": "^1.19.2"
}
2) Бабель Дж. С.: -
Это можно разделить на 2 части
а) Решение 1 благодаря timonweb.com
б) Решение 2
используйте Babel 6 (более старая версия babel-preset-stage-3 ^ 6.0)
создайте файл .babelrc
в корневой папке
{
"presets": ["env", "stage-3"]
}
Установить babel-preset-stage-3
yarn add babel-cli babel-polyfill babel-preset-env bable-preset-stage-3 nodemon --dev
Изменение в package.json
"scripts": {
+ "start:dev": "nodemon --exec babel-node -- ./src/index.js",
+ "start": "npm run build && node ./build/index.js",
+ "build": "npm run clean && babel src -d build -s --source-maps --copy-files",
+ "clean": "rm -rf build && mkdir build"
},
"devDependencies": {
+ "babel-cli": "^6.26.0",
+ "babel-polyfill": "^6.26.0",
+ "babel-preset-env": "^1.7.0",
+ "babel-preset-stage-3": "^6.24.1",
+ "nodemon": "^1.19.4"
},
Запустите свой сервер
yarn start / npm start
Ооо, нет, мы создаем новую проблему
regeneratorRuntime.mark(function _callee(email, password) {
^
ReferenceError: regeneratorRuntime is not defined
Эта ошибка появляется только тогда, когда вы используете async/await в своем коде.
Затем используйте polyfill, который включает пользовательскую среду выполнения регенератора и core-js.
добавить поверх index.js
import "babel-polyfill"
Это позволяет вам использовать async/await
используйте Бабель 7
Нужно обновлять каждую вещь в вашем проекте
давай начнем с бабел 7
.babelrc
{
"presets": ["@babel/preset-env"]
}
Некоторые изменения в package.json
"scripts": {
+ "start:dev": "nodemon --exec babel-node -- ./src/index.js",
+ "start": "npm run build && node ./build/index.js",
+ "build": "npm run clean && babel src -d build -s --source-maps --copy-files",
+ "clean": "rm -rf build && mkdir build",
....
}
"devDependencies": {
+ "@babel/cli": "^7.0.0",
+ "@babel/core": "^7.6.4",
+ "@babel/node": "^7.0.0",
+ "@babel/polyfill": "^7.0.0",
+ "@babel/preset-env": "^7.0.0",
+ "nodemon": "^1.19.4"
....
}
и используйте import "@babel/polyfill"
в начальной точке
import "@babel/polyfill"
import express from 'express'
const app = express()
//GET request
app.get('/', async (req, res) {
// await operation
res.send('hello world')
})
app.listen(4000, () => console.log('🚀 Server listening on port 400!'))
Вы думаете, почему start:dev
Шутки в сторону. Это хороший вопрос, если вы новичок. Каждый раз, когда вы меняете, каждый раз запускаете сервер
затем используйте yarn start:dev
в качестве сервера разработки. Каждый сервер изменений автоматически перезапускается для получения дополнительной информации о nodemon.