Week 4 - Data structures and loops

Arrays

Loops

Objects

Package managers

Tools (IDE code editing)

Style - Autoformatting

Practice

Assignment

Back to core program

Package managers

What are package managers?

Package managers are tools that help you install, update, and manage external code libraries (packages) in your projects. Instead of manually downloading and copying code files, package managers automate this process and handle dependencies.

npm (Node Package Manager) is JavaScript's most popular package manager. It gives you access to over 2 million packages: pre-built solutions for common problems like formatting dates, making HTTP requests, or adding animations.

Yarn is an alternative package manager created by Facebook (now Meta). It offers faster installations and better security features. While npm and Yarn work differently under the hood, they're largely interchangeable for basic usage.

In this curriculum, we'll focus on npm since it comes bundled with Node.js and is the standard tool. Once you understand npm, learning Yarn is straightforwardβ€”the concepts are the same.

# npm commands
npm install
npm install package-name

# Equivalent Yarn commands
yarn
yarn add package-name

<aside> πŸ’‘

Using packages means you don't have to reinvent the wheel. Why spend hours building a feature when someone has already created, tested, and maintained a solution?

</aside>

https://www.youtube.com/watch?v=P3aKRdUyr0s&t=14s

Package security awareness

While npm is an incredibly useful tool, it's important to understand that the open-source ecosystem can be targeted by attackers.

<aside> ⚠️

Recent attacks have compromised popular packages by targeting maintainers through phishing. Always verify package authenticity and keep dependencies updated.

</aside>

Best practices for staying safe:

The JavaScript community responds quickly to security incidents, but vigilance is your first line of defense.

Installing Node.js and npm

npm comes bundled with Node.js. To check if you have them installed:

node --version   # v18.0.0 or similar
npm --version    # 9.0.0 or similar

If not installed, download Node.js from nodejs.org (choose LTS version).

Understanding package.json

Every Node.js project has a package.json file, a manifest that describes your project and lists its dependencies. It’s like a contract that determines which dependencies need to be used for development.

You can create one with npm init -y. This generates a package.json file:

{
  "name": "my-project",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \\"Error: no test specified\\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {}
}

Key sections:

<aside> ⌨️

Create a new folder, navigate to it in your terminal, and run npm init -y. Open the generated package.json and examine its structure.

</aside>

Understanding package-lock.json

When you run npm install, npm automatically generates a package-lock.json file. This file locks the exact versions of all packages and their dependencies.

{
  "name": "my-project",
  "version": "1.0.0",
  "lockfileVersion": 3,
  "requires": true,
  "packages": {
    "node_modules/chalk": {
      "version": "4.1.2",
      "resolved": "<https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz>",
      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
      "dependencies": {
        "ansi-styles": "^4.1.0",
        "supports-color": "^7.1.0"
      }
    }
  }
}
// In package.json, you might see:
"dependencies": {
  "chalk": "^4.1.2"  // The ^ means "4.1.2 or any compatible newer version"
}

// package-lock.json ensures everyone gets exactly 4.1.2

Key benefits:

<aside> πŸ’‘

Always commit package-lock.json to Git. When teammates run npm install, they'll get the exact same dependency tree as you.

</aside>

Why both package.json and package-lock.json?

package.json defines what you want. **It lists your direct dependencies:

"dependencies": {
  "chalk": "^4.1.2"  // "4.1.2 or any compatible version"
}

package-lock.json locks what you actually have. It locks the entire dependency tree (including chalk's dependencies, and their dependencies...):

"chalk": {
  "version": "4.1.2",  // Exactly 4.1.2
  "resolved": "<https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz>"
}

<aside> πŸ’‘

package-lock.json locks thousands of nested dependencies. Your package.json might list 10 packages, but those 10 packages depend on hundreds more. The lock file ensures everyone's entire dependency tree matches exactly.

</aside>

How it works in practice

Imagine you and a teammate both run npm install a few days apart. Without package-lock.json, you might get different versions of nested dependencies if updates were published in between.

# Developer A installs chalk
npm install chalk  # Gets 4.1.2, creates/updates package-lock.json

# Developer A commits both files to Git
git add package.json package-lock.json
git commit -m "Add chalk dependency"

# Developer B pulls the code
git pull
npm install  # Gets exact same version (4.1.2) from lock file

# Later: Developer A decides to update
npm update chalk  # Gets 4.1.5, updates lock file
git commit -m "Update chalk to 4.1.5"

# Developer B pulls again
git pull
npm install  # Now gets 4.1.5

<aside> πŸ’‘

Updates are coordinated through Git. One developer updates, commits the lock file, and everyone else gets the same versions when they pull. No one gets surprise updates.

</aside>

Without package-lock.json, running npm install at different times could give different versions. With it, everyone gets identical dependencies until someone explicitly updates and commits the change.

Installing Packages

Installing a package

npm install package-name

This does three things:

  1. Downloads the package to a node_modules folder
  2. Adds it to dependencies in package.json
  3. Creates/updates package-lock.json (locks exact versions)

Example:

npm install chalk

Your package.json now includes:

{
  "dependencies": {
    "chalk": "^5.6.2" // version might be different
  }
}

The node_modules folder

When you install packages, npm downloads them into a node_modules folder in your project:

my-project/
β”œβ”€β”€ node_modules/          # All installed packages
β”‚   β”œβ”€β”€ chalk/
β”‚   β”œβ”€β”€ ansi-styles/       # chalk's dependency
β”‚   β”œβ”€β”€ supports-color/    # chalk's dependency
β”‚   └── ...hundreds more
β”œβ”€β”€ package.json
β”œβ”€β”€ package-lock.json
└── index.js

This folder can become massive (easily hundreds of megabytes or even gigabytes).

npm.png

<aside> ⚠️

Never commit node_modules to Git (it's huge and unnecessary). Always add it to .gitignore. Others can recreate it by running npm install.

</aside>

Installing multiple packages

npm install package1 package2 package3

Installing a specific version

npm install [email protected]