Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reference Typescript project outside of the source folder

I have 2 CRA projects in a mono-repo - P1 and P2.

root/
  projects/
    p1/
      package.json
      tsconfig.json
      src/
        shared/
          **/*.ts
    p2/
      package.json
      tsconfig.json
      src/
        **/*.ts

P1 contains some shared infrastructure source files, which I want to reuse in P2.

Note: I know about the disadvantages and negative sides of this approach, but...

What I tried:

  1. Include P1 from P2 and import:

    • P1 tsconfig.json modified with

      "include": [..., "root/projects/p1/src/shared/**/*.ts]

    • P2 source file imports .ts files by relative path

    Result:

    You attempted to import <path> which falls outside of the project src/ directory. Relative imports outside of src/ are not supported.
    You can either move it inside src/, or add a symlink to it from project's node_modules/
    
  2. Use yarn workspaces

    This one is easy. Yarn does not allow to have workspaces outside of the project root

    You cannot and must not reference a workspace that is located outside of this filesystem hierarchy.

  3. Typescript 3.0+ projects references:

    • Update p1 tsconfig.json with

    "compilerOptions": { "composite": true }

    • Add reference to P1 tsconfig.json

    references: [ { "path": "{...}/p1/" ]

    • Build P1 with tsc -b to produce declaration files

    • now I need to import it somehow.

      • create tsconfig.paths.json to configure paths section

      • add rootDir tp P1 tsconfig.json to point to root/ folder

      • add paths "@lib/*": ["<relative-path-to-p1>/p1/src/shared/*"]

    Result:

    Cannot find module: '@lib/....'. Make sure this package is installed

    Also I see that VSCode recognizes my configuration properly and import intellisense works properly

  4. Use react-app-rewired

    in my config-overrides.js I added something like

    module.exports = function override(config, env) {
      config.resolve.alias = {
        "@lib": path.resolve(__dirname, '...p1/src/shared/')
      }
    }
    

    This works for all aliases inside the project. But in my case it fails with

    You attempted to import <root>/p1/src/shared... which falls outside of the project src/ directory. Relative imports outside of src/ are not supported.
    You can either move it inside src/, or add a symlink to it from project's node_modules/
    
like image 760
deeptowncitizen Avatar asked Nov 06 '22 10:11

deeptowncitizen


1 Answers

  1. Add customize-cra and react-app-rewired packages

  2. Add to referenced tsconfig.json:

{
  "compilerOptions": {
    ...
    "composite": true,
    "declaration": true,
    "declarationMap": true
}
  1. Create tsconfig.paths.json in the base project
{
  "compilerOptions": {
    "baseUrl": "src",
    "paths": {
      "@alias/*": ["..relative/to/base/url/path/*"]
    }
  }
}
  1. In tsconfig.json add such lines:
{
  "extends": "./tsconfig.paths.json",
  "compilerOptions": {
    "baseUrl": "<the same value as in paths file>"
  },
  "references": [
    { "path": "../relative/path/to/referenced/project/tsconfig.json/file" }
  ]
  1. Create config-override.js file in the project root
const { override, removeModuleScopePlugin, getBabelLoader, addWebpackAlias } = require("customize-cra");
const path = require("path");
const fs = require('fs');

const updateAliases = (config) => {
  const aliases = {
    "@alias": ["absolute/path/to/base/url"]
  };

  return addWebpackAlias(aliases)(config);
};

const updateIncludes = (config) => {
  const loader = getBabelLoader(config, false);
  const commonPath = path.normalize(path.join(process.cwd(), "../relative/path/to/referenced/project/tsconfig.json/file")).replace(/\\/g, "\\");
  loader.include = [loader.include, commonPath];
  return config;
};

module.exports = override(
  updateAliases,
  updateIncludes,
  removeModuleScopePlugin()
);

  1. Use react-app-rewired instead of react-scripts in package.json

Note: This is the modified code, so some minor changes may be required.

like image 174
deeptowncitizen Avatar answered Nov 15 '22 06:11

deeptowncitizen