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

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

问题:

什么是webpack和webpack开发服务器?官方文档说它是一个模块打包器,但对我来说,它只是一个任务执行器。有什么不同?你会在哪里使用browserify?我们不能对节点/ES6导入执行同样的操作吗?你什么时候会对npm+插件使用gulp/grunt?当您需要使用组合时,请提供示例


当前回答

什么是webpack和webpack开发服务器?官方文档说它是一个模块打包器,但对我来说,它只是一个任务执行器。有什么不同?

webpack-dev-server是一个实时重载的web服务器,webpack开发人员使用它来获得即时反馈。它只应在开发期间使用。

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

顾名思义,Webpack将为web创建一个SINGLE包。该包将被最小化,并合并为一个文件(我们仍然生活在HTTP 1.1时代)。Webpack的神奇之处在于将资源(JavaScript、CSS、图像)组合在一起,并像这样注入它们:<script src=“assets/bundle.js”></script>。

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

你会在哪里使用browserify?我们不能对节点/ES6导入执行同样的操作吗?

您可以在与使用Webpack完全相同的任务上使用Browserify。–不过,Webpack更紧凑。

请注意,Webpack2中的ES6模块加载器功能使用的是System.import,这不是一个浏览器本机支持的。

你什么时候会对npm+插件使用gulp/grunt?

你可以忘记古尔普、格朗特、布罗科利、早午餐和鲍尔。直接使用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或类似工具。

其他回答

Webpack和Browserify

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

例如,假设您编写了分成模块的ES6代码,并希望能够在浏览器中运行它。如果这些模块是Node模块,浏览器将无法理解它们,因为它们只存在于Node环境中。ES6模块也不能在IE11这样的旧浏览器中工作。此外,您可能使用了浏览器尚未实现的实验性语言特性(ES下一个建议),因此运行这样的脚本只会抛出错误。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 starter项目,它向您展示了涵盖整个构建和部署过程的NPM和JS脚本的完美组合。您可以在根文件夹的package.json中的名为scripts的属性中找到这些NPM脚本。在那里,您将主要遇到babel node tools/run start之类的命令。Babel节点是一个CLI工具(不用于生产),它首先编译ES6文件tools/run(位于工具中的run.js文件)-基本上是一个runner实用程序。这个运行程序将一个函数作为参数并执行它,在本例中它是start-另一个实用程序(start.js),负责绑定源文件(客户端和服务器)并启动应用程序和开发服务器(开发服务器可能是Webpack dev server或Browsersync)。

更准确地说,start.js创建了客户端和服务器端捆绑包,启动了一个express服务器,并在成功启动后初始化了浏览器同步,在编写本文时是这样的(请参阅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)

重要的部分是proxy.target,他们在其中设置要代理的服务器地址,该地址可以是http://localhost:3000,并且Browsersync启动服务器侦听http://localhost:3001,其中生成的资产被用于自动变化检测和热模块更换。正如您所看到的,还有另一个配置属性文件,其中包含单独的文件或模式。浏览器同步会监视更改并在发生某些更改时重新加载浏览器,但正如评论所说,Webpack会自行使用HMR监视js源,因此它们会在那里进行协作。

现在我没有任何类似Grunt或Gulp配置的示例,但使用Gulp(和Grunt有点类似),您可以在gulfile.js中编写单独的任务,如

gulp.task('bundle', function() {
  // bundling source files with some gulp plugins like gulp-webpack maybe
});

gulp.task('start', function() {
  // starting server and stuff
});

在这里,你将要做的事情基本上与初学者工具包中的相同,这一次是任务执行器,它为你解决了一些问题,但在学习使用过程中会出现自己的问题和一些困难,正如我所说的,依赖性越多,就越可能出错。这就是我喜欢摆脱这种工具的原因。

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

比较browserify与gulf与webpack

正如你所看到的,webpack维护得很好,平均每4天就会有一个新版本发布。但Gulp似乎拥有他们中最大的社区(Github上有超过2万名明星)Grunt似乎有点被忽视了(与其他人相比)

所以如果需要选择一个而不是另一个,我会和古尔普一起去

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


我也一直在寻找这一点,因为有很多工具,每一种都在不同的方面为我们带来好处。该社区分为Browserify、Webpack、jspm、Grunt和Gulp等工具。你也可能听说过Yeoman或Slush。这不是一个问题,只是让每个试图理解明确前进道路的人感到困惑。

无论如何,我想贡献一些东西。

目录

目录1.包装经理净现值鲍尔Bower和NPM的区别纱线jspm公司2.模块装载机/捆绑需要JS浏览器化Web包系统JS3.任务执行者咕哝吞咽4.脚手架工具Slush和Yeoman


1.包装经理

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

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

NPM

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

鲍尔

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

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

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

鲍尔

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

npm 3重复数据消除和重复数据消除有一些更新,请打开文档了解更多详细信息。

Yarn

Facebook最近发布了一个新的JavaScript包管理器,与NPM相比具有更多的优势。使用Yarn,您仍然可以使用NPMand Bower注册表来获取包。如果您以前安装过包,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

需要JS

它是一个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之间的关系?

浏览器化

开始允许在浏览器中使用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>

Web包

它将所有静态资产(包括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

系统JS

它是一个模块加载器,可以在运行时以当前使用的任何流行格式(CommonJS、UMD、AMD、ES6)导入模块。它构建在ES6模块加载器polyfill之上,足够智能,可以检测所使用的格式并适当处理。SystemJS还可以使用插件转换ES6代码(使用Babel或Traceur)或其他语言,如TypeScript和CoffeeScript。

想知道什么是节点模块,以及为什么它在浏览器中不适合。

更有用的文章:https://medium.com/@室内装饰/浏览-vs-webpack-b3d7ca08a0a9#.c1q7ao3h4http://jamesknelson.com/which-build-system-should-i-use-for-my-javascript-app/https://appendto.com/2016/06/the-short-history-of-javascript-module-loaders/


为什么选择jspm和SystemJS?ES6模块化的主要目标之一是使其真正简单在互联网(Github、npm等)。只需要两件事:安装库的单个命令一行代码导入库并使用它所以使用jspm,你可以做到。使用以下命令安装库:jspminstall-jquery使用单行代码导入库,无需在HTML文件中进行外部引用。显示.jsvar$=require('jquery');$('body').append(“我已导入jQuery!”);然后在System.config({…})中配置这些内容导入模块。通常,当运行jspminit时,会有一个文件为此命名为config.js。要运行这些脚本,我们需要在HTML页面上加载system.js和config.js。之后,我们将使用SystemJS模块加载器。索引html<script src=“jspm_packages/system.js”></script><script src=“config.js”></script><脚本>System.import(“scripts/display.js”);</script>注意:您也可以在Webpack中使用npm,因为Angular 2已经应用了它。由于jspm是为了与SystemJS集成而开发的,并且它在现有npm源代码的基础上工作,所以您的答案取决于您。


3.任务执行者

任务运行器和构建工具主要是命令行工具。为什么我们需要使用它们:一个词:自动化。在执行诸如缩小、编译、单元测试、linting等重复性任务时,您需要做的工作就越少,而这些任务以前需要我们花费大量时间使用命令行甚至手动完成。

咕哝

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

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://preslav.me/2015/01/06/gulp-vs-grunt-why-one-why-the-other/


4.脚手架工具

Slush和Yeoman

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

在此处查找更多信息。

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上阅读更多。谢谢访问:)

Yarn是最近的一个包装经理,可能值得一提。因此,这里是:https://yarnpkg.com/

据我所知,它可以获取npm和bower依赖项,并具有其他值得赞赏的特性。

什么是webpack和webpack开发服务器?官方文档说它是一个模块打包器,但对我来说,它只是一个任务执行器。有什么不同?

webpack-dev-server是一个实时重载的web服务器,webpack开发人员使用它来获得即时反馈。它只应在开发期间使用。

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

顾名思义,Webpack将为web创建一个SINGLE包。该包将被最小化,并合并为一个文件(我们仍然生活在HTTP 1.1时代)。Webpack的神奇之处在于将资源(JavaScript、CSS、图像)组合在一起,并像这样注入它们:<script src=“assets/bundle.js”></script>。

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

你会在哪里使用browserify?我们不能对节点/ES6导入执行同样的操作吗?

您可以在与使用Webpack完全相同的任务上使用Browserify。–不过,Webpack更紧凑。

请注意,Webpack2中的ES6模块加载器功能使用的是System.import,这不是一个浏览器本机支持的。

你什么时候会对npm+插件使用gulp/grunt?

你可以忘记古尔普、格朗特、布罗科利、早午餐和鲍尔。直接使用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或类似工具。