Skip to content

Latest commit

 

History

History
199 lines (141 loc) · 6.05 KB

README.md

File metadata and controls

199 lines (141 loc) · 6.05 KB

Build Status

Template project for setting up a TypeScript monorepo

Table of content

Packages

@cassler/cra-babel-example   v1.0.0 examples/cra-ejected-babel (PRIVATE)
@cassler/cra                 v1.0.0 examples/cra               (PRIVATE)
@cassler/jest-babel-example  v1.0.0 examples/jest-babel        (PRIVATE)
@cassler/jest-example        v1.0.0 examples/jest-tsjest       (PRIVATE)
@cassler/nextjs              v1.0.0 examples/nextjs            (PRIVATE)
@cassler/ts-node             v1.0.0 examples/ts-node           (PRIVATE)
@cassler/webpack-example     v1.0.0 examples/webpack           (PRIVATE)
@cassler/bar                 v1.0.0 packages/bar
@cassler/color               v1.0.0 packages/colors
@cassler/components          v1.0.0 packages/components
@cassler/eslint-config      MISSING packages/eslint-config     (PRIVATE)
@cassler/fonts               v1.0.0 packages/fonts
@cassler/foo                 v1.0.0 packages/foo
@cassler/hooks               v1.0.0 packages/hooks
@cassler/snippets            v1.0.0 packages/snippets

Features

The main focus of this repo is making the Go to definition feature in IDEs work without any surprises, meaning it will work after a fresh clone without needing to build the project.

find-usage

The secondary focus is to remove surprises when publishing packages. The repo is set up so that each package gets a clean build output without any artifacts from other packages.

build-output

Setup

This repo uses yarn workspaces and Lerna. I recommend yarn for monorepos due to its easier setup, but everything here works with npm and lerna bootstrap as well and you can check that out in the npm branch.

yarn install

Docs

See the following blog posts:

If you're looking for the project references solution checkout the project-references branch.

Examples

This repo contains full examples of integrating with other tools and frameworks that need to be made aware that they're working with a monorepo. You can find each example in the examples/ folder.

ts-node

Use tsconfig-paths to resolve the path aliases at runtime:

{
  "scripts": {
    "start": "ts-node -r tsconfig-paths/register src/index.ts"
  }
}

See the full example here.

Babel

Use babel-plugin-module-resolver to resolve the path aliases:

module.exports = {
  presets: [
    ["@babel/preset-env", { targets: { node: "current" } }],
    "@babel/preset-typescript",
  ],

  plugins: [
    [
      "module-resolver",
      {
        alias: {
          "^@cassler/(.+)": "../\\1/src",
        },
      },
    ],
  ],
};

See the full example here.

webpack

Use tsconfig-paths-webpack-plugin to resolve the path aliases:

const TsconfigPathsPlugin = require("tsconfig-paths-webpack-plugin");

module.exports = {
  resolve: {
    plugins: [new TsconfigPathsPlugin()],
  },
};

See the full example here.

jest

If you use Babel then see this example from the Babel section above.

If you use ts-jest then you can use its pathsToModuleNameMapper helper:

const { pathsToModuleNameMapper } = require("ts-jest/utils");
const { compilerOptions } = require("../../tsconfig.json");

module.exports = {
  preset: "ts-jest",

  moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, {
    // This has to match the baseUrl defined in tsconfig.json.
    prefix: "<rootDir>/../../",
  }),
};

See the full example here.

create-react-app

Use react-app-rewired to extend CRA's webpack config and apply the tsconfig-paths-webpack-plugin:

const TsconfigPathsPlugin = require("tsconfig-paths-webpack-plugin");

module.exports = (config) => {
  // Remove the ModuleScopePlugin which throws when we
  // try to import something outside of src/.
  config.resolve.plugins.pop();

  // Resolve the path aliases.
  config.resolve.plugins.push(new TsconfigPathsPlugin());

  // Let Babel compile outside of src/.
  const tsRule = config.module.rules[2].oneOf[1];
  tsRule.include = undefined;
  tsRule.exclude = /node_modules/;

  return config;
};

See the full example here.

NextJS

Use next-transpile-modules to tell NextJS to compile your dependencies:

const path = require("path");

const withTM = require("next-transpile-modules")(
  // All of the packages will resolve to our monorepo so we can match that path.
  [path.resolve(__dirname, "..")]
);

module.exports = withTM();

See the full example here.