惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

美团技术团队
T
The Exploit Database - CXSecurity.com
aimingoo的专栏
aimingoo的专栏
小众软件
小众软件
T
Tailwind CSS Blog
V
V2EX
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
WordPress大学
WordPress大学
Hugging Face - Blog
Hugging Face - Blog
IT之家
IT之家
PCI Perspectives
PCI Perspectives
腾讯CDC
酷 壳 – CoolShell
酷 壳 – CoolShell
Recent Commits to openclaw:main
Recent Commits to openclaw:main
大猫的无限游戏
大猫的无限游戏
The Cloudflare Blog
N
News and Events Feed by Topic
博客园 - 三生石上(FineUI控件)
Help Net Security
Help Net Security
雷峰网
雷峰网
有赞技术团队
有赞技术团队
Last Week in AI
Last Week in AI
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
量子位
GbyAI
GbyAI
O
OpenAI News
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
AI
AI
S
Security Affairs
F
Fortinet All Blogs
L
LINUX DO - 最新话题
博客园 - 【当耐特】
Webroot Blog
Webroot Blog
Schneier on Security
Schneier on Security
W
WeLiveSecurity
Security Latest
Security Latest
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
T
Tenable Blog
L
LINUX DO - 热门话题
Google DeepMind News
Google DeepMind News
Simon Willison's Weblog
Simon Willison's Weblog
Cyberwarzone
Cyberwarzone
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
C
CERT Recently Published Vulnerability Notes
Engineering at Meta
Engineering at Meta
P
Palo Alto Networks Blog
博客园 - 叶小钗
T
Threatpost
H
Heimdal Security Blog
Microsoft Security Blog
Microsoft Security Blog

oida.dev | TypeScript, Rust

TypeScript's `erasableSyntaxOnly` Flag Unsafe for work Tokio: Macros Tokio: Channels Tokio: Getting Started Network Applications on the Tokio Stack Remake, Remodel, Reduce. The `never` type and error handling in TypeScript 5 Inconvenient Truths about TypeScript Refactoring in Rust: Introducing Traits Refactoring in Rust: Abstraction with the Newtype Pattern Announcing the TypeScript Cookbook TypeScript: Iterating over objects The road to universal JavaScript 10 years of oida.dev Rust: Tiny little traits The TypeScript converging point How not to learn TypeScript Getting started with Rust Introducing Slides and Coverage TypeScript: The humble function overload TypeScript + React: Children types are broken TypeScript: In defense of any Rust: Enums to wrap multiple errors Dissecting Deno Error handling in Rust TypeScript: Unexpected intersections Upgrading Node.js dependencies after a yarn audit TypeScript: Array.includes on narrow types TypeScript + React: Typing Generic forwardRefs shared, util, core: Schroedinger's module names Learning Rust and Go TypeScript: Narrow types in catch clauses TypeScript: Low maintenance types Tidy TypeScript: Name your generics Tidy TypeScript: Avoid traditional OOP patterns Tidy TypeScript: Prefer type aliases over interfaces Tidy TypeScript: Prefer union types over enums My new book: TypeScript in 50 Lessons Go Preact! ❤️ this in JavaScript and TypeScript TypeScript and ECMAScript Modules TypeScript + React: Why I don't use React.FC TypeScript + React: Component patterns TypeScript: Augmenting global and lib.dom.d.ts Vite with Preact and TypeScript TypeScript: Union to intersection type 11ty: Generate Twitter cards automatically Are large node module dependencies an issue? TypeScript: Variadic Tuple Types Preview TypeScript: Improving Object.keys Remake, Remodel. Part 4. TypeScript + React: Typing custom hooks with tuple types TypeScript: Assertion signatures and Object.defineProperty TypeScript: Check for object properties and narrow down type Boolean in JavaScript and TypeScript void in JavaScript and TypeScript Symbols in JavaScript and TypeScript Why I use TypeScript TypeScript + React: Extending JSX Elements TypeScript: Validate mapped types and const context TypeScript: Match the exact object shape TypeScript: The constructor interface pattern Streaming your Meetup - Part 4: Directing and Streaming with OBS Streaming your Meetup - Part 3: Speaker audio Streaming your Meetup - Part 2: Speaker video Streaming your Meetup - Part 1: Basics and Projector TypeScript and React Guide: Added a new styles chapter TypeScript and React Guide: Added a new render props chapter TypeScript and React: Styles and CSS TypeScript and React TypeScript and React Guide: Added a new prop types chapter TypeScript without TypeScript -- JSDoc superpowers TypeScript: Mapped types for type maps JAMStack vs serverless web apps The Unsung Benefits of JAMStack Sites TypeScript: Ambient modules for Webpack loaders My most favourite talks in 2018 TypeScript and React Guide: Added a new context chapter TypeScript: Built-in generic types TypeScript: Type predicates JSX is syntactic sugar TypeScript and React Guide: Added a new hooks chapter Getting your CfP application right FAQ on our Angular Connect Talk: Automating UI development TypeScript and Substitutability Debugging Node.js apps in TypeScript with Visual Studio Code From Medium: Deconfusing Pre- and Post-processing From Medium: PostCSS misconceptions Saving and scraping a website with Puppeteer Wordpress as CMS for your JAMStack sites My most favourite podcast episodes in 2017 My most favourite talks in 2017 My most favourite books in 2017 The Best Request Is No Request, Revisited Not so hidden figures - Organizing ScriptConf My podcast journey to ScriptCast Grid layout, grid layout everywhere! #scriptconf and #devone Object streams in Node.js
Cutting the mustard - 2018 edition
2018-02-13 · via oida.dev | TypeScript, Rust

The other day I was holding a workshop on performance optimisation for single page applications. For this workshop I needed an example that I could optimise step by step. I decided not to use a framework, as I didn’t know the experiences and background of my attendees. Also, I didn’t want to draw attention to framework details, rather focus on concepts that build on the platform and that are universally applicable to SPAs.

Coding modern JavaScript for quite a while (especially on Node!), I used every new language feature in my demo app: import/export, async/await, fetch, classes, arrow functions, template strings and literals. Basically everything that clashes with good old ES5 syntax-wise.

After I wrote the first couple of lines, I was naturally thinking about transpiling everything down to something all browser could understand. Then I paused for a little while and asked myself: Do I really have to?

Browsers don’t need to get there, they are here! #

So before installing Babel and Webpack or Browserify, I realised something: Just like every single browser on all my books knows how to interpret CSS Grid, every single browser on all my books has implemented a great deal of ESnext syntax features. Features that would cause syntax errors on older platforms.

I knew that from features like classes or arrow functions. But even things like async/await – which I rarely used before – are available on all major platforms. This is amazing! This is living in the future! No need to transpile, no need to have a build script. Code, deploy, run!

See the code below. This is the standard client.js file from glitch.com, but refactored to use modern JavaScript instead of jQuery and old syntax.

const $ = (sel) => document.querySelector(sel);

export async function init() {
console.log("hello world :o");
const res = await fetch("/dreams");
const dreams = await res.json();
$("#dreams").innerHTML = dreams.map((dream) => `<li>${dream}</li>`).join("");

$("form").addEventListener("submit", async (ev) => {
ev.preventDefault();
const dream = $("input").value;
const res = await fetch(`/dreams?dream=${dream}`, { method: "POST" });
if (res.ok) {
$("#dreams").innerHTML = $("#dreams").innerHTML + `<li>${dream}</li>`;
$("input").value = "";
$("input").focus();
}
});
}

Look at all the goodness we can use now:

  • async/await - write asynchronous code in a synchronous way. Syntactic sugar for your promises!
  • fetch - like XHR, but actually easy to use!
  • Arrow functions - anonymous functions, easier to write, easier to scope
  • Template strings - no more weird string concatenation
  • Modules - export and import from other JavaScript files, natively

But wait, you might say, what about the browsers that don’t support all those new features? Yeah, what about those?

Cutting the mustard - 5 years ago #

I loved it when Chris Heilmann said at ScriptConf that “it’s not okay to block old browsers, but it’s a waste of time to support them 100%”. This is wonderful call to do progressive enhancement. Create a solid foundation, enhance when features are ready. You can do this for every feature on its own. Or you can be more aggressive and make a clean cut in which browsers you support and which you don’t.

The BBC calls it cutting the mustard. Having a strict set of rules a browser has to pass to get the full experience.

if (
"querySelector" in document &&
"localStorage" in window &&
"addEventListener" in window
) {
// bootstrap the javascript application
}

If a browser does not fulfil one criteria, it won’t get any JavaScript and has to live with the plain old, but still usable, HTML only experience. The rules are a sign of the times. This article was published more than five years ago. It distinguishes between “HTML4” browsers (which had no unified API and would most likely need jQuery) and “HTML5” browsers.

I think we now face a similar distinction between ES5 browsers and modern ESnext browsers. And I think we can once again make a clean cut: Deliver a solid, but reduced experience to non ESnext browsers, get the full featured experience on modern browsers.

Cutting the mustard - now! #

The rules in the BBC article were checking for features available in the platform. This time it’s a bit different, as we most likely don’t even get to feature checks. The syntax updates are so entirely different, that some browsers might throw syntax errors before the whole script is parsed and executed.

But, there’s a way to safely activate the feature-rich enhancement on modern platforms without causing any error at all. And it’s baked right into the platform itself!

Along with all the modern syntax features comes a (not so) little but important specification: Modules. Not only modules in the sense of importing and exporting methods from other files, but also a script type that’s available in HTML:

<script type="module">
import { init } from "./client.js";
init();
</script>

At time of writing this script type is available in all modern browsers (in Firefox behind a flag) and features a wonderful behaviour for our cause: Browsers that understand this type will load the module as defined. Browsers that don’t know what to do with that will simply ignore the whole lot. Perfect!

But what about Firefox!, I hear you say. Firefox supports all the goodness I’ve shown you earlier, but modules are still behind a flag. However, as history shows, this is something that can change rather quickly. Every other browser features ES modules. And ES modules work pretty well in Firefox when the flag is activated. So the path for Firefox to feature ES modules in all upcoming releases is a good one. We just have to wait a little.

And if you just can’t wait, than you can use a proposal by Jouni: Doing feature tests for async functions.

Using it now #

We reached a point with evergreen browsers where we can define another checkpoint, a new status quo for browser features. Just as we distinguished between non-HTML5 browsers and HTML5 browsers back in the day, we can make a watershed for non-ES6 and ES6 browsers from now on. A common understanding on what’s supported and what isn’t.

After piecing all together, I decided to use this right away. All my new sites and projects will try to live without transpiling or bundling. Maybe a little Rollup to reduce the amount of files, but no extra module loading behaviour that doesn’t come from platform. And inside my scripts I can freely use all the syntax I love and know from Babel-times and Node.js.

Related Articles