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

В настоящее время я конвертирую бессерверный API-интерфейс лямбда-микросервисов AWS в машинописный текст. Я надеюсь, что смогу поддерживать существующие файлы js, добавляя больше файлов ts по мере продвижения. У меня возникли проблемы с настройкой веб-пакета и машинописного текста, и я получаю эту ошибку во время выполнения при вызове одной из моих лямбда-выражений.

× Unhandled exception in handler 'getInstitutionInfo'.
× Runtime.UserCodeSyntaxError: SyntaxError: Cannot use import statement outside a module
      at _loadUserApp (C:\git\my-project\node_modules\serverless-offline\src\lambda\handler-runner\in-process-runner\aws-lambda-ric\UserFunction.js:307:15)
      at async module.exports.load (C:\git\my-project\node_modules\serverless-offline\src\lambda\handler-runner\in-process-runner\aws-lambda-ric\UserFunction.js:341:21)
      at async InProcessRunner.run (file:///C:/git/my-project/node_modules/serverless-offline/src/lambda/handler-runner/in-process-runner/InProcessRunner.js:41:21)
      at async MessagePort.<anonymous> (file:///C:/git/my-project/node_modules/serverless-offline/src/lambda/handler-runner/worker-thread-runner/workerThreadHelper.js:24:14)
× SyntaxError: Cannot use import statement outside a module

Кажется, жалуется на один из пакетов, которые я использую, а не на мой код. Это мой tsconfig.json

{
  "$schema": "https://json.schemastore.org/tsconfig",
  "compilerOptions": {
    "lib": [
      "es2020"
    ],
    "module": "commonjs",
    "target": "es2020",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "sourceMap": true,
    "allowJs": true,
    "outDir": ".erb/dll"
  }
}

и моя конфигурация веб-пакета

const path = require('path');
const slsw = require('serverless-webpack');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const nodeExternals = require('webpack-node-externals');

module.exports = {
  // `mode` will be set to `production` and comes with included optimizations
  // when building to be run on AWS or similar.
  // https://webpack.js.org/configuration/mode/
  mode: slsw.lib.webpack.isLocal ? 'development' : 'production',
  // to determine what source maps to use per dev or prod
  // https://webpack.js.org/configuration/devtool/
  devtool: slsw.lib.webpack.isLocal ? 'source-map' : 'cheap-source-map',

  // the provided argument will be an object referencing functions as defined
  // in your `serverless.yml` .
  // https://webpack.js.org/concepts/entry-points/
  entry: slsw.lib.entries,
  target: 'node',
  resolve: {
    // What file extensions we want Webpack to care about, and in what order
    // https://webpack.js.org/configuration/resolve/#resolveextensions
    extensions: ['.cjs', '.mjs', '.js', '.ts'],
    // `yarn add -D tsconfig-paths-webpack-plugin` if you need path aliases
    // plugins: [new TsconfigPathsPlugin()],
  },
  // Where the bundled files will be output. Not strictly necessary with
  // Serverless Webpack.
  // https://webpack.js.org/configuration/output/
  output: {
    libraryTarget: 'commonjs2',
    path: path.join(__dirname, '.webpack'),
    filename: '[name].js',
  },
  // Anything that will be available to the bundled code in the runtime
  // environment and does not need to be included in any of the bundles.
  //
  // In AWS Lambda, the `aws-sdk` is available and we almost certainly want to
  // exclude it from our bundle(s). Similarly, because it's a Node lambda,
  // Node's native modules will also be available.
  externals: ['aws-sdk', nodeExternals()],
  module: {
    // Instruct Webpack to use the `ts-loader` for any TypeScript files, else it
    // won't know what to do with them.
    rules: [
      {
        test: /\.[jt]s?$/,
        loader: 'ts-loader',
        exclude: [
          [
            /node_modules/,
            path.resolve(__dirname, '.webpack'),
            path.resolve(__dirname, '.serverless'),
          ],
        ],
        // And here we have options for ts-loader
        // https://www.npmjs.com/package/ts-loader#options
        options: {
          // Disable type checking, this will lead to improved build times
          transpileOnly: true,
          // Enable file caching, can be quite useful when running offline
          experimentalFileCaching: true,
        },
      },
    ],
  },
  // We still want type checking, just without the burden on build performance,
  // so we use a plugin to take care of it on another thread.
  plugins: [new ForkTsCheckerWebpackPlugin()],
};

Ваша лямбда работает как esm или cjs? Ваша конфигурация TS предполагает, что вы хотите cjs, и ошибка подразумевает, что в вашем проекте не применяется модуль типа. Можете ли вы переключиться на esm, т. е. использовать среду выполнения узла, которая его поддерживает? В противном случае вам понадобится что-то вроде babel для переноса этой зависимости для использования cjs.

morganney 19.05.2023 15:54

@morganney Может быть глупый вопрос, но как мне это узнать? Я предполагаю, что это то, во что скомпилирован код, то есть commonjs. В package.json не указан «тип», а версия узла, на которой он развернут, равна 18.

Real World 19.05.2023 16:48

Node 18 поддерживает esm. Я бы предложил перенести ваше приложение на цель сборки esm. В противном случае вы добавляете дополнительные инструменты сборки для поддержки старой модульной системы. Вы также можете увидеть, есть ли у этой зависимости версия, опубликованная как cjs, и использовать ее вместо этого.

morganney 19.05.2023 19:36
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
74
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Стек вызовов был отвлекающим маневром, поскольку он не показывал стек вызовов, где на самом деле произошла ошибка. Проблема была с пакетом npm, который мы создали с помощью импорта esm, но он был импортирован в проект, использующий commonjs. Исправление состояло в том, чтобы пересобрать пакет с помощью babel, чтобы заменить его на commonjs.

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