Reduce Loopback4 build times in development (build + restart dev server) - node.js

I am using Loopback4 to develop api in Node.
I was using the instruction given to build and watch with nodemon
It worked, but it was getting slow, like about 15 seconds in my case.
I search for other other solution and came up with idea of using Turborepo and the nodemon solution.
I wanted to know if there are better solutions or any issues with it
Gist of the solution
run build in watch mode and restart the dev server if js files in dist folder change
use Turbo repo to run these build and restart server tasks
Steps
Setup build and watch with nodemon as described in the thread
you should have something like this in the script
"scripts": {
"dev:server:watch": "nodemon server.js"
}
// watch src folder
// ignore dist
// ext only ts files
// npm start to start the dev server on any changes to the files
"nodemonConfig": {
"verbose": true,
"watch": [
"src/"
],
"ignore": [
"dist/*"
],
"ext": "ts",
"exec": "npm start"
}
Install turbo build system
yarn add turbo --dev
Update nodemon config to restart server on changes in js files in dist folder after build step
"nodemonConfig": {
"verbose": true,
"watch": [
"./dist/"
],
"ext": "js",
"exec": "yarn run start"
},
Add turbo.json
{
"pipeline": {
"dev": {
"dependsOn": ["build:watch", "dev:server:watch"]
},
"build:watch": {
"outputs": [
".dist/**"
]
},
"lint": {
"outputs": []
}
}
}
Add dev script in package.json "scripts"
"dev": "turbo run dev",
Run
yarn run dev
This seems to have reduced the build times to about 3 seconds
Can anyone confirm if this is an acceptable solution, points out any issues
Thanks

Related

Cannot use import statement outside a module

I'm faced with a problem with my API in Heroku. I have a Node JS API, built with Typescript and hosted in Heroku. Everything looks correct when I try to execute the local script and build the script, but when I need to run the start script, things don't work.
My configurations are:
Node: v18.12.1
NPM: v8.19.2
I have some scripts to transpile .ts files to .js files with babel
"build": "babel src --extensions \".js,.ts\" --out-dir dist --copy-files",
"dev:server": "ts-node-dev -r tsconfig-paths/register --inspect --transpile-only --ignore-watch node_modules src/shared/infra/http/server.ts",
"start": "node dist/shared/infra/http/server.js"
When I execute dev:server and build script, everything runs with success, but when I run the start script, I receive this error:
enter image description here
I checked some points, like my tsconfig.json and my babel.config, but everything looks correct.
module.exports = {
presets: [
['#babel/preset-env', { targets: { node: 'current' } }],
'#babel/preset-typescript',
],
plugins: [
[
'module-resolver',
{
alias: {
'#modules': './src/modules',
'#config': './src/config',
'#shared': './src/shared',
},
},
],
'babel-plugin-transform-typescript-metadata',
['#babel/plugin-proposal-decorators', { legacy: true }],
['#babel/plugin-proposal-class-properties', { loose: true }],
[
'const-enum',
{
transform: 'removeConst',
},
],
],
};
Because of it, when I deploy API in Heroku, I recive this error:
enter image description here.
I don't have an idea why this occur, because about 1 month ago the API was running perfectly on Heroku production instance.
I appreciate it if anyone can help and give me some tips, about this problem.
What I tried
Check and change my npm and node versions
Check babel confgs
Add "type":"module"in my packages.json

Firebase functions - compile typescript code before running emulators:start

I have a Firebase project setup with /functions directory, where all the source code is getting compiled from /src to the /dist directory.
The question is: how to configure Firebase in such way that it will run tsc command each time before starting the Local Emulator Suite? I wonder if there is a similar property to functions.predeploy in firebase.json config, but for the Local Emulator Suite:
{
"firestore": {
"rules": "firestore.rules",
"indexes": "firestore.indexes.json"
},
"functions": {
"predeploy": [
"npm --prefix functions run build"
],
// something like this:
"preemulator": [
"npm --prefix functions run build"
]
}
}
Here is a build script from package.json:
"scripts": {
// ...
"build": "./node_modules/.bin/tsc",
}

VSCode Task to run various node commands

I have a monorepo where I wish to create a script for starting up a specific project locally.
The project is completely Node.js based.
For me to set up this project locally for development, I need to run the following commands in this order:
Start up the docker images
cd docker/dockerForTests
docker-compose up -d
Start up the Web Auth server
cd src/project/webAuthentication
setenvs projectAuthentication && npm start
Start up the API
cd src/project/api
setenvs projectAPI && npm start
Start up the web client
cd src/project/web
setenvs projectWeb && npm start
I usually start each section up in a new terminal window, within VSCode, for ease of use.
To automate this process, I found out about VSCode Tasks.
Although it appears they are designed for 'building' or 'watching' tasks, I thought that I could modify the behavior to run the above commands for me.
Here was my attempt:
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"runner": "terminal",
"version": "2.0.0",
"tasks": [
{
"label": "Start Docker",
"dependsOrder": "sequence",
"type": "shell",
"command": "cd docker/dockerForTests && docker-compose up -d",
},
{
"label": "Start Web Auth",
"dependsOrder": "sequence",
"type": "process",
"command": "cd src/project/webAuthentication && setenvs projectAuthentiction && npm start"
},
{
"label": "Start Up Local Development Environment",
"presentation": {
"echo": true,
"reveal": "always",
"focus": true,
"panel": "new",
"showReuseMessage": false,
"clear": true
},
"dependsOn": [
"Start Docker",
"Start Web Auth"
],
"problemMatcher": []
}
]
}
The first command works fine, but I wanted it to be like the integrated terminal, where it hangs for input once the command has finished running.
Secondly, the second task does not work as it's not a Node command.
I would like it to work like the regular, bash input.
How can I automate my above workflow? Is it even possible?
At least for points 2, 3 and 4 concurrently works fine, and it should work fine for point 1 as well. With following scripts in scripts section of package.json in your root directory you should be able to launch your dev env with just one command
"start-docker": "cd docker/dockerForTests && docker-compose up -d",
"start-auth": "cd src/project/webAuthentication && setenvs projectAuthentication && npm start",
"start-api": "cd src/project/api && setenvs projectAPI && npm start",
"start-client": "cd src/project/web && setenvs projectWeb && npm start",
"start-dev": "concurrently \"npm run start-docker\" \"npm run start-auth\" \"npm run start-api\" \"npm run start-client\""
This doesn't use VSCode task, but would simplify your life anyway.
You should be able to add the necessary scripts to the root package.json's scripts section. Once you do that, you should see them as VS Code tasks, thanks to VS Code's automatic task detection.
See https://code.visualstudio.com/docs/editor/tasks#_task-autodetection for details.

Loopback 4 Debugger nodemon Solution

How to debug loopback 4 / node application with nodemon in visual studio code?
Looking for a solution that rebuilds the app when the loopback typescript code is changed. With option for debugging.
Regards,
Kelvijn
I finally found a solution to debug Loopback 4/node.js. If anyone has suggestions please do, this is the first solution that really does what I want.
Start Debugger by running:
npm run debug
With nodemon run the below command
nodemon --exec run debug
Add breakpoints by clicking on the left side of the line numbers in visual studio code.
Then in Visual Studio Code start application on debug mode by
Visual Studio Code (top-bar) -> Debug -> Start Debugging
package.json
"debug": "npm run build && node --nolazy --inspect-brk=9229 .",
"build": "lb-tsc es2017 --outDir dist"
launch.json
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "attach",
"timeout": 1000000,
"name": "Attach",
"port": 9229,
"restart": true
}
]
}
tsconfig.json
Note: This file is by default extended by loopback, so you don't have to modify this.
{
"compilerOptions": {
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"target": "ES5",
"lib": ["es2015"],
"allowJs": true,
"skipLibCheck": true
},
"include": ["src"],
"exclude": ["node_modules", "platforms"]
}
Application structure
This is an alternative solution for nodemon.
tsc-watch is a similar tool that can be used with loopback 4. Basically, it works similar to the nodemon. To add tsc-watch as dev package,
run npm install tsc-watch --save-dev in your project location
add following lines to the package.json > scripts
"start": "node -r source-map-support/register .",
"dev": "tsc-watch -b --onSuccess \"npm start\""
now run npm run dev
For more details visit tsc-watch on npm or github
Create your own nodemon.json in root project source and put this in file
{
"ignore": [
"**/*.test.ts",
"**/*.spec.ts",
".git",
"node_modules"
],
"watch": [
"src"
],
"exec": "npm start",
"ext": "ts"
}
and run nodemon that's. Just make sure you installed nodemon in global scope.
Thanks for all the answers here I have manage to have something that works for my setup. I use yarn with loopback 4. Thanks to #dat-ho for the starting point.
First install nodemon in global scope
then add the nodemon config to package.json. I added this at the bottom of the file after devDependencies.
"nodemonConfig": {
"verbose": true,
"watch": [
"src/"
],
"ignore": [
"dist/*"
],
"ext": "ts",
"exec": "yarn run clean && yarn start"
}
The changes from previous answer was that nodemon detects the npm start script and it re runs npm start fine, but it does not rebuild and the changes were not shown in the running code. so I added the line "exec": "yarn run clean && yarn start" to clean and rerun the npm start command.
You can then add the following start:dev command to the package.json scripts section:
"start": "node -r source-map-support/register .",
"start:dev": "nodemon '--inspect'",
From there just run yarn start:dev and will rebuild when any typescript file changes. Hope this works for you guys. It took me a substantial amount of research to having this working. Hopefully the loopback guys can have something similar in future.

Use flag `--experimental-worker` with babel-node

babel-node --experimental-worker app.js
Using this command for starting my project in development mode. Output is:
error: unknown option--experimental-worker'
config .babelrc:
{ "presets": [ ["env", { "targets": { "node": "current" } }], "stage-0", "flow" ], "plugins": [ "transform-decorators-legacy", "transform-flow-strip-types" ] }
This flag is needed to use worker threads. Using babel 6.26
I just ran into this today and replied to the issue on GitHub here. I've pasted my fix below:
I was using Nodemon, and it turns out that there's an option to
include environment variables as NODE_OPTIONS in the nodemon.json
file. This did the trick for me:
{
"watch": ["server"],
"ext": "js",
"env": {
"NODE_OPTIONS": "--experimental-worker"
},
"exec": "babel-node server/server.js"
}
How to integrate Nodemon + worker_threads into a normal NodeJS app:
Set up Nodemon
Add a nodemon.json file to the root folder (example here)
Add this to nodemon.json:
"env": {
"NODE_OPTIONS": "--experimental-worker"
}
If you're setting up Nodemon for the first time, I found
this tutorial very helpful.
The idea is to split your command into two phases:
Phase 1:
babel app.js --out-file app-compiled.js
And phase 2:
node --experimental-worker app-compiled.js
In npm scripts you can then combine the two:
"scripts": {
"pre-build": "babel ./app.js --out-file ./app-compiled.js",
"serve": "yarn pre-build && node --experimental-worker ./app-compiled.js"
}
It not actually for me already. I am refused to use nodemon and run my code with command
node --experimental-worker -r babel-register $NODE_DEBUG_OPTION app.js
It`s help me use exeprimental workers with babel, but with nodemon - not

Resources