Skip to content

Next.js webpack throws loader error when importing external packages #31348

@floroz

Description

@floroz

What version of Next.js are you using?

12.0.3

What version of Node.js are you using?

16.13.0

What browser are you using?

Chrome, Safari

What operating system are you using?

macOS

How are you deploying your application?

Vercel

DISCLAIMER: Thank you for all the amazing work you do for the open-source community, providing us with great tools such as Next.js!

The issue

We are migrating our React application to Next.js within our monorepo project, but we have encountered a number of issues when trying to import UI components and styles from outside the Next.js root directory.

Observations on the issue

  • consuming packages outside the root directory of a Next.js application, under a workspace managed repository, seems to only be possible by using the experimental.externalDir flag.
  • There isn't a clear way to allow the use of external CSS modules or stylesheets without modifying the Next.js webpack's configuration.

Relates to:

Expected Behavior

We want separate Next.js applications to consume and share the same UI components from outside their root directories.

In our example, we want admin and shop to consume and share the same components from libs/ui.

To Reproduce

The setup

For the purpose of illustration, I've setup an example repository that uses npm workspaces for managing the symlinks between the dependencies.

The project structure of this demo closely resembles (in principles) what we currently have in our repository.

├── apps
│   ├── admin
│   │   ├── node_modules
│   │   ├── pages
│   │   └── public
│   └── shop
│       ├── node_modules
│       ├── pages
│       └── public
├── libs
│   ├── shared
│   │   └── src
│   └── ui
│       └── src
├── package-lock.json
└── package.json

Scenario

  1. In apps/shop/pages/index.tsx (a Next.js application) we try to import and consume a button coming from the shared UI layer.
import { Button } from "@tundra/ui";

export default function Home() {
  return (
    <div>
      <h1>Hello World</h1>
      <Button />
    </div>
  );
}
  1. Once we try to start the application, we see this error:
../../libs/ui/src/button.tsx
Module parse failed: Unexpected token (7:9)
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

Screenshot 2021-11-12 at 15 02 57

  1. At which point, I enable the experimental.externalDir flag in the next.config.js and restart the application

  2. The error we now see is:

error - ../../libs/ui/src/button.module.css
CSS Modules cannot be imported from within node_modules.
Read more: https://nextjs.org/docs/messages/css-modules-npm
Location: ../../libs/ui/src/button.tsx

Screenshot 2021-11-12 at 15 04 37

  1. If we now go into the libs/ui/src/button.tsx and comment out the CSS Modules import, and reload the application
import React from "react";
import { randomString } from "@tundra/shared";
// import styles from "./button.module.css";
const styles = { button: "button" };

export const Button = () => {
  return <div className={styles.button}>{randomString()}</div>;
};
  1. it now renders the button correctly (without the styles being applied).

Screenshot 2021-11-12 at 15 14 20

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugIssue was opened via the bug report template.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions