Skip to content

Commit e96cc6f

Browse files
authored
Merge pull request #190 from rajbos/copilot/fix-npm-peer-dependencies
Enforce npm ci to prevent package-lock.json churn from peer dependencies
2 parents b1ad503 + bcdd6b4 commit e96cc6f

File tree

3 files changed

+87
-1
lines changed

3 files changed

+87
-1
lines changed

.devcontainer/devcontainer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,6 @@
2323
}
2424
}
2525
},
26-
"postCreateCommand": "npm install",
26+
"postCreateCommand": "npm ci",
2727
"remoteUser": "node"
2828
}

.npmrc

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# NPM Configuration for Copilot Token Tracker Extension
2+
# This file documents the npm configuration used by this project
3+
4+
# IMPORTANT: This project uses package-lock.json for reproducible builds
5+
# - Use `npm ci` for installing dependencies (recommended)
6+
# - Use `npm install` only when adding/updating dependencies
7+
# - CI/CD workflows use `npm ci` exclusively
8+
9+
# Use package-lock.json for reproducible builds (default behavior)
10+
package-lock=true
11+
12+
# Do not use legacy peer dependency resolution (default in npm 7+)
13+
# Some dependencies have peer dependencies we don't use (e.g., react from @vscode/webview-ui-toolkit)
14+
# This is expected and does not affect functionality
15+
legacy-peer-deps=false
16+
17+
# Save exact versions (no ^ or ~ prefixes) when adding new dependencies
18+
# This ensures maximum reproducibility
19+
save-exact=true

CONTRIBUTING.md

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ If you prefer not to use the devcontainer, you can set up the extension locally:
140140
### Prerequisites
141141

142142
- [Node.js](https://nodejs.org/) 18.x or 20.x
143+
- [npm](https://www.npmjs.com/) (comes with Node.js)
143144
- [Visual Studio Code](https://code.visualstudio.com/)
144145
- [Git](https://git-scm.com/)
145146

@@ -158,6 +159,8 @@ If you prefer not to use the devcontainer, you can set up the extension locally:
158159
npm install
159160
```
160161

162+
**Note:** The project uses `package-lock.json` for reproducible builds. The `.npmrc` file ensures consistent behavior across different npm versions and environments. CI/CD workflows use `npm ci` to ensure exact dependency versions are installed.
163+
161164
3. **Build the extension:**
162165

163166
```bash
@@ -239,6 +242,70 @@ npx vsce package
239242
- `npm test` - Run tests (requires VS Code)
240243
- `npm run watch-tests` - Run tests in watch mode
241244

245+
## NPM and Dependency Management
246+
247+
The project uses **`package-lock.json`** for reproducible builds and dependency consistency across all environments.
248+
249+
### Key Files
250+
251+
- **`.npmrc`**: Configures npm behavior (use `save-exact=true`, etc.)
252+
- **`package-lock.json`**: Lockfile that pins exact dependency versions (committed to the repository)
253+
- **`package.json`**: Defines project dependencies and scripts
254+
255+
### Installation Commands
256+
257+
**RECOMMENDED for day-to-day development:**
258+
259+
- **`npm ci`**: Clean install from lockfile
260+
- Requires `package-lock.json` to exist
261+
- Installs exact versions from the lockfile (no modifications)
262+
- Deletes `node_modules` before installing
263+
- **Use this after pulling changes** to avoid lockfile churn
264+
- **Used in all CI/CD workflows** for reproducible builds
265+
- Faster and more reliable than `npm install`
266+
267+
**Only when adding/updating dependencies:**
268+
269+
- **`npm install`**: Install/update dependencies
270+
- Respects `package-lock.json` and may update it
271+
- Use when adding new dependencies: `npm install <package>`
272+
- Use when updating dependencies: `npm install <package>@latest`
273+
- **After adding dependencies, commit both `package.json` and `package-lock.json`**
274+
275+
### Best Practices
276+
277+
1. **Use `npm ci` for routine development** - This prevents accidental lockfile changes and ensures you have the exact dependency versions
278+
2. **Only use `npm install` when intentionally changing dependencies** - This makes dependency updates explicit and trackable
279+
3. **Always commit both files together** - When you modify dependencies, commit both `package.json` and `package-lock.json` in the same commit
280+
4. **Don't manually edit `package-lock.json`** - Let npm manage it automatically
281+
282+
### Why We Use package-lock.json
283+
284+
1. **Reproducible Builds**: Ensures all developers and CI/CD get identical dependency versions
285+
2. **Consistency**: Prevents "works on my machine" issues caused by different dependency versions
286+
3. **Security**: Locks down transitive dependencies to prevent supply chain attacks
287+
4. **Performance**: CI/CD can cache dependencies more effectively with a lockfile
288+
289+
### About Peer Dependencies and "peer": true
290+
291+
Different npm versions (7+) may add or remove `"peer": true` properties in `package-lock.json` when running `npm install`. This is expected behavior for peer dependencies that aren't satisfied.
292+
293+
Some dependencies (like `@vscode/webview-ui-toolkit`) declare peer dependencies (e.g., `react`) that we don't use directly. You may see entries like this in `package-lock.json`:
294+
295+
```json
296+
"node_modules/react": {
297+
"version": "19.2.3",
298+
"peer": true,
299+
...
300+
}
301+
```
302+
303+
**This is normal and doesn't affect functionality.** To avoid lockfile churn from these changes:
304+
305+
- **Use `npm ci` for routine development** (doesn't modify the lockfile)
306+
- Only use `npm install` when you're intentionally adding or updating dependencies
307+
- If you accidentally modify the lockfile, run `git checkout package-lock.json` to restore it
308+
242309
## Code Guidelines
243310

244311
### Project Structure

0 commit comments

Comments
 (0)