I'm having trouble getting my head around how to configure this monorepo so it bundles, builds, and executes without problems.
It's a fullstack serverless (AWS) monorepo using npm workspaces, built entirely in TS.
It's It's structured like so:
my-monorepo/
├── node_modules
├── packages/
│ ├── lib/
│ │ ├── index.ts
│ │ ├── random.ts
│ │ ├── package.json
│ │ └── tsconfig.json
│ ├── lambda/
│ │ ├── test.ts
│ │ ├── package.json
│ │ └── tsconfig.json
│ └── web/
│ └── react-vite/
│ ├── App.tsx
│ ├── package.json
│ └── tsconfig.json
├── package.json
├── tsconfig.base.json
└── tsconfig.json
I'm simply trying to make it so all external and internal npm package references work, so I can share code between all projects out of the /lib
folder.
Here's lambda/test.ts
:
import { ulid } from "ulid";
import { random } from "@my-monorepo/lib";
export async function routesHandler(event: any) {
try {
return {
statusCode: 200,
// body: JSON.stringify(`${random.randomPhrase()} Lambda!`)
body: JSON.stringify(`Hello Lambda! How about a ULID? -> ${ulid()}`)
};
} catch (e) {
console.log("It's dead:", e);
}
}
This executes just fine, and prints:
Compiling with Typescript...
Using local tsconfig.json - ./packages/lambda/tsconfig.json
Typescript compiled.
{
"statusCode": 200,
"body": "\"Hello Lambda! How about a ULID? -> 01HE33FGF9DE4Q6H8K1KP42KEA\""
}
When I try to call from the random
module by swapping the body lines in the lambda above, like this:
return {
statusCode: 200,
body: JSON.stringify(`${random.randomPhrase()} Lambda!`)
//body: JSON.stringify(`Hello Lambda! How about a ULID? -> ${ulid()}`)
};
I get this:
import * as random from "./random"; ^^^^^^
SyntaxError: Cannot use import statement outside a module
/lib/index.ts:
import * as random from "./random";
import * as model from "./model/model";
export {
random,
model
};
/lib/random.ts:
const randomPhrase = (): string => {
const phrases = [
"Gadzooks!",
"Eureka!",
"D'oh!",
"Egads!",
"Bazinga!"
];
return phrases[Math.round(Math.random() * phrases.length)];
};
export {
randomPhrase
};
It has to be a combination of tsconfig
props that I'm getting wrong, because I can execute code from the /lib
within App.tsx
in the web/react-vite
project, it renders and works as expected. Here's that snippet:
import { random } from "@my-monorepo/lib";
function App() {
return (
<div>Welcome to React...{random.randomPhrase()}</div>
)
}
export default App
I see what I should:
Here's the root config stuff:
./package.json
{
"name": "my-monorepo",
"type": "module",
"private": true,
"workspaces": [
"packages/lambda",
"packages/web/react-vite",
"packages/lib"
],
"devDependencies": {
...
},
"dependencies": {
...
}
}
./tsconfig.base.json
{
"compilerOptions": {
"target": "ES2022",
"module": "CommonJS",
"declaration": true,
"sourceMap": true,
"strict": true,
"moduleResolution": "node",
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"composite": true
},
"exclude": ["node_modules"],
"include": [
"packages/lib/*",
"packages/lib/**/*"
]
}
./tsconfig.json
{
"references": [
{
"path": "packages/lambda"
},
{
"path": "packages/lib"
}
]
}
/lib config files:
lib/package.json:
{
"name": "@my-monorepo/lib",
"version": "1.0.0",
"main": "index.ts",
"type": "module"
}
lib/tsconfig.json:
{
"extends": "../../tsconfig.base.json"
}
/lambda config files:
lambda/package.json
{
"name": "@my-monorepo/lambda",
"version": "1.0.0",
"main": "test.ts",
"type": "module",
"dependencies": {
"@my-monorepo/lib": "^1.0.0",
"ulid": "^2.3.0"
}
}
lambda/tsconfig.json
{
"extends": "../../tsconfig.base.json"
}
UPDATE 1:
I was able to manually compile the /lib
project and change the main reference in package.json
to "main": "build/index.js"
, and get it working locally. However...was hoping to avoid that manual build step, if possible.
It also didn't help me at all once the Lambda was deployed to AWS. I still get this error on execution:
{
"errorType": "Runtime.ImportModuleError",
"errorMessage": "Error: Cannot find module '@my-monorepo/lib'\nRequire stack:\n- /var/task/index.js\n- /var/runtime/index.mjs",
"trace": [
"Runtime.ImportModuleError: Error: Cannot find module '@my-monorepo/lib'",
"Require stack:",
"- /var/task/index.js",
"- /var/runtime/index.mjs",
" at _loadUserApp (file:///var/runtime/index.mjs:1087:17)",
" at async UserFunction.js.module.exports.load (file:///var/runtime/index.mjs:1119:21)",
" at async start (file:///var/runtime/index.mjs:1282:23)",
" at async file:///var/runtime/index.mjs:1288:1"
]
}
It ALSO breaks the reference in the React app - so I suppose it's a matter of figuring out how to get the Lambda to bundle/build with the source TS files like the Vite build does.
from How do I properly structure, configure, and bundle npm references in a Typescript monorepo using npm workspaces?
No comments:
Post a Comment