Development of a custom module with TS in React App

Viewed 32

I have 2 projects with common functionality.

I need to develop my own npm module that will use common code snippets for this.

I made a separate project that will contain this shared code (eg util).

At the moment I have done the following: we have 3 projects: project-a, project-b, front-components

I'm posting a "front-components" project in our company's npm. Then I just include it in the rest of the projects as dependencies in the package.json

To develop this module locally, I do the following:

  1. I copy the node_modules folder from the desired project to "front-components"

    ln -s ../project-a/node_modules ./node_modules

  2. Making an npm link from project-a

    npm link ../front-components

  3. Developing

But now I am facing difficulty in configuring tsconfig.json

For example, in "front-components" there is such code:

import { DATE_FORMAT } from 'constants/date';

And I get an error:

Module not found: Can't resolve 'constants/date' in '..../front-components/src/hooks'

I think that the problem is in tsconfig.json, but I can't figure out why it occurs.

Question 1: Can I use some other approach to avoid copying node_modules into "front-components"? (I need the files to be in .ts and .tsx format, not d.ts)

Question 2: How can I solve the problem with imports?

P.S.: Maybe you have some advice on how to develop this kind of bundles, I will be grateful

tsconfig.json

{
  "compilerOptions": {
    /* Basic Options */
    "target": "es6", // Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'.
    "module": "esnext", // Specify library files to be included in the compilation.
    "lib": [
      // Specify library files to be included in the compilation.
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true, // Allow javascript files to be compiled
    "jsx": "react-jsx", // Generates corresponding '.d.ts' file.
    "noEmit": true, // Do not emit outputs.
    "isolatedModules": true, // Transpile each file as a separate module (similar to 'ts.transpileModule').

    /* Strict Type-Checking Options */
    "strict": true, // Enable all strict type-checking options.

    /* Additional Checks */
    "noFallthroughCasesInSwitch": true, // Report errors for fallthrough cases in switch statement.
    "noUncheckedIndexedAccess": true, // Include 'undefined' in index signature results.

    /* Module Resolution Options */
    "moduleResolution": "node", // Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6).
    "baseUrl": "src", // Base directory to resolve non-absolute module names.
    "allowSyntheticDefaultImports": true, // Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'.
    "esModuleInterop": true, // Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'.

    /* Advanced Options */
    "skipLibCheck": true, // Skip type checking of declaration files.
    "forceConsistentCasingInFileNames": true, // Disallow inconsistently-cased references to the same file.

    "resolveJsonModule": true
  },
  "include": ["src", "./global.d.ts"],
  "files": ["node_modules/front-components/src/index.ts"],
  "exclude": ["node_modules"]
}
1 Answers

As both your projects depends on same UI components it sounds like what you need is monorepo. It gives you a flexibility in dependency management in a way you need (current approach seems to be overcomplicated and not so efficient). Depending on package manager you use you can choose the approach for it. Here's a yarn workspaces based example. I do not mean you have to switch to yarn berry, it's just one very minimalistic example that gives you a breath idea of monorepo. My personal preference is Nx, so google for more info and good luck, enjoy coding!

Related