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

推荐订阅源

K
Kaspersky official blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
V
Visual Studio Blog
F
Full Disclosure
B
Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
L
Lohrmann on Cybersecurity
月光博客
月光博客
I
Intezer
博客园 - 三生石上(FineUI控件)
Hacker News - Newest:
Hacker News - Newest: "LLM"
D
Darknet – Hacking Tools, Hacker News & Cyber Security
博客园_首页
P
Proofpoint News Feed
C
Check Point Blog
N
News | PayPal Newsroom
H
Heimdal Security Blog
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
G
GRAHAM CLULEY
WordPress大学
WordPress大学
C
CERT Recently Published Vulnerability Notes
Y
Y Combinator Blog
Recorded Future
Recorded Future
Application and Cybersecurity Blog
Application and Cybersecurity Blog
T
Tailwind CSS Blog
W
WeLiveSecurity
L
LINUX DO - 热门话题
Microsoft Azure Blog
Microsoft Azure Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Schneier on Security
Schneier on Security
爱范儿
爱范儿
Martin Fowler
Martin Fowler
U
Unit 42
T
Troy Hunt's Blog
S
Securelist
V
V2EX
V2EX - 技术
V2EX - 技术
MongoDB | Blog
MongoDB | Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
博客园 - 聂微东
人人都是产品经理
人人都是产品经理
M
MIT News - Artificial intelligence
T
Tor Project blog
Cisco Talos Blog
Cisco Talos Blog
罗磊的独立博客
小众软件
小众软件
阮一峰的网络日志
阮一峰的网络日志
Vercel News
Vercel News

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 Cutting the mustard - 2018 edition 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
Gulp 4: The new task execution system - gulp.parallel and gulp.series
2015-09-29 · via oida.dev | TypeScript, Rust

One of the major changes in Gulp 4 is the new task execution system. In this article, I want to show you what’s new and how you can migrate the best.

Task execution chains in Gulp 3 #

Before we take a look at the new, let’s see what was there previously. Usually, Gulp would allow defining a dependency to a task. It would make sure that this dependency task gets executed before the original task gets triggered. Look at this code:

// Per default, start scripts and styles
gulp.task('default', ['scripts', 'styles'], function() {...});

// Both scripts and styles call clean
gulp.task('styles', ['clean'], function() {...});
gulp.task('scripts', ['clean'], function() {...});

// Clean wipes out the build directory
gulp.task('clean', function() {...});

A very basic Gulpfile. You want to build scripts and styles, but before you do so, clean the original build directory so you can start at a blank slate. The syntax is very elegant and similar to those of other build tools.

When Gulp’s started, it creates a dependency tree like the one below.

How Gulp 3 orders tasks

So it realizes that clean is a dependency of two tasks. In this way, it makes sure that it is executed only once.

One thing to keep in mind there: All those tasks are executed for maximum concurrency. So the execution order is something like shown in the next figure.

Gulp 3 dependency check and execution order

First clean, then scripts and styles in parallel, and after that we can execute the default task function.

There are however several problems with it:

  • Once you define the dependency chain in that way, the execution of this dependency is mandatory.
  • This is a particular problem if you want to have watchers that listen on one type only. Imagine triggering the styles task every time you change one of your CSS files. It would execute first clean, and then styles, practically deleting your efforts from “script”.
  • Also, there is currently no way of executing tasks sequentially. The “first clean, then task” style of executing can be done just with dependencies, leading to the problems above.

One Gulp plugin that tried to bridge the gap here was run-sequence. It’s functionality is now part of Gulp 4 with the addition of the new task manager “Undertaker”.

Task execution functions for Gulp 4 #

Gulp 4 drops the dependency parameter completely and replaces them with execution functions that can be used instead:

  • gulp.series for sequential execution
  • gulp.parallel for parallel execution.

Each of those functions allow for parameters of the following kind:

  • The name of the task to execute
  • Another function to execute

So if you want to execute styles and scripts in parallel, you can write something like this:

gulp.task('default', gulp.parallel('scripts', 'styles'));

The cool thing is, gulp.parallel and gulp.series are functions, and accept functions. So you can nest them as much as you want, creating complex execution orders:

Parallel and series nested

The execution of the graph above is: A, then B, then C and D parallel, then E.

Migration #

Since we aim for the maximum currency, one would think to replace all dependency arrays with gulp.parallel functions, like that:

gulp.task('styles', gulp.parallel('clean', function() {...}));
gulp.task('scripts', gulp.parallel('clean', function() {...}));

gulp.task('clean', function() {...});

gulp.task('default', gulp.parallel('scripts', 'styles'));

The first problem with this approach is that clean always gets executed with the actual task that creates the output. In a concurrent world, this can mean that we immediately delete the files we created. We don’t want that. So let’s exchange the tasks that are meant to be executed after another with gulp.series.

gulp.task('styles', gulp.series('clean', function() {...}));
gulp.task('scripts', gulp.series('clean', function() {...}));

gulp.task('clean', function() {...});

gulp.task('default', gulp.parallel('scripts', 'styles'));

Better. However, there are still problems. First of all, the dependency is still hard-wired: “Clean” gets called every time we call scripts or styles.

Second, Gulp 4 does not have any dependency check (because they aren’t dependencies) anymore, so our execution tree looks something like that:

The problem replacing the arrays with gulp.parallel

“Clean” gets executed twice. This is fatal, because it might actually be that results from one task would be deleted by the next execution tree.

To make a good and robust migration, without hard wires and by keeping the original execution order, do the following. Look at the original execution order:

Gulp 3 dependency check and execution order

The execution order of the tasks in the original tree are: clean, styles and scripts in parallel, and then the default task.

Each step that can be done in concurrent will be combined in a gulp.parallel function. The others are ordered in a gulp.series function. Like that:

Our original execution chain restructured

The accompanying source code:

// The tasks don't have any dependencies anymore
gulp.task('styles', function() {...});
gulp.task('scripts', function() {...});

gulp.task('clean', function() {...});

// Per default, start scripts and styles
gulp.task('default',
gulp.series('clean', gulp.parallel('scripts', 'styles'),
function() {...}));

The execution order at default stays the same as previously, but all the other tasks can be used on their own, without being bound on dependencies.

Hurray for flexibility!

Related Articles