网站搜索

typescript - Next.js 13 项目引用路径别名时抛出 webpack 错误


我正在将一个小型且旧的 React 项目(以及它的 NestJS 服务器)迁移到 Next.js 13。我是通过一个名为 Create T3 App 的 CLI 脚手架来进行的。我在我参与的所有项目中都经常使用项目引用,并且我正在尝试在这里这样做:

tsconfig.json:

{
  "compilerOptions": {
    "target": "es2017",
    "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,
    "noUncheckedIndexedAccess": true,

    "baseUrl": ".",
    "paths": {
      "@core/*": ["../../../../libs/core/src/*"]
    }
  },
  "references": [
    { "path": "../../../../libs/core/" }
  ],
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "**/*.cjs", "**/*.mjs"],
  "exclude": ["node_modules"]
}

但它一直抛出这个 webpack 加载器错误:

错误 - ../../../../libs/core/src/path/to/file.ts 模块解析失败:意外的标记 (4:12) 你可能需要一个合适的加载器来处理此文件类型,目前没有配置任何加载器来处理此文件。请查看 https://webpack.js.org/concepts#loaders

文件上没有标红的错误,vscode 的智能感知工作正常。

我已经尝试将别名添加到 webpack,如下所示:

next.config.mjs:

// @ts-check
/**
 * Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation.
 * This is especially useful for Docker builds.
 */
!process.env.SKIP_ENV_VALIDATION && (await import("./src/env/server.mjs"));
import path from 'path';

/** @type {import("next").NextConfig} */
const config = {
  reactStrictMode: true,
  swcMinify: true,
  i18n: {
    locales: ["en"],
    defaultLocale: "en",
  },
  webpack: (config, { buildId, dev, isServer, defaultLoaders, nextRuntime, webpack }) => {
    return {
      ...config, 
      resolve: { 
        ...config.resolve,
        alias: {
          ...config.resolve.alias,
          '@core': path.resolve('../../../../libs/core/src'),
        }
      }
    }
  },
};
export default config;

这没有改变错误信息。

我尝试过将 ts-loader 添加到 webpack,但它在应用的其他部分会抛出错误。如果可能的话,我希望在不使用 babel 的情况下解决这个问题。

有人知道如何在 Next.js 13 中让外部项目的路径别名生效吗?


答案分解:

使用 @Yilmaz 建议的名为 next-transpile-modules 的包,我能够使项目引用及其别名正常工作。此解决方案要求在 tsconfig.json 中正确设置 "baseUrl" 和 "paths" 字段,并在 next.config.mjs 中添加以下内容:

import transpile from 'next-transpile-modules';

const withModules = transpile([
  '../../../../libs/core'
]);

/** @type {import("next").NextConfig} */
const config = {
  ...
};

export default withModules(config);

答案#1

你的 tsconfig.json 不符合默认的 next13 typescript 配置。我使用 --typescript 创建了一个 next 应用,这是默认的 tsconfig.json。我没有修改它

{
  "compilerOptions": {
    "target": "es5",
    "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,
    "plugins": [
      {
        "name": "next"
      }
    ]
  },
  "include": [
    "next-env.d.ts",
    "**/*.ts",
    "**/*.tsx",
    ".next/types/**/*.ts"
  ],
  "exclude": [
    "node_modules"
  ]
}

如果你遵循 next-transpile-modules npm 包并在 next.config.js 中进行设置

import transpile from 'next-transpile-modules';

const withModules = transpile([
  '../../../../libs/core'
]);

/** @type {import("next").NextConfig} */
const config = {
  ...
};

export default withModules(config);

相关文章