Не понимаю в чем дело. Узел v5.6.0 NPM v3.10.6

Код:

function (exports, require, module, __filename, __dirname) {
    import express from 'express'
};

The error:

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

Ответы (16)

Узел 13 + Поскольку Узел 13, вы можете использовать либо расширение .mjs, либо установить {"type": "module" } в вашем package.json. Вам не нужно использовать флаг - экспериментальные модули.Модули теперь помечены как стабильные в node.js

Узел 12 Поскольку Узел 12, вы можете использовать либо расширение .mjs, либо установить "type": "module" в вашем package.json. И вам нужно запустить узел с флагом - experimental-modules.

Узел 9 В Узле 9он включен за флагом и использует расширение .mjs.

node --experimental-modules my-app.mjs

Хотя import действительно является частью ES6, , к сожалению, он еще не поддерживается в NodeJS по умолчанию и только совсем недавно получил поддержку в браузерах.

См. таблицу совместимости браузера в MDN и в этой проблеме узла.

Из Джеймса М. Снелла Обновление модулей ES6 в Node.js (февраль 2017 г.):

Работа ведется, но это займет некоторое время - в настоящее время мы рассматриваем как минимум год.

Пока поддержка не появится изначально (теперь отмечен как стабильный в Node 13 +), вам придется продолжать использовать классические операторы require:

const express = require("express");

Если вы действительно хотите использовать новые возможности ES6 / 7 в NodeJS, вы можете скомпилировать его с помощью Babel.Вот пример сервера.

В моем проекте используется узел v10.21.0, который все еще не поддерживает ключевое слово ES6 import. Есть несколько способов заставить узел распознавать import, один из них - запустить узел с node --experimental-modules index.mjs (расширение mjs - уже описано в одном из ответов здесь). Но, таким образом, вы не сможете использовать ключевое слово для конкретного узла, например require, в своем коде. Если необходимо использовать ключевое слово nodejs require вместе с ключевым словом ES6 import, тогда выходом будет использование пакета esm npm. После добавления пакета esm в качестве зависимости узел необходимо запустить со специальной конфигурацией, например: node -r esm index.js

если вы можете использовать babel, попробуйте добавить скрипты сборки в package.json (- presets = es2015), как показано ниже. это делается для предварительной компиляции кода импорта в es2015

"build": "babel server --out-dir build --presets=es2015 && webpack"

Начиная с Node.js v12 (и сейчас он, вероятно, довольно стабилен, но все еще помечен как «экспериментальный»), у вас есть несколько вариантов использования ESM (ECMAScript Modules) в Node.js (для файлов есть третий способ преобразования строк), вот что в документации сказано:

Флаг - экспериментальные модули может использоваться для включения поддержки Модули ECMAScript (модули ES).

После включения Node.js будет рассматривать следующие модули как модули ES при передаче в узел в качестве начального ввода или когда на него ссылаются операторы import внутри Код модуля ES:

  • Файлы, оканчивающиеся на .mjs.

  • Файлы, оканчивающиеся на .jsили файлы без расширений, если ближайший родительский package.json файл содержит поле верхнего уровня "тип" со значением «модуль».

  • Строки, переданные в качестве аргумента в - eval или - print, или переданы по конвейеру в узел через STDIN, с флагом - input-type = module.

Node.js будет рассматривать как CommonJS все другие формы ввода, такие как файлы .js где ближайший родительский файл package.json не содержит файлов верхнего уровня "тип" поле, либо строковый ввод без флага - тип ввода. Такое поведение сохранить обратную совместимость. Однако теперь, когда Node.js поддерживает оба Модули CommonJS и ES по возможности лучше указывать явно. Node.js будет рассматривать следующее как CommonJS при передаче на node в качестве начального ввода, или при ссылке import в коде модуля ES:

  • Файлы с расширением .cjs.

  • Файлы, оканчивающиеся на .jsили файлы без расширений, если ближайший родительский package.json файл содержит поле верхнего уровня "тип" со значением commonjs.

  • Строки, переданные в качестве аргумента в - eval или - print, или переданы в узел через STDIN, с флагом - input-type = commonjs.

Когда я начинал с экспрессом, всегда хотел, чтобы решение использовало импорт, а не требовать

const express = require("express");
// to 
import express from "express"

Часто проходите через эту строку: - К сожалению, Node.js еще не поддерживает импорт ES6.

Теперь, чтобы помочь другим, я создаю здесь два новых решения

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) Babel js: -

Можно разделить на 2 части

a) Решение 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

используйте Babel 7

Необходимо обновить все в вашем проекте давай начнем с Babel 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

Если вы все еще не можете использовать «импорт», вот как я с этим справился: Просто переведите его на дружественный к узлу require. Пример:

import { parse } from 'node-html-parser';

То же, что:

const parse = require('node-html-parser').parse;

Как упоминалось в других ответах, 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')

Теперь вы можете писать операторы импорта, не получая ошибок.

Надеюсь, это поможет.

РЕДАКТИРОВАТЬ:

Вам необходимо запустить новый файл, который вы создали с помощью вышеуказанного кода. В моем случае это был 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-node имя_файла.js

Или вы можете запустить, используя npm start, добавив следующий код в свой package.json файл:

    "scripts": {
        "start": "babel-node src/index.js"
    }

Просто установите более новую версию Node. Пока что Node v10 es6 не поддерживается. Вам нужно отключить несколько флагов или использовать

операторы import поддерживаются в стабильном выпуске Node, начиная с версии 14.x LTS.

Все, что вам нужно сделать, это указать "тип": "модуль" в package.json.

Я собираюсь обратиться к другой проблеме в рамках исходного вопроса, которой больше никто не знает. После недавнего преобразования CommonJS в ESM в моем собственном проекте NodeJS я почти не видел обсуждения того факта, что вы не можете размещать импорт где угодно, как вы могли бы с require. Мой проект сейчас отлично работает с импортом, но когда я использую код в вопросе, я сначала получаю сообщение об ошибке из-за отсутствия именованной функции. После названия функции я получаю следующее ...

import express from 'express'
       ^^^^^^^

SyntaxError: Unexpected identifier
    at Loader.moduleStrategy (internal/modules/esm/translators.js:88:18)

Вы не можете размещать импорт внутри функций, как могли бы вы. Они должны быть размещены в верхней части файла, вне блоков кода. Я сам потратил довольно много времени на эту проблему.

Итак, хотя все вышеперечисленные ответы отлично помогают вам заставить импорт работать в вашем проекте, ни один из них не учитывает тот факт, что код в исходном вопросе не может работать так, как написано.

Я пытался заставить это работать. Вот что работает:

  1. Используйте последнюю версию узла. Пользуюсь v14.15.5. Проверьте свою версию, запустив: node --version
  2. Назовите файлы так, чтобы все они оканчивались на .mjs, а не на .js

Пример:

mod.mjs

export const STR = 'Hello World'

test.mjs

import {STR} from './mod.mjs'
console.log(STR)

Выполнить: node test.mjs

Вы должны увидеть «Hello World».

К сожалению, Node.js пока не поддерживает импорт из ES6.

Чтобы выполнить то, что вы пытаетесь сделать (импортировать модуль Express), этого кода должно хватить

var express = require("express");

Также убедитесь, что у вас установлен Express, запустив

$ npm install express

См. Node.js Docs для получения дополнительной информации об изучении Node.js.

предложение 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, например

$node -r @babel/register executeMyFileWithESModules.js

Ошибка: SyntaxError: неожиданный токен импорт или SyntaxError: неожиданный токен экспорт


Решение: Измените весь ваш импорт, например,

const express = require ('экспресс');
const webpack = require ('webpack');
const path = require ('путь');
const config = require ('../ webpack.config.dev');
const open = require ('open');

А также измените свой export default = foo; на module.exports = foo;

В моем случае он искал файл .babelrc, и он должен содержать что-то вроде этого:

{
  "presets": ["es2015-node5", "stage-3"],
  "plugins": []
}

Я в шоке esm не упоминается. Этот небольшой, но мощный пакет позволяет использовать либо import, или require.

Установите esm в свой проект

$ npm install --save esm

Обновите сценарий запуска узла, чтобы использовать esm

узел -r esm app.js

esm просто работает. Я потратил ТОННУ времени с .mjs и - экспериментальные модули только для того, чтобы узнать, что файл .mjs не может импортировать файл, который использует требуется или module.exports. Это была огромная проблема, тогда как esm позволяет вам смешивать и сопоставлять, и он просто вычисляет это ... esm просто работает.

2022 WebDevInsider