内容简介:为什么我放弃 Gulp 和 Grunt 而使用 npm Scripts
我知道你在想什么。 什么?!Gulp不是刚刚干掉了Grunt吗? 为什么我们不能在Javascript的地盘上消停一会儿呢?我知道,但是…
我发现Gulp和Grunt是没有必要的抽象,npm Script 已经足够强大,并且通常更好用。
让我们从一个例子开始
我原来是一个Gulp的超级粉丝。但是在我的最近一个项目中, 最终我的 gulpfile 中有几百行代码和一大堆 Gulp 插件。我曾经为了用 Gulp 整合 Webpack、Browsersync、hot reloading、Mocha等等东西而需要花费很多尽力。为什么? 好吧,有些插件的文档没覆盖到我的使用场景。有些插件只公开了部分我需要的API。有个插件有一个奇怪的bug,它能监视的文件数很小。另一个插件则在命令行中输出信息时把颜色都给去掉了。
这些都是可以解决的问题, 但是我在直接调用这些 工具 的时候,一个问题也没有出现。
后来我注意到很多开源的项目都直接使用了 npm Scripts 。我决定退一步重新评估,我真的需要Gulp吗?结果证明我不需要。
我决定在我新的开源项目上尝试使用 npm Scripts。我创建了一个富开发环境,并只用 npm Scripts 为 React 应用创建了一个进程。好奇是什么样子? 请查看 React Slingshot 。 我将在 Pluralsight (愚人码头注:一家美国软件开发在线教育网站) 的 “ 构建JavaScript开发环境 ” 中介绍如何使用 npm Scripts 来创建构建过程。
令人惊讶的是,相比Gulp,我现在更喜欢使用 npm Scripts 来 Gulp。 这是为什么。
Gulp和Grunt有什么问题?
用了一段时间后,我发现类似 Gulp 和 Grunt 的任务执行工具有三个主要的问题:
- 依赖插件作者
- 难以调试
- 脱节的文档
我们先来思考一下这些问题。
问题#1: 依赖插件作者
当你使用新技术或者不流行的技术时,可能根本没有相关的插件。即使有插件,它可能已经过时了。例如,Babel 6 最近发布了。API改变了不少,所以很多 Gulp 插件不兼容最新的版本。使用 Gulp 的时候,我经常束手无策,因为我需要的 Gulp 插件还没更新。
Gulp 和 Grunt 遇到问题你通常都要等作者提供更新,或者自己修复。这会延迟您使用新版本的现代工具。这限制了你使用很多流行工具的最近版本。相比之下, 当我使用 npm Scripts 时,我直接使用工具,而没有额外的抽象层。 这意味着,当Mocha,Istanbul,Babel,Webpack,Browserify等工具新版本发布时,我可以立即使用新版本。
在插件数量方面,跟 npm 没有相比性:
Gulp 大约有 2,100个插件。 Grunt 大约有 5,400 个。 npm提供超过227,000个包,而且每天以400+的速度增长。
当您使用 npm Scripts 时,您不需要搜索 Grunt 或 Gulp 插件。您可以选择 227,000+ 的 npm 包。
公平起见,如果你需要的 Grunt 或 Gulp 插件不可用,你可以直接使用 npm 包。但是,你不再需要利用 Gulp 或 Grunt 来完成这个特定的任务。
问题#2: 难以调试
使用 Grunt 和 Gulp 构建失败时,调试是比较麻烦的。因为你是多了一层额外的抽象层,所以引发bug的潜在原因将更多:
- 是不是基础工具出错了?
- 是不是 Grunt / Gulp 插件出错了?
- 是不是我的配置错了?
- 是不是我用了不兼容的版本?
使用 npm Scripts 不会出现问题2,并且我发现问题3也很少出现,因为我一般直接调用工具的命令行接口。最重要的是,我直接使用 npm 代替任务运行器的抽象后,我项目中包的数量减少了,因此问题4也很少出现。
问题#3:脱节的文档
我需要的核心工具的文档几乎总是比相应的 Grunt 和 Gulp 插件文档的要好。例如,如果我使用 gulp-eslint 时,我需要将时间分别花在 gulp-eslint 文档和 ESLint 网站上。 我必须在插件和它抽象的工具之间来回切换上下文。 Gulp 和 Grunt 中的核心的痛点是:
只了解工具是远远不够的。Gulp 和 Grunt 还要求你理解插件的抽象概念。
大多数构建相关的工具提供了清晰,强大和具有完善文档的命令行接口。看看 ESLint 的 CLI 文档 就是一个很好的例子。我发现在 npm Scripts 中阅读并且实现一个简短的命令行调用会更清晰,低冲突,并且更容易调试(因为没有了一层抽象).
现在我已经列出了所有痛点,问题是,为什么我们还会认为我们需要像 Gulp 和 Grunt 之类的任务执行器?
为什么我们忽略了npm的构建功能?
我认为有四个关键的误解导致 Gulp 和 Grunt 变得这么流行:
- 人们认为使用 npm Scripts 需要很高的命令行编写能力
- 人们认为 npm Scripts 不够强大
- 人们认为 Gulp 的流处理对快速构建来说是必不可少的
- 人们认为 npm Scripts 不能跨平台运行
让我们一个一个消除这些误解。
误解#1:npm Scripts 需要很高的命令行编写能力
要享受使用 npm Scripts 的力量,你不需要掌握很多有关操作系统的命令行。当然, grep,sed,awk 和 pipe 是值得学习终身受用的技能,但要使用 npm Scripts 你也不用成为 Unix 或者 Windows 命令行大师。你也可以使用 npm 中的数千个包来完成工作。
例如,你可能不知道在 Unix 中强制删除的命令行是:rm -rf。不过没关系。 你可以使用 rimraf 来完成相同的工作(并且它可以跨平台使用)。大多数 npm 包是在假设你对操作系统命令行知识知之甚少的前提下提供接口。当你要用某个功能的时候,只需要在 npm 上搜索你需要的包,阅读文档,学习即可。我之前都是搜索Gulp插件,现在我搜索 npm 包。顺便提供一个不错的资源: libraries.io
误解#2: npm Scripts 不够强大
npm Scripts 其实是很强大的。这些是常规的 pre和post钩子 :
{
"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"
}
}
你所需要做的就是遵循约定。上面的脚本会根据前缀按顺序执行。prebuild 脚本会在 build 脚本之前执行,它对比 build 脚本有前缀 ”pre”,而 post 脚本会在 build 脚本后面执行因为有前缀 ”post” 。所以如果我创建了 Scripts : prebuild , build 和 postbuild ,当我输入 npm run build 时,它们将会自动按顺序执行。
你也可以通过调用另一个脚本,把一个大任务拆分:
{
"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"
}
}
上面的例子中, prebuild 任务调用了 clean 任务。这允许你把你的脚本拆分成更小、命名更恰当、单一职责、一行内完成。
你可以使用 && 操作符将多个 Scripts 串联成一行。 在上述的 clean 步骤将会顺序执行各个 Scripts 。如果你曾经为了让任务列表能在 Gulp 中按顺序执行而苦苦挣扎过,那么这种简洁真的会让你笑出声来。
并且如果一个命令实在太复杂了,你也可以调用其他的文件:
{
"name": "npm-scripts-example",
"version": "1.0.0",
"description": "npm scripts example",
"scripts": {
"build": "node build.js"
}
}
上面的例子中,我在 build 任务中调用了一个独立的脚本。这个脚本将会通过Node执行, 而且因此我可以应用任何我需要的 npm 包, 并且应用所有 JavaScript 中的功能。
我就不继续说了, 主要的特性都在这里 。还有,这里还有 一个 npm 作为构建工具的简短介绍 , 或者查看 React Slingshot 项目并将其当作所有这些行为的一个例子。
误解#3: Gulp 的流处理对快速构建来说是必不可少的
Gulp可以从Grunt上快速取得市场主导权,一个原因就是 Gulp 基于内存操作的stream操作要比Grunt的文件操作要快。但是但其实要使用stream的力量你完全可以不用 Gulp。 事实上,流功能早就已经内置到了 Unix 和 Windows 的命令行中。 管道( | )操作符可以将一个命令以流的形式输出作为另一个命令的输入。 而重定向( > )操作符可以将定向输出到一个文件中。
所以, 举个例子, 在Unix中我可以使用 grep 读取一个文件的内容,并将其输出输出到一个新文件中:
grep 'Cory House' bigFile.txt > linesThatHaveMyName.txt
上面所做的就是流,没有中间的文件被写。(想知道上面的命令怎么跨平台使用吗?那继续读下去…)
你同样可以使用’&’操作符在Unix上同时执行两个命令:
npm run script1.js & npm run script2.js
上面两个脚本将同时执行,想要跨平台的同时执行脚本,使用 npm-run-all 。这引出了我们的下一个误解…
误解#4: npm Scripts 不能跨平台运行
很多项目都是在特定的操作系统使用,所以没有跨平台的忧虑。但如果你需要跨平台运行,npm Scripts 也能够很好的工作。无数的开源项目就是证明。接下来就是怎么做了。
你的操作系统命令行执行 npm Scripts ,所以在 Linux 和OSX,你的 npm Scripts 通过Unix命令行执行。而在 Windows 上,npm Scripts 通过 Windows 命令行执行。因此,如果你要你的构建脚本可以在所有平台上执行,你需要同时让Unix和Windows开心。 这里有3个方法:
方法1:使用 跨平台的命令 。很幸运的是竟然有如此多的跨平台命令,以下是其中一小部分:
- `&&` 串联任务 (运行一个任务后,再运行另一个任务)
- `<` 输入文件内容到命令
- `>` 重定向命令输出到一个文件
- `|` 重定向命令输出到另一个命令
方法2:使用 node packages 。你可以使用 node packages 来取代 shell 命令。例如,使用 rimraf 取代 rm -rf 。使用 cross-env 来跨平台地设置环境变量。在 Google , npm 或者 lirbraries.io 上搜索你所需要的 node package ,一般都能找到一个可以跨平台的。另外,如果你的命令行调用过长,你可以调用单独脚本中的 node packages,类似这样:
node scriptName.js
上面脚本是一个普通的老的 javascript 文件,通过 Node 执行。 如果你仅仅是想用命令行调用一个脚本,你可以不使用 .js 文件。你可以运行任何你的操作系统能执行的脚本, 例如 Bash 、 Python 、 Ruby 或 Powershell 等等。
方法3:使用 ShellJS 。ShellJS是一个通过 Node 执行 Unix 命令行的 npm package。所以这可以让你在任何平台上面执行 Unix 命令,包括 Windows。
我在 React Slingshot 项目中使用了方法1和方法2。
痛点
不可否认地是, npm Scripts 也存在一些缺点:因为 JSON 规范不支持添加注释,所以你不能在 package.json 里添加注释。有几个方法可以用来处理这个限制:
- 简短、命名良好、目的单一的 Scripts
- 单独为 Scripts 提供文档(例如写在一个 `README.md` 文件中)
- 调用单独的`.js`文件
我更倾向于第1种方法。如果你将每个脚本都分解成只有单一职责, 将很少再需要注释。 脚本的名字可以完全描述其意图,就好像所有简短且命名良好的函数一样。 就像我在《 简洁代码:编写人能看懂的代码 》中的讨论一样,短小且单一职责的函数很少需要注释。当我觉得注释是必要的时,我使用方法3,并将脚本移到单独的文件中。这让我在需要时可以使用javascript的所有能力。
package.json 也不支持变量。这听起来像是一个大问题,但由于以下两个原因,它不再是问题。 首先,最通常的需要变量的情况是要解决环境问题,但这你可以在命令行中设置。其次,如果你因为其他原因需要用到变量,你完全可以调用一个单独的js文件。 在React-starter-kit项目中你可以找到该做法的一个优雅的例子。
总之,仍然会有可能创建让人很难看懂的又长又臭的命令行参数。而确保 npm Scripts 分离成简洁、单一职责并且命名规范容易理解的小功能,代码审查和不断的重构是一个不错的方法。而如果 Scripts 复杂到真的需要注释,你应该把单一的脚本分离成多个命名规范的脚本,或者抽离到分离的文件。
抽象要恰当
Gulp 和 Grunt 都是我使用过的抽象工具。抽象是有用的,但是也有代价。它们让我们依赖于插件的维护者和文档,并且越来越多的依赖使他们更复杂。我已经觉得我不再需要 Gulp 和 Grunt 这样的任务执行器了。
想要更多细节?在 Pluralsight 网站上 “ 构建JavaScript开发环境 ”中从头开始学习如何使用npm脚本创建构建过程。
评论? 可以在文章底部、 Reddit 或 Hacker News 上进行评论。
最后, 我离第一个建议这么做的人已经很遥远。 下面是一些非常棒的链接:
- 用npm run完成任务自动化 — James Holliday
- 使用npm脚本实现进阶前端自动化 — Kate Hudson
- 如何将npm用成一个构建工具 — Kieth Cirkel
- npm作为构建工具介绍 — Marcus Hammarberg
- Gulp非常棒,但是我们真的需要它吗? — Gonto
- NPM脚本之于构建工具 — Andrew Burgess
原文地址:https://medium.freecodecamp.com/why-i-left-gulp-and-grunt-for-npm-scripts-3d6853dd22b8#.an2bjgxt8
以上所述就是小编给大家介绍的《为什么我放弃 Gulp 和 Grunt 而使用 npm Scripts》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 我承认,要放弃使用Lombok了!
- 和 Pipelining 说再见,cURL 放弃使用管道技术
- Elasticsearch 从入门到放弃:索引基本使用方法
- 为什么我放弃 Gulp 和 Grunt 而使用 npm Scripts
- GO 从入门开始放弃
- Elixir 从入门到放弃
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
The Book of CSS3
Peter Gasston / No Starch Press / 2011-5-13 / USD 34.95
CSS3 is the technology behind most of the eye-catching visuals on the Web today, but the official documentation can be dry and hard to follow. Luckily, The Book of CSS3 distills the heady technical la......一起来看看 《The Book of CSS3》 这本书的介绍吧!
XML 在线格式化
在线 XML 格式化压缩工具
RGB CMYK 转换工具
RGB CMYK 互转工具