typescript - Hvordan bygge og pakke kun de relevante avhengighetene ved bruk av nx?
Jeg har et prosjekt som bruker nx som har mange pakker i seg. Problemet mitt er at jeg bare har én package.json-fil, så hvis jeg ønsker å bygge bare én pakke, må jeg fortsatt bygge rotprosjektet ved å bruke npm install.
Dette er et problem fordi jeg under CI/CD-steget må bygge hele prosjektet, noe som tar for lang tid, og det genererer også en enkelt node_modules-mappe som blir enorm (3 GB), noe som også gjør at buntstørrelsen min blir uhåndterlig stor.
Hvordan kan jeg bygge individuelle pakker på en måte slik at node_modules-mappen kun inneholder avhengighetene som min pakke trenger, i stedet for å ha alle avhengighetene til alle pakkene?
Hvis det ikke er mulig, hvordan kan jeg kompilere en enkelt kjørbar main.js-fil som pakker alle de avhengighetene?
Redigering: Jeg prøvde å splitte package.json-filen for alle pakkene, men hver gang jeg bygger en individuell pakke, blir fortsatt alle avhengigheter lastet inn i node_modules-mappen i roten. Er det mulig å ha en node_modules-mappe for hver enkelt pakke?
Svar #1
Jeg fant en løsning som ikke er ideell, men den fungerer i det minste. Det generatePackageJson gjør, er at det oppretter en package.json-fil i bygge-mappen som kan brukes til å kjøre byggingen på nytt for å produsere en node_modules-mappe som kun inneholder avhengighetene til det spesifikke målet. Så i mitt tilfelle gjorde jeg følgende: jeg la til "generatePackageJson": true til mitt build-mål i min backend-pakke:
{
"sourceRoot": "apps/backend/src",
"projectType": "application",
"targets": {
"build": {
// ...
"options": {
"outputPath": "dist/apps/backend",
"main": "apps/backend/src/main.ts",
"tsConfig": "apps/backend/tsconfig.app.json",
"generatePackageJson": true, // 👈
"assets": [
"apps/backend/src/assets"
]
}
// ...
}
}
}
Nå, hvis jeg kjører nx build backend, vil jeg ha noe i dist/apps/backend som kan brukes som et frittstående prosjekt. Dessverre sjekker npm foreldremapper for package.json-filer og ødelegger alt, så jeg endte opp med å skrive et byggeskript som rydder opp i prosjektet og gjør distribusjon enkel. (Dette fungerer med Heroku, men det er lett å tilpasse til andre PaaS/IaaS-løsninger. Jeg skal lime det inn her ordrett:
Merk at dette skriptet kjøres fra rotmappen, så vår backend dist-mappe er på
dist/apps/backendi forhold til hvor dette skriptet kjøres. (Jeg holder skriptene iscript-mappen. Du skal heller ikke kjøre dette lokalt da det sletter ting fra prosjektet. Kjøre det kun i et CI/CD-miljø.
#!/bin/bash
print_usage() {
echo "💀 $1"
echo "Help below 👇"
echo ""
echo "Builds the specified project for Heroku."
echo ""
echo "Usage: ./heroku-build <nx-project-name>"
echo ""
echo "__Note that__ this script is intended to be used from CI/CD, you probably won't need it during development."
exit 1
}
if [ -z "$1" ]; then
print_usage "Project name is missing!"
fi
Heroku build is a little bit different because they have a slug size (deployment size) limit of 500MB.
If you build the project (not just the package) you'll end up with a `node_modules` folder that's ridiculously big (3GB)
but it can't be pruned properly. If you think you can prune it without this hacky solution go ahead, but it is unlikely
that you'll be able to figure it out. **If** you try it please increment the counter below:
total_hours_wasted_trying_to_prune_node_modules=13
So how this works is that Heroku will run `npm install --prod` that will delete devDependencies too, so
💀 DON'T MOVE nx and @nrwl packages to devDependencies! 💀
After the project is built you'll have the horrendous `node_modules` folder, but it's not a big deal as we'll delete it.
Build the project with nx
nx build $1 --prod
This step is necessary because npm will look for `package.json` files in the parent folder and it will use the `node_modules`
folder from the parent folder. We don't want that, we want to have only the necessary packages (backend) in the `node_modules` folder.
mv package.json package.json.bak
mv package-lock.json package-lock.json.bak
We get rid of all the unnecessary packages.
rm -Rf node_modules
We install the necessary packages.
In the `nx build` step nx generates a `package.json` that only contains the dependencies of the backend project
so this will *only* (😒) download 500MB from npm.
npm install dist/apps/backend
More reading on this problem:
#
- https://stackoverflow.com/questions/73373307/how-to-build-and-package-only-the-relevant-dependencies-using-nx?noredirect=1#comment129738870_73373307
- https://github.com/nrwl/nx/issues/1518
- https://github.com/nestjs/nest/issues/1706#issuecomment-579248915
