NPM vs.鲍尔vs.布洛塞利菲vs.古普vs.咕噜声vs. Webpack

我试图总结我对最流行的JavaScript包管理器、捆绑器和任务运行器的了解。如果我错了,请纠正我:

  • npmbower是包管理器。他们只是下载依赖,不知道如何自己构建项目。他们知道的是在获取所有依赖后调用webpack/gulp/grunt
  • bower类似于npm,但构建了一个扁平化的依赖树(不像npm递归地构建)。这意味着npm获取每个依赖项的依赖项(可能会多次获取相同的依赖项),而bower希望你手动包含子依赖项。有时bowernpm分别用于前端和后端(因为每个兆字节在前端可能都很重要)。
  • gruntgulp是任务运行器,用于自动化所有可以自动化的东西(即编译CSS/Sass、优化图像、制作捆绑包并缩小/转译它)。
  • grunt vs.gulp(就像maven vs.gradle或配置vs.代码)。Grunt基于配置单独的独立任务,每个任务打开/处理/关闭文件。Gulp需要更少的代码并且基于Node流,这允许它构建管道链(不重新打开相同的文件)并使其更快。
  • webpackwebpack-dev-server)-对我来说,它是一个具有热重载更改的任务运行器,可以让您忘记所有JS/CSS观察者。
  • npm/bower+插件可能会取代任务运行器。他们的能力通常是交叉的,所以如果你需要使用gulp/grunt而不是npm+插件,会有不同的含义。但是任务运行器绝对更适合复杂的任务(例如“在每个构建中创建捆绑包,从ES6转换到ES5,在所有浏览器模拟器上运行它,制作屏幕截图并通过ftp部署到dropbox”)。
  • browserify允许为浏览器打包节点模块。browserify vsnoderequire实际上是AMD vs Common JS

提问:

  1. 什么是#0和#1?官方留档说它是一个模块捆绑器,但对我来说它只是一个任务运行器。有什么区别?
  2. 你会在哪里使用#0?我们不能对节点/ES6导入做同样的事情吗?
  3. 你什么时候会使用gulp/grunt而不是npm+插件?
  4. 当您需要使用组合时,请提供示例
304829 次浏览

Webpack和Browserfy

Webpack和Browserfy执行几乎相同的工作,即处理要在目标环境中使用的代码(主要是浏览器,尽管您可以针对Node等其他环境)。这种处理的结果是一个或多个适合目标环境的捆绑组装脚本。

例如,假设你编写了ES6代码并将其划分为模块,并且希望能够在浏览器中运行它。如果这些模块是Node模块,浏览器将无法理解它们,因为它们仅存在于Node环境中。ES6模块也无法在IE11等旧浏览器中工作。此外,你可能使用了浏览器尚未实现的实验语言功能(ES下一个提案),因此运行此类脚本只会引发错误。Webpack和Browserfy等工具通过将此类代码转换为浏览器能够执行的形式解决了这些问题。最重要的是,它们使得对这些包应用各种优化成为可能。

然而,Webpack和Browserfy在许多方面有所不同,Webpack默认提供了许多工具(例如代码拆分),而Browserfy只能在下载插件后才能做到这一点,但使用两者会导致非常相似的结果。这取决于个人偏好(Webpack更流行)。顺便说一句,Webpack不是任务运行器,它只是你文件的处理器(它通过所谓的加载器和插件处理它们),它可以由任务运行器运行(以及其他方式)。


webpack开发服务器

Webpack Dev Server提供了与Browsersync类似的解决方案——一个开发服务器,您可以在使用它时快速部署您的应用程序,并立即验证您的开发进度,开发服务器会在代码更改时自动刷新浏览器,甚至将更改后的代码传播到浏览器,而无需重新加载所谓的热模块替换。


任务运行程序与NPM脚本

我一直在使用Gulp,因为它的简洁和简单的任务编写,但后来发现我根本不需要Gulp或Grunt。我所需要的一切都可以使用NPM脚本通过他们的API运行第三方工具来完成。在Gulp、Grunt或NPM脚本之间进行选择取决于您团队的品味和经验。

虽然Gulp或Grunt中的任务即使对于不太熟悉JS的人来说也很容易阅读,但它是另一个需要和学习的工具,我个人更喜欢缩小我的依赖关系并使事情变得简单。另一方面,用NPM脚本和(可能是JS)脚本的组合来替换这些任务,这些脚本运行那些第三方工具(例如,为清理目的配置和运行rimraf的节点脚本)可能更具挑战性。但在大多数情况下,这三个人在结果上是平等的。


示例

至于例子,我建议你看看这个React启动项目,它向你展示了NPM和JS脚本的一个很好的组合,涵盖了整个构建和部署过程。你可以在根文件夹的package.json中找到那些NPM脚本,在一个名为scripts的属性中。在那里你会遇到像babel-node tools/run start这样的命令。Babel-node是一个CLI工具(不适合生产使用),它首先编译ES6文件tools/run(run.js文件位于工具)——基本上是一个运行工具。这个运行程序接受一个函数作为参数并执行它,在本例中是start-另一个实用程序(start.js)负责捆绑源文件(客户端和服务器)并启动应用程序和开发服务器(开发服务器可能是Webpack Dev Server或Browsersync)。

更准确地说,start.js创建客户端和服务器端捆绑包,启动一个Express服务器,并在成功启动后初始化Browser-sync,在撰写本文时看起来像这样(请参阅启动项目获取最新代码)。

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 workfiles: ['build/content/**/*.*'],}, resolve)

重要的部分是proxy.target,他们在那里设置他们想要代理的服务器地址,可能是http://localhost:3000,Browsersync启动一个服务器监听http://localhost:3001,在那里生成的资产被提供自动更改检测和热模块替换。如您所见,还有另一个配置属性files,其中包含单独的文件或模式Browser-sync监视更改并在发生某些更改时重新加载浏览器,但正如评论所说,Webpack负责使用HMR单独监视js源,因此它们在那里合作。

现在我没有任何类似的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});

基本上,你要做的事情和入门工具包中的几乎一样,这次使用任务运行器,它为你解决了一些问题,但在学习使用过程中也出现了自己的问题和一些困难,正如我所说,你的依赖关系越多,出错的可能性就越大。这就是我喜欢摆脱这些工具的原因。

您可以在npm比较上找到一些技术比较

比较浏览序列化vs. grunt-goup vs. webpack

正如你所看到的,webpack维护得非常好,平均每4天就会有一个新版本。但Gulp似乎拥有最大的社区(Github上有超过20K颗星)Grunt似乎有点被忽视(与其他人相比)

所以如果需要选择一个而不是另一个,我会选择Gulp

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.包管理器
    • NPM
    • 鲍尔
    • BowerNPM的区别
    • 纱线
    • jspm
  • 2.模块加载器/捆绑
    • 是否必填
    • 浏览序列化
    • webpack
    • SystemJS
  • 3.任务运行器
    • Grunt
    • Gulp
  • 四、脚手架工具
    • Slush和Yeoman

1.包管理器

包管理器简化了安装和更新项目依赖项,这些依赖项是库,例如:jQuery, Bootstrap等-您网站上使用的所有内容,而不是您编写的。

浏览所有图书馆网站,下载和解压缩档案,将文件复制到项目中-所有这些都被终端中的一些命令所取代。

国家防范机制

它代表:Node JS package manager可帮助您管理软件依赖的所有库。您可以在名为package.json的文件中定义您的需求,并在命令行中运行npm install…然后BANG,您的包已下载并准备使用。它可用于front-endback-end库。

鲍尔

对于前端包管理,概念与NPM相同。您的所有库都存储在名为bower.json的文件中,然后在命令行中运行bower install

鲍尔建议他们的用户迁移到npm或sern。请小心

BowerNPM的区别

BowerNPM之间最大的区别是NPM不嵌套依赖树,而鲍尔需要一个扁平的依赖树,如下所示。

引用那么,npm和bow有什么区别呢?

国家防范机制

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

鲍尔

project root[bower_components] // default directory for dependencies-> dependency A-> dependency B // needs A-> dependency C // needs B and D-> dependency D

有一些关于#0的更新,详情请打开文档查看

纱线

最近JavaScript发表 byFacebook的新包管理器与NPM相比有更多的优势。使用Yarn,您仍然可以使用#2#4注册表来获取包。如果您之前安装过包,yarn会创建一个缓存副本,这有助于offline package installs

jspm

JSPM是SystemJS通用模块加载器的包管理器,构建在动态ES6模块加载器之上。它不是一个拥有自己一套规则的全新包管理器,而是它可以在现有包源之上工作。开箱即用,它适用于GitHubnpm。由于大多数基于Bower的包都基于GitHub,我们也可以使用jspm安装这些包。它有一个注册表,列出了大多数常用的前端包,以便更容易安装。

看看#0jspm之间的区别:包管理器:鲍尔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>

计算机可以比你做得更好,这就是为什么你应该使用一个工具来自动将所有内容捆绑到一个文件中。

然后我们听到了RequireJSBrowserifyWebpackSystemJS

它是一个JavaScript文件和模块加载器。它针对浏览器内使用进行了优化,但它可以在其他JavaScript环境中使用,例如Node

例如:myModule.js

// package/lib is a dependency we requiredefine(["package/lib"], function (lib) {// behavior for our modulefunction foo() {lib.log("hello world!");}
// export (expose) foo to other modules as foobarreturn {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>

阅读更多关于CommonJSAMD以轻松理解。通用JS、AMD和需要JS之间的关系?

浏览

开始允许在浏览器中使用CommonJS格式的模块。因此,Browserify与其说是模块加载器,不如说是模块捆绑器:Browserify完全是一个构建时工具,生成一组代码,然后可以在客户端加载。

从安装了node&npm的构建机器开始,并获取包:

npm install -g –save-dev browserify

CommonJS格式编写您的模块

//entry-point.jsvar foo = require("../foo.js");console.log(foo(4));

高兴时,发出捆绑命令:

browserify entry-point.js -o bundle-name.js

Browserfy递归查找入口点的所有依赖项并将它们组装成一个文件:

<script src="”bundle-name.js”"></script>

Webpack

它将所有静态资源(包括JavaScript、图像、CSS等)捆绑到一个文件中。它还使您能够通过不同类型的加载器处理文件。您可以使用CommonJSAMD模块语法编写JavaScript。它以一种从根本上更加集成和固执己见的方式攻击构建问题。在Browserify中,您使用Gulp/Grunt和一长串转换和插件来完成工作。Webpack提供了开箱即用的足够功能,您通常根本不需要GruntGulp

基本用法是超越简单。安装Webpack喜欢浏览:

npm install -g –save-dev webpack

并向命令传递一个切入点和一个输出文件:

webpack ./entry-point.js bundle-name.js

SystemJS

它是可以在运行时以任何流行格式导入模块今天使用的模块加载器(CommonJS, UMD, AMD, ES6)。它构建在ES6模块加载器Poly填充之上,并且足够智能来检测正在使用的格式并适当地处理它。SystemJS还可以使用插件转换ES6代码(使用BabelTraceur)或其他语言,例如TypeScriptCoffeeScript

想知道什么是node module以及为什么它不能很好地适应浏览器。

更有用的文章:


为什么是jspmSystemJS

ES6模块化的主要目标之一是让它变得非常简单从任何地方安装和使用任何Javascript库互联网(Githubnpm等)。只需要两件事:

  • 安装库的单个命令
  • 只需一行代码即可导入库并使用它

jspm,你可以做到。

  1. 使用命令安装库:jspm install jquery
  2. 只需一行代码即可导入库,无需在超文本标记语言文件中进行外部引用。

display.js

var $ = require('jquery');
$('body').append("I've imported jQuery!");
  1. 然后在System.config({ ... })之前配置这些东西导入您的模块。通常当运行jspm init时,会有一个文件config.js就是为了这个目的

  2. 要运行这些脚本,我们需要在超文本标记语言页面上加载system.jsconfig.js。之后,我们将使用SystemJS模块加载器。

index.html

<script src="jspm_packages/system.js"></script><script src="config.js"></script><script>System.import("scripts/display.js");</script>

注意:您还可以将npmWebpack一起使用,因为Angular 2已经应用了它。由于jspm是为与SystemJS集成而开发的,并且它可以在现有的npm源代码之上工作,因此您的答案取决于您。


3.任务运行方

任务运行器和构建工具主要是命令行工具。为什么我们需要使用它们:一个词:自动化。当执行像缩小、编译、单元测试、lint这样的重复性任务时,你需要做的工作越少,以前我们花了很多时间使用命令行甚至手动完成。

咕噜声

您可以为您的开发环境创建自动化来预处理代码或使用配置文件创建构建脚本,处理复杂的任务似乎非常困难。在过去几年中很流行。

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']);

自动化就像Grunt一样,但不是配置,您可以使用流编写JavaScript,就像它是一个节点应用程序一样。现在更喜欢。

这是一个Gulp示例任务声明。

//import the necessary gulp pluginsvar gulp = require("gulp");var sass = require("gulp-sass");var minifyCss = require("gulp-minify-css");var rename = require("gulp-rename");
//declare the taskgulp.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://preslav.me/2015/01/06/gulp-vs-grunt-why-one-why-the-other/


4.脚手架工具

Slush和Yeoman

您可以使用它们创建入门项目。例如,您计划使用超文本标记语言和SCSS构建一个原型,然后而不是手动创建一些文件夹,如scss、css、img、字体。您只需安装yeoman并运行一个简单的脚本。然后这里的一切都适合您。

找到更多这里

npm install -g yonpm install --global generator-h5bpyo h5bp

查看更多:https://www.quora.com/What-are-the-differences-between-NPM-Bower-Grunt-Gulp-Webpack-Browserify-Slush-Yeoman-and-Express


我的回答与问题的内容不匹配,但是当我在谷歌上搜索这些知识时,我总是看到问题在顶部,所以我决定总结回答。我希望你们发现它有帮助。

如果你喜欢这篇文章,你可以在我的博客trungk18.com上阅读更多。感谢访问:)

Yarn是最近的包管理器,可能值得一提。
所以,这里是:https://yarnpkg.com/

据我所知,它既可以获取npm依赖项,也可以获取bhouse依赖项,并且还有其他值得赞赏的特性。

什么是webpack&webpack-dev-server?官方留档说它是一个模块捆绑器,但对我来说它只是一个任务运行器。有什么区别?

webpack开发服务器是一个实时重新加载的Web服务器,webpack开发人员使用它来获取他们所做的即时反馈。它只应在开发期间使用。

这个项目很大程度上受到了nof5单元测试工具的启发。

顾名思义,webpack将为web创建一个单一age。包将被最小化,并组合成一个文件(我们仍然生活在HTTP 1.1时代)。webpack组合了资源(JavaScript、CSS、图像)并像这样注入它们:<script src="assets/bundle.js"></script>

它也可以被称为模块捆绑器,因为它必须了解模块依赖关系,以及如何获取依赖关系并将它们捆绑在一起。

你会在哪里使用浏览序列化?我们不能对节点/ES6导入做同样的事情吗?

您可以在与使用webpack完全相同的任务上使用浏览序列化。-webpack更紧凑,不过。

请注意,webpack 2中的ES6模块加载器功能正在使用System.import,这不是单个浏览器本地支持的。

你什么时候会在npm+插件上使用大口/咕噜声?

您可以忘记Gulp, Grunt, Brokoli,早午餐和鲍尔。直接使用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'),

您可以在为项目创建配置文件时使用GulpGrunt配置文件生成器。这样您就不需要安装文书或类似的工具。

OK,他们都有一些相似之处,他们以不同和相似的方式为你做同样的事情,我把它们分成3主要群体如下:


1)模块捆绑器

作为流行的webpack和浏览序列化,像任务运行器一样工作,但具有更大的灵活性,并且它会将所有内容捆绑在一起作为您的设置,因此您可以将结果指向bundle.js例如在一个包含CSS和Javascript的文件中,有关每个文件的更多详细信息,请查看下面的详细信息:

webpack

webpack是现代JavaScript应用程序的模块捆绑器。当webpack处理您的应用程序,它递归地构建依赖项包含应用程序需要的每个模块的图,然后是包将所有这些模块分成少量的bundle-通常只有一个-要被浏览器加载。

这是令人难以置信的配置,但要开始,你只需要了解四个核心概念:入口、输出、加载器和插件。

本文档旨在对这些内容进行高级概述概念,同时提供详细概念的链接用例。

更多这里

浏览序列化

Browserfy是一个开发工具,它允许我们编写node.js风格编译以在浏览器中使用的模块。就像节点一样,我们编写我们的模块在单独的文件中,导出外部方法和使用module.exports和导出变量的属性。我们甚至可以需要其他模块使用需要函数,如果我们省略它将解析到node_modules中的模块的相对路径目录。

更多这里


2)任务运行器

大口和咕噜是任务运行器,基本上他们做什么,创建任务并随时运行它们,例如,您安装一个插件来缩小您的CSS,然后每次运行它来缩小,有关每个的更多详细信息:

吞咽

gulp.js是Fractal Innovations的开源JavaScript工具包和GitHub上的开源社区,用作流式构建前端Web开发中的系统。它是一个基于Node.js和节点包管理器(npm),用于自动化Web开发中涉及的耗时且重复的任务,例如缩小、串联、缓存破坏、单元测试、lint、优化等,Gulp使用代码过度配置方法来定义其任务并依靠其小型、单一用途的插件来Gulp生态系统提供了1000多个这样的插件可供选择

更多这里

咕噜

Grunt是一个JavaScript任务运行器,一个用于自动执行任务的工具执行经常使用的任务,如缩小,编译,单元测试、打印等。它使用命令行界面来运行自定义在文件中定义的任务(称为Gruntfile)。Grunt是由Ben Alman,用Node.js.它通过npm分发。目前,有超过五千个插件可用于生态系统

更多这里


3)包管理器

包管理器,他们所做的是管理您在应用程序中需要的插件,并通过github等使用package.json为您安装它们,非常方便地更新您的模块,安装它们并共享您的应用程序,每个的更多详细信息:

npm

npm是JavaScript编程语言的包管理器。它是JavaScript运行时环境的默认包管理器Node.js.它由一个命令行客户端(也称为npm)和一个公共包的在线数据库,称为npm注册表。该注册表是通过客户端访问的,可用的包可以是通过npm网站浏览和搜索。

更多这里

凉亭

鲍尔可以管理包含超文本标记语言、CSS、JavaScript、字体的组件甚至图像文件。鲍尔不会连接或缩小代码或做其他任何东西-它只是安装正确版本的包你需要和他们的依赖。要开始,鲍尔通过从到处都是,照顾狩猎,寻找,下载和保存你要找的东西。鲍尔在一个清单文件,bower.json.

更多这里

和最近的包管理器不应该错过,它在真实的工作环境中年轻而快速,与我之前主要使用的npm相比,对于重新安装模块,它会双重检查node_modules文件夹以检查模块的存在,似乎安装模块需要更少的时间:

纱线

Yarn是您的代码的包管理器。它允许您使用和与来自世界各地的其他开发人员共享代码。Yarn这样做快速,安全,可靠,所以你永远不必担心。

Yarn允许您使用其他开发人员的解决方案来解决不同的问题问题,使您更容易开发您的软件。如果您有问题,您可以报告问题或贡献回来,当问题已修复,您可以使用Yarn使其保持最新状态。

代码通过称为包的东西共享(有时称为作为一个模块)。一个包也包含所有正在共享的代码作为描述包的package.json文件。

更多这里


Webpack是一个捆绑器。像Browserfy一样,它在代码库中查找模块请求(requireimport)并递归解析它们。更重要的是,你可以配置Webpack来解析不仅仅是类似JavaScript的模块,而是CSS、图像、超文本标记语言,几乎所有的东西。让我特别兴奋的是Webpack,你可以在同一个应用程序中结合编译和动态加载的模块。因此,一个人得到了真正的性能提升,特别是在HTTP/1. x上。作为bundler的替代方案,可以考虑Rollup.jshttps://rollupjs.org/),它在编译期间优化代码,但剥离所有找到的未使用块。

对于AMD,而不是RequireJS,可以使用原生ES2016 module system,但加载了System.jshttps://github.com/systemjs/systemjs

此外,我想指出npm经常被用作像gruntgulp这样的自动化工具。看看https://docs.npmjs.com/misc/scripts。我个人现在只使用npm脚本,避免使用其他自动化工具,尽管过去我非常喜欢grunt。对于其他工具,你必须依赖无数的包插件,这些插件通常写得不好,也没有得到积极维护。npm知道它的包,所以你可以按名称调用任何本地安装的包,比如:

{"scripts": {"start": "npm http-server"},"devDependencies": {"http-server": "^0.10.0"}}

实际上,如果包支持CLI,您通常不需要任何插件。