SyntaxError: невозможно использовать оператор импорта вне модуля

У меня есть проект ApolloServer, который вызывает у меня проблемы, поэтому я подумал, что могу обновить его, и столкнулся с проблемами при использовании последней версии Babel. Мой "index.js":

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

И когда я запускаю его, я получаю сообщение об ошибке "SyntaxError: Невозможно использовать оператор импорта вне модуля". Сначала я попытался убедить TPTB* в том, что это модуль (безуспешно). Поэтому я изменил "импорт" на "требовать", и это сработало.

Но теперь у меня есть около двух десятков "импортированных" в другие файлы, дающие мне ту же ошибку.

* Я уверен, что корень моей проблемы в том, что я даже не уверен, что жалуется на проблему. Я вроде как предположил, что это Babel 7 (так как я пришел из Babel 6 и мне пришлось изменить предустановки), но я не уверен на 100%.

Большая часть того, что я нашел для решений, похоже, неприменима к обычным Node. Как этот здесь:

Импорт модуля ES6 с сообщением "Неперехваченная ошибка синтаксиса: неожиданный идентификатор"

Говорит, что это было решено добавлением "type=module", но обычно это происходит в HTML, которого у меня нет. Я также пробовал использовать старые пресеты моего проекта:

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

Но это вызывает у меня еще одну ошибку: "Ошибка: файлы плагинов / предустановок не могут экспортировать объекты, только функции".

ОБНОВЛЕНИЕ: вот зависимости, с которых я начал:

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

36 ответов

Решение

Убедитесь, что у вас установлена ​​последняя версия Node (или, по крайней мере, 13.2.0+). Затем выполните одно из следующих действий, как описано в документации:

Опция 1

У ближайшего родителя package.json файл, добавьте верхний уровень "type" поле со значением "module". Это гарантирует, что все.js а также .mjsфайлы интерпретируются как модули ES. Вы можете интерпретировать отдельные файлы как CommonJS, используя.cjs расширение.

// package.json
{
  "type": "module"
}

Вариант 2

Явно назовите файлы с помощью .mjsрасширение. Все остальные файлы, например.js будет интерпретироваться как CommonJS, что по умолчанию, если type не определено в package.json.

Если кто-то сталкивается с этой проблемой с Typescript, ключом к ее решению для меня было изменение

    "target": "esnext",
    "module": "esnext",

к

    "target": "esnext",
    "module": "commonjs",

В моем tsconfig.json. Я был под впечатлением "esnext"был" лучшим ", но это была просто ошибка.

Для тех, кто был так же сбит с толку, как и я, читая ответы, в вашем файле package.json добавьте"type": "module"на верхнем уровне, как показано ниже:

{
  "name": "my-app",
  "version": "0.0.0",
  "type": "module",
  "scripts": { ...
  },
  ...
}

Согласно официальному документу (https://nodejs.org/api/esm.html):

Операторы импорта разрешены только в модулях ES. Для аналогичных функций в CommonJS см. Import().

Чтобы Node обрабатывал ваш файл как модуль ES, вам необходимо (https://nodejs.org/api/esm.html):

  • добавить "тип": "модуль" в package.json
  • добавить флаг "--experimental-modules" к вызову узла

Я столкнулся с той же проблемой, но даже хуже: мне нужно было как "импортировать", так и "требовать"

  1. Некоторые новые модули ES6 работают только с импортом.
  2. Некоторые CommonJS работают с require.

Вот что у меня сработало:

  1. Превратите свой js файл в.mjs, как это предлагается в других ответах

  2. "require" не определяется в модуле ES6, поэтому вы можете определить его следующим образом:

    import { createRequire } from 'module'
    const require = createRequire(import.meta.url);
    

    Теперь require можно использовать обычным образом.

  3. Используйте импорт для модулей ES6 и требуйте для commonJS.

Некоторые полезные ссылки: собственная документация Node.js игровой. разница между import и require. У Mozilla есть хорошая документация по импорту

У меня была такая же проблема, и следующее исправило ее (с использованием узла 12.13.1):

  • Измените расширение файлов.js на.mjs
  • Добавьте флаг --experimental-modules при запуске вашего приложения.
  • Необязательно: добавьте "type": "module" в свой package.json

подробнее: https://nodejs.org/api/esm.html

Сначала мы установим @babel/cli, @babel/core and @babel/preset-env.

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

Затем мы создадим файл.babelrc для настройки babel.

$ touch .babelrc

Здесь будут размещены любые параметры, с которыми мы, возможно, захотим настроить babel.

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

С недавними изменениями в babel вам нужно будет транспилировать ES6, прежде чем узел сможет его запустить.

Итак, мы добавим наш первый скрипт build в package.json.

"scripts": {
  "build": "babel index.js -d dist"
}

Затем мы добавим наш стартовый скрипт в package.json.

"scripts": {
  "build": "babel index.js -d dist", // replace index.js with your filename
  "start": "npm run build && node dist/index.js"
}

Теперь запустим наш сервер.

$ npm start

Пробовал всеми методами, но ничего не помогло

Я получил одну ссылку из git hub.

Чтобы использовать импорт сценариев типов с nodejs, я установил следующие пакеты.

1. npm i typescript

2. npm i ts-node

Не требуется type: module в package.json

Например

{
  "name": "my-app",
  "version": "0.0.1",
  "description": "",
  "scripts": {
   
  },
  "dependencies": {
    "knex": "^0.16.3",
    "pg": "^7.9.0",
    "ts-node": "^8.1.0",
    "typescript": "^3.3.4000"
  }
}

Node v14.16.0
Для тех, кто пробовал .mjs и получил:

      Aviator@AW:/mnt/c/Users/Adrian/Desktop/Programming/nodejs_ex$ node just_js.mjs
file:///mnt/c/Users/Adrian/Desktop/Programming/nodejs_ex/just_js.mjs:3
import fetch from "node-fetch";
       ^^^^^

SyntaxError: Unexpected identifier

и кто пробовал import fetch from "node-fetch";
и кто пробовал const fetch = require('node-fetch');

      Aviator@AW:/mnt/c/Users/Adrian/Desktop/Programming/nodejs_ex$ node just_js.js
(node:4899) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
(Use `node --trace-warnings ...` to show where the warning was created)
/mnt/c/Users/Adrian/Desktop/Programming/nodejs_ex/just_js.js:3
import fetch from "node-fetch";
^^^^^^

SyntaxError: Cannot use import statement outside a module  

и кто пробовал "type": "module" в package.json, но продолжайте видеть ошибку,

      {
  "name": "test",
  "version": "1.0.0",
  "description": "to get fetch working",
  "main": "just_js.js",
  "type": "module",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "MIT"
}

Я смог без проблем переключиться на аксиомы.

import axios from 'axios';<- ставить вверху файла.
Пример:

      axios.get('https://www.w3schools.com/xml/note.xml').then(resp => {

    console.log(resp.data);
});

Шаг 1

yarn add esm

или

npm i esm --save

Шаг 2

package.json

  "scripts": {
    "start": "node -r esm src/index.js",
  }

Шаг 3

nodemon --exec npm start

Если вы используете импорт JavaScript ES6 :

  1. установитьcross-env
  2. в изменении"test": "jest"к"test": "cross-env NODE_OPTIONS=--experimental-vm-modules jest"
  3. большеpackage.json, добавьте это:
          ...,
    "jest": {
        "transform": {}
    },
    "type": "module"

Объяснение:

cross-env позволяет изменять переменные среды без изменения команды npm. Затем в файле package.json вы изменяете команду npm, чтобы включить экспериментальную поддержку ES6 для Jest, и настраиваете Jest для этого.

Я нашел, что обновление 2020 года для ответа в этой ссылке полезно для ответа на этот вопрос, а также для того, чтобы рассказать вам, ПОЧЕМУ он это делает:

Использование Node.js по сравнению с импортом / экспортом ES6

Вот отрывок:

« Обновление 2020

Начиная с Node v12, поддержка модулей ES включена по умолчанию, но на момент написания статьи это все еще экспериментально. Файлы, включающие модули узлов, должны либо оканчиваться на .mjs, либо ближайший файл package.json должен содержать "type": "module". Документация по Node содержит массу дополнительной информации, в том числе о взаимодействии между модулями CommonJS и ES ".

Я новичок в Node.js, и у меня возникла та же проблема с функцией AWS Lambda (с использованием Node.js), когда я исправлял ее.

Я обнаружил некоторые различия между CommonJS и ES6 JavaScript:

ЭС6:

  • Добавьте «тип»: «модуль» в файл package.json .

  • Используйте «импорт» для использования из lib.

    Пример : импортировать jwt_decode из jwt-decode

  • Код метода обработчика лямбда должен быть определен следующим образом

    "exports.handler = асинхронный (событие) => {}"

CommonJS:

  • Не добавляйте «type»: «module» в файл package.json .

  • Используйте «require» для использования из lib.

    Пример : const jwt_decode = require("jwt-decode");

  • Код метода обработчика лямбда должен быть определен следующим образом:

    "экспорт константного обработчика = асинхронный (событие) => {}"

В моем случае. Я думаю, что проблема в стандартном исполняемом файле узла. node target.ts

Я заменил это на nodemon и на удивление это сработало!

Способ использования стандартного исполняемого файла (раннера):

node target.ts

Способ использования исполняемого файла nodemon (runner):

nodemon target.ts

Не забудьте установить nodemon с помощью npm install nodemon

ПРИМЕЧАНИЕ: это отлично подходит для разработки. Но во время выполнения вы можете выполнить node с составленным js файл!

Чтобы использовать импорт, выполните одно из следующих действий.

  1. Переименуйте файл .js в .mjs.
  2. В файле package.json добавьте {type:module}

Если вы хотите использовать BABEL, у меня есть для этого простое решение!

Помните, что это для примера nodejs: как сервер expressJS!

Если вы собираетесь использовать React или другой фреймворк, загляните в документацию Babel!

Во- первых , установите (не устанавливайте ненужные вещи, которые только испортят ваш проект!)

      npm install --save-dev @babel/core @babel/node

Всего 2 ВАО

затем настройте файл babel в своем репо!

имя файла:

      babel.config.json

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


если вы не хотите использовать файл babel, используйте:

Запустите в своей консоли, и script.js станет вашей точкой входа!

      npx babel-node --presets @babel/preset-env -- script.js

полная информация здесь; https://babeljs.io/docs/en/babel-узел

У меня была эта ошибка в моем рабочем пространстве NX после обновления вручную. Следующие изменения в каждом jest.config.jsпочинил это:

      transform: {
  '^.+\\.(ts|js|html)$': 'jest-preset-angular',
},

к

      transform: {
  '^.+\\.(ts|mjs|js|html)$': 'jest-preset-angular',
},

Эта ошибка также возникает при запуске команды

node filename.ts

и нет

node filename.js

Проще говоря, с помощью команды node нам нужно будет запустить файл JavaScript (filename.js), а не файл TypeScript, если мы не используем такой пакет, как ts-node

в package.json напишите {"type": "module"}

это устранило мою проблему, у меня была такая же проблема

Если вы используете приложение vite-react .js с Speedy Web Compiler ( SWC) и пытались импортировать различные методы библиотеки тестирования jest ({import { describe, expect, test } from "@jest/globals";), все ваши тесты будут выполняться индивидуально и вне модуля. Следовательно, вы можете получить ошибку:

Синтаксическая ошибка: невозможно использовать оператор импорта вне модуля.

Поскольку вы используете SWC, конфигурация Babel не поможет. Таким образом, это можно решить, просто указав простую зависимость разработчика:

npm install --save-dev @types/jest

Позже удалите оператор импорта, используйте методы (опишите, тестируйте, ожидайте, afterAll, afterEach, beforeAll, beforeEach,fail, fdescribe, fit, it, jasmine, jest, pending, spyOn, xdescribe, xit, xtest) напрямую, так как они обрабатываются как глобалы. Установите ссылку и другую документацию здесь! @types/шутка

Проверьте свой sum.test.js с помощьюnpm run test, предположим, что у вас есть"test": "jest"в командах сценариев и шутке в зависимости от разработчика:

Просто добавь --presets '@babel/preset-env'

например

babel-node --trace-deprecation --presets '@babel/preset-env' ./yourscript.js

ИЛИ

в babel.config.js

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

Для людей, приходящих в эту тему из-за этой ошибки в функциях Netlify даже после добавления "type": "module"в файле package.json обновите свой netlify.tomlиспользовать «esbuild». Поскольку esbuild поддерживает ES6, это сработает.

      [functions]
  node_bundler = "esbuild"

Ссылка: https://docs.netlify.com/functions/build-with-javascript/#automated-dependency-bundling

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

С модулями ES6 вы еще не можете импортировать каталоги. Ваш импорт должен выглядеть так:

import fs from './../node_modules/file-system/file-system.js'

Документация сбивает с толку. Я использую Node.js для выполнения некоторой локальной задачи на своем компьютере.

Предположим, мой старый скрипт был test.js. Внутри него , если я хочу использовать

      import something from "./mylocalECMAmodule";

выдаст такую ​​ошибку:

      (node:16012) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
SyntaxError: Cannot use import statement outside a module
...

Это не ошибка модуля, а ошибка Node.js. Запретить загрузку чего-либо вне «модуля».

Чтобы это исправить, просто переименуйте ваш старый скрипт test.js в test.mjs .

Вот и все.

У меня была эта проблема, когда я выполнял миграцию

Его проблема es5 vs es6

Вот как я это решил

я бегу

npm install @babel/register

и добавить

require("@babel/register")

вверху моего файла.sequelizerc мой

и приступим к выполнению моего продолжения миграции. Это применимо и к другим вещам, кроме продолжения

Вавилон делает транспилирование

Если вы используете узел, вам следует обратиться к этому документу . Просто настройте babel в своем приложении node, он будет работать, и он сработал для меня.

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

Недавно возникла проблема. Исправление, которое сработало для меня, заключалось в добавлении этого в babel.config.json в разделе плагинов.

["@babel/plugin-transform-modules-commonjs", {
    "allowTopLevelThis": true,
    "loose": true,
    "lazy": true
  }],

У меня был какой-то импортированный модуль с //, и ошибка "не может использовать импорт вне модуля".

В случае, если ваш запущенный nodemon для версии узла 12, используйте эту команду.server.js - это "главный" внутри package.json файл, замените его соответствующим файлом внутри файла package.json

nodemon --experimental-modules server.js

Когда я использую миграции продолжения с npx sequelize db:migrateЯ получил эту ошибку, поэтому моим решением было добавить в файл .sequelizerc следующую строку require('@babel/register');как показано на следующем изображении

babel и babelимейте в виду, что вы должны установить регистрацию

Неверный MIME-тип для файлов модуля JavaScript

Общим источником проблемы является тип MIME для файлов JavaScript типа «модуль», который не распознается как тип «модуля» сервером, клиентом или механизмом ECMAScript, который обрабатывает или доставляет эти файлы.

Проблема заключается в том, что разработчики файлов Module JavaScript неправильно связали модули с новым расширением «.mjs» (.js), но затем присвоили ему тип сервера типа MIME «text/javascript». Это означает, что типы .js и .mjs одинаковы. На самом деле новый тип файлов JavaScript .js также изменился на «application/javascript», что еще больше запутало проблему. Таким образом, файлы Module JavaScript не распознаются ни одной из этих систем, независимо от разрабатываемых систем обработки файлов Node.js или Babel.

Основная проблема заключается в том, что этот новый «модульный» подтип JavaScript еще известен большинству серверов или клиентов (современные браузеры HTML5). Другими словами, у них нет никакого способа узнать, что на самом деле представляет собой тип файла модуля , кроме типа JavaScript!

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

Единственное решение для сервера или клиента состоит в том, чтобы change your server or browser to deliver a new Mime-type that trigger ES6 support of Module files, которые имеют расширение. На данный момент единственный способ сделать это — либо создатьHTTP content-typeна сервере "module" для любого файла с.mjsрасширение и измените расширение файла в файлах модуля JavaScript на «.mjs» или добавьте тег сценария HTML сtype="module"добавляется к любому внешнему<script>элемент, который вы используете, который загружает ваш внешний.jsФайл модуля JavaScript.

Как только вы обманом заставите браузер или движки JavaScript принять новый тип файла Module, они начнут выполнять свои скриптовые цирковые трюки в движках JS или системах Node.js, которые вы используете.

Другие вопросы по тегам