Skip to content

Project Structure

Eric Redekopp edited this page Dec 18, 2022 · 3 revisions
  • Modelcollab is stored as a monorepo. The structure is based on a typical Java application structure.
  • Each module is stored as its own typescript project in its own directory under the top modelcollab directory, with its own package.json if necessary.
  • Compiled files are placed in the module/build/ directory under each project
  • Main source files are in module/src/main
  • Test files are in module/src/ts

tsconfig

Typescript requires some figuring to work in a monorepo configuration. This is all already done in the existing tsconfig files. There is one in the top-level directory that describes the common TS options for all modules. Each module must also create its own tsconfig.json for project-specific settings.

The tsconfig files were based on the ones found in this project: https://github.com/rhyek/typescript-monorepo-example

Adding a new module

  1. Create a new directory for the module under the top-level modelcollab directory.
  2. Create directories src/main/ts and src/test/ts for main and test source code.
  3. Create a tsconfig file as described in the "template" section of this document.
  4. Add any modules from which you will be importing code to the "modules" and "paths" fields.
  5. Install those modules as local dependencies with npm, e.g. npm install ../database.
  6. See the "note on imports" to decide how other modules will be imported.

Template

{ 
    "extends": "../tsconfig.json",        
    "compilerOptions": {
        "baseUrl": "./src",
        "outDir": "./build",
        "paths": {
            "src": ["./src/main"],
            "test": ["./src/test"]
        }
//      Add any extra compiler options on here
    },
    "include": [
        "src"        
    ],
    "exclude": [
        "node_modules",
        "build"
    ],
    "references": [
        {
//          For example, or replace with any modules that you use.
            "path": "../database"
        }
    ] 
}

Note on imports

Typescript project references are not properly supported by create-react-app, which was used to create the webui of this project. It is noted in this issue on the CRA Github repo. At the time of this writing, it remains open and incomplete. The options to solve this are to eject from CRA and manage the React project manually - which we would prefer not to do - or to use a band-aid solution until CRA is able to solve this properly. We have opted for the latter option.

Modules without project reference support

In modules which do not support TS project references (i.e., the webui), the temporary solution is to import from build files instead of src files. This means that such modules need to build their dependencies manually before building the main project or even using a text editor that supports eslint.

For example, the webui must first go to database/ and call npm run build before it will build properly, and this needs to be repeated with every change to the database module. To import a database file in the webui, we must import the built version such as import MyClass from "database/build/...";. If we try to import one from src, it causes the error You may need an additional loader to handle the result of these loaders. due to CRA not transpiling any .ts files found outside of its base directory. An additional consequence of this is that intellisense will not update itself properly until the dependency is rebuilt again.

This is fairly annoying but has thus far not proven to be horrifically frustrating. Hopefully CRA adds support soon but if it takes too long we may decide to eject from CRA and fix this manually.

Modules with project reference support

In modules which support TS project references, we can avoid the manual build process mentioned above and simply add the --build flag to tsc which will rebuild any changed files in depended local projects. This also allows us to import directly from the .ts files in the src directory which means that intellisense will update immediately rather than having to build the project again to see those changes.

Clone this wiki locally