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

标签:#JavaScript

找到 1022 篇相关文章

AI 资讯

4 ways canvas text rendering breaks in multilingual apps (that en/ja testing will never catch)

I run a large fleet of "preview it, then download it as PNG" web tools — name tags, certificate generators, price cards, badges — in five languages: Japanese, English, Spanish, French, Portuguese. Canvas 2D text rendering looks correct as long as you only test Japanese and English. It breaks when you run es/fr/pt through it. After stepping on these repeatedly, the failures collapse into four patterns. The premise: Latin languages run 1.4–2× longer than Japanese Design data first. The same label, measured across five locales: Example ja en es fr pt Tool name 22 chars 35 62 48 50 "Standard" button 4 8 10 20 12 Rule of thumb: fr/pt come out 1.4–1.7× longer than ja; es can balloon to nearly 3×. A font size and maxWidth tuned to fit Japanese will not fit the Latin locales. All four failure patterns grow from this. Pattern 1: hand-rolled wrapping via text.split(/\s+/) collapses on CJK The classic snippet — split on spaces, wrap word by word — does nothing for Japanese or Chinese, where words aren't space-delimited. An entire sentence becomes one unbreakable token and clips at the canvas edge. Test with real Japanese input and check that the final line renders to its last character. "Most of it showed up" is not a pass. Pattern 2: an ASCII-only tokenizer splits words at accented characters Fix pattern 1 with a character-class tokenizer like [A-Za-z0-9'\-_] and you've traded one regression for another: ç é ã ó ñ aren't in that class, so produção fragments into produ / ç / ão mid-word. An English test will never catch this. Generate actual PNGs with fr/es/pt samples and eyeball the area around accented characters. I never found another detection method — string-comparison tests can't see a rendering-level split. Pattern 3: the important word at the end vanishes into "…" Since fr/pt run 1.4–1.7× longer than the ja the layout was tuned for, text overflows its two lines and gets ellipsized. The cruel part: what disappears is the tail of the phrase — often the semantically criti

2026-07-23 原文 →
AI 资讯

I turned my phone into a remote deck for my Windows laptop — no cloud, no accounts, one npm start

It started with the dumbest problem in computing: I'm in bed, a movie is playing on my laptop across the room, and pausing it requires physically getting up . Every existing fix annoyed me in some way. Remote desktop apps are overkill and route through someone's cloud. Remote-control apps want accounts, subscriptions, or a native app install. I just wanted my phone to poke my laptop over my own Wi-Fi. So I built LapDeck : one Node.js process on the laptop, a PWA on the phone. Scan a QR code once and your phone becomes an app launcher, touchpad, keyboard, live screen viewer, and media/power remote. MIT licensed, plain JavaScript, no build step. This post is about the four problems that turned out to be more interesting than I expected. The architecture in one line Phone (PWA) ── WebSocket + MJPEG over Wi-Fi ──► Node.js agent (Windows) The agent serves the PWA, exposes a WebSocket for commands, and streams the screen as MJPEG. The protocol is deliberately dumb JSON envelopes — no protobuf, no RPC framework — so a native Android client or a CLI script can speak it in an afternoon. Windows-specific glue (volume, brightness, power, capture) is isolated in src/win/ , so a macOS/Linux port only has to reimplement that layer. Problem 1: mobile keyboards lie to you The obvious way to build a remote keyboard is to listen for keydown and forward key codes. On mobile, this collapses immediately: swipe typing, autocorrect, and IME composition don't emit per-key events. Android will happily tell you every key is keyCode 229 . The fix: stop listening to keys entirely. I keep a hidden input, and on every input event I diff the field's value against the last known state — compute the common prefix, then emit "delete N chars, type this string" to the laptop. Swipe-type a whole word and the laptop receives one clean text insertion. IME composition, autocorrect rewrites, emoji — all just become diffs. The lesson generalizes: on mobile web, treat the text field as the source of truth, n

2026-07-22 原文 →
AI 资讯

Stop Screenshotting Architecture Diagrams: Build Them as Single-File HTML

TL;DR Spent today rebuilding two training diagrams — a layered reference architecture and a workflow swimlane — as single-file HTML instead of exported images. The trick: data in a plain JS array, layout in CSS Grid, connectors in an SVG overlay measured at runtime . Result: diagrams you can step through, click into, and hand over as one file that opens offline. Why not just export a PNG? Because a screenshot is stale by the next sprint, and nobody re-opens the drawing tool to fix it. Approach Editable by a dev Interactive Portable PNG from a drawing tool No (need the source file) No Yes Mermaid in a doc Yes No Needs a renderer Hand-built HTML Yes (it's a data array) Yes One file, opens anywhere The third option costs a few hours once. After that, updating a component is editing one object in an array. Separate the data from the drawing This is the whole design. Nothing about position, colour, or DOM lives in the content: const TIERS = [ { key : ' clients ' , label : ' Clients ' , sub : ' consumers · admins ' }, { key : ' edge ' , label : ' Edge ' , sub : ' TLS · load balancing ' }, // ... ]; const COMPONENTS = [ { id : ' app ' , tier : ' app ' , x : . 34 , label : ' Control Plane ' , tech : ' PHP-FPM ' , role : ' Governance UI and sync orchestration. ' , points : [{ type : ' info ' , text : ' Pushes approved config downstream ' }] }, // ... ]; const LINKS = [[ ' consumers ' , ' edge ' ], [ ' edge ' , ' gateway ' ], /* ... */ ]; tier picks the row. x is a fraction (0..1) across that row , not a pixel. So the layout survives any viewport without me hand-tuning coordinates. Layout: Grid for the boxes, SVG on top for the wires +--------------------------------------------------+ | lane label | [card 1] [card 2] [card 3] | <- CSS Grid row |------------+-------------------------------------| | lane label | [card 4] [card 5] | +--------------------------------------------------+ ^ ^ sticky column SVG overlay (position:absolute; inset:0) draws paths between measured centre

2026-07-22 原文 →
开源项目

🔥 HughYau / qiushi-skill - 求是Skill——从经典唯物辩证法与实践哲学中提炼出一条总原则和九大方法论工具武装AI大脑。Qiushi-Skill:

GitHub热门项目 | 求是Skill——从经典唯物辩证法与实践哲学中提炼出一条总原则和九大方法论工具武装AI大脑。Qiushi-Skill: Build agents that investigate first, focus on the main contradiction, validate in practice, and keep pushing until the work is actually done. | Stars: 3,597 | 14 stars today | 语言: JavaScript

2026-07-22 原文 →
AI 资讯

Stop Scattering if (role === 'admin') Everywhere: A 3-Level Permission Tree for Page & Section Access

Most apps start their access control with something like this: function canEditReportsSummary ( role ) { return [ ' EDITOR ' , ' ADMIN ' ]. includes ( role ); } It works, right up until you have a dozen pages, each with a few sections, each needing independent read/write rules per role. Now you've got dozens of these little arrays scattered across the codebase, and adding a new role means hunting down every single one and hoping you didn't miss any. 0 There's a much simpler model that scales cleanly: a three-level permission tree — page → section → { r, w } - plus one generic function that walks it. No new library, no framework lock-in, just a data structure and ~5 lines of code. The shape of the data Instead of scattering role checks in code, define one permission tree per role . Three levels deep: Page — the top-level feature/route ( dashboard , reports , settings ) Section — a sub-area within that page ( overview , summary , billing ) Action — r (read) or w (write) { "dashboard" : { "overview" : { "r" : true , "w" : false }, "analytics" : { "r" : true , "w" : false } }, "reports" : { "summary" : { "r" : true , "w" : false }, "export" : { "r" : false , "w" : false } }, "settings" : { "general" : { "r" : true , "w" : false }, "billing" : { "r" : false , "w" : false } } } This one blob fully describes what a single role can see and do. Give each role its own tree, e.g. for three common roles: Page Section Viewer Editor Admin dashboard overview r r, w r, w dashboard analytics r r r, w reports summary r r, w r, w reports export – r r, w settings general r r r, w settings billing – – r, w Notice how this reads almost like a spreadsheet a product owner could fill in — that's the point. It's declarative data, not scattered if statements, so non-engineers can review it and engineers don't have to guess what a role does. The generic access-check function Once permissions are just nested objects, checking access is one small, reusable, framework-agnostic function: function

2026-07-22 原文 →
开发者

I'm speaking at React Day Berlin 2026 — bridging React into a Preact form engine

I'm excited to share that I'll be speaking at React Day Berlin 2026 this December! My talk How I Brought React Into a Preact Form Engine: A Production Bridge Pattern I'll walk through how we integrated React into an existing Preact-based form engine in production — the bridge pattern we used, the trade-offs, and what I'd do differently next time. Duration: up to 20 minutes Dates: December 4 & 7, 2026 Format: remote or in-person (TBD) Join me (free stream access) You can register through my speaker badge and get partial free access to watch the stream: 👉 My React Day Berlin 2026 badge Speaker page: reactday.berlin/#person-sam-abaasi ReactDayBerlin #react #preact #javascript #webdev See you there!

2026-07-22 原文 →
AI 资讯

From Variables to Closures

🚀 JavaScript Fundamentals (Week-03): Understanding the Concepts That Every Developer Should Know "Writing JavaScript code is one thing, but understanding what happens behind the scenes is what makes you a better developer." When I first started learning JavaScript, I knew how to declare variables and write functions. However, I often found myself asking questions like: Why are there three ways to declare variables? What exactly is hoisting? How does JavaScript execute my code? Why can an inner function access variables from its parent function? What does the this keyword actually refer to? Why do developers keep talking about writing clean code? This week, I focused on understanding these core JavaScript concepts instead of simply memorizing syntax. In this article, I'll explain each concept in a beginner-friendly way with examples and practical explanations. 📚 Topics Covered Variables ( var , let , const ) Hoisting Lexical Scope Execution Context Call Stack Closures this Binding DRY Principle KISS Principle Let's start from the beginning. 📦 Variables in JavaScript What is a Variable? A variable is a named container used to store data in memory . Instead of writing the same value repeatedly, we store it inside a variable and reuse it whenever required. For example, let name = " Sai " ; console . log ( name ); Output Sai Here, let → Variable declaration keyword name → Variable name "Sai" → Stored value Why Do We Need Variables? Imagine writing this: console . log ( " Sai " ); console . log ( " Sai " ); console . log ( " Sai " ); If the value changes, every occurrence must be updated. Using variables, let name = " Sai " ; console . log ( name ); console . log ( name ); console . log ( name ); Now changing one line updates every usage. Variables improve: Readability Reusability Maintainability Types of Variables JavaScript provides three ways to declare variables. var let const Although all three create variables, they behave differently. var var was introduced in the

2026-07-22 原文 →
AI 资讯

Show DEV: I built a daily web puzzle out of 1-star travel reviews

I built PunFiction: 1-Star Travel Reviews , a free daily web puzzle where you guess world landmarks by deciphering unhinged travel reviews from confused travelers. Tech Stack: Vanilla JS, CSS, HTML, GitHub Pages, MongoDB Atlas The Concept The internet can feel like it's literally overflowing with consumer complaints. I decided to take that negative energy and turn it into a 2-minute daily browser game for your morning coffee break. The Game Loop: Read an absurd 1-star review of a famous world landmark. Decipher the rhyming pun clues to guess the destination. Solving the puzzle unlocks an illustrated cartoon postcard and a sassy reply from the landmark 'manager'. The Tech Stack I wanted PunFiction to feel lightweight and lightning fast. Vanilla JavaScript: No React, Vue, or Svelte. Pure DOM manipulation and client-side logic. Zero Dependencies: No npm install spiral, no build-step headaches, and zero third-party scripts. No Accounts: Daily state, win streaks, and game progress live in localStorage. MongoDB Atlas: Light backend for aggregate puzzle stats (success rates, guess counts, no PII stored). Hosted on GitHub Pages: Static asset delivery via CDN. Give It a Spin If you like wordplay, geography, or just laughing at terrible tourist complaints, give today's daily puzzle a shot: 👉 Play PunFiction: 1-Star Travel Reviews I’d love to hear your thoughts on the UX, the game feel, or your take on building lightweight web games. Drop your feedback (or your worst pun) in the comments!

2026-07-22 原文 →
AI 资讯

Six open-source pieces, one JavaScript agent stack

Most agent projects do not fail because the first model call is difficult. They become difficult when the prototype needs memory, tools, evaluation, a user interface, documentation that coding agents can navigate, and a repeatable review process. That is the problem the open-source AgentsKit ecosystem is trying to solve for JavaScript teams. It is a set of independent projects with shared contracts, rather than one application that must own the whole stack. The six public pieces 1. AgentsKit: the composable foundation AgentsKit provides focused JavaScript and TypeScript packages for runtimes, adapters, tools, skills, memory, RAG, evaluation, observability, sandboxing, and UI bindings. Its core has zero runtime dependencies and a CI-enforced 10 KB gzipped budget. Six formal contracts keep adapters, tools, memory, retrievers, skills, and runtimes substitutable. You can run a first local agent without an API key: npm install @agentskit/core @agentskit/runtime tsx Then connect OpenAI, Anthropic, Gemini, Ollama, or another adapter without changing the rest of the runtime composition. 2. AgentsKit Chat: one interaction model, seven renderers AgentsKit Chat defines an interactive agent experience once and renders it through React, React Native, Ink, Vue, Svelte, Solid, or Angular. It also supports deterministic local answers before an optional backend call. That matters for documentation and support interfaces where exact project facts should not require an LLM. pnpm dlx @agentskit/chat-cli@0.4.0 init my-chat --renderer react --yes 3. Registry: reusable source, not another dependency The AgentsKit Registry distributes ready-to-use agents in a shadcn-style model: the CLI copies the source into your project, so you can inspect and modify it. npx agentskit add research npx agentskit add code-review The public catalog currently includes research, code-review, and knowledge-promotion agents, and is open to contributions. 4. Agents Playbook: engineering rules that can execute Ag

2026-07-22 原文 →
AI 资讯

A resumable, human-in-the-loop AI agent in ~200 lines with zero dependencies

Most "AI agent" libraries fall into one of two buckets. Either they're a big framework you spend an afternoon configuring, or they're a tiny toy that drops the one feature you actually need in production: the ability to stop and ask a human before the agent does something you can't undo. I wanted the middle. So I wrote yieldagent : a small agent loop you can read end to end, with human-in-the-loop pause/resume built in, and no runtime dependencies. This post walks through how it works and why it's built the way it is. What an agent loop actually is Strip away the branding and an "agent" is a loop: Send the conversation to the model, along with the tools it's allowed to call. If the model asks to call a tool, run it and append the result. Repeat until the model answers without asking for a tool. That's it. The model decides the control flow at runtime; your job is to run the tools and feed the results back. Here's the core, lightly trimmed: for ( let step = 0 ; step < maxSteps ; step ++ ) { const reply = await call ( messages , toolSpecs ); messages . push ( reply ); if ( ! reply . tool_calls ?. length ) { yield { type : " final " , text : reply . content , messages }; return ; } for ( const tc of reply . tool_calls ) { const args = JSON . parse ( tc . function . arguments ); const result = await tools [ tc . function . name ]. run ( args ); messages . push ({ role : " tool " , tool_call_id : tc . id , content : JSON . stringify ( result ) }); } } Everything else in the library is in service of making this loop observable, testable, and safe to run against the real world. Why an async generator Notice the yield . The loop is an async generator, so the caller drives it: for await ( const step of agent ({ call , tools , messages })) { if ( step . type === " tool-start " ) console . log ( " -> " , step . tool , step . args ); if ( step . type === " final " ) console . log ( step . text ); } Every step (each tool call, each result, and the final answer) is handed back to

2026-07-22 原文 →
AI 资讯

How AI Helped Me Discover Automation

It started with one simple question: Why am I still doing this manually? I was working on a spreadsheet, checking information row by row, sending emails, and updating statuses. The process was not difficult, but it was repetitive. One small mistake could mean sending incorrect information, overlooking a request, or forgetting to update a row. I knew there had to be an easier way. I wanted the spreadsheet to detect when a status changed to Sent , find the email address in the same row, send the correct message, and add a timestamp after the email was sent. The idea sounded simple in my head. The problem was that I did not know how to build it. I was still learning how to code, so I asked AI for help. My first prompt was something like: Create a script that sends an email from Google Sheets. AI immediately generated a script. It looked impressive, but it did not work the way I expected. The script checked the wrong column, used information from the wrong cells, and failed when some required details were missing. That was when I realized the problem was not only the code. My instructions were too vague. I tried again, but this time I described the entire process: When the status in Column G changes to "Sent," get the email address from Column E and send a confirmation email. After the email is sent successfully, add a timestamp to Column H. Do not send the email if any required information is missing. The result was much closer to what I needed. When I changed the status to Sent and received the email automatically, I felt genuinely excited. It was only a small automation, but it removed several manual steps from the process. After building that first workflow, I started noticing repetitive tasks everywhere. A form submission could automatically send a confirmation email. A spreadsheet could detect missing information before processing a request. A completed action could record the date and time. Reports could be organized without manually copying every row. Tasks that

2026-07-22 原文 →
AI 资讯

Making a WebSocket survive Chrome's Manifest V3

The bug reports all sounded the same. "It disconnected again." No error, no warning, nothing on screen to explain it. Someone would open a GitHub issue, start a planning-poker vote, then stop to actually read the thing they were estimating. Thirty seconds later they'd look back and the room had quietly gone still. Other people's votes weren't showing up, and their own weren't reaching the room. It had simply stopped, without a word. If you've ever built anything real on Chrome's Manifest V3, you can probably guess where this is going. The socket didn't drop because the network hiccupped. It dropped because Chrome reached over and killed the process it was living in. This is the story of that bug, and what it actually takes to keep a WebSocket alive inside a Manifest V3 extension. TL;DR: Manifest V3 runs your background code in a service worker that Chrome terminates after ~30s idle. If your WebSocket lives there, it dies with it, silently. The fix is three parts: a heartbeat so extension activity keeps the worker awake, auto-reconnect that pulls a fresh snapshot so drops are invisible, and a try/catch around every port message because the worker can die between your null-check and the call. Why the socket doesn't live where you'd expect First, some context on how the extension is wired, because it explains why this bug was even possible. It puts a button on GitHub issues and boards. Click it, and a live planning-poker room opens right there in the page. Votes flow over a WebSocket to a Cloudflare Durable Object that owns the room's state. Standard real-time stuff. The obvious place to open that socket is the content script, the code injected into the GitHub page. That's where the UI lives, so why not open the socket right next to it? Firefox is why not. A content script runs in the page's world, which means it inherits the page's Content Security Policy. GitHub ships a strict connect-src , and Firefox enforces it against content scripts. Try to open wss://… from the

2026-07-22 原文 →
AI 资讯

RSPack 2.0: Performance Gains, Leaner Dependencies and ESM Core

Rspack, developed by ByteDance, has released version 2.0, featuring enhanced performance, reduced dependencies, and a focus on modern ECMAScript modules. Key updates include a pure ESM core, improved static analysis, and support for RSC. Performance benchmarks show big improvements in build times. The project has experienced substantial growth, with npm downloads exceeding 5 million weekly. By Daniel Curtis

2026-07-21 原文 →
AI 资讯

🐘 TypeScript for PHP? YES, that's possible! And it's not what you think...

It is time to bring opposites together, to stir up these stagnant waters, and to restore an industry that is dynamic from within, with multiple connections that were previously impossible or unimaginable. In the previous parts of this series, we explored how PureScript acts as a quiet rewrite of the Web , offering a territory of mathematical precision above JavaScript, and how its universal polymorphism allows it to target wildly different runtimes like Node.js, Erlang's BEAM, Chez Scheme, etc. But hey, what about the elephant in the room? Yes, what is running the majority of the web, today, in the shadow? You know. The eternal one, the big one, the one whose death everyone talks about, but who never truly dies. PHP. While the modern JavaScript ecosystem (among others) races toward edge computing and containerized microservices, around 70% of the web is still powered by PHP . From legacy WordPress sites to affordable shared hosting (cPanel, OVH, GoDaddy, basic LAMP stacks), a massive portion of the internet lives in environments where escaping the PHP runtime is either financially unviable, technically impossible, or simply unnecessary. And yet... For a long time, the PHP ecosystem has been left without a true, strictly typed functional and safe alternative, like TypeScript for Javascript. Even though recent PHP versions introduced fantastic features (short closures, match expressions, Fibers), the frustration that comes with its historical limitations and dynamic typing remains very real for some of its users. Very well! This is why I built phpurs : a brand new compiler backend that transpiles PureScript directly to modern PHP 8.4+ syntax. It is no longer a proof of concept. It is passing the official PureScript test suite , and it is ready for production. Here is how we bring the elegance of purely functional programming to the big web, while keeping deployment as simple as a legacy FTP upload, or anything alike. The easy deployment paradox In modern DevOps, deplo

2026-07-21 原文 →