2

Summary

I have a closed source Next.js site with Typescript. I'm trying to import a few React components from an external open source Next.js project (that I also own). I'm trying to do this in a way where node_modules are shared, or entirely from the closed source project, and also so that I get hot reloading in Next.js when I modify files in the external project.

I'm struggling to find a combination of tsconfig.json and next.config.js / webpack.config that achieves what I want.

Problem Detail

I have two Next.js projects with Typescript:

  • "A" which is closed source. This is a Next.js site with Typescript. It's closed source because this site has authentication, security etc in it. This project imports from project B.
  • "B" which is open source. This project mainly contains a large Editor component (think a code editor). I want this project to be open source because I want the Editor to be open source. For convenience, this project also is a Next.js app, so that you can run a server with hot reloading on it locally to develop on the editor without requiring access to the closed source project.

The folder structure is something like

A/ (closed source)
  node_modules/
  tsconfig.json
  next.config.jstsx
  pages/
    index.tsx
B/ (open source)
  node_modules/
  tsconfig.json
  next.config.js
  components/
    Editor.tsx
  pages/
    index.tsx

And ultimately, what I'd like to do, is that in project A be able to import files from project B, as if they were local to project A:

import Editor from '../../B/components/Editor.tsx`

Such that:

  • When I run the Next.js app in project A, and I modify the Editor component in project B, the Next.js site hot reloads the changes
  • When Editor.tsx does something like import React from 'react';, it uses the dependencies from project A, to avoid bundling two versions of React into the local site.

Editor.tsx in project B also imports some Node modules that aren't currently in project A, like some third party React libraries. Ideally I would like the Next.js site running in A to figure out that those dependencies need to come from B/node_modules, while common libraries like React come from A/node_modules, but I'm also fine forcing A to have to install those same dependencies.

Where I'm having trouble with this is finding the right combination of next.config.js and tsconfig.json to make this work, and it's not clear to me how Next.js's hot reloading and loading interplay with Typescript's external dependencies.

What I've tried most recently is putting this in my next.config.js:

  transpilePackages: [
    path.resolve(__dirname, '../B'),
  ],

And this in my tsconfig.json:

  "references": [
    { "path": "../B" }
  ],

To test this is doing what I want, I rm -rf node_modules in project B, to make sure those node_modules aren't being used.

But in my A site, when I import ../B/components/Editor.tsx, I get:

- error ../B/src/plugins/Editor.tsx
Module not found: Can't resolve 'react/jsx-dev-runtime'

This tells me that Next.js is trying to use React from B/node_modules, even though React is installed in A/

I have tried a few configurations of tsconfig's rootDirs and paths, as well as next.config.js's transpileModules', as well as trying to modify the webpack.config.rules and webpack.config.snapshot.managedPaths and webpack.config.watchOptions. But it's not clear to me how all of these play together (or don't), especially given the interplay of Typescript and Webpack.

Sorry for the long question, I'm trying to lay out my assumptions in case I have something wrong, or you see a creative solution to my needs.

Andy Ray
  • 30,372
  • 14
  • 101
  • 138

0 Answers0