How to configure jest with `ts-jest` to parse/transform projects in the `packages/` folder of a basic Turborepo project? - jestjs

Has anybody here used ts-jest in the context of Turborepo?
My understanding for a standard Turborepo setup is that in general, the configs and common packages live in /packages/* (e.g. /packages/jest-config, but most of your apps will live in /apps/. My issue is that jest is running tests in /packages/ui just fine, but can't seem to transform/parse tests in /apps/my-app properly. Here's what my jest config looks like so far:
module.exports = {
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
modulePathIgnorePatterns: [
'<rootDir>/test/__fixtures__',
'<rootDir>/node_modules',
'<rootDir>/dist',
],
projects: [{
displayName: 'ui',
preset: 'ts-jest',
testEnvironment: 'jest-environment-jsdom',
testMatch: ['<rootDir>/../ui/**/*.#(spec|test).ts?(x)'],
},
{
displayName: 'my-app',
preset: 'ts-jest',
testEnvironment: 'jest-environment-jsdom',
testMatch: ['<rootDir>/../../apps/my-app/**/*.#(spec|test).ts?(x)'],
}],
transform: {
'^.+\\.tsx?$': 'ts-jest',
},
};
Here's the folder structure to help clarify (and in case my testMatch settings are all wrong, and Turbo's cache is just letting me get away with it for the packages/ui/ stuff, I only started adding them when troubleshooting the apps/ folder):
monorepo-root
├─ packages
│ ├─ ui/
│ │ └─ MyButton.text.tsx # passes
│ └─ jest-config/
│ └─ jest-preset.js
└─ apps/
└─ my-app/
└─ MyButton.text.tsx # fails
Pertinent parts of error:
FAIL my-app src/components/MyButton.test.tsx
● Test suite failed to run
Jest encountered an unexpected token
Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.
...
Details:
/Users/me/repos/monorepo-root/apps/my-app/src/components/MyButton.test.tsx:14
(0, test_utils_1.render)(<MyButton_1.MyButton onClick={onClick}/>);
^
SyntaxError: Unexpected token '<'
at Runtime.createScriptFromCode (../../node_modules/jest-runtime/build/index.js:1605:14)
Any help getting this working would be really appreciated! To summarize: tests in /packages/ui are working, identical tests in /apps/my-app are not. I'm not sure if this is a ts-jest issue or a Turborepo issue, but I'm hoping someone here has some experience with both. Thanks!

Related

How can I set up Typescript to import types from another Prisma folder?

We're using Typescript, Prisma and TRPC in two NodeJS services that need to communicate with each other. Both services have their own database, so the generated Prisma client in node_modules is different between the folders. The folder structure is set up like so:
.
├── service_1/
│ ├── tsconfig.json
│ ├── package.json
│ └── ...rest of project
└── service_2/
├── tsconfig.json
├── package.json
└── ...rest of project
Because we're using TRPC, service_1 imports types directly from service_2 like the following example:
import type { AppRouter } from '../../../../service_2/src/routers/index'
This works fine in VSCode, however we want to put typechecking as an CI action on service_1, but running tsc -p ./tsconfig.json --noEmit in the root of service_1 shows a lot of errors like this:
../service_2/src/services/dog.ts:53:10 - error TS2339: Property 'dog' does not exist on type 'PrismaClient<PrismaClientOptions, never, RejectOnNotFound | RejectPerOperation | undefined>'.
53 prisma.dog.findMany({
We surmise that this is caused by Typescript using the generated #prisma/client package from the service_1 folder even when typechecking service_2, but we've tried changing a number of options in our tsconfig.json to no avail.
Our current tsconfig.json in service_1 looks like this:
{
"compilerOptions": {
"jsx": "react-jsx",
"strict": true,
"paths": {
"/*": ["./*"]
},
"baseUrl": "./",
"noEmit": true,
"esModuleInterop": true
},
"exclude": [
"**/node_modules/*",
"**/dist/*",
"**/.git/*",
],
}
Some of the options we've tried include:
Setting rootDir to ./
Setting rootDir to ../
Setting rootDirs to ["./", "../service_2"]
Adding #ts-ignore or #ts-nocheck above the type import
Adding service_2 to the exclude option
Is there a way to get typechecking across two projects like this with separate node_modules on one that imports from another?

ESLint Configuration File - indicated in cousin folder

I am trying to add an eslint configuration to my project. I do not want to add it in the root folder but in the .vscode one.
I have the following folder structure :
my-poney-project
├── .vscode
│ └── my-poney-project.code.workspace
│ └── .eslintrc.json
├── lib
│ └── source.js
└─┬ tests
└── test.js
and I want to lint file which are present in the lib and tests folder, with the eslint configuration in the .vscode folder.
Currently my my-poney-project.code.workspace file contains the following :
{
"folders": [{
"path": ".."
}],
"settings": {
"eslint.alwaysShowStatus": true,
"eslint.debug": true,
}
Do you know how could I indicate to eslint to use the .vscode\.eslintrc.json whereas it is not in a parent folder of the files I am trying to lint (lib and test)?
For example, is there a parameter to add in the my-poney-project.code.workspace ?
References which may be related to this question :
https://eslint.org/docs/user-guide/configuring/configuration-files#cascading-and-hierarchy
https://eslint.org/docs/user-guide/configuring/configuration-files#personal-configuration-files-deprecated
I would be grateful for any comments or responses,
Cheers !

Problem deploying Firebase Functions from AWS Code Build

I'm having a difficulty deploying Firebase functions from CI (namely AWS CodeBuild) due to unknown reasons.
The firebase deploy command is invoked with --token argument, so it doesn't seem like an authentication issue, in fact, hosting files are being deployed without any issues.
One suspicion I have is that when I run this locally, it works like a charm, and the obvious difference is the part that says package . (263 B) for uploading because when I run it locally, it has way more than 263-bytes (local says 69.23 MB). Also, because it runs locally without any issues, I don't think there is any issue with firebase.json is configured incorrectly.
Has anyone ran into a similar issue?
$ export DOTENV_RUNTIME=qa1 && cross-env NODE_ENV=production firebase deploy --only hosting,functions --token $FIREBASE_TOKEN
...
i deploying functions, hosting
i functions: ensuring required API cloudfunctions.googleapis.com is enabled...
i functions: ensuring required API cloudbuild.googleapis.com is enabled...
✔ functions: required API cloudbuild.googleapis.com is enabled
✔ functions: required API cloudfunctions.googleapis.com is enabled
i functions: preparing . directory for uploading...
i functions: packaged . (263 B) for uploading
✔ functions: . folder uploaded successfully
i hosting[project-xyz]: beginning deploy...
i hosting[project-xyz]: found 47 files in public
✔ hosting[project-xyz]: file upload complete
i functions: updating Node.js 12 function nextServer(us-central1)...
⚠ functions[nextServer(us-central1)]: Deployment error.
Build failed: function.js does not exist; Error ID: 7485c5b6
Functions deploy had errors with the following functions:
nextServer
To try redeploying those functions, run:
firebase deploy --only "functions:nextServer"
To continue deploying other features (such as database), run:
firebase deploy --except functions
Error: Functions did not deploy properly.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
Here are the contents of some of the relevant configuration files:
firebase.json
{
"hosting": {
"public": "public",
"rewrites": [
{
"source": "**",
"function": "nextServer"
}
]
},
"functions": {
"source": ".",
"ignore": [
".git/**",
".firebase/**",
".firebaserc",
"**/node_modules/**",
"**/public/**",
"**/src/**"
]
}
}
package.json
{
...
"main": "dist/server/index.js",
"engines": {
"node": "12"
},
...
}
Here's the root directory structure.
$ tree -v -L 1 -a
.
├── .firebase
├── .firebaserc
├── .git
├── .gitignore
├── README.md
├── dist
├── firebase.json
├── node_modules
├── package.json
├── public
├── src
└── yarn.lock
I went through the firebase-tools source code and found that when using AWS Code Build, the source is downloaded and built under /codebuild/output/src123456789/src/github.com/.... If you ignore **/src/**, no files would be targeted for deploy because the path name contains src. This also answers why the packaged size was so small.
Thanks to #nVitius for raising questions.

Serverless NodeJS File/Folder Structure

I'm setting up my first project using serverless and while I'm finding a lot of great "getting started" tutorials, I'm having a hard time finding anything about actual project structure.
My thoughts is to use the below structure for my functions, shared libs and core configuration/dependencies:
.
├── functions/
│   │
│ ├── users/
│ │ ├── handler.js
│ │ └── serverless.yml
│ │
│ └── roles/
│ ├── handler.js
│ └── serverless.yml
│
├── shared/
│ └── common.js
│
├── node_modules/
└── package.json
My main curiosity is around deployment and how that pertains to dependencies and shared files. Additionally, automating deploy of this structure seems strange as I'm gathering I would need to deploy each of the functions separately which I can script, but wondering if that's needed or advised.
I have dealt with this a bit and found it quite frustrating. If you deploy from your setup, what does your api look like? With individual serverless.yaml files you end up with independent api endpoints (assuming you are triggering with api calls and not something like s3).
I ended up with a structure like this:
|- serverless/
|--- serverlsss.yml
|--- web pack.config.js
|--- dist/
|--- node_modules() /* dev and common code */
|--- src/
|----- function1/
|-------- node_modules
|-------- package.json
|-------- index.js
|----- function2/
|-------- node_modules
|-------- package.json
|-------- index.js
I use the serverless webpack plugin to output the the individual functions into the dist/ directory. The serverless.yaml then points to these.
The webpack.config.js looks like this:
const nodeExternals = require('webpack-node-externals');
const path = require('path');
module.exports = {
entry: {
'function1': './src/function1/index.js',
'function2': './src/function2/index.js',
},
target: 'node',
output:{
libraryTarget: 'commonjs2',
path: path.join(__dirname, './dist'),
filename: '[name].js'
},
externals: [nodeExternals()],
module: {
loaders: [
/* Babel is nice, but it's adding a some bulk and I don't need it
{
test: /\.js$/,
loaders: ['babel'],
include: __dirname,
exclude: /node_modules/,
}, */
{
test: /\.json$/,
loaders: ['json']}
],
},
};
// externals: [nodeExternals()],
// nodeExternals seems to break aws-sdk when serving locally
// aws-sdk should be in dev-dependencies of root folder
// that way it's available in dev but doesn't get packaged.
// It's available to the lambdas when deployed.
After that just make sure you set the individual flag in serverless.yml
package:
individually: true
The webpack plugin is quite nice and does most of the heavy lifting. With this I can do a single deploy and all the functions end up as individual lambda functions all under one api endpoint. You also get the Webpack dev server so you can run serverless webpack serve to test your functions.
It was a bit of a pain to setup, but it's been working pretty well.

How can I use jasmine with a server-side typescript project?

I have a project that contains modules for both the server and client of my application, which are each built using webpack. I'm using Karma with Jasmine to test my client (which uses Angular) and I would like to use Jasmine to test the server, which is written in typescript, too.
Unfortunately, the only guides that I could find online used jasmine-node (which to be untouched for the past few years) instead of jasmine-npm. Can anyone suggest a way that I can use Jasmine, or an alternative, for testing within my project?
I've tried writing a jasmine.json file, or editing the one generated by jasmine with the init cli command, however this doesn't seem to work with typescript files.
At the moment, my project's structure is like so:
├── client
│ ├── karma.conf.js
│ ├── protractor.conf.js
│ ├── src
│ ├── tsconfig.json
│ └── webpack.config.js
├── server
│ ├── src
│ ├── tsconfig.json
│ └── webpack.config.js
└── node_modules
Its definately possible to use jasmine for your server side tests. Follow these steps and you'll be fine:
1) In your package.json add the following dev dependencies:
"jasmine": "latest",
"jasmine-core": "latest",
2) Setup your jasmine.json so that it will include all files you want to run tests on, etc.
{
"spec_dir": "dist/dev/server/spec",
"spec_files": [
"unit/server/**/*[sS]pec.js"
],
"helpers": []
}
3) Add unit.ts that will bootstrap your testing process:
const Jasmine = require("jasmine");
let j = new Jasmine();
j.loadConfigFile("./jasmine.json");
j.configureDefaultReporter({
showColors: true
});
j.execute();
Now all you have to do is compile and run your resulting unit.js in nodejs.

Resources