You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NextJS引入自研NPM库报错:Cannot use import statement outside a module

Next.js引入自研ESM库时出现"Cannot use import statement outside a module"错误

错误详情

error - /Users/apple/testing-build/node_modules/foobar/dist/some-library.es.js:1
import t, { useState as M } from "react";
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at Object.compileFunction (node:vm:360:18)
    at wrapSafe (node:internal/modules/cjs/loader:1094:15)
    at Module._compile (node:internal/modules/cjs/loader:1129:27)
...

环境与已尝试方案

  • Node版本:18.13.0
  • 已尝试操作:将应用和库的package.json中type字段设为module,或统一改为CJS规范,问题仍未解决

自研库相关配置

库的tsconfig.json

{
  "compilerOptions": {
    "target": "ESNext",
    "useDefineForClassFields": true,
    "lib": ["DOM", "DOM.Iterable", "ESNext"],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "noFallthroughCasesInSwitch": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "ESNext",
    "moduleResolution": "Node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx",
    "sourceMap": true,
    "baseUrl": ".",
  },
  "include": ["./src/**/*.*"],
  "references": [{ "path": "./tsconfig.node.json" }]
}

库的dist代码示例(ESM格式)

// Beginning parts imports the libraries required
import t, { useState as D } from "react";
import l, { css as r } from "styled-components";
import { generateMedia as R } from "styled-media-query";

// ....

// The Ending part exports the components
export {
  ot as Accordian,
  Le as Badge,
  K as Button,
  nt as Card,
  lt as CollapsibleText,
  ct as Header,
  at as If
};

库的Vite配置

import { resolve } from 'node:path';

import { defineConfig, loadEnv, splitVendorChunkPlugin } from 'vite';
import { externalizeDeps } from 'vite-plugin-externalize-deps';
import nodeResolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import dts from 'vite-plugin-dts';
import react from '@vitejs/plugin-react';
import * as pkg from './package.json';

function verifyEnv(mode) {
  switch (mode) {
    case 'test':
    case 'local':
    case 'production':
    case 'dev': {
      return true;
    }

    case 'development': {
      throw new Error(
        'Seems like you provided mode as `development` means you probably wanted to use `dev` which is another script. Prefer our script over `vite dev`.'
      );
    }

    default: {
      throw new Error(
        `Either you provided an incorrect environment or you didn't send anything. Env received was ${process.env.NODE_ENV}.`
      );
    }
  }
}

export default defineConfig(({ mode }) => {
  verifyEnv(mode);
  const appEnv = loadEnv(mode, `${process.cwd()}/.env.${mode}`);

  return {
    build: {
      outDir: 'dist',
      rollupOptions: {
        input: './src/index.ts',
        treeshake: 'smallest',
        plugins: [nodeResolve({ mainFields: ['module', 'main'], browser: true }), commonjs()],
        output: {
          globals: {
            ...pkg.dependencies
          }
        }
      },
      lib: {
        entry: resolve(process.cwd(), 'src/index.ts'),
        name: 'Foo Components',
        formats: ['es', 'umd'],
        fileName: (format) => `foo-components.${format}.js`
      }
    },
    resolve: {
      alias: [
        { find: '@src', replacement: resolve(__dirname, './src') },
        { find: '@utils', replacement: resolve(__dirname, './src/utils') },
        { find: '@themes', replacement: resolve(__dirname, './src/themes') },
        { find: '@components', replacement: resolve(__dirname, './src/components') },
        { find: '@dlsCss', replacement: resolve(__dirname, './src/design/dls.min.css') }
      ]
    },
    plugins: [
      react({
        exclude: /\.stories\.(t|j)sx?$/,
        include: ['./src/**/*.tsx', './src/**/*.ts'],
        babel: { configFile: true }
      }),
      dts({
        include: ['./src/components']
      }),
      splitVendorChunkPlugin(),
      externalizeDeps()
    ],
    define: {
      __APP_ENV__: appEnv
    }
  };
});

库的Babel配置

module.exports = {
  presets: [
    [
      '@babel/preset-env',
      {
        targets: {
          browsers: ['> 0.25%, not dead']
        },
        modules: false,
        corejs: '3.6.5',
        useBuiltIns: 'entry'
      }
    ],
    '@babel/preset-react',
    '@babel/preset-typescript'
  ],
  plugins: [
    '@babel/plugin-proposal-optional-chaining',
    '@babel/plugin-syntax-optional-chaining',
    'styled-components',
    '@babel/plugin-proposal-class-properties',
    '@babel/plugin-syntax-dynamic-import'
  ],
  env: {
    production: {
      only: ['app'],
      plugins: [
        'transform-react-remove-prop-types',
        '@babel/plugin-transform-react-inline-elements',
        '@babel/plugin-transform-react-constant-elements'
      ]
    },
    test: {
      plugins: [
        '@babel/plugin-transform-modules-commonjs',
        'dynamic-import-node',
        [
          'auto-import',
          {
            declarations: [{ default: 'React', path: 'react' }]
          }
        ]
      ]
    }
  }
};

Next.js应用配置(tsconfig.json)

{
  "compilerOptions": {
    "target": "es5", // Also tried with `ESNext`
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "incremental": true,
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"]
    }
  },
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
  "exclude": ["node_modules"]
}

求解决思路

需要解决在Next.js应用中引入该自研ESM库时的模块语法错误问题,恳请提供可行的排查方向或解决方案。


内容的提问来源于stack exchange,提问作者frostzt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 18:01:09