NPM vs. Bower vs. Browserify vs. Gulp vs. Grunt vs. Webpack NPM、Bower、Browserify、Gulp、Grunt和Webpack之间的比较

2067
我正在试图总结我对最流行的JavaScript包管理器、打包工具和任务运行器的了解。如果我有错,请纠正我:
  • npmbower是包管理器。它们只是下载依赖项,不知道如何自己构建项目。它们只知道在获取所有依赖项后调用webpack/gulp/grunt
  • bower类似于npm,但它构建的是扁平化的依赖树(不像npm是递归的)。这意味着npm为每个依赖项获取依赖项(可能会多次获取相同的依赖项),而bower则要求您手动包含子依赖项。有时前端和后端会同时使用bowernpm(因为每个兆字节在前端可能很重要)。
  • gruntgulp是任务运行器,可以自动化所有可以自动化的事情(例如编译CSS/Sass、优化图像、创建捆绑包并进行压缩/转译)。
  • gruntgulp(类似于mavengradle或配置与代码)的比较。Grunt基于配置独立的任务,每个任务打开/处理/关闭文件。Gulp需要更少的代码,基于Node流,允许构建管道链(无需重新打开相同的文件),因此更快。
  • webpackwebpack-dev-server)- 对我来说,它是一个具有热重载功能的任务运行器,可以让您忘记所有的JS/CSS监视器。
  • npm/bower + 插件可以替代任务运行器。它们的功能常常重叠,因此如果您需要在npm + 插件和gulp/grunt之间进行选择,会有不同的影响。但是对于复杂的任务(例如“在每次构建时创建捆绑包,从ES6转译为ES5,在所有浏览器模拟器上运行,并通过ftp将截图部署到dropbox”),任务运行器绝对更好。
  • browserify允许将Node模块打包为浏览器可用。实际上,browserifynoderequireAMD vs CommonJS

问题:

  1. webpackwebpack-dev-server是什么?官方文档说它是一个模块打包工具,但对我来说它只是一个任务运行器。它们有什么区别?
  2. 在哪些情况下会使用browserify?我们不能使用node/ES6的导入语法来实现相同的功能吗?
  3. 在什么情况下会使用gulp/grunt而不是npm + 插件?
  4. 请提供需要使用组合的示例

59
是时候考虑加入Rollup了吗? - gman
184
这是一个非常合理的问题。像我这样的伪Web开发人员会因为所有以周为单位实现的软件包而跌跌撞撞。 - user1972382
158
https://hackernoon.com/how-it-feels-to-learn-javascript-in-2016-d3a717dd577f - Fisherman
47
@Fisherman 我完全是个新手,这似乎完全疯狂… - David Stosik
15
@Fisherman,我刚读到的“推荐”评论甚至更糟糕!D: 我只想建立一个使用几个CSS/JS库的静态页面,并且会受益于有一个可以将它们编译在一起的工具...添加一些模板引擎来减轻我的Ctrl-C/Ctrl-V手指的压力,那就完美了...然而,几个小时过去了,仍然在寻找方法... - David Stosik
显示剩余10条评论
7个回答

1106

Webpack和Browserify

Webpack和Browserify基本上执行相同的工作,即处理您的代码以在目标环境中使用(主要是浏览器,但您也可以针对其他环境(如Node)进行目标定向)。这样处理的结果是一个或多个捆绑包 - 组装的脚本适合于目标环境。

例如,假设您编写了分为模块的ES6代码,并希望能够在浏览器中运行它。如果这些模块是Node模块,则浏览器无法理解它们,因为它们仅存在于Node环境中。ES6模块也无法在旧版浏览器(如IE11)中运行。此外,您可能已经使用了实验性的语言特性(ES next proposals),但浏览器尚未实现,因此运行此类脚本会引发错误。像Webpack和Browserify这样的工具通过将这种代码转换为浏览器能够执行的形式来解决这些问题。除此之外,它们还使得对这些捆绑包应用各种优化成为可能。

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

Webpack开发服务器

Webpack开发服务器提供了与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(位于tools中的run.js文件) - 基本上是一个运行程序。该运行程序将一个函数作为参数并执行它,在本例中是start - 另一个实用程序(start.js)负责打包源文件(客户端和服务器端)并启动应用程序和开发服务器(开发服务器可能是Webpack Dev Server或Browsersync)。

更准确地说,start.js 创建了客户端和服务器端的包,启动了一个 express 服务器,并在成功启动后初始化 Browser-sync。写作时,Browser-sync 的情况如下所示(请参考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,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
});

在这里,你将会做和起始套件中基本上差不多的事情,只不过这一次会使用任务运行器,它可以为你解决一些问题,但同时也会带来自己的问题和在学习使用时的一些困难。正如我所说,依赖项越多,出错的可能性就越大。这就是我喜欢摆脱这些工具的原因。


3
好的,Webpack和Browserify是如何在浏览器中重复使用Node模块的呢? - VB_
5
Webpack将依赖项(导出的模块值)汇集到一个对象(installedModules)中。因此,每个模块都是该对象的属性,这样的属性名称表示其id(例如1、2、3等)。每次在源代码中需要该模块时,Webpack将该值转换为带有模块ID参数的函数调用(例如__webpack_require__(1)), 它会根据模块ID在installedModules中查找并返回正确的依赖项。我不确定Browserify如何处理它。 - Dan Macak
@Dan Skočdopole 你能进一步阐述吗? - Asim K T
1
我不同意介绍gulp或grunt的基本用法,这两者很容易通过谷歌进行比较。webpack-dev-server需要先了解webpack,而这超出了此问题/答案的范围,但我已经介绍了一些Browsersync配置。你对starter-kit的看法是正确的,我也更详细地阐述了它。 - Dan Macak
6
降低依赖项以保持简单性,而不是遵循(更)流行的观点,即必须使用每个新软件包!+1 - madannes
显示剩余5条评论

735

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和Gulp这样的工具之间分裂。你可能也听说过Yeoman或Slush。这并不是问题,只是让每个人都很困惑,想要找到一个清晰的前进方向。
无论如何,我想做出一些贡献。
目录
- 目录 - 1. 包管理器 - NPM - Bower - Bower和NPM的区别 - Yarn - jspm - 2. 模块加载器/打包工具 - RequireJS - Browserify - Webpack - SystemJS - 3. 任务运行器 - Grunt - Gulp - 4. 脚手架工具 - Slush和Yeoman

1. 包管理器

包管理器简化了安装和更新项目依赖的过程,这些依赖是诸如:jQuery, Bootstrap等库,即你网站上使用的非自己编写的内容。

浏览所有库的网站,下载和解压缩文件,将文件复制到项目中——所有这些操作都可以用几个命令在终端中完成。

NPM

它代表:Node JS包管理器,帮助您管理软件所依赖的所有库。您可以在一个名为package.json的文件中定义您的需求,然后在命令行中运行npm install...然后,您的包就下载好并准备好使用了。它可以用于前端和后端库。

Bower

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

Bower建议用户迁移到npm或yarn。请小心。

Bower和NPM的区别

Bower和NPM最大的区别在于,NPM使用嵌套的依赖树,而Bower需要使用扁平的依赖树,如下所示。
引用自Bower和npm之间的区别是什么? 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

最近,Facebook发布了一个新的JavaScript包管理器Yarn,相比于NPM,它具有更多的优势。使用Yarn,您仍然可以使用NPMBower注册表来获取包。如果您之前安装过一个包,yarn会创建一个缓存副本,方便进行离线包安装

jspm

JSPM是一个用于SystemJS通用模块加载器的包管理器,建立在动态ES6模块加载器之上。它不是一个全新的包管理器,具有自己的一套规则,而是在现有的包源之上工作。它可以直接与GitHub和npm配合使用。由于大多数基于Bower的包都是基于GitHub的,我们也可以使用jspm来安装这些包。它还有一个注册表,列出了大多数常用的前端包,以便更容易地进行安装。
看看Bower和jspm之间的区别: 包管理器: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的内容,以便轻松理解。CommonJS、AMD和RequireJS之间的关系?

Browserify

旨在允许在浏览器中使用CommonJS格式的模块。因此,Browserify不仅仅是一个模块加载器,更是一个模块打包工具:Browserify完全是一个构建时工具,它生成一束代码,然后可以在客户端加载。

从已安装了node和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

Webpack将所有静态资源,包括JavaScript、图片、CSS等,打包成一个单独的文件。它还可以通过不同类型的加载器处理文件。你可以使用CommonJS或AMD模块语法编写JavaScript。它以更加整合和有见地的方式解决了构建问题。在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模块加载器的填充之上,并且足够智能,能够检测使用的格式并进行适当处理。SystemJS还可以使用插件转译ES6代码(使用BabelTraceur)或其他语言,如TypeScriptCoffeeScript

想知道什么是node模块以及为什么它不适合在浏览器中使用。

更多有用的文章: - [链接1](https://medium.com/@housecor/browserify-vs-webpack-b3d7ca08a0a9#.c1q7ao3h4) - [链接2](http://jamesknelson.com/which-build-system-should-i-use-for-my-javascript-app/) - [链接3](https://appendto.com/2016/06/the-short-history-of-javascript-module-loaders/)
为什么选择jspm和SystemJS?
ES6模块化的主要目标之一是使从互联网的任何地方(Github、npm等)安装和使用任何Javascript库变得非常简单。只需要两个步骤:
1. 一个命令来安装库 2. 一行代码来导入和使用库
所以,使用jspm,你可以做到这一点。
1. 使用命令安装库:jspm install jquery 2. 使用一行代码导入库,无需在HTML文件中引用外部文件。
display.js
var $ = require('jquery'); $('body').append("我已经导入了jQuery!");
然后,在导入模块之前,你需要在System.config({ ... })中配置这些内容。通常在运行jspm init时,会生成一个名为config.js的文件用于此目的。
为了使这些脚本运行,我们需要在HTML页面上加载system.js和config.js。之后,我们将使用SystemJS模块加载器加载display.js文件。
index.html 注意:你也可以使用npm和Webpack,因为Angular 2已经应用了它。由于jspm是为了与SystemJS集成,并且它是在现有的npm源之上工作的,所以你可以根据自己的需求选择。

3. 任务运行器

任务运行器和构建工具主要是命令行工具。为什么我们需要使用它们:简单来说就是自动化。当执行重复性任务时,比如压缩、编译、单元测试、代码检查,使用命令行或者手动操作会花费很多时间,而使用任务运行器可以减少工作量。

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,但不同的是,你可以像编写Node应用程序一样使用流来编写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://preslav.me/2015/01/06/gulp-vs-grunt-why-one-why-the-other/

4. 脚手架工具

Slush 和 Yeoman

你可以使用它们创建起始项目。例如,如果你计划使用 HTML 和 SCSS 构建一个原型,那么你可以安装 yeoman 并运行一个简单的脚本,而不是手动创建一些文件夹,如 scss、css、img、fonts。然后一切都会为你完成。

在这里找到更多信息here

npm install -g yo
npm install --global generator-h5bp
yo h5bp

查看更多:https://www.quora.com/What-are-the-differences-between-NPM-Bower-Grunt-Gulp-Webpack-Browserify-Slush-Yeoman-and-Express
我的回答与问题的内容不符,但当我在谷歌上搜索这个知识时,我总是看到这个问题排在前面,所以我决定简要回答一下。

68

好的,它们都有一些相似之处,在不同和相似的方式下为您完成相同的任务,我将它们分为3个主要组:


1) 模块打包工具

webpack 和 browserify 是流行的模块打包工具,类似于任务运行器,但更加灵活。同时,它会根据您的设置将所有内容捆绑在一起,因此您可以将结果指向一个单独的文件(例如 bundle.js),其中包括 CSS 和 JavaScript。有关每个工具的详细信息,请查看以下详情:

webpack

webpack 是现代 JavaScript 应用程序的模块打包工具。当 webpack 处理您的应用程序时,它会递归构建依赖图,包括您的应用程序所需的每个模块,然后将所有这些模块打包成少量的捆绑包 - 通常只有一个 - 以供浏览器加载。

它非常可配置,但是要开始使用,您只需要了解四个核心概念:入口、输出、加载器和插件。

本文档旨在提供这些概念的高级概述,同时提供链接到详细概念特定用例的链接。

更多 这里

browserify

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

更多这里


2) 任务运行器

gulp和grunt是任务运行器,它们的基本作用是创建任务并在需要时运行这些任务。例如,您可以安装一个插件来压缩CSS,然后每次运行该插件来进行压缩。更多关于每个工具的详细信息如下:

gulp

gulp.js是由Fractal Innovations和GitHub社区开发的一款开源JavaScript工具包,用于前端Web开发中的流式构建系统。它是基于Node.js和Node Package Manager(npm)的任务运行器,用于自动化与Web开发相关的耗时和重复性任务,例如缩小文件、合并文件、缓存破坏、单元测试、代码检查、优化等等。gulp使用代码优于配置的方法来定义其任务,并依赖于其小型、单一目的的插件来执行它们。gulp生态系统提供了1000多个这样的插件可供选择。

更多这里

grunt

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

更多信息


3) 软件包管理器

软件包管理器的作用是通过 package.json 管理你应用程序中需要的插件,并通过 github 等方式为你安装它们。非常方便更新模块、安装它们和分享你的应用程序。以下是每个软件包管理器的更多详细信息:

npm

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

更多信息

bower

Bower可以管理包含HTML、CSS、JavaScript、字体甚至图像文件的组件。Bower不会合并或缩小代码,也不会执行其他任何操作——它只会安装您需要的正确版本的软件包及其依赖项。为了开始使用,Bower通过从各个地方获取和安装软件包来工作,负责寻找、查找、下载和保存您正在查找的东西。Bower在一个清单文件bower.json中跟踪这些软件包。
更多这里 而最近的不容错过的包管理器是yarn。与我之前主要使用的npm相比,在真实的工作环境中,它年轻快速,对于重新安装模块,它会对node_modules文件夹进行双重检查以检查模块的存在,并且似乎安装模块所需的时间更短。
Yarn 是一个用于管理代码的软件包管理器。它允许您与世界各地的其他开发人员共享代码,并能够快速、安全、可靠地进行操作,因此您无需担心。使用 Yarn,您可以使用其他开发人员对不同问题的解决方案,使您更容易开发软件。如果您遇到问题,可以报告问题或贡献代码,当问题被修复后,您可以使用 Yarn 来保持所有内容的最新状态。代码是通过称为软件包(有时称为模块)的东西进行共享。软件包包含所有要共享的代码以及描述软件包的 package.json 文件。

更多信息 在这里



有没有gulp插件列表?真的有1000多个吗?npm只返回大约20个? - flurbius
1
很棒的总结。应该是任何关于现代Web开发讨论的入门点。 - Adam Bubela
1
@flurbius 是的,这里有:https://gulpjs.com/plugins/。目前似乎有3,465个Gulp插件。 - Matias Kinnunen
Parcel 怎么样? - carloswm85

54

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

比较browserify、grunt、gulp和webpack

正如您所见,webpack非常好维护,平均每4天发布新版本。但是,Gulp似乎拥有它们中最大的社区(在Github上超过20K个星标)。相比之下,Grunt似乎有点被忽略了。

因此,如果需要从中选择一个,我会选择Gulp。


6
Webpack现在在Github上有26k的star,而Gulp有25.7k。不能再仅靠受欢迎程度来做决策了... - Rayee Roded

17

什么是webpack和webpack-dev-server?官方文档说它是一个模块打包工具,但我认为它只是一个任务运行器。有什么区别?

webpack-dev-server是一个实时重新加载的Web服务器,Webpack开发人员用它来获得他们所做的即时反馈。它只应在开发过程中使用。

这个项目受nof5单元测试工具的启发。

Webpack顾名思义将为Web创建一个单一。该包将被最小化,并合并为一个文件(我们仍然处于HTTP 1.1时代)。 Webpack通过组合资源(JavaScript、CSS、图像)并注入它们来执行魔术,如下所示:<script src="assets/bundle.js"></script>

它也可以被称为模块打包工具,因为它必须理解模块依赖关系,以及如何抓取依赖项并将它们捆绑在一起。

你会在哪些情况下使用Browserify呢?我们不能用node/ES6引入做同样的事吗?

你可以在与使用Webpack相同的任务中使用 Browserify。- 尽管Webpack更为紧凑。

请注意,Webpack2中的ES6模块加载器特性使用的是System.import,这并没有得到任何浏览器的本地支持。

何时应该使用gulp/grunt而不是npm +插件?

你可以忘记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'),

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

14
Webpack是一个打包工具。与Browserfy类似,它会在代码库中查找模块请求(requireimport)并递归解析它们。更重要的是,你可以配置Webpack不仅解析像JavaScript一样的模块,还包括CSS、图片、HTML等所有东西。最让我兴奋的是,Webpack可以同时结合编译和动态加载的模块,从而实现真正的性能提升,尤其是在HTTP/1.x下。如何做到这一点,我在这里用示例描述了:http://dsheiko.com/weblog/state-of-javascript-modules-2017/ 作为打包工具的替代品,可以考虑使用Rollup.js (https://rollupjs.org/),它在编译过程中通过剥离所有未使用的块来优化代码。
对于AMD,可以选择原生的ES2016模块系统,但要使用System.js进行加载 (https://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,则通常不需要任何插件。

13

Yarn 是一个近期值得一提的软件包管理器。
因此,这里就介绍一下:https://yarnpkg.com/

据我所知,它可以获取 npm 和 bower 的依赖,并具有其他受欢迎的功能。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接