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

推荐订阅源

美团技术团队
V
Vulnerabilities – Threatpost
Schneier on Security
Schneier on Security
O
OpenAI News
N
News | PayPal Newsroom
Simon Willison's Weblog
Simon Willison's Weblog
P
Privacy International News Feed
T
The Exploit Database - CXSecurity.com
Martin Fowler
Martin Fowler
Recent Commits to openclaw:main
Recent Commits to openclaw:main
月光博客
月光博客
SecWiki News
SecWiki News
T
Threat Research - Cisco Blogs
S
Securelist
K
Kaspersky official blog
S
Secure Thoughts
博客园 - Franky
Project Zero
Project Zero
D
Darknet – Hacking Tools, Hacker News & Cyber Security
量子位
小众软件
小众软件
C
CERT Recently Published Vulnerability Notes
Apple Machine Learning Research
Apple Machine Learning Research
博客园 - 三生石上(FineUI控件)
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Cyberwarzone
Cyberwarzone
PCI Perspectives
PCI Perspectives
V
Visual Studio Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
Spread Privacy
Spread Privacy
Security Archives - TechRepublic
Security Archives - TechRepublic
T
Tor Project blog
IT之家
IT之家
雷峰网
雷峰网
Last Week in AI
Last Week in AI
T
Threatpost
博客园 - 【当耐特】
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Application and Cybersecurity Blog
Application and Cybersecurity Blog
C
Check Point Blog
H
Help Net Security
B
Blog RSS Feed
N
News and Events Feed by Topic
I
Intezer
Webroot Blog
Webroot Blog
G
GRAHAM CLULEY
L
LangChain Blog
Hugging Face - Blog
Hugging Face - Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
H
Heimdal 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 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