今日已更新 160 条资讯 | 累计 24117 条内容
关于我们

标签:#javascript

找到 658 篇相关文章

AI 资讯

Angular's Official Agent Skills Helps AI Coding Tools Write Modern Angular

Google's Angular team has released a repository called angular/skills, focusing on Agent Skills that enhance AI coding agents' ability to write modern Angular code. The repository includes skills for generating code and scaffolding applications, reinforcing current Angular conventions. It serves as a snapshot, aiming to improve AI suggestions by providing updated context. By Daniel Curtis

2026-06-12 原文 →
AI 资讯

How to Build a LinkedIn Outreach Pipeline (Without Getting Your Account Banned)

TL;DR: A LinkedIn outreach pipeline is a background worker that signs in with your own session, opens profiles, sends connection requests and messages on a schedule you control, and can post content straight to your feed. The hard was staying invisible to LinkedIn's detection. We got to our nineteenth build in about two weeks. Along the way, the session kept dying after three profiles (a device fingerprint mismatch), the stealth layer turned out to be detectable on its own, an authenticated proxy refused to connect, and Chrome froze in ways no timeout caught. This is every failure and the fix that finally held. We built a LinkedIn marketing pipeline inside Ozigi because our own go-to-market runs on it. I didn't just want it to be another tool; I needed it to send real messages to real people without getting my personal account flagged. The very first version we built worked for sourcing and reaching three leads, then the session died. The second version got past that and froze instead. This pattern repeated for two weeks and led us from building v1 of our LinkedIn worker to the current version 26. This article is like a cleaned-up version of our build log for educational purposes. If you are trying to reach people on LinkedIn from code, you will hit most of these walls in roughly this order. I will name the exact failure each time, because "it stopped working" helped me precisely never. What Does a LinkedIn Outreach Pipeline Actually Do? A complete LinkedIn outreach pipeline does four jobs: It signs in with your session cookie so LinkedIn sees you, not a script. It opens a lead's profile. It sends a connection request or a message, depending on whether you are already a first-degree connection. And it can publish a post to your feed. The first three are outreach. The fourth is content. They share the same infrastructure, which matters later. None of these look overly complicated logic. You click a button, type into a box, press send. But the reason this turned into

2026-06-12 原文 →
AI 资讯

How ESLint Actually Works: The Quality Gate Behind Modern JavaScript

A few days ago, I shared an article: You Don't Need Another Agent. You Need a Linter. Then I did what I do with anything I write: shared it around — a few publications, a few channels. Two reasons: First, feedback. I'd genuinely rather get roasted and fix my blind spots than stay comfortable and wrong. Second, let's be honest: reach. Every writer enjoys seeing a few more views. Most of the responses were positive. One wasn't. A publication rejected it with the reason: LOW_QUALITY Fair enough. It means there's room for improvement. Funny enough, my caffeinated 1 AM brain disagreed. Then it did what every developer does when someone says "this isn't good enough." It took that personally. So I went back and reread the article. And after the initial ego check, I realized something serious: The article talked in detail about ESLint, why it matters more in an AI-assisted world than ever. What it did not do was answer the question that actually matters: What is ESLint, how does it work, and why has half the JavaScript ecosystem quietly built its quality process around it? So let's fix that. Now, this isn't a sequel to my last piece about untangling vibe-coded code. It stands on its own — one thing, done properly . A complete teardown of ESLint: What it is How it works internally Why companies use it as a quality gate The different classes of problems it solves How plugins work How to write your own rules Where it fails Why it still beats many AI-based review systems Fair warning. This article is going to be technical. There will be syntax trees. There will be compiler concepts. There will be enough JavaScript internals to make frontend developers slightly uncomfortable. I'll try my best to keep it readable not letting it turn into another manual - which nobody finishes. Let's start with the question most people never ask. What Is ESLint Actually Doing? Most developers describe ESLint like this: It checks code for mistakes. Technically true. Also completely useless. That's

2026-06-12 原文 →
AI 资讯

Summing 50,000 emission line items in the wrong order changes your total

Floating-point addition isn't associative. For a corporate inventory with tens of thousands of rows, naive summation drifts — and the number you disclose depends on row order. Here's why, and the fix. Here's a result that should bother anyone building carbon software. Take a corporate emissions inventory — tens of thousands of line items, each a number in tonnes CO₂e. Sum it. Now sort the same rows differently and sum again. The totals don't match. Not by much — maybe the third or fourth decimal place — but they don't match, and nothing in your code changed except the order. If you've never seen this, open a console: 0.1 + 0.2 === 0.3 // false That's the same bug, scaled up to a reporting deliverable. Why order changes the answer IEEE 754 doubles have 52 bits of mantissa. That's about 15–16 significant decimal digits of precision — generous, until you add numbers of very different magnitudes. When you add a small number to a large running total, the small number gets shifted right to line up the exponents before the addition happens. Bits that fall off the end of the mantissa are gone. Add a 0.0001 tCO₂e line to a running total of 80000.0 and there simply aren't enough mantissa bits to hold both the 80,000 and the 0.0001 — the small value is partially or completely swallowed. Float addition, as a result, isn't associative. (a + b) + c is not guaranteed to equal a + (b + c) . Sum your rows largest-first and the small values vanish early against a big accumulator. Sum smallest-first and they accumulate into something large enough to survive. Same data, different total. Here's the effect, deliberately constructed to be visible: const big = 80000 ; const smalls = Array ( 50000 ). fill ( 0.0001 ); // small values first, then the big one let a = 0 ; for ( const x of [... smalls , big ]) a += x ; // big value first, then the smalls let b = 0 ; for ( const x of [ big , ... smalls ]) b += x ; console . log ( a ); // 80004.99999999... console . log ( b ); // 80004.99999999...

2026-06-12 原文 →
AI 资讯

Stop Declaring Tools Dead — lucide-react is Still Fine

Every few months, a post goes viral: "Please stop using [perfectly good tool]." This time it's lucide-react. And honestly? The take is lazy What's the actual problem? Nothing. The library is actively maintained, tree-shakable, TypeScript-friendly, and has 1000+ consistent icons. A new icon library dropped? Cool. That doesn't make this one broken. Tools don't expire — context does Before switching anything in production, ask: Is it maintained? ✅ Does it solve my problem? ✅ Is my team comfortable with it? ✅ Then keep using it. Real usage — still clean in 2026 import { Search , Bell , User } from ' lucide-react ' ; export default function Navbar () { return ( < nav > < Search size = { 20 } /> < Bell size = { 20 } strokeWidth = { 1.5 } /> < User size = { 20 } color = "#6366f1" /> </ nav > ); } Tree-shaking works perfectly — only Search, Bell, and User are bundled. Not the entire library. When you should switch Unpatched security vulnerability Repo abandoned for 2+ years Bundle size issue you've actually measured If none of these apply, you're switching for hype, not logic. The real issue "Please stop using X" posts get engagement. Developers see them, second-guess stable choices, and waste hours migrating things that weren't broken. Don't let LinkedIn trends drive your architecture. Build products. Not migrations.

2026-06-12 原文 →
AI 资讯

Parallel AI Coding with Git Worktrees: Run Multiple Agents Without Conflicts

Parallel AI Coding with Git Worktrees: Run Multiple Agents Without Conflicts Most parallel AI development problems stem from a single architectural mistake: multiple agents sharing the same working directory. Teams spin up three Claude Code instances, point them at the same project folder, and watch as file writes collide, branch checkouts interrupt each other, and lock files corrupt. The symptom looks like a race condition. The root cause is filesystem design. Git worktrees solve this by giving each agent its own isolated working directory while sharing a single .git repository. This distinction is critical. Developers get parallel execution without the storage overhead of full clones, and agents operate on separate branches without stepping on each other's file handles. The pattern has existed since Git 2.5, but AI coding workflows finally make it essential infrastructure. The Collision Problem: Why Multiple AI Agents Can't Share a Working Directory When you run git checkout feature-A in a directory where another process is reading files, the filesystem state changes underneath that reader. The other process doesn't see atomic transitions—it sees partial writes, missing files, and inconsistent dependency graphs. TypeScript compilers fail with "Cannot find module" errors. Dev servers crash because watched files disappeared mid-read. Lock files from package managers become corrupted when two agents run npm install simultaneously on different branches with different dependency trees. The obvious solution—staggering agent execution so only one runs at a time—defeats the purpose of parallel development. Teams that try this pattern end up with AI agents waiting in queue, each one blocking the next until it finishes. The bottleneck shifts from human typing speed to serial execution, and the productivity gains evaporate. Full repository clones work but waste disk space. A 2GB monorepo cloned five times for five agents consumes 10GB of redundant Git objects. Sparse checkou

2026-06-12 原文 →
AI 资讯

How to Convert JSON to XML Without Breaking Your Integration

Working with modern APIs means living in JSON. But the moment your project touches a legacy enterprise system - a bank, a government service, or a SOAP endpoint that hasn't changed in a decade - you're suddenly dealing with XML. The challenge isn't just swapping syntax; it's understanding where the two formats are structurally incompatible, and what breaks silently when you ignore that. Why JSON and XML Don't Simply Map to Each Other JSON is compact and type-aware - it distinguishes between numbers, booleans, strings, and arrays natively. XML is verbose, treats all content as text, and has no concept of arrays. It only has repeated sibling elements. This gap is where most conversion bugs are born. A JSON array with just one item can silently become a plain object if your converter doesn't handle the edge case explicitly. The Three Biggest Conversion Pitfalls First is array ambiguity - XML has no array type, so a JSON array becomes repeated sibling elements. A single-item array is indistinguishable from a plain object unless your converter explicitly preserves the list context. Second is type erasure - XML flattens numbers, booleans, and strings into plain text, destroying the type information that many downstream systems depend on. Third is the single root element rule - JSON can have multiple top-level keys, but every valid XML document must have exactly one root element wrapping everything else. Handling Arrays the Right Way Always nest array items inside a named parent element. A JSON users array should produce a parent element containing individual child elements. This structure makes the list unambiguous to any downstream XML parser and prevents silent data loss during round-trips. Escaping Special Characters Characters that are perfectly valid inside a JSON string will break an XML parser immediately. Your conversion logic must escape these four: less-than becomes <, greater-than becomes >, ampersand becomes &, and double-quote becomes ". Skipping even one of

2026-06-12 原文 →
AI 资讯

Validate and Mask Environment Variables in Node.js and TypeScript

Configuring environment variables seems simple, but it frequently leads to two common issues in production-grade applications: Missing Variables: A developer adds a new variable locally but forgets to update the .env.example file. Other team members pull the changes, and their local environments crash. Leaked Credentials: A debug log like console.log(process.env) prints database connection strings or API tokens to the terminal, leaving them visible in plaintext logs. To solve this, we created @novaedgedigitallabs/envkit . It is a zero-dependency (other than Zod) utility that validates, loads, and masks environment variables, and keeps your example configurations updated automatically. Key Features Schema Validation: Define your environment variables with Zod to enforce types and formats. Log Masking: Automatically redact sensitive credentials in console output. Example Syncing: Automatically append missing variables to your .env.example file without overwriting comments or values. Module Support: Runs in ESM and CommonJS. Getting Started Install the package and Zod: npm install @novaedgedigitallabs/envkit zod Initialize your configuration in a file like env.ts : import { createEnv } from ' @novaedgedigitallabs/envkit ' ; import { z } from ' zod ' ; export const env = createEnv ({ schema : { DATABASE_URL : z . string (). url (), JWT_SECRET : z . string (). min ( 32 ), PORT : z . coerce . number (). default ( 3000 ), NODE_ENV : z . enum ([ ' development ' , ' production ' , ' test ' ]). default ( ' development ' ), }, secrets : [ ' JWT_SECRET ' , ' DATABASE_URL ' ], generateExample : true , // Appends new keys to .env.example at runtime }); Because the variables are validated using Zod, your editor will provide full TypeScript autocomplete and type safety: env . PORT ; // Resolved as a number env . JWT_SECRET ; // Resolved as a string Preventing Secret Leaks in Logs Logging environment configs is a common debugging habit. With envkit, any variables listed in the secre

2026-06-12 原文 →
开发者

Announcing Limn Engine — A Lightweight 2D Game Framework for the Browser

Announcing Limn Engine I'm excited to launch Limn Engine — a lightweight, zero-dependency HTML5 Canvas game framework for the browser. No npm install. No build step. No bloated dependency tree. Drop in a single script and start making 2D games. The Core Idea: Display + Component Limn Engine is built around two classes that cover 90% of what you need in a 2D game: Display — The Game Shell A singleton Display class that manages the canvas, runs the game loop, handles keyboard and mouse input, controls the camera, and manages scenes. Setting up a game is a one-liner: const display = new Display (); display . start ( 800 , 600 ); Let me try creating it step by step . Component — Every Object in Your Game A unified Component class that combines position, size, color/image, velocity, physics, and collision detection. No separate "Sprite" and "Body" classes — one object does it all. const player = new Component ( 40 , 40 , " blue " , 100 , 100 ); Components support three modes: Rectangle — solid color shapes for rapid prototyping Image — loaded from spritesheets or single image files Text — the Tctxt subclass for text elements with backgrounds, padding, and alignment Key Features Dual-Canvas High-Performance Rendering Call display.perform() to activate dual-canvas mode. Static backgrounds and tilemaps are drawn once to an offscreen buffer, then composited as a single drawImage() call per frame. This dramatically reduces draw calls and improves frame rates for complex scenes. display . perform (); display . start ( 800 , 600 ); Tilemap Levels Define game worlds as 2D arrays and initialize the tilemap engine with one call. Supports dynamic tile placement during gameplay — great for destructible environments and breakable blocks. display . map = [ [ 1 , 1 , 1 , 1 , 1 ], [ 1 , 0 , 0 , 0 , 1 ], [ 1 , 0 , 9 , 0 , 1 ], [ 1 , 0 , 0 , 0 , 1 ], [ 1 , 1 , 1 , 1 , 1 ] ]; display . tileMap (); Sprite & AnimatedSprite Load horizontal spritesheets and define named animation clips (idle,

2026-06-11 原文 →
AI 资讯

🚀 New React Challenge: Build a Spreadsheet with Formula Evaluation

You've built todo apps, counters, and forms. But can you handle a grid of 50 cells that reference each other through formulas? This challenge pushes your state management skills into real spreadsheet territory — formula evaluation, two-way cell bindings, and an interface that juggles editing, selection, and keyboard shortcuts all at once. 🔥 Start the Challenge Now 🧩 Overview Build a spreadsheet with real-time formula evaluation. You'll wire up a 10-row × 5-column grid where cells support basic values and Excel-style formulas (like =A1+B2), column and row selection, and a formula bar that mirrors what you're typing. ✅ Requirements Render a spreadsheet with column headers A through E and rows 1 through 10 Each cell uses an <output> element for the computed value and an <input> overlaid for editing Click a cell to edit; press Enter or blur to commit the change Formulas starting with = must be evaluated: Arithmetic: =1+1 → 2 Cell references: A1= 5 and B1= =A1+3 → 8 Click a column header to select/deselect that column Click a row number to select/deselect that row Selecting a column deselects any row and vice-versa Backspace clears the selected column or row Click outside the table deselects everything A formula bar ( fx ) mirrors the editing cell's value Cells must start empty — no default values 💡 Notes Use useState for cells, selected column, and selected row. No need for useReducer here. Each cell uses two overlapping layers: a visible <output> for the computed value and an invisible <input> for the raw formula. Toggle with opacity-0 / opacity-100 so the input stays mounted. Evaluate formulas with eval : generate JS const declarations from all cell values, wrap them in an IIFE, and evaluate. Recompute every cell on any change — cells can reference each other. 🧪 Tests renders the app title renders the spreadsheet with column headers A-E and rows 1-10 renders cells with initial empty values allows editing a cell and displays the new computed value evaluates a simple fo

2026-06-11 原文 →
AI 资讯

I built an AI chat over my CV on a zero-pound inference budget

My CV is a PDF, and PDFs do not answer questions. So I built ask.hiten.dev : a streaming chat grounded in my actual career history, where a recruiter can ask "why should I hire you over another senior frontend engineer?" and get a real answer. The constraint that made it interesting: the total inference budget is zero. No OpenAI bill, no hosted vector DB, nothing. Here is what that actually took. Four free providers and a failover chain No single free tier is reliable enough to put in front of strangers. Groq's free tier caps at 100k tokens/day, and I hit that cap on day one. OpenRouter's free models come and go. Cerebras occasionally queues you out at busy times. The fix is boring and effective: an ordered provider chain, all OpenAI-compatible, walked per-request until one answers. Groq (llama-3.3-70b) -> OpenRouter (gpt-oss-120b:free) -> NVIDIA (llama-3.3-70b) -> Cerebras (gpt-oss-120b) Each provider is just a base URL, a key and a model name. The API route tries each in order; the first 2xx with a body wins, and the response streams straight through. The client gets an X-Provider header so I can see who served what in the logs. Two details that mattered: Empty env vars are not unset. Docker Compose's ${VAR:-} yields an empty string, which defeats ?? defaults in Node. Every key goes through a helper that coerces "" to undefined , otherwise a provider with no key "exists" and fails every request. You cannot cheaply probe a token-per-day cap. My health check hits GET /models on each provider (auth check, 60s cache). It tells you "key works, service up", not "you have tokens left". The failover chain covers the gap: a TPD-capped provider fails fast and the next one picks up. If every provider is down, the page itself says so. The health check runs server-side at render time, and instead of a broken chat you get a short maintenance note. Never ship a chat UI that can fail after the user has typed. Open-weight models do not follow formatting orders My site's voice avoi

2026-06-11 原文 →