如何在 next.js 中加载导出 Typescript 的库

Gh0*_*05d 21 typescript webpack next.js webpack-4

当尝试从导出Typescript 的私有库导入组件时,我们收到以下错误消息:

Module parse failed: Unexpected token (82:7)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| 
| // Types
> export type {
Run Code Online (Sandbox Code Playgroud)

我该如何解决这个问题?我尝试在tsconfig文件中显式包含库节点模块:

  "include": [
    "next-env.d.ts",
    "**/*.ts",
    "**/*.tsx",
    "node_modules/@private-lib/*.*"
  ],
  "exclude": [""]
Run Code Online (Sandbox Code Playgroud)

但不幸的是,没有效果。似乎可以更改next.jswebpack配置,但不幸的是,尝试插入 Typescript 加载器并不起作用:

module.exports = {
  webpack: (config, options) => {
    config.module.rules.push({
      test: /\.(ts|js)x?$/,
      use: [
        options.defaultLoaders.babel,
        {
          loader: "ts-loader",
          options: {
            transpileOnly: true,
            experimentalWatchApi: true,
            onlyCompileBundledFiles: true,
          },
        },
      ],
    });

    return config;
  },
};
Run Code Online (Sandbox Code Playgroud)

它会产生以下错误:

./node_modules/process/browser.js
TypeError: /home/blub/bla/website/node_modules/process/browser.js: Property left of AssignmentExpression expected node to be of a type ["LVal"] but instead got "BooleanLiteral"
Run Code Online (Sandbox Code Playgroud)

那么有没有人也遇到过这个问题并可以指出我正确的方向?这里似乎有很多魔力在起作用,我有点迷失了。

dir*_*ugh 23

在遇到看起来相同的问题后,我遇到了这个SO问题:带有打字稿的next.js项目(yarn create next-app --typescript)。

  • 纱线:17年1月22日
  • 下一个:12.0.7
  • 节点:14.18.1

对我来说,这种情况发生在ts从文件(项目内部)包含一个包(next.js 项目外部tsx)之后。幕后似乎存在转译魔法,并试图将 ts 文件解析为纯 js 的某个版本。

我的问题已由next-transpile-modules (^9.0.0) 解决。具体来说,假设您:

  1. next.config.js像这样开始
/** @type {import('next').NextConfig} */

module.exports = {
  reactStrictMode: true,
  env: {
  },
}

Run Code Online (Sandbox Code Playgroud)
  1. 有外部 TS 库private-lib,其中import { ... } from '/path/to/private-lib'某个 tsx 文件会导致编译时错误。

使固定:

  1. yarn add next-transpile-modules
  2. yarn add file:/path/to/private-lib
  3. 更改 ts/tsx 文件中的导入语句private-lib
  4. 更新next.config.js看起来像这样
/** @type {import('next').NextConfig} */
// see https://github.com/martpie/next-transpile-modules#readme
const withTM = require('next-transpile-modules')(['private-lib']);

module.exports = withTM({
  reactStrictMode: true,
  env: {
  },
})
Run Code Online (Sandbox Code Playgroud)

YMMV,HTH,#FixMagicWithMoreMagic


Jax*_*mas 22

这个问题有点老了,所以我想我应该发布一个更新,以扩展direct-laugh的原始答案,供任何偶然发现这个问题的人使用。

如前所述,通过转译模块next.config.js似乎是解决方案。尽管使用 NextJS 13.1,无需安装额外的next-transpile-modules软件包,因为这些功能在 NextJS 13.1 中本身就可用。

在 中next.config.js,只需添加transpilePackages选项并包含包的名称ts

module.exports = {
  ...
  transpilePackages: ['my-ts-package'],
}
Run Code Online (Sandbox Code Playgroud)

请参阅模块转译


tmh*_*005 6

我猜问题出在转译jsx?文件上,因此仅在以下情况下ts-loader转译文件是安全的:tsx?ts-loadder

webpack: (config, options) => {
  config.module.rules.push({
    test: /\.(ts)x?$/, // Just `tsx?` file only
    use: [
      // options.defaultLoaders.babel, I don't think it's necessary to have this loader too
      {
        loader: "ts-loader",
        options: {
          transpileOnly: true,
          experimentalWatchApi: true,
          onlyCompileBundledFiles: true,
        },
      },
    ],
  });

  return config;
},

Run Code Online (Sandbox Code Playgroud)

另一件事,如果您的存储库现在使用jsx?文件,这意味着将tsx?文件导入到jsx?文件中,您可能必须{ "allowJs": true }启用tsconfig.json