I want to have a monorepo using yarn workspaces in which I hold:
- a react 17 app
- a react 18 app
- a nestjs app
- a shared layer with common functions for all of them (e.g: date format func)
I cloned this project https://github.com/mightyhorst/medium-react-nestjs-monorepo and it manages to share types between them. I had to add typescript and react stuff to nohoist
so it doesn't hoist the wrong versions and it works fine - both react apps & nest can use the shared types. The problem comes when I add a function in the common layer.
workspaces/common/src/index.ts
WORKS
export interface User {
email: string
}
DOESN'T WORK
export interface User {
email: string
}
export function hello() { console.log('world') }
I get this error when running any react app (although there is nothing wrong with the type):
../common/src/model.ts 4:7
Module parse failed: Unexpected token (4:7)
File was processed with these loaders:
* ./node_modules/@pmmmwh/react-refresh-webpack-plugin/loader/index.js
You may need an additional loader to handle the result of these loaders.
| $RefreshSetup$(module.id);
|
> export interface User{
| email: string;
| firstName?: string;
I get this error when running nestjs:
export * from "./model";
^^^^^^
SyntaxError: Unexpected token 'export'
at wrapSafe (internal/modules/cjs/loader.js:984:16)
at Module._compile (internal/modules/cjs/loader.js:1032:27)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1097:10)
at Module.load (internal/modules/cjs/loader.js:933:32)
at Function.Module._load (internal/modules/cjs/loader.js:774:14)
at Module.require (internal/modules/cjs/loader.js:957:19)
at require (internal/modules/cjs/helpers.js:88:18)
at Object.<anonymous> (/home/elbit/Projects/medium-react-nestjs-monorepo/workspaces/nestjs/dist/src/main.js:5:18)
at Module._compile (internal/modules/cjs/loader.js:1068:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1097:10)
I feel like this is a common thing but I cannot find the solution.
CodePudding user response:
I got it working using:
yarn-workspaces
without lerna to handle all the packages- set
"workspaces": { "nohoist": ["**"] }
within each package (in package.json) craco
to handlecommon
package and aliases (viacraco-alias
)@ef-carbon/tspm
to resolvetsconfig.compilerOptions.paths
for any package that isn't React
My craco.config.js
const path = require("path");
const { getLoader, loaderByName } = require("@craco/craco");
const CracoAlias = require("craco-alias");
const packages = [];
packages.push(path.join(__dirname, "../common"));
module.exports = {
webpack: {
configure: (webpackConfig, arg) => {
const { isFound, match } = getLoader(
webpackConfig,
loaderByName("babel-loader")
);
if (isFound) {
const include = Array.isArray(match.loader.include)
? match.loader.include
: [match.loader.include];
match.loader.include = include.concat(packages);
}
return webpackConfig;
},
},
plugins: [
{
plugin: CracoAlias,
options: {
source: "tsconfig",
baseUrl: ".",
tsConfigPath: "./tsconfig.paths.json",
},
},
],
};
My tsconfig.json
of a non-react app
{
"compilerOptions": {
"allowJs": true,
"baseUrl": "./",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"isolatedModules": true,
"module": "commonjs",
"moduleResolution": "node",
"outDir": "build",
"paths": { "@ui/common/*": ["../common/src/*"] },
"resolveJsonModule": true,
"rootDirs": [".", "../common/build"],
"skipLibCheck": true,
"strict": true,
"target": "es5"
},
"include": ["src", "../common/src"]
}