提问者:小点点

NPM vs.Bower vs.Browserify vs.Gulp vs.Grunt vs.Webpack


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

    amp;是包管理器。他们只是下载依赖项,不知道如何自己构建项目。他们知道的是在获取所有依赖项后调用。/li> 类似于,但是构建了一个扁平化的依赖树(与不同,后者是递归的)。这意味着获取每个依赖项的依赖项(可能多次获取相同的依赖项),而则期望您手动包含子依赖项。有时分别用于前端和后端(因为每个MB在前端可能很重要)。/li> 是任务运行器,用于自动化所有可以自动化的事情(即编译CSS/SASS,优化映像,制作包和缩小/传输包)。/li> vs.(类似于vs.或配置vs.code)。Grunt基于配置单独的独立任务,每个任务opens/handles/closs文件。Gulp需要更少的代码量,并且是基于节点流的,这允许它构建管道链(W/O重新打开相同的文件),并使其速度更快。 (codewebpack-dev-server/code>)-对我来说,它是一个任务运行器,可以热重载更改,允许您忘记所有的JS/CSS观察器。 +插件可以替换任务运行程序。它们的能力经常交叉,因此如果您需要在+插件上使用,就会有不同的含义。但是任务运行器肯定更适合于复杂的任务(例如“在每个构建中创建bundle,从ES6转到ES5,在所有浏览器模拟器上运行它,制作屏幕截图并通过FTP部署到dropbox)。/li> 允许为浏览器打包节点模块。实际上是AMD与commonjs./li>

问题:

    (&A)是什么;?官方文档说它是一个模块捆绑器,但对我来说它只是一个任务运行器。有什么区别?/li> 将在何处使用?我们对Node/ES6导入不也是这样吗? +plugins?/li>之上使用
  1. 请提供需要使用组合的示例/li>

共3个答案

匿名用户

Webpack和Browserify的工作几乎相同,都是处理要在目标环境中使用的代码(主要是浏览器,但也可以针对其他环境,如Node)。这种处理的结果是适合于目标环境的一个或多个包组装脚本。

例如,假设您编写了分成模块的ES6代码,并且希望能够在浏览器中运行它。如果这些模块是节点模块,浏览器将无法理解它们,因为它们仅存在于节点环境中。ES6模块也不能在IE11这样的旧浏览器上运行。此外,您可能使用了浏览器尚未实现的实验性语言特性(ES next Provisions),因此运行这样的脚本只会引发错误。Webpack和Browserify等工具通过将这些代码转换为浏览器能够执行的形式来解决这些问题。最重要的是,它们使得在这些bundle上应用大量的优化成为可能。

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

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

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

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

至于示例,我建议您看一看这个React starter项目,它向您展示了涵盖整个构建和部署过程的NPM和JS脚本的良好组合。您可以在根文件夹的中的一个名为的属性中找到这些NPM脚本。在这里,您将主要遇到之类的命令。Babel-node是一个CLI工具(不是用于生产),它首先编译ES6文件(位于tools中的run.js文件)-基本上是一个runner实用程序。这个运行程序将一个函数作为参数并执行它,在本例中,它是-另一个实用程序(codestart.js/code>),负责捆绑源文件(包括客户端和服务器)并启动应用程序和开发服务器(开发服务器可能是Webpack开发服务器或Browsersync。

更确切地说,创建客户端和服务器端包,启动express服务器,并在成功启动后初始化Browser-sync,在编写本文时,它看起来是这样的(请参阅react starter项目以获取最新代码)。

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)

重要的部分是,它们在其中设置想要代理的服务器地址(可以是http://localhost:3000),Browsersync启动一个在http://localhost:3001上侦听的服务器,在那里生成的资产通过自动更改检测和热模块替换提供服务。正如您所看到的,还有另一个配置属性,其中包含单独的文件或模式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
});

这一次使用task runner,它为您解决了一些问题,但在学习用法过程中也会出现自己的问题和一些困难,正如我所说的,依赖关系越多,出错的可能性就越大。这就是我喜欢摆脱这些工具的原因。

匿名用户

2018年10月更新

如果您还不确定前端开发,您可以快速查看一下这里的一个优秀资源。

https://github.com/kamranahmedse/developer-roadmap

2018年6月更新

如果您从一开始就没有学习过现代JavaScript,那么学习现代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

我也一直在寻找这个问题,因为有很多工具在那里,每一个都在不同的方面给我们带来好处。该社区被划分为一些工具,如。您可能还会听到。这不是问题,只是让每个试图理解一条清晰的前进道路的人感到困惑。

不管怎样,我想贡献点什么。

    之间的差异

包管理器简化了项目依赖项的安装和更新,这些依赖项是诸如等的库--所有在您的站点上使用的,不是您编写的东西。

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

它代表:帮助您管理软件所依赖的所有库。您可以在一个名为的文件中定义您的需求,并在命令行中运行。然后砰的一声,你的软件包就下载好了,可以使用了。它可以同时用于库。

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

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

之间最大的区别在于,NPM做嵌套的依赖树,而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

鲍尔

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

有一些关于的更新,请打开文档了解更多详细信息。

最近由发布的的一个新的包管理器,与相比具有更多的优点。对于Yarn,您仍然可以使用注册表来获取包。如果您以前安装过一个包,将创建一个缓存副本,以便于

JSPM是通用模块加载器的包管理器,它构建在动态模块加载器之上。它并不是一个具有自己规则集的全新包管理器,而是在现有包源的基础上工作。开箱即用,它与一起工作。由于大多数基于的包都基于,我们也可以使用安装这些包。它有一个注册表,列出了大多数常用的前端包,以便于安装。

请参阅之间的区别:包管理器:Bower vs jspm

任何规模的大多数项目都会将其代码拆分到几个文件中。您可以只在每个文件中包含一个单独的/code>标记,但是,/code>会建立一个新的HTTP连接,对于小文件(这是模块化的目标),建立连接的时间可能比传输数据要长得多。下载脚本时,不能更改页面上的内容。

  • 下载时间的问题可以通过将一组简单的模块连接到单个文件中并将其缩小来解决。/li>

例如

<head>
    <title>Wagon</title>
    <script src=“build/wagon-bundle.js”></script>
</head>
    <不过,灵活的性能是以牺牲灵活性为代价的。如果您的模块具有相互依赖性,那么这种灵活性的缺乏可能会成为一个搅局者。/li>

例如

<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>

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

然后我们听说了

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

例如: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,
  };
});

中,我们可以将作为依赖项导入并使用它。

require(["package/myModule"], function(myModule) {
    myModule.foobar();
});

然后在中,我们可以用引用use。

<script src=“app/require.js” data-main=“main.js” ></script>

阅读有关的更多信息,以便于理解。CommonJS,AMD和RequireJS之间的关系?

开始允许在浏览器中使用格式化模块。因此,不仅是模块加载器,也是模块绑定器:完全是一个构建时工具,生成一个随后可以在客户端加载的代码包。

从具有节点(&AM)的生成计算机开始;npm已安装,并获取软件包:

npm install -g –save-dev browserify

格式编写模块

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

又高兴之时,向束下命令:

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

Browserify递归地查找entry-point的所有依赖项,并将它们组装到单个文件中:

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

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

基本用法不简单。安装类似Browserify的Webpack:

npm install -g –save-dev webpack

并向命令传递入口点和输出文件:

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

它是一个模块加载器,可以在运行时以当今使用的任何流行格式(CodeCommonJS,UMD,AMD,ES6/CODE)导入模块。它构建在模块加载器polyfill之上,并且足够聪明,可以检测正在使用的格式并适当地处理它。还可以使用插件传输ES6代码(使用)或其他语言,如

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

更有用的文章:

为什么要

模块化的主要目标之一是使从Internet上的任何地方安装和使用任何Javascript库(codegithub/code>,等)变得非常简单。只需要两件事:

因此,使用,您可以实现这一点。

  1. 使用命令安装库:
  2. 用一行代码导入库,无需在HTML文件中进行外部引用。/li>

display.js

var $ = require('jquery');

$('body').append("I've imported jQuery!");

然后在导入模块之前在中配置这些内容。通常在运行时,会有一个名为的文件用于此目的。

要使这些脚本运行,我们需要在HTML页面上加载。之后,我们将使用模块加载器加载文件。

index.html

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

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

任务运行程序和生成工具主要是命令行工具。为什么我们需要使用它们:用一个词:自动化。在执行像缩小,编译,单元测试,linding这样的重复性任务时,你必须做的工作就越少,这些任务以前需要我们用命令行甚至手动来完成很多次。

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

中的每个任务都是不同插件配置的数组,它们只是以严格独立和顺序的方式一个接一个地执行。

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

自动化就像一样,但是您可以用流编写而不是配置,就像它是一个节点应用程序。更喜欢这些日子。

这是一个示例任务声明。

//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/

您可以使用它们创建初学者项目。例如,您正计划用HTML和SCSS构建一个原型,然后不是手动创建一些文件夹,比如SCSS,css,img,Fonts。您只需安装并运行一个简单的脚本即可。那么这里的一切都是为了你。

在这里找到更多。

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

我的答案与问题的内容不匹配,但当我在谷歌上搜索这些知识时,我总是看到问题在最上面,所以我决定简单地回答它。希望你们觉得有用。

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

匿名用户

好吧,他们都有一些相似之处,他们用不同的,相似的方式为你做同样的事情,我把他们分成三个主要组如下:

null

webpack和browserify是常用的,工作起来像任务运行程序,但更灵活,而且它将把所有东西捆绑在一起作为您的设置,因此您可以将结果作为bundle.js指向一个单独的文件(例如,包括CSS和Javascript),关于每个文件的更多细节,请查看下面的细节:

WebPack

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

它具有令人难以置信的可配置性,但要入门,您只需了解四个核心概念:入口,输出,加载器和插件。

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

更多信息请点击此处

浏览修改

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

更多信息请点击此处

2)任务运行者

gulp和grunt都是任务运行器,基本上就是它们的工作,创建任务并在你想要的时候运行它们,例如,你安装了一个插件来缩小你的CSS,然后每次都运行它来缩小,更多关于每一个的细节:

大口大口地喝

gulp.js是由Fractal Innovations和GitHub的开源社区开发的一个开源JavaScript工具包,在前端web开发中用作流式构建系统。gulp是一个建立在Node.js和Node Package Manager(npm)上的任务运行器,用于自动化web开发中涉及的耗时和重复的任务,如缩小,连接,缓存破坏,单元测试,linting,优化等。gulp使用代码配置方法定义其任务,并依赖于其小型的,单一用途的插件来执行这些任务。gulp生态系统有1000+这样的插件可供选择。

更多信息请点击此处

咕噜声

Grunt是一个JavaScript任务运行器,用于自动执行常用任务,如缩小,编译,单元测试,链接等。它使用命令行接口运行文件(称为Gruntfile)中定义的自定义任务。Grunt由Ben Alman创建,用node.js编写。它是通过国家预防机制分发的。目前,在Grunt生态系统中有超过5000个可用的插件。

更多信息请点击此处

3)包经理

软件包管理器,他们所做的是管理你需要的插件在你的应用程序和安装他们为你通过github等使用package.json,非常方便的更新你的模块,安装他们和分享你的应用程序,更多细节为每个:

NPM

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

更多信息请点击此处

鲍尔

Bower可以管理包含HTML,CSS,JavaScript,字体甚至图像文件的组件。Bower并不连接或缩小代码或做任何其他事情--它只是安装您需要的软件包的正确版本和它们的依赖项。首先,Bower的工作方式是从各地获取和安装软件包,负责搜索,查找,下载和保存您要查找的东西。Bower在清单文件Bower.json中跟踪这些包。

更多信息请点击此处

而最近的软件包管理器也是不容错过的,它在实际工作环境中比我以前经常使用的npm年轻且快速,对于重装模块,它会双重检查node_modules文件夹来检查模块的存在,而且安装模块似乎也花费了更少的时间:

纱线

Yarn是代码的包管理器。它允许您使用代码并与来自世界各地的其他开发人员共享代码。纱线可以快速,安全,可靠地实现这一点,因此您永远不必担心。

Yarn允许您使用其他的DevelopersSolutions来解决不同的问题,使您更容易地开发您的软件。如果您有问题,您可以报告问题或做出反馈,当问题得到解决时,您可以使用纱线来保持所有问题都是最新的。

代码通过称为包(有时称为模块)的东西共享。包包含所有共享的代码以及描述包的package.json文件。

更多信息请点击此处