hi_001_angular_mod

[1] Reviving a “Lost” Angular Dev Environment on Windows (2025)

When you inherit an Angular project without its original developer-or when you simply come back to an old codebase months later-there’s a special kind of archaeology involved. This post documents how I brought an older Angular app back to life on Windows 10: version wrangling, VS Code setup, npm dependency conflicts, Webpack quirks, and a few very Windows-specific traps.

If you’re facing “it used to work on their machine,” grab a coffee. Here’s the field guide I wish I had.

The Starting Point

What I had

  • Source tree: src, node_modules (stale), dist (old build), plus angular.json, package.json, tsconfig*, etc.
  • Tooling installers mentioned by the previous dev: Node 20.10.0, VS Code 1.85.
  • Windows 10.

What I actually used

  • nvm-windows to manage Node versions.
  • Node 16.20.2 for maximum compatibility with older Angular/Webpack stacks.
  • VS Code with Angular Language Service, ESLint, Prettier.
  • Why Node 16? Older Angular toolchains can be allergic to OpenSSL 3 (Node 18/20). Node 16 is the “safe mode” for legacy builds.

Step 1: Clean, Predictable Tooling

# Powershell

# Install and select Node 16
nvm install 16.20.2
nvm use 16.20.2
node -v
npm -v

 

In VS Code, I enabled Format on Save with Prettier and kept ESLint fixes on save. Not strictly required—but little guardrails help.

Step 2: Fresh Dependencies

Old node_modules is not a time capsule—it’s drift. I removed it and reinstalled:

# Powershell

rd -r -fo node_modules 2>$null
del package-lock.json 2>$null
npm install

 

If your first npm install fails with peer dependency noise (mine did: jasmine-core vs karma-jasmine-html-reporter), you have two options:

  • Quick unblock:
npm install --legacy-peer-deps
  • Clean fix: bump the offending dev deps to compatible ranges (e.g., jasmine-core >= 3.8).

I went “quick unblock” to get the project running, then circled back for tidying.

Step 3: ng serve… and the Unexpected Traps

Trap A — The NODE_OPTIONS flag

I initially had –openssl-legacy-provider baked into npm scripts. With Node 16 that flag is not allowed.
Fix: remove it from package.json scripts and from your shell:

# Powershell

# package.json scripts → keep it simple
"start": "ng serve -o",
"build": "ng build --configuration=production"

# clear in the current shell
$env:NODE_OPTIONS = $null

 

Trap B — Webpack hates ! in paths

Webpack treats the exclamation mark as loader syntax. My project sat in a folder like:

A:\!_work\…\…\

 

Fix: move the project to a path without ! or spaces, e.g.:

A:\work\…\…\

 

Then reinstall once to clear cached absolute paths:

# Powershell

rd -r -fo node_modules 2>$null
del package-lock.json 2>$null
npm install

 

Trap C — “Can’t resolve ‘querystring’”

Legacy dev-server tried to load querystring (a Node core polyfill no longer auto-provided).

Fix: install the browser-friendly package:

# Powershell

npm i querystring

 

(If you hit more missing shims like url, buffer, util, add them similarly. In my case only querystring was needed.)

After these, ng serve -o finally launched on http://localhost:4200

Step 4: Production Build & Windows-ism

The first prod build succeeded. The second threw:

# bash

EPERM: operation not permitted, mkdir '...\dist\SOMETHING'

 

That’s Windows blocking writes (locked folder, Defender’s Controlled Folder Access, sync client, or a stale Node process).

Fix checklist

1. Kill dev server: Ctrl+C (then Y if prompted).

Optionally nuke stray processes:

# Powershell

taskkill /IM node.exe /F 2>$null

 

2. Remove dist cleanly:

# Powershell

cmd /c 'attrib -r -h -s dist\* /s /d' 2>nul
Remove-Item .\dist -Recurse -Force 2>$null

 

3. Rebuild:

# Powershell

npm run build

 

4. As a workaround, you can output elsewhere:

# Powershell

npx ng build --configuration=production --output-path .\build-out

 

If Defender’s Ransomware Protection is on, either add node.exe, VS Code, and your project folder as allowed apps/paths, or temporarily disable that protection for the build.

 

Deploy: What to Upload

Only upload the contents of dist/<project-name>/ (HTML/JS/CSS/assets).

Don’t upload src, node_modules, or config files.

If your site lives under a sub-path (e.g., /app/), build with:

# Powershell

npx ng build --configuration=production --base-href /app/ --deploy-url /app/

 

If you use Angular Router and direct links 404 on the server, add a rewrite so unknown routes fall back to index.html.

What I Learned

  • Pin a Node LTS that matches your toolchain. Node 16 is a lifesaver for older Angular/webpack stacks.
  • Paths matter. Avoid special characters (!, ?, #) and spaces in project paths on Windows.
  • Legacy polyfills are not automatic. If dev-server barks for querystring (or friends), add the package explicitly.
  • Windows can lock folders. Kill stray Node processes, clear dist, and watch Defender/backup tools.
  • Keep scripts boring. The fewer environment flags in package.json, the fewer “it works on my shell” mysteries.

 

Copy-Paste Quickstart

# Powershell

# 1) Node
nvm install 16.20.2
nvm use 16.20.2
$env:NODE_OPTIONS = $null

# 2) Fresh deps
rd -r -fo node_modules 2>$null
del package-lock.json 2>$null
npm install

# 3) Dev
npm run start # http://localhost:4200

# If 'querystring' error:
npm i querystring
npm run start

# 4) Prod build
# (close dev server first: Ctrl+C)
cmd /c 'attrib -r -h -s dist\* /s /d' 2>nul
Remove-Item .\dist -Recurse -Force 2>$null
npm run build

# 5) Deploy
# Upload the contents of dist/<project-name>/ via FTP/SFTP

 

Final Thought

Resurrecting an old Angular app isn’t about luck; it’s about sequencing: pick the right Node, clean your deps, remove magical flags, and keep the path clean. Once you tame those three, most of the “mysterious” build errors disappear—and you can get back to actually building the thing.

 

Buy me a coffee?

If you enjoyed this story, you can buy me a coffee. You don’t have to – but it means a lot and I always turn it into a new adventure.

Buy a coffee for Steve

Subscribe

You'll receive an email notification for every new post!

No spam emails! Read my privacy policy for more info.

Steve

Who am I? Who are you reading? Who are you supporting?

Steve
Tags: No tags

Add a Comment

Your email address will not be published. Required fields are marked *