我正在尝试总结我对最流行的JavaScript包管理器,捆绑包和任务运行器的了解。如果我错了,请纠正我:
npm
& bower
是包管理员。他们只是下载依赖项,不知道如何自己构建项目。他们知道的是在获取所有依赖项后调用webpack
/ gulp
/ grunt
。bower
与npm
类似,但构建了扁平的依赖树(与递归执行的npm
不同)。含义npm
获取每个依赖项的依赖项(可能会获取相同的几次),而bower
期望您手动包含子依赖项。有时bower
和npm
分别用于前端和后端(因为每个兆字节在前端可能很重要)。grunt
和gulp
是任务运行器,可以自动执行可自动化的所有内容(即编译CSS / Sass,优化图像,制作捆绑并缩小/转换它)。grunt
与gulp
的对比(与maven
与gradle
或配置与代码相似)。 Grunt基于配置单独的独立任务,每个任务打开/处理/关闭文件。 Gulp需要的代码量较少,并且基于节点流,这使得它可以构建管道链(无需重新打开同一个文件)并使其更快。 webpack
(webpack-dev-server
) - 对我来说,这是一个热门重新加载更改的任务运行器,可以让你忘记所有JS / CSS观察者。 npm
/ bower
+插件可以替换任务运行器。他们的能力经常交叉,所以如果你需要使用gulp
/ grunt
而不是npm
+插件,会有不同的含义。但是任务运行者肯定更适合复杂的任务(例如“在每个构建创建捆绑包上,从ES6转换到ES5,在所有浏览器模拟器上运行它,制作屏幕截图并通过ftp部署到dropbox”)。browserify
允许为浏览器打包节点模块。 browserify
vs node
的{{1}}实际上是AMD vs CommonJS。问题:
require
& webpack
?官方文档说它是一个模块捆绑器但对我来说它只是一个任务运行器。 有什么区别? webpack-dev-server
?我们不能对node / ES6导入做同样的事情吗? browserify
/ gulp
而不是grunt
+插件? 答案 0 :(得分:931)
Webpack和Browserify几乎完成相同的工作,处理您的代码以在目标环境中使用(主要是浏览器,但您可以定位其他环境,如Node)。此类处理的结果是一个或多个捆绑 - 适合目标环境的汇编脚本。
例如,我们假设您编写了一个分为模块的ES6代码,并希望能够在浏览器中运行它。如果这些模块是节点模块,浏览器不会理解它们,因为它们仅存在于节点环境中。 ES6模块也无法在IE11等旧版浏览器中运行。此外,您可能已经使用了浏览器尚未实现的实验语言功能(ES下一个提议),因此运行此类脚本只会引发错误。像Webpack和Browserify这样的工具通过将这些代码转换为表单浏览器能够执行来解决这些问题。最重要的是,它们可以对这些捆绑包应用各种各样的优化。
然而,Webpack和Browserify在许多方面有所不同,默认情况下Webpack提供了许多工具(例如代码拆分),而Browserify只能在下载插件后执行此操作,但使用两者导致非常相似的结果。归结为个人偏好(Webpack更具时尚性)。顺便说一句,Webpack不是一个任务运行器,它只是文件的处理器(它通过所谓的加载器和插件处理它们),它可以由任务运行器运行(以及其他方式)。
Webpack Dev Server为Browsersync提供了类似的解决方案 - 一个开发服务器,您可以在其中快速部署应用程序,并立即通过开发服务器在代码更改时自动刷新浏览器甚至传播更改来验证您的开发进度代码到浏览器而无需重新加载所谓的热模块替换。
我一直在使用Gulp的简洁和简单的任务写作,但后来发现我根本不需要Gulp和Grunt。我所需要的一切都可以使用NPM脚本通过其API运行第三方工具。 在Gulp,Grunt或NPM脚本之间进行选择取决于团队的品味和经验。
虽然Gulp或Grunt中的任务很容易阅读,即使对于不太熟悉JS的人来说,它也是另一种需要和学习的工具,我个人更喜欢缩小我的依赖关系并使事情变得简单。另一方面,使用NPM脚本和运行第三方工具(例如,节点脚本配置和运行rimraf以进行清理)的(可更新的JS)脚本的组合替换这些任务可能更具挑战性。但在大多数情况下,这三者在结果方面是相同的。
至于这些例子,我建议你看看这个React starter project,它向你展示了NPM和JS脚本的完美组合,涵盖了整个构建和部署过程。您可以在根文件夹的package.json中的名为scripts
的属性中找到这些NPM脚本。那里你将遇到像babel-node tools/run start
这样的命令。 Babel-node是一个CLI工具(不适合生产使用),它首先编译ES6文件tools/run
(位于tools中的run.js文件) - 基本上是一个运行程序实用程序。此运行器将函数作为参数并执行它,在本例中为start
- 另一个实用程序(start.js)负责捆绑源文件(客户端和服务器)并启动应用程序和开发服务器( dev服务器可能是Webpack Dev Server或Browsersync)。
更准确地说,start.js创建客户端和服务器端捆绑包,启动快速服务器并在成功启动后进入浏览器同步,这在撰写时看起来像这样(请参阅react starter project了解最新代码)。
const bs = Browsersync.create();
bs.init({
...(DEBUG ? {} : { notify: false, ui: false }),
proxy: {
target: host,
middleware: [wpMiddleware, ...hotMiddlewares],
},
// no need to watch '*.js' here, webpack will take care of it for us,
// including full page reloads if HMR won't work
files: ['build/content/**/*.*'],
}, resolve)
重要的部分是proxy.target
,他们设置了他们想要代理的服务器地址,可能是http://localhost:3000,而浏览器同步启动服务器监听http://localhost:3001,其中生成的资产是配备自动更换检测和热模块更换。正如您所看到的,还有另一个配置属性files
具有单独的文件或模式浏览器同步监视更改并重新加载浏览器(如果有的话),但正如评论所说,Webpack负责自己观察js源HMR,所以他们在那里合作。
现在我没有任何Grunt或Gulp配置的等效示例,但是使用Gulp(和Grunt有些相似),您可以在gulpfile.js中编写单独的任务,如
gulp.task('bundle', function() {
// bundling source files with some gulp plugins like gulp-webpack maybe
});
gulp.task('start', function() {
// starting server and stuff
});
你在做什么基本上与入门套件中的相同,这次是使用任务运行器,它为你解决了一些问题,但在学习使用过程中出现了自己的问题和一些困难,而且比如说,你拥有的依赖性越多,就越可能出错。这就是我想摆脱这些工具的原因。
答案 1 :(得分:629)
2018年10月更新
如果你仍然不确定前端开发,可以在这里快速浏览一下优秀的资源。
https://github.com/kamranahmedse/developer-roadmap
2018年6月更新
如果你从一开始就不去那里学习现代JavaScript很难。如果您是新来者,请记得查看这篇优秀的文章,以便更好地了解。
https://medium.com/the-node-js-collection/modern-javascript-explained-for-dinosaurs-f695e9747b70
2017年7月更新
最近,我发现了一个非常全面的Grab团队指南,介绍如何在2017年进行前端开发。您可以在下面查看。
https://github.com/grab/front-end-guide
我已经搜索了很长一段时间,因为那里有很多工具,每个工具都有不同的方面让我们受益。社区分为Browserify, Webpack, jspm, Grunt and Gulp
等工具。您可能还听说过Yeoman or Slush
。这不是一个真正的问题,对于每个试图理解明确前进道路的人来说,这只会令人困惑。
无论如何,我想贡献一些东西。
<强> 1。包管理器
软件包管理器简化了项目依赖项的安装和更新,这些项目依赖项是以下库:jQuery, Bootstrap
等 - 您网站上使用的所有内容,并且不是由您编写的。
浏览所有图书馆网站,下载和解压缩档案,将文件复制到项目中 - 所有这些都将被终端中的一些命令所取代。
NPM
代表:Node JS package manager
可帮助您管理软件所依赖的所有库。您可以在名为package.json
的文件中定义您的需求,并在命令行中运行npm install
...然后BANG,您的软件包已下载并可供使用。可以同时用于front-end and back-end
库。
Bower
:对于前端包管理,概念与NPM相同。所有库都存储在名为bower.json
的文件中,然后在命令行中运行bower install
。
Bower
和NPM
之间的最大区别是NPM嵌套了 依赖树,而Bower需要一个平面依赖树,如下所示。
<强> NPM 强>
project root
[node_modules] // default directory for dependencies
-> dependency A
-> dependency B
[node_modules]
-> dependency A
-> dependency C
[node_modules]
-> dependency B
[node_modules]
-> dependency A
-> dependency D
<强> Bower 强>
project root
[bower_components] // default directory for dependencies
-> dependency A
-> dependency B // needs A
-> dependency C // needs B and D
-> dependency D
npm 3 Duplication and Deduplication
上有一些更新, 请打开文档了解更多详情。
Yarn
:最近由JavaScript
Facebook
published的新包管理员与NPM
相比具有更多优势。使用Yarn,您仍然可以使用NPM
和Bower
注册表来获取包。如果您之前已安装过软件包,yarn
会创建一个便于offline package installs
的缓存副本。
jspm
:是SystemJS
通用模块加载器的包管理器,构建于动态ES6
模块加载器之上。它不是一个全新的包管理器,它有自己的一套规则,而是在现有的包源之上工作。开箱即用,适用于GitHub
和npm
。由于大多数基于Bower
的软件包都基于GitHub
,因此我们也可以使用jspm
安装这些软件包。它有一个注册表,列出了大多数常用的前端软件包,以便于安装。
查看
Bower
和jspm
之间的差异: Package Manager: Bower vs jspm
<强> 2。模块加载器/捆绑
任何规模的大多数项目都会将代码拆分为多个文件。您可以只使用单个<script>
标记包含每个文件,但是,<script>
建立新的http连接,对于小文件 - 这是模块化的目标 - 建立连接的时间可以采用比传输数据要长得多。在下载脚本时,页面上不能更改任何内容。
E.g
<head>
<title>Wagon</title>
<script src=“build/wagon-bundle.js”></script>
</head>
E.g
<head>
<title>Skateboard</title>
<script src=“connectors/axle.js”></script>
<script src=“frames/board.js”></script>
<!-- skateboard-wheel and ball-bearing both depend on abstract-rolling-thing -->
<script src=“rolling-things/abstract-rolling-thing.js”></script>
<script src=“rolling-things/wheels/skateboard-wheel.js”></script>
<!-- but if skateboard-wheel also depends on ball-bearing -->
<!-- then having this script tag here could cause a problem -->
<script src=“rolling-things/ball-bearing.js”></script>
<!-- connect wheels to axle and axle to frame -->
<script src=“vehicles/skateboard/our-sk8bd-init.js”></script>
</head>
计算机可以做得更好,这就是为什么你应该使用工具自动将所有内容捆绑到一个文件中。
然后我们听说RequireJS
,Browserify
,Webpack
和SystemJS
RequireJS
:是JavaScript
文件和模块加载器。它针对浏览器内使用进行了优化,但可以在其他JavaScript环境中使用,例如Node
。例如: myModule.js
// package/lib is a dependency we require
define(["package/lib"], function (lib) {
// behavior for our module
function foo() {
lib.log( "hello world!" );
}
// export (expose) foo to other modules as foobar
return {
foobar: foo
}
});
在main.js
中,我们可以将myModule.js
作为依赖项导入并使用它。
require(["package/myModule"], function(myModule) {
myModule.foobar();
});
然后在我们的HTML
中,我们可以参考使用RequireJS
。
<script src=“app/require.js” data-main=“main.js” ></script>
详细了解
CommonJS
和AMD
以便轻松理解。 Relation between CommonJS, AMD and RequireJS?
Browserify
:开始允许在浏览器中使用CommonJS
格式化的模块。因此,Browserify
不像模块捆绑器那样是模块加载器:Browserify
完全是一个构建时工具,产生一组代码,然后可以在客户端加载。从具有节点&amp ;;的构建机器开始。 npm安装,并获得包:
npm install -g –save-dev browserify
以CommonJS
格式
//entry-point.js
var foo = require('../foo.js');
console.log(foo(4));
快乐时,发出捆绑命令:
browserify entry-point.js -o bundle-name.js
Browserify以递归方式查找入口点的所有依赖项,并将它们组合到一个文件中:
<script src=”bundle-name.js”></script>
Webpack
:它将您的所有静态资源(包括JavaScript
,图片,CSS等)捆绑到一个文件中。它还使您能够通过不同类型的加载器处理文件。您可以使用JavaScript
或CommonJS
模块语法编写AMD
。它以一种从根本上更加综合和自以为是的方式攻击构建问题。在Browserify
中,您使用Gulp/Grunt
以及一长串变换和插件来完成工作。 Webpack
提供了足够的功能,您通常不需要Grunt
或Gulp
。基本用法不仅仅是简单的。像Browserify一样安装Webpack:
npm install -g –save-dev webpack
并将命令传递给入口点和输出文件:
webpack ./entry-point.js bundle-name.js
SystemJS
:是一个模块加载器,可以在运行时以今天使用的任何流行格式导入模块(CommonJS, UMD, AMD, ES6
)。它建立在ES6
模块加载器polyfill之上,并且足够智能以检测正在使用的格式并适当地处理它。 SystemJS
还可以使用插件来转换ES6代码(使用Babel
或Traceur
)或其他语言,例如TypeScript
和CoffeeScript
。 想知道
node module
是什么以及为什么它不适应浏览器。更有用的文章:
为什么
jspm
和SystemJS
?
ES6
模块化的主要目标之一是让它变得非常简单 从任何地方安装和使用任何Javascript库 互联网(Github
,npm
等)。只需要两件事:
- 安装库的单个命令
- 导入库并使用它的一行代码
因此,使用
jspm
,您可以执行此操作。
- 使用以下命令安装库:
jspm install jquery
- 使用一行代码导入库,无需在HTML文件内部进行外部引用。
醇><强> display.js 强>
var $ = require('jquery'); $('body').append("I've imported jQuery!");
然后您在
System.config({ ... })
之前配置这些内容 导入您的模块。通常在运行jspm init
时,会有一个文件 为此目的命名为config.js
。- 醇>
要运行这些脚本,我们需要在HTML页面上加载
system.js
和config.js
。之后我们将使用加载display.js
文件SystemJS
模块加载器。<强>的index.html 强>
<script src="jspm_packages/system.js"></script> <script src="config.js"></script> <script> System.import("scripts/display.js"); </script>
注意:您也可以将
npm
与Webpack
一起使用,因为Angular 2已应用它。由于jspm
是为了与SystemJS
集成而开发的,因此它可以在现有npm
来源之上运行,因此您的答案由您决定。
第3。任务运行员
任务运行器和构建工具主要是命令行工具。我们为什么需要使用它们:总之:自动化。在执行重复性任务(例如缩小,编译,单元测试,linting )时,您需要做的工作越少,以前需要花费很多时间才能完成命令行甚至手动操作。
Grunt
:您可以为开发环境创建自动化,以预处理代码或使用配置文件创建构建脚本,并且处理复杂任务似乎非常困难。在过去几年流行。 Grunt
中的每个任务都是一组不同的插件配置,只需一个接一个地以严格独立的顺序方式执行。
grunt.initConfig({
clean: {
src: ['build/app.js', 'build/vendor.js']
},
copy: {
files: [{
src: 'build/app.js',
dest: 'build/dist/app.js'
}]
}
concat: {
'build/app.js': ['build/vendors.js', 'build/app.js']
}
// ... other task configurations ...
});
grunt.registerTask('build', ['clean', 'bower', 'browserify', 'concat', 'copy']);
Gulp
:自动化就像Grunt
一样,但您可以使用类似于节点应用程序的流来编写JavaScript
而不是配置。喜欢这些日子。这是Gulp
样本任务声明。
//import the necessary gulp plugins
var gulp = require('gulp');
var sass = require('gulp-sass');
var minifyCss = require('gulp-minify-css');
var rename = require('gulp-rename');
//declare the task
gulp.task('sass', function(done) {
gulp.src('./scss/ionic.app.scss')
.pipe(sass())
.pipe(gulp.dest('./www/css/'))
.pipe(minifyCss({
keepSpecialComments: 0
}))
.pipe(rename({ extname: '.min.css' }))
.pipe(gulp.dest('./www/css/'))
.on('end', done);
});
查看更多:https://medium.com/@preslavrachev/gulp-vs-grunt-why-one-why-the-other-f5d3b398edc4#.fte0nahri
<强> 4。脚手架工具
Slush and Yeoman
:您可以使用它们创建启动项目。例如,您计划使用HTML和SCSS构建原型,然后手动创建一些文件夹,如scss,css,img,fonts。您只需安装yeoman
并运行一个简单的脚本即可。那么一切都在这里给你。 查找更多here。
npm install -g yo
npm install --global generator-h5bp
yo h5bp
我的回答与问题的内容并不完全匹配,但当我在Google上搜索这些知识时,我总是在顶部看到这个问题,以便我决定总结回答。希望你们发现它有用。
答案 2 :(得分:52)
好的,他们都有一些相似之处,他们以不同和相似的方式为你做同样的事情,我把它们分成 3个主要群体,如下所示:
<小时/> 1)模块捆绑商
webpack和browserify作为流行的,像任务运行器一样工作但具有更大的灵活性,因为它会将所有内容捆绑在一起作为您的设置,因此您可以将结果指向bundle.js,例如在包含CSS和CSS的单个文件中Javascript,有关每个的更多详细信息,请查看以下详细信息:
<强>的WebPack 强>
webpack是现代JavaScript应用程序的模块捆绑器。什么时候 webpack处理您的应用程序,它递归地构建一个依赖项 包含应用程序所需的每个模块的图表,然后是包 将所有这些模块分成少量捆绑 - 通常只有一个 - 由浏览器加载。
这是令人难以置信的可配置,但要开始你只需要 了解四个核心概念:入口,输出,加载器和插件。
本文档旨在对这些内容进行高级概述 概念,同时提供特定详细概念的链接 用例。
更多here
<强> browserify 强>
Browserify是一个开发工具,允许我们编写node.js样式 编译用于浏览器的模块。就像节点一样,我们写 我们的模块在单独的文件中,导出外部方法和 使用module.exports和exports变量的属性。我们甚至可以 要求使用require函数的其他模块,如果我们省略了 它将解析为node_modules中的模块的相对路径 。目录
更多here
2)任务选手
gulp和grunt是任务运行者,基本上是他们所做的,创建任务并随时运行它们,例如你安装一个插件来缩小你的CSS,然后每次运行它来进行缩小,更多关于每个的详细信息: / p><强>吞强>
gulp.js是Fractal Innovations开源的JavaScript工具包 和GitHub上的开源社区,用作流式构建 前端Web开发中的系统。它是一个基于任务的跑步者 Node.js和节点包管理器(npm),用于自动化 Web开发中涉及的耗时且重复的任务 缩小,连接,缓存破坏,单元测试,linting, 优化等gulp使用代码配置方法 定义它的任务并依赖于它的小型,单一用途的插件 把它们拿出来。 gulp生态系统有1000多个这样的插件可供使用 可供选择。
更多here
<强>咕噜强>
Grunt是一个JavaScript任务运行器,一个用于自动的工具 执行常用的任务,如缩小,编译,单位 测试,linting等。它使用命令行界面来运行自定义 在文件中定义的任务(称为Gruntfile)。 Grunt是由 Ben Alman,用Node.js编写。它通过npm分发。 目前,有超过五千个插件可供使用 Grunt生态系统。
更多here
3)套餐经理
软件包管理器,他们所做的是管理您在应用程序中需要的插件,并使用package.json通过github等为您安装插件,非常方便更新模块,安装它们并共享您的应用程序,更多详细信息:
<强> NPM 强>
npm是JavaScript编程语言的包管理器。它 是JavaScript运行时环境的默认包管理器 Node.js的它由命令行客户端(也称为npm)和一个 公共包的在线数据库,称为npm注册表。该 通过客户端访问注册表,可用的包可以 通过npm网站浏览和搜索。
更多here
<强>亭子强>
Bower可以管理包含HTML,CSS,JavaScript,字体的组件 甚至是图像文件。 Bower不会连接或缩小代码或做 其他任何东西 - 它只是安装正确版本的软件包 你需要和他们的依赖。 首先,Bower通过从中获取和安装包来工作 到处都是,照顾狩猎,寻找,下载和保存 你正在寻找的东西。鲍尔跟踪这些包裹 清单文件,bower.json。
更多here
和最新的软件包管理器不应该被错过,它在实际工作环境中年轻而快速,与之前我大多使用的npm相比,对于重新安装模块,它会对node_modules进行双重检查检查模块是否存在的文件夹,似乎安装模块花费的时间更少:
<强>纱强>
Yarn是您的代码的包管理器。它允许你使用和 与来自世界各地的其他开发者共享代码。纱线做到了这一点 快速,安全,可靠,让您无需担心。
Yarn允许您使用其他开发人员的解决方案 问题,使您更容易开发您的软件。如果你 有问题,你可以报告问题或贡献回来,当时 问题是固定的,您可以使用Yarn来保持最新状态。
代码通过称为包的东西共享(有时称为 作为一个模块)。包中包含所有共享的代码 作为描述包的package.json文件。
更多here
答案 3 :(得分:49)
您可以在npmcompare
上找到一些技术比较Comparing browserify vs. grunt vs. gulp vs. webpack
正如您所看到的,webpack得到了很好的维护,平均每4天推出一个新版本。 但Gulp似乎拥有最大的社区(在Github上有超过20K的明星) Grunt似乎有点被忽视(与其他人相比)
因此,如果需要选择一个而不是另一个,我会选择Gulp
答案 4 :(得分:41)
关于npm:npm3的一个小注释尝试以平面方式安装依赖项
https://docs.npmjs.com/how-npm-works/npm3#npm-v3-dependency-resolution
答案 5 :(得分:12)
纱线是最近的包装经理,可能值得一提。那么,有:https://yarnpkg.com/
Afaik,它可以同时获取npm和bower依赖项,还有其他值得欣赏的功能。
答案 6 :(得分:12)
什么是webpack&amp;的WebPack-dev的服务器?官方文档说它是一个模块捆绑器,但对我来说它只是一个任务运行器。有什么区别?
webpack-dev-server是一个实时重新加载的Web服务器, Webpack 开发人员使用它来获得他们所做的即时反馈。它只应在开发过程中使用。
这个项目深受nof5单元测试工具的启发。
顾名思义 Webpack 将为 web 创建 SINGLE 包年龄。软件包将被最小化,并合并为一个文件(我们仍然生活在HTTP 1.1时代)。 Webpack 可以将资源(JavaScript,CSS,图像)组合在一起并注入它们:<script src="assets/bundle.js"></script>
。
它也可以称为模块bundler ,因为它必须了解模块依赖关系,以及如何获取依赖关系并将它们捆绑在一起。
你在哪里使用browserify?我们不能对节点/ ES6导入做同样的事情吗?
您可以使用 Browserify 执行与使用 Webpack 完全相同的任务。 - Webpack 虽然更紧凑。
请注意, Webpack2 中的ES6 module loader features正在使用 System.import ,而不是单个浏览器本身支持。
你什么时候会在npm +插件上使用gulp / grunt?
你可以forget Gulp,Grunt,Brokoli,Brunch和Bower 。直接使用npm命令行脚本,你可以在这里为 Gulp 删除这些额外的包:
var gulp = require('gulp'),
minifyCSS = require('gulp-minify-css'),
sass = require('gulp-sass'),
browserify = require('gulp-browserify'),
uglify = require('gulp-uglify'),
rename = require('gulp-rename'),
jshint = require('gulp-jshint'),
jshintStyle = require('jshint-stylish'),
replace = require('gulp-replace'),
notify = require('gulp-notify'),
在为项目创建配置文件时,您可以使用 Gulp 和 Grunt 配置文件生成器。这样您就不需要安装 Yeoman 或类似的工具。
答案 7 :(得分:9)
Webpack
是一个捆绑包。与Browserfy
类似,它在代码库中查找模块请求(require
或import
)并以递归方式解析它们。更重要的是,您可以配置Webpack
不仅可以解析类似JavaScript的模块,还可以解决CSS,图像,HTML等问题。特别让我对Webpack
感到兴奋的是,您可以将编译和动态加载的模块组合在同一个应用程序中。因此,可以获得真正的性能提升,特别是在HTTP / 1.x上。你是如何做到的我在这里用例子描述了http://dsheiko.com/weblog/state-of-javascript-modules-2017/
作为bundler的替代方法,人们可以想到Rollup.js
(https://rollupjs.org/),它在编译期间优化代码,但剥离所有找到的未使用的块。
对于AMD
,可以使用原住民RequireJS
代替ES2016 module system
,但加载System.js
(https://github.com/systemjs/systemjs)
此外,我要指出npm
经常被用作grunt
或gulp
等自动化工具。查看https://docs.npmjs.com/misc/scripts。我个人现在使用npm脚本只避免使用其他自动化工具,尽管在过去我非常关注grunt
。使用其他工具,您必须依赖无数的软件包插件,这些插件通常写得不好而且没有被主动维护。 npm
知道它的包,因此您可以通过以下名称调用任何本地安装的包:
{
"scripts": {
"start": "npm http-server"
},
"devDependencies": {
"http-server": "^0.10.0"
}
}
实际上,如果软件包支持CLI,您通常不需要任何插件。