Streamlining Your Next.js Builds with a Separate TypeScript Configuration

When working on a complex project with both Storybook and Next.js, you might run into issues during the build process. I recently hit a frustrating roadblock when my Next.js build started compiling Storybook files. It turned out that the build was trying to process *.stories.* files, which shouldn’t have been included. To avoid such conflicts, I found a way to use a separate TypeScript configuration for builds, and this guide will walk you through how I did it.

Thank me by sharing on Twitter 🙏

Here’s how you can streamline your Next.js build process by configuring it to use a dedicated tsconfig.build.json while keeping your default tsconfig.json intact for development and linting in VSCode.

Why Use a Separate TypeScript Config for Builds?

In any real-world project, you often end up with configurations or files that you only need during development but not during production. Storybook, for example, is invaluable for building and testing components, but its files don’t belong in the production build. Using a separate tsconfig.build.json allows you to:

1. Exclude non-essential files (like Storybook stories) from production builds.

2. Keep development tools running smoothly—VSCode will still use tsconfig.json to lint everything, including the excluded files.

3. Avoid build errors caused by Storybook dependencies being processed by Next.js.

This configuration saves you time and ensures your build stays clean and efficient.

Setting up the Project Structure

Before making any changes, here’s what the project structure looks like:

/my-app
├── .storybook/
├── components/
│   └── Button.tsx
│   └── Button.stories.tsx
├── pages/
├── tsconfig.json
├── tsconfig.build.json
├── next.config.js

• The tsconfig.json file is used for development (including VSCode).

• tsconfig.build.json will be the version Next.js refers to when building the app.

• The .stories.tsx files should only affect Storybook and not production.

Step 1: Create a tsconfig.build.json

First, create a tsconfig.build.json file in the root of your project. This file will extend the settings from tsconfig.json but exclude files that don’t belong in the production build.

JSON
{
  "extends": "./tsconfig.json",
  "exclude": [
    "**/*.stories.tsx",
    "**/*.stories.jsx",
    "**/*.stories.mdx",
    "**/*.test.tsx",
    "**/*.test.ts"
  ]
}

This configuration tells TypeScript to inherit all settings from your main tsconfig.json but skip any stories and test files during the build. These files are not necessary for production and might introduce unwanted dependencies or errors.

Step 2: Modify the next.config.js File

The next step is to make Next.js use the new tsconfig.build.json during the build process. This is as simple as adding a configuration option in the next.config.js file.

Here’s what the next.config.js file looks like after the change:

JSON
module.exports = {
  ...
  typescript: {
    tsconfigPath: "./tsconfig.build.json",
  },
};

This tells Next.js to use tsconfig.build.json instead of the default tsconfig.json when it builds the app. With this setup, your development environment remains unaffected, and the build process runs more efficiently.

Step 3: Confirm VSCode Still Works with tsconfig.json

Since tsconfig.json remains the primary configuration file for development, VSCode will continue to lint all your files, including Storybook stories and tests. No further configuration is required for this step. You can verify that VSCode is working correctly by opening a .stories.tsx file and checking for any linting feedback.

If you run into issues, try restarting the TypeScript server in VSCode. You can do this by opening the command palette (Ctrl+Shift+P or Cmd+Shift+P on Mac) and selecting “TypeScript: Restart TS Server.”

Step 4: Run the Build to Verify

Now, it’s time to make sure everything is working as expected. Run the following command to build your project:

ShellScript
npm run build

If you are using Yarn, the command will be:

ShellScript
yarn build

During the build, Next.js will use the tsconfig.build.json configuration. You should no longer see any errors related to .stories files or other development-only dependencies.

If the build completes without issues, congratulations! You’ve successfully excluded unnecessary files from the build while keeping your development environment intact.

Troubleshooting Tips

If something isn’t working quite right, here are a few things to check:

1. Clear the .next directory:

Sometimes, Next.js caches old build artifacts. Try deleting the .next directory and rebuilding:

rm -rf .next
npm run build

2. Check your imports:

Make sure none of your production components accidentally import Storybook files. For example, ensure Button.tsx isn’t importing anything from Button.stories.tsx.

3. Restart VSCode if needed:

If you notice any issues with TypeScript linting in VSCode, try restarting the editor or the TypeScript server.

Conclusion

Splitting your TypeScript configuration into tsconfig.json for development and tsconfig.build.json for production is a simple yet powerful way to streamline your Next.js builds. It ensures that files meant only for development, like Storybook stories and tests, don’t interfere with the production build while keeping your development environment fully functional.

By making this small adjustment, I was able to resolve my build issues and avoid future headaches. Now my builds are faster, cleaner, and free from unnecessary clutter. This approach is easy to set up and can save you time and trouble, especially as your project grows in complexity.

Share this:

Leave a Reply