博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
gulp 和npm_为什么我离开Gulp和Grunt去看npm脚本
阅读量:2520 次
发布时间:2019-05-11

本文共 17332 字,大约阅读时间需要 57 分钟。

gulp 和npm

I know what you’re thinking. WAT?! Didn’t Gulp just kill Grunt? Why can’t we just be content for a few minutes here in JavaScript land? I hear ya, but…

我知道你在想什么 WAT ?! 古尔普不是杀死了咕unt吗? 为什么我们不能只在JavaScript领域呆上几分钟呢? 我听到了,但是…

I’ve found Gulp and Grunt to be unnecessary abstractions. npm scripts are plenty powerful and often easier to live with.
我发现Gulp和Grunt是不必要的抽象。 npm脚本功能强大,通常更易于使用。

让我们从一个例子开始... (Let’s Begin With An Example…)

I was a big fan of Gulp. But on my last project, I ended up with 100’s of lines in my gulpfile and around a dozen Gulp plugins. I was struggling to integrate Webpack, Browsersync, hot reloading, Mocha and much more using Gulp. Why? Well, some plugins had insufficient documentation for my use case. Some plugins only exposed part of the API I needed. One had an odd bug where it would only watch a small number of files. Another stripped colors when outputting to the command line.

我是Gulp的忠实粉丝。 但是在我的上一个项目中,我最终在gulpfile中添加了100行代码,并使用了大约12个Gulp插件。 我正在努力使用Gulp集成Webpack,Browsersync,热重装,Mocha以及更多功能。 为什么? 好吧,有些插件没有针对我的用例的文档。 一些插件仅公开了我需要的API的一部分。 一个人有一个奇怪的错误,即它只能观看少量文件。 当输出到命令行时,另一种颜色被剥离。

These are solvable problems, but none of these issues occurred when I called the tools directly.

这些是可解决的问题,但是当我直接调用工具时,这些问题都没有发生。

Lately I’ve noticed many open-source projects are simply using npm scripts. I decided to step back and re-examine. Did I really need Gulp? It turns out I didn’t.

最近,我注意到许多开源项目都只是使用npm脚本。 我决定退后一步,重新检查。 我真的需要Gulp吗? 原来我没有。

I decided to try using just npm scripts on my new open source project. I created a rich dev environment and build process for React applications using just npm scripts. Curious what this looks like? Check out . I walk through how to create this build process using npm scripts in “” on Pluralsight.

我决定尝试在新的开源项目中仅使用npm脚本。 我仅使用npm脚本创建了一个丰富的开发环境并为React应用程序构建过程。 好奇这是什么样子? 查看 。 我将在Pluralsight上的“ ”中逐步介绍如何使用npm脚本创建此构建过程。

The surprising thing is, I now prefer working with npm scripts over Gulp. Here’s why.

令人惊讶的是,与Gulp相比,我现在更喜欢使用npm脚本。 这就是为什么。

Gulp和Grunt有什么问题? (What’s Wrong with Gulp and Grunt?)

Over time, I’ve noticed three core issues with task runners like Gulp and Grunt:

随着时间的流逝,我已经注意到任务执行者(例如Gulp和Grunt)的三个核心问题:

  1. Dependence on plugin authors

    对插件作者的依赖
  2. Frustrating debugging

    令人沮丧的调试
  3. Disjointed documentation

    脱节的文件

Let’s consider each of these issues.

让我们考虑所有这些问题。

问题1:对插件作者的依赖 (Issue 1: Dependence on Plugin Authors)

When you’re working with new or unpopular technologies, no plugin may exist at all. And when a plugin exists, it may be outdated. For example, Babel 6 was recently released. The API changed significantly, so many Gulp plugins were incompatible with the latest version. When using Gulp, I was stuck because the Gulp plugin I needed wasn’t updated yet.

当您使用新技术或不受欢迎的技术时,可能根本不存在任何插件。 并且当插件存在时,它可能已过时。 例如,Babel 6是最近发布的。 API发生了重大变化,因此许多Gulp插件与最新版本不兼容。 使用Gulp时,我陷入了困境,因为所需的Gulp插件尚未更新。

With Gulp or Grunt, you must wait for plugin maintainers to provide updates, or fix it yourself. This delays your ability to utilize new versions of modern tools. In contrast, when I use npm scripts, I consume tools directly without an extra layer of abstraction. This means when new versions of Mocha, Istanbul, Babel, Webpack, Browserify and so on are released, I’m able to utilize the new versions immediately.

使用Gulp或Grunt,您必须等待插件维护者提供更新或自行修复。 这会延迟您使用现代工具的新版本的能力。 相反, 当我使用npm脚本时,无需使用额外的抽象层即可直接使用工具 。 这意味着当发布新版本的Mocha,Istanbul,Babel,Webpack,Browserify等时,我能够立即使用这些新版本。

In terms of selection, nothing beats npm:

在选择方面,npm胜过一切:

When you use npm scripts, you don’t search for a Grunt or Gulp plugin. You choose from over 227,000 npm packages.

使用npm脚本时,无需搜索Grunt或Gulp插件。 您可以从超过227,000个npm软件包中进行选择。

To be fair, if the Grunt or Gulp plugin you need isn’t available, you can certainly utilize npm packages directly. But then you’re no longer leveraging Gulp or Grunt for that specific task.

公平地说,如果您需要的Grunt或Gulp插件不可用,您当然可以直接使用npm软件包。 但是,您不再需要利用Gulp或Grunt来完成特定任务。

问题2:令人沮丧的调试 (Issue 2: Frustrating Debugging)

As integrations fail, debugging in Grunt and Gulp can be frustrating. Since you’re working with an extra layer of abstraction, there are more potential causes for any bug:

由于集成失败,在Grunt和Gulp中进行调试可能会令人沮丧。 由于您正在使用额外的抽象层,因此,存在更多可能导致任何错误的原因:

  1. Is the base tool broken?

    基本工具是否损坏?
  2. Is the Grunt/Gulp plugin broken?

    Grunt / Gulp插件是否损坏?
  3. Is my configuration broken?

    我的配置坏了吗?
  4. Am I using incompatible versions?

    我使用的版本不兼容吗?

Using npm scripts eliminates #2. And I find #3 is far less common since I typically call the tool’s command line interface directly. Finally, #4 is less common since I’ve reduced the number of packages in my project by utilizing npm directly instead of using a task runner’s abstraction.

使用npm脚本消除了#2。 而且我发现#3不太常见,因为我通常直接调用该工具的命令行界面。 最后,#4不太常见,因为我通过直接利用npm而不是使用任务运行程序的抽象来减少项目中的软件包数量。

问题3:脱节的文档 (Issue 3: Disjointed Documentation)

The documentation for the core tools I need is nearly always better than the associated Grunt and Gulp plugins. For example, if I use gulp-eslint, I end up splitting my time between the docs and the ESLint website. I have to switch context between the plugin and the tool it is abstracting. The core piece of friction in Gulp and Grunt is this:

我所需的核心工具的文档几乎总是比相关的Grunt和Gulp插件更好。 例如,如果我使用gulp-eslint,最终我会在文档和ESLint网站之间时间。 我必须在插件和正在抽象的工具之间切换上下文。 Gulp和Grunt的核心摩擦是:

Understanding the tool isn’t enough. Gulp and Grunt require you to understand the plugin’s abstraction.

仅仅了解该工具还不够。 Gulp和Grunt要求您了解插件的抽象。

Most build-related tools offer clear, powerful, and well-documented command line interfaces. See the as a good example. I find reading and implementing a short command line call in npm scripts clearer, lower friction, and easier to debug (since there’s a layer of abstraction removed).

大多数与构建相关的工具都提供清晰,功能强大且有据可查的命令行界面。 请参阅的作为一个很好的示例。 我发现在npm脚本中阅读和实现简短的命令行调用更加清晰,摩擦更少,更易于调试(因为已删除了抽象层)。

Now that I’ve established the pain points, the question is, why do we think we need task runners like Gulp and Grunt?

现在,我已经确定了痛点,问题是,为什么我们认为我们需要像Gulp和Grunt这样的任务赛跑者?

为什么我们忽略了npm的构建? (Why Have We Ignored npm for builds?)

I believe there are four core misconceptions that led to Gulp and Grunt becoming so popular:

我相信有四个核心误解导致Gulp和Grunt如此流行:

  1. People think npm scripts require strong command line skills

    人们认为npm脚本需要强大的命令行技能
  2. People think npm scripts aren’t powerful enough

    人们认为npm脚本不够强大
  3. People think Gulp’s streams are necessary for fast builds

    人们认为Gulp的流对于快速构建是必要的
  4. People think npm scripts don’t run cross platform

    人们认为npm脚本不能跨平台运行

Let’s address these misconceptions in order.

让我们按顺序解决这些误解。

误解1 npm脚本需要强大的命令行技能 (Misconception 1: npm Scripts Require Strong Command-Line Skills)

You don’t have to know much about your operating system’s command line to enjoy the power of npm scripts. Sure, are lifelong skills worth learning, but you don’t have to be a Unix or Windows command line wizard to use npm scripts. You can leverage the 1000’s of packages in npm to get the job done instead.

您无需对操作系统的命令行了解太多,就可以享受npm脚本的强大功能。 当然, 是一生值得学习的技能,但是您不必是Unix或Windows命令行向导即可使用npm脚本 。 您可以在npm中利用1000个软件包来完成工作。

For instance, you might not know that in Unix this forcefully deletes a directory: rm -rf. That’s okay. You can use which does the same thing (and it works cross-platform to boot). Most npm packages offer interfaces that assume very little knowledge of your OS’s command line. Just search npm for packages that do what you need, read the docs, learn as you go. I used to search for Gulp plugins. Now I search for npm packages instead. A great resource: .

例如,您可能不知道在Unix中这会强制删除目录:rm -rf。 没关系。 您可以使用来做同样的事情(它可以跨平台启动)。 大多数npm软件包提供的界面假定您对操作系统的命令行了解很少。 只需在npm中搜索可以满足您需求的软件包,阅读文档,边走边学。 我曾经搜索Gulp插件。 现在,我搜索npm软件包。 很棒的资源: 。

误解2:npm脚本不够强大 (Misconception #2: npm Scripts Aren’t Powerful Enough)

npm scripts are surprisingly powerful on their own. There are convention-based :

npm脚本本身具有强大的功能。 有基于约定的 :

{  "name": "npm-scripts-example",  "version": "1.0.0",  "description": "npm scripts example",  "scripts": {    "prebuild": "echo I run before the build script",    "build": "cross-env NODE_ENV=production webpack",    "postbuild": "echo I run after the build script"  }}

All you do is follow convention. The scripts above will run in order based on their prefix. The prebuild script will run before the build script because it has the same name, but is prefixed with “pre”. The postbuild script will run after the build script because it has the prefix of “post”. So if I create scripts named prebuild, build, and postbuild, they’ll run automatically in that order when I type `npm run build`.

您要做的就是遵循惯例。 上面的脚本将根据其前缀按顺序运行。 预构建脚本将在构建脚本之前运行,因为它具有相同的名称,但前缀为“ pre”。 postbuild脚本将在构建脚本之后运行,因为它的前缀为“ post”。 因此,如果我创建名为prebuild,build和postbuild的脚本,那么当我输入`npm run build`时,它们将按照该顺序自动运行。

You can also decompose big problems by calling one script from another:

您还可以通过从另一个脚本中调用一个脚本来分解大问题:

{  "name": "npm-scripts-example",  "version": "1.0.0",  "description": "npm scripts example",  "scripts": {    "clean": "rimraf ./dist && mkdir dist",    "prebuild": "npm run clean",    "build": "cross-env NODE_ENV=production webpack"  }}

In this example the prebuild task calls the clean task. This allows you to decompose your scripts into small, well-named, single responsibility, one-liners.

在此示例中,预构建任务将调用clean任务。 这使您可以将脚本分解为名称明确的单一职责的一小部分代码。

You can call multiple scripts serially on a single line using &&. The scripts in the clean step above will run one after the other. This simplicity will really make you smile if you’re someone who has struggled with getting a list of tasks to run in order in Gulp.

您可以使用&&在一行上依次调用多个脚本。 上面干净步骤中的脚本将一个接一个地运行。 如果您一直在努力让任务列表按顺序在Gulp中运行,那么这种简单性将使您微笑。

And if a command gets too complicated, you can always call a separate file:

而且,如果命令变得太复杂,则始终可以调用一个单独的文件:

{  "name": "npm-scripts-example",  "version": "1.0.0",  "description": "npm scripts example",  "scripts": {    "build": "node build.js"  }}

I’m calling a separate script in the build task above. That script will be run by Node and thus can utilize any npm packages I need, and utilize all the power of JavaScript inside.

我在上面的构建任务中调用了一个单独的脚本。 该脚本将由Node运行,因此可以利用我需要的任何npm软件包,并利用内部JavaScript的所有功能。

I could go on, but . Also, there’s also a short . Or, check out for an example of all this in action.

我可以继续,但是 。 另外,还将有一个简短的 。 或者,查看以获取所有这些示例的示例。

误解3:快速构建需要Gulp的流 (Misconception 3: Gulp’s Streams Are Necessary for Fast Builds)

Gulp quickly gained traction over Grunt because Gulp’s in-memory streams are faster than Grunt’s file-based approach. But you don’t need Gulp to enjoy the power of streaming. In fact, streaming has always been built into both Unix and Windows command lines. The pipe (|) operator streams the output of one command to the input of another command. And the redirection (>) operator redirects output to a file.

Gulp很快就吸引了Grunt,因为Gulp的内存中流比Grunt的基于文件的方法要快。 但是您不需要Gulp来享受流媒体的力量。 实际上, 流传输始终内置在Unix和Windows命令行中 。 管道(|)运算符将一个命令的输出流式传输到另一命令的输入。 重定向(>)运算符会将输出重定向到文件。

So, for example, in Unix I can use `grep` the contents of a file and redirect the output to a new file:

因此,例如,在Unix中,我可以使用`grep`文件的内容并将输出重定向到新文件:

grep ‘Cory House’ bigFile.txt > linesThatHaveMyName.txt

The work above is streamed. No intermediate files are written. (Wondering how to do the command above in a cross-platform way? Read on…)

以上工作已流式传输。 没有写入中间文件。 (想知道如何以跨平台方式执行上面的命令吗?请继续阅读...)

You can also use the `&` operator to run two commands at the same time on Unix:

您也可以在Unix上使用`&`运算符同时运行两个命令:

npm run script1.js & npm run script2.js

The two scripts above will run in at the same time. To run scripts concurrently cross platform, use . This leads to the next misconception…

上面的两个脚本将同时运行。 要跨平台同时运行脚本,请使用 。 这导致了下一个误解……

误解4:npm脚本不能跨平台运行 (Misconception 4: npm Scripts Don’t Run Cross-platform)

Many projects are tied to a specific operating system, so cross-platform concerns don’t matter. But if you need to run cross-platform, npm scripts can still work great. Countless open source projects are proof. Here’s how.

许多项目都与特定的操作系统相关联,因此跨平台的关注无关紧要。 但是,如果您需要运行跨平台,npm脚本仍然可以很好地工作。 无数开源项目就是证明。 这是如何做。

Your operating system’s command line runs your npm scripts. So on Linux and OSX, your npm scripts run on a Unix command line. On Windows, npm scripts run on the Windows command line. Thus, if you want your build scripts to run on all platforms, you need to make both Unix and Windows happy. Here are three approaches:

操作系统的命令行运行npm脚本。 因此,在Linux和OSX上,您的npm脚本在Unix命令行上运行。 在Windows上,npm脚本在Windows命令行上运行。 因此,如果要使构建脚本在所有平台上运行,则需要使Unix和Windows都满意。 这是三种方法:

Approach 1: Use . There’s a surprising number of cross-platform commands. Here’s a few:

方法1:使用 。 跨平台命令数量惊人。 这里有一些:

&& chain tasks (Run one task after another)< input file contents to a command> redirect command output to a file| redirect command output to another command

Approach 2: Use node packages. You can use node packages instead of shell commands. For instance, use instead of `rm -rf`. Use to set environment variables in a cross-platform way. Search Google, npm or for what you want to do and there is almost certainly a node package that will get it done cross-platform. And if your command line calls get too long, you can call Node packages in separate scripts as well like this:

方法2:使用节点包。 您可以使用节点包而不是shell命令。 例如,使用而不是`rm -rf`。 使用以跨平台的方式设置环境变量。 在Google,npm或搜索您想做什么,几乎可以肯定有一个节点程序包可以跨平台完成它。 而且,如果您的命令行调用太长,则可以在单独的脚本中调用Node程序包,如下所示:

node scriptName.js

The script above is plain old JavaScript, run by Node. And since you’re just calling a script on the command line, you’re not limited to .js files. You can run any script that your OS can execute such as Bash, Python, Ruby, or Powershell as well.

上面的脚本是由Node运行的普通JavaScript。 而且,由于您只是在命令行上调用脚本,因此您不仅限于.js文件。 您也可以运行OS可以执行的任何脚本,例如Bash,Python,Ruby或Powershell。

Approach 3: Use . ShellJS is an npm package that runs Unix commands via Node. So this gives you the power to run Unix commands on all platforms, including Windows.

方法3 :使用 。 ShellJS是一个npm软件包,可通过Node运行Unix命令。 因此,这使您能够在包括Windows在内的所有平台上运行Unix命令。

I used a combination of approach #1 and #2 on .

我在上结合了方法1和方法2。

痛点 (Pain Point)

There are admittedly some downsides: The JSON spec doesn’t support comments, so you can’t add comments in package.json. There are a few ways to work around this limitation:

诚然有一些缺点:JSON规范不支持注释,因此您不能在package.json中添加注释。 有几种方法可以解决此限制:

  1. Write small, well-named, single purpose scripts

    编写小型的,名字明确的,单一目的的脚本
  2. Document scripts separately (in a README.md for instance)

    单独编写文档脚本(例如在README.md中)
  3. Call a separate .js file

    调用一个单独的.js文件

I prefer option #1. If you break each script down to have a single responsibility, comments are rarely necessary. The script’s name should fully describe the intent, just like any small well-named function. As I discuss in “”, small single responsibility functions rarely require comments. When I feel a comment is necessary, I use option #3 and move the script to a separate file. This gives me all the compositional power of JavaScript when I need it.

我更喜欢选择#1。 如果将每个脚本分解为一个职责,则很少需要注释。 脚本的名称应充分描述其意图,就像任何小的命名函数一样。 正如我在“ ”中所讨论的那样,小的单一职责功能很少需要注释。 当我觉得有必要发表评论时,我使用选项#3并将脚本移到单独的文件中。 这在需要时为我提供了JavaScript的全部组合功能。

Package.json also doesn’t support variables. This sounds like a big deal, but it’s not for two reasons. First, the most common need for variables revolves around environment, which you can set on the command line. Second, if you need variables for other reasons, you can call a separate .js file. Check out for an elegant example of this pattern.

Package.json也不支持变量。 这听起来很重要,但这并不是出于两个原因。 首先,最常见的变量需求围绕环境,您可以在命令行上进行设置。 其次,如果由于其他原因需要变量,则可以调用一个单独的.js文件。 查看以获得该模式的优雅示例。

Finally, there’s also a risk of creating long, complex command line arguments that are difficult to understand. Code reviews and diligent refactoring are a great way to assure npm scripts are decomposed into small, well-named, single purpose functions that everyone understands. If it’s complex enough to need a comment, you should likely refactor the single script into multiple well named scripts or extract it to a separate file.

最后,还有创建难以理解的长而复杂的命令行参数的风险。 代码审查和勤奋的重构是确保npm脚本被分解为每个人都可以理解的小型,有名字的,单一目的的功能的好方法。 如果复杂到需要注释的程度,您应该将单个脚本重构为多个命名良好的脚本,或者将其提取到单独的文件中。

抽象必须合理 (Abstractions Must Be Justified)

Gulp and Grunt are abstractions over the tools I use. Abstractions are useful, but abstractions have a cost. They leak. They make us dependent upon the plugin maintainers and their documentation. And they add complexity by increasing the number of dependencies. I’ve decided task runners like Gulp and Grunt are abstractions I no longer need.

Gulp和Grunt是我使用的工具的抽象。 抽象是有用的,但是抽象是有代价的。 他们泄漏。 它们使我们依赖于插件维护者及其文档。 并且它们通过增加依赖性数量而增加了复杂性。 我已经确定像Gulp和Grunt这样的任务运行者是我不再需要的抽象。

Looking for details? I walk through how to create a build process using npm scripts from scratch in “” on Pluralsight.

寻找细节? 我将在Pluralsight上的“ ”中逐步介绍如何使用npm脚本创建构建过程。

Comments? Chime in below or on or .

注释? 在或下方或上方 。

Finally, I’m far from the first person to suggest this. Here are some excellent links:

最后,我离提出这个建议的第一个人还很远。 这里有一些很好的链接:

  • — James Holliday

    — James Holliday

  • — Kate Hudson

    — Kate Hudson

  • — Kieth Cirkel

    — Kieth Cirkel

  • — Marcus Hammarberg

    — Marcus Hammarberg

  • — Gonto

    —贡托

  • — Andrew Burgess

    Burgess

Cory House is the author of “”, “” and . He is a Software Architect at VinSolutions and on software practices like front-end development and clean coding. Cory is a Microsoft MVP, Telerik Developer Expert, and founder of .

Cory House是“ ”,“ ”以及 。 他是VinSolutions的软件架构师,并就前端开发和干净编码等软件实践对 。 Cory是Microsoft MVP,Telerik开发专家和创始人。

翻译自:

gulp 和npm

转载地址:http://korwd.baihongyu.com/

你可能感兴趣的文章
Linux发送qq、网易邮件服务配置
查看>>
几道面试题
查看>>
【转】使用 WebGL 进行 3D 开发,第 1 部分: WebGL 简介
查看>>
js用正则表达式控制价格输入
查看>>
chromium浏览器开发系列第三篇:chromium源码目录结构
查看>>
java开发操作系统内核:由实模式进入保护模式之32位寻址
查看>>
第五讲:单例模式
查看>>
Python编程语言的起源
查看>>
Azure ARMTemplate模板,VM扩展命令
查看>>
(转)arguments.callee移除AS3匿名函数的侦听
查看>>
onNewIntent调用时机
查看>>
MYSQL GTID使用运维介绍(转)
查看>>
04代理,迭代器
查看>>
解决Nginx+PHP-FPM出现502(Bad Gateway)错误问题
查看>>
Java 虚拟机:互斥同步、锁优化及synchronized和volatile
查看>>
2.python的基本数据类型
查看>>
python学习笔记-day10-01-【 类的扩展: 重写父类,新式类与经典的区别】
查看>>
查看端口被占用情况
查看>>
浅谈css(块级元素、行级元素、盒子模型)
查看>>
Ubuntu菜鸟入门(五)—— 一些编程相关工具
查看>>