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

Next.js开发npm包时如何读取项目根目录的中间件配置.ts文件

报错原因说明

你遇到的Cannot import a module outside a module报错本质是Next.js的模块沙箱限制,以及Node.js的ES Module/CommonJS互操作限制:node_modules下的包默认被禁止导入项目目录内的用户文件,避免打包时出现不可控的依赖。

可行解决方案

方案1:导出初始化函数让用户传入配置(最推荐)

无需主动读取用户配置文件,完全规避跨模块导入问题,对用户无额外配置要求:

  1. 你的npm包调整导出逻辑,暴露配置注册函数和相关依赖:
// ngn包入口文件
import type { Keyable, Middleware } from './types'

// 全局存储运行时中间件配置
let runtimeMiddlewares: Keyable<Array<Middleware>> = {}

export function defineNgnConfig(config: { middlewares: Keyable<Array<Middleware>> }) {
  runtimeMiddlewares = config.middlewares
  // 内部API处理逻辑直接读取该变量即可
}

// 导出所有内置中间件、类型供用户直接调用
export * from './middlewares'
export * from './types'
  1. 用户侧的配置文件写法调整为:
// 用户项目根目录下的ngn.config.ts
import {
  defineNgnConfig,
  withSetCookie,
  decryptCookies,
  withRequest,
  withValidator,
  withIp,
  withThrottle
} from 'ngn'
// 支持用户导入自定义中间件
import customAuth from './src/middlewares/customAuth'

export default defineNgnConfig({
  middlewares: {
    "/": [
      withRequest,
      withIp,
      withThrottle,
      decryptCookies,
      withSetCookie,
      withValidator,
      customAuth
    ]
  }
})
  1. 仅需提示用户在Next.js的全局入口(如app/layout.tsx、pages/_app.tsx)或next.config.js中导入一次该配置文件即可,所有模块解析都在用户项目的编译上下文内完成,不会出现导入报错。

方案2:运行时动态编译配置文件

如果确实需要你的包主动读取用户配置,可使用轻量编译工具在运行时编译配置文件,无需webpack:

// 包内部的配置加载逻辑
import { readFileSync } from 'fs'
import { transform } from 'esbuild'
import path from 'path'
import { createRequire } from 'module'

async function loadUserConfig() {
  // 定位用户项目根目录下的配置文件
  const configPath = path.resolve(process.cwd(), 'ngn.config.ts')
  const configContent = readFileSync(configPath, 'utf-8')

  // 编译TS为可执行的CommonJS代码
  const { code } = await transform(configContent, {
    loader: 'ts',
    format: 'cjs',
    tsconfigRaw: readFileSync(path.resolve(process.cwd(), 'tsconfig.json'), 'utf-8')
  })

  // 执行代码获取导出的配置
  const module = { exports: {} }
  const require = createRequire(import.meta.url)
  eval(code)
  return module.exports.default
}

该方案需要注意将esbuild作为你的包的依赖项,同时兼容用户的TS配置。

webpack打包为单CommonJS文件的思路说明

该方案技术上可行,但需要用户额外配置Next.js的webpack规则,将配置文件设为单独的打包入口输出为CommonJS文件,上手成本更高,不推荐使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 03:57:03