Hans Tausend
Hans Tausend

Reputation: 93

Import local typescript react package as a dependency with hot reloading

I currently have the following problem, I want to use a local react package (my-react-package) as a dependency in another react app (my-react-app), both are written in typescript.

├── my-react-app
│   └── package.json
│   └── src
└── my-react-package
    └── package.json
    └── src

I am importing my-react-package via "my-react-package": "file:../my-react-package", in my-react-app/package.json .

When using the dist build output of my-react-package it works fine, but each time I make a change in I need to build it again, which is very time-consuming for development.

That is why I have tried to use the react code in my-react-package/src directly. But when changing my-react-package/package.json from "main": "dist/index.js", to "main": "src/index.ts", importing it leads to the following error in my-react-app:

./node_modules/my-react-package/src/hooks/state/session.ts 34:31
Module parse failed: Unexpected token (34:31)
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
| import { useState, Dispatch, SetStateAction } from 'react'
| 
> export function useSessionState<_, S>(key: string, initialState: S): [S, Dispatch<SetStateAction<S>>] {
|   try {
|     const storedState = sessionStorage.getItem(key)

I assume this error is related to how webpack handles typescript dependencies. As I am using create-react-app, so I want to avoid messing with the webpack.config.js file.

I also want to avoid having my-react-package as a folder in my-react-app/src as I am planning to import my-react-package from multiple other react apps in the future.

Is there a way, my-react-package can remain as its own package while I get hot-reloading to work when importing it locally?

Upvotes: 6

Views: 3796

Answers (2)

J&#225;n Jakub Naništa
J&#225;n Jakub Naništa

Reputation: 1926

The problem is that TypeScript will not try to parse or compile anything in your node_modules, it will assume all those dependencies are ready to be consumed. In order to be able to consume a TypeScript module you need to explicitly tell TypeScript to compile it. This though will require you to change your webpack.config.js. The steps to achieve this are outlined here.

I would discourage you from taking this road though - I would rather suggest looking into a monorepo setup (using yarn or lerna). In such setup you no longer need to set the dependency as file:..., which in turn allows you to:

  1. Open a terminal and start a build/watch task in your my-react-package
  2. Open another terminal and start a build/watch task in your my-react-app

Now The changes that you make to your my-react-package will be picked up by the watch task in your my-react-app

Upvotes: 0

Splox
Splox

Reputation: 761

If you really don't want to rebuild every time, you can directly access the files like so:

import { thing } from "../my-react-package/src/thing"

However, what you probably want is to automatically recompile every time you make a change.

Your question didn't specify whether my-react-package uses webpack, so if it doesn't, you can watch the files being saved and automatically recompile via:

tsc -w

If you are using just raw webpack for your my-react-package, you can edit your webpack.config.js like so:

module.exports = {
  //...
  watch: true
};

This will tell webpack to automatically rebuild.

Alternatively, if you used create-react-app for my-react-package, you can install npm-watch:

npm i npm-watch

And then edit your package.json:

{
  // ...
  "devDependencies": {
    "npm-watch": "^0.1.8",
    "react-scripts": "0.9.5",
  },
  "dependencies": {
    "react": "^15.4.2",
    "react-dom": "^15.4.2"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject",
    "watch": "npm-watch"
  },
  "watch": {
    "build": "src/"
  }
}

Hope this helps.

Upvotes: 3

Related Questions