How to load libraries which export Typescript in next.js

16.2k Views Asked by At

When trying to import a component from a private library which exports Typescript, we get the following error message:

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 {

How could I fix that? I tried to explicitly include the libraries node modules in the tsconfig file:

  "include": [
    "next-env.d.ts",
    "**/*.ts",
    "**/*.tsx",
    "node_modules/@private-lib/*.*"
  ],
  "exclude": [""]

but unfortunately, to no avail. There seems to be the possibility to change the webpack configuration of next.js, but trying to just shove in a Typescript loader did not work, unfortunately:

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;
  },
};

It produces this error:

./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"

So is anybody out there who also faced this problem and could point me into the right direction? There seems to be a lot of magic at work here and I am kind of lost.

3

There are 3 best solutions below

0
On

I'm guessing the issue is from transpiling jsx? files with ts-loader so it's safe to just only transpile tsx? file in case of 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;
},

One more thing, If your repo is now using jsx? files which means importing tsx? file in a jsx? file, you might have to enable { "allowJs": true } in tsconfig.json

4
On

I landed on this SO question after encountering what looks like the same issue: next.js project with typescript (yarn create next-app --typescript).

  • yarn: 1.22.17
  • next: 12.0.7
  • node: 14.18.1

For me, this happened right after including a ts package (external to the next.js project) from within a tsx file (internal to the project). There appears to be transpiling magic behind the scenes, and is attempting to parse the ts file as some version of plain js.

My problem was solved by next-transpile-modules (^9.0.0). Specifically, assuming you:

  1. have next.config.js starting like this
/** @type {import('next').NextConfig} */

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

  1. have external TS library private-lib where import { ... } from '/path/to/private-lib' from a tsx file somewhere leads to the compile-time error.

FIX:

  1. yarn add next-transpile-modules
  2. yarn add file:/path/to/private-lib
  3. change the import statements in the ts/tsx files for private-lib
  4. update next.config.js to look something like this
/** @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: {
  },
})

YMMV, HTH, #FixMagicWithMoreMagic

1
On

This question is kind of old, so I thought I'd post an update to extend on directed-laugh's original answer for anyone who stumbles across this issue.

As mentioned, transpiling the modules via next.config.js seems to be the solution. Though with NextJS 13.1 there is no need to install the additional next-transpile-modules package as these features are available natively in NextJS 13.1.

In next.config.js, just add the transpilePackages option and include the name of the ts package.

module.exports = {
  ...
  transpilePackages: ['my-ts-package'],
}

See Module Transpilation