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 likeimport 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.