node.js Gulp + Webpack 还是 JUST Webpack?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33558396/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 19:29:44  来源:igfitidea点击:

Gulp + Webpack or JUST Webpack?

node.jswebpackgulp

提问by PositiveGuy

I see people using gulp with webpack. But then I read webpack can replace gulp? I'm completely confused here...can someone explain?

我看到有人在 webpack 中使用 gulp。但是后来我看了 webpack 可以代替 gulp 吗?我在这里完全糊涂了……有人可以解释一下吗?

UPDATE

更新

in the end I started with gulp. I was new to modern front-end and just wanted to get up and running quick. Now that I've got my feet quite wet after more than a year, I'm ready to move to webpack. I suggest the same route for people who start off in the same shoes. Not saying you can't try webpack but just sayin if it seems complicated start with gulp first...nothing wrong with that.

最后我从 gulp 开始。我是现代前端的新手,只想快速启动和运行。一年多后,我的脚已经湿透了,我准备转向 webpack。我建议穿着相同鞋子的人走同样的路线。不是说你不能尝试 webpack,而是说如果它看起来很复杂,首先从 gulp 开始......没有错。

If you don't want gulp, yes there's grunt but you could also just specify commands in your package.json and call them from the command-line without a task runner just to get up and running initially. For example:

如果您不想要 gulp,是的,有 grunt,但您也可以只在 package.json 中指定命令并从命令行调用它们,而无需任务运行器,只是为了最初启动和运行。例如:

"scripts": {
      "babel": "babel src -d build",
      "browserify": "browserify build/client/app.js -o dist/client/scripts/app.bundle.js",
      "build": "npm run clean && npm run babel && npm run prepare && npm run browserify",
      "clean": "rm -rf build && rm -rf dist",
      "copy:server": "cp build/server.js dist/server.js",
      "copy:index": "cp src/client/index.html dist/client/index.html",
      "copy": "npm run copy:server && npm run copy:index",
      "prepare": "mkdir -p dist/client/scripts/ && npm run copy",
      "start": "node dist/server"
    },

采纳答案by 4m1r

This answer might help. Task Runners (Gulp, Grunt, etc) and Bundlers (Webpack, Browserify). Why use together?

这个答案可能会有所帮助。 任务运行器(Gulp、Grunt 等)和捆绑器(Webpack、Browserify)。为什么一起用?

...and here's an example of using webpack from within a gulp task. This goes a step further and assumes that your webpack config is written in es6.

...这是在 gulp 任务中使用 webpack 的示例。这更进一步,假设您的 webpack 配置是用 es6 编写的。

var gulp = require('gulp');
var webpack = require('webpack');
var gutil = require('gutil');
var babel = require('babel/register');
var config = require(path.join('../..', 'webpack.config.es6.js'));

gulp.task('webpack-es6-test', function(done){
   webpack(config).run(onBuild(done));
});

function onBuild(done) {
    return function(err, stats) {
        if (err) {
            gutil.log('Error', err);
            if (done) {
                done();
            }
        } else {
            Object.keys(stats.compilation.assets).forEach(function(key) {
                gutil.log('Webpack: output ', gutil.colors.green(key));
            });
            gutil.log('Webpack: ', gutil.colors.blue('finished ', stats.compilation.name));
            if (done) {
                done();
            }
        }
    }
}

I think you'll find that as your app gets more complicated, you might want to use gulp with a webpack task as per example above. This allows you to do a few more interesting things in your build that webpack loaders and plugins really don't do, ie. creating output directories, starting servers, etc. Well, to be succinct, webpack actually can do those things, but you might find them limited for your long term needs. One of the biggest advantages you get from gulp -> webpack is that you can customize your webpack config for different environments and have gulp do the right task for the right time. Its really up to you, but there's nothing wrong with running webpack from gulp, in fact there's some pretty interestingexamples of how to do it. The example above is basically from jlongster.

我想您会发现随着您的应用程序变得越来越复杂,您可能希望按照上面的示例将 gulp 与 webpack 任务一起使用。这允许您在构建中做一些 webpack 加载器和插件真正不做的更有趣的事情,即。创建输出目录,启动服务器等。简而言之,webpack 实际上可以做这些事情,但你可能会发现它们对于你的长期需求是有限的。您从 gulp -> webpack 获得的最大优势之一是您可以针对不同的环境自定义您的 webpack 配置,并让 gulp 在正确的时间执行正确的任务。这真的取决于你,但是从 gulp 运行 webpack 并没有错,事实上有一些非常有趣的例子来说明如何做到这一点。.

回答by TetraDev

NPM scriptscan do the same as gulp, but in about 50x less code. In fact, with no code at all, only command line arguments.

NPM 脚本可以执行与 gulp 相同的功能,但代码减少了大约 50 倍。事实上,根本没有代码,只有命令行参数。

For example, the use case you described where you want to have different code for different environments.

例如,您描述的用例中,您希望为不同的环境使用不同的代码。

With Webpack + NPM Scripts, it's this easy:

使用 Webpack + NPM 脚本,就这么简单:

"prebuild:dev": "npm run clean:wwwroot",
"build:dev": "cross-env NODE_ENV=development webpack --config config/webpack.development.js --hot --profile --progress --colors --display-cached",
"postbuild:dev": "npm run copy:index.html && npm run rename:index.html",

"prebuild:production": "npm run clean:wwwroot",
"build:production": "cross-env NODE_ENV=production webpack --config config/webpack.production.js --profile --progress --colors --display-cached --bail",
"postbuild:production": "npm run copy:index.html && npm run rename:index.html",

"clean:wwwroot": "rimraf -- wwwroot/*",
"copy:index.html": "ncp wwwroot/index.html Views/Shared",
"rename:index.html": "cd ../PowerShell && elevate.exe -c renamer --find \"index.html\" --replace \"_Layout.cshtml\" \"../MyProject/Views/Shared/*\"",

Now you simply maintain two webpack config scripts, one for development mode, webpack.development.js, and one for production mode, webpack.production.js. I also utilize a webpack.common.jswhich houses webpack config shared on all environments, and use webpackMerge to merge them.

现在你只需维护两个 webpack 配置脚本,一个用于开发模式,webpack.development.js,一个用于生产模式,webpack.production.js. 我还利用了一个webpack.common.js在所有环境中共享的 webpack 配置,并使用 webpackMerge 来合并它们。

Because of the coolness of NPM scripts, it allows for easy chaining, similar to how gulp does Streams/pipes.

由于 NPM 脚本的酷炫,它允许轻松链接,类似于 gulp 处理 Streams/pipes 的方式。

In the example above, to build for developement, you simply go to your command line and execute npm run build:dev.

在上面的示例中,要为开发而构建,您只需转到命令行并执行npm run build:dev.

  1. NPM would first run prebuild:dev,
  2. Then build:dev,
  3. And finally postbuild:dev.
  1. NPM 将首先运行prebuild:dev
  2. 然后build:dev
  3. 最后postbuild:dev

The preand postprefixes tell NPM which order to execute in.

prepost前缀告诉NPM其顺序执行。

If you notice, with Webpack + NPM scripts, you can run a native programs, such as rimraf, instead of a gulp-wrapper for a native program such as gulp-rimraf. You can also run native Windows .exe files as I did here with elevate.exeor native *nix files on Linux or Mac.

如果您注意到,使用 Webpack + NPM 脚本,您可以运行本机程序,例如rimraf,而不是本机程序的 gulp -wrapper,例如gulp-rimraf. 您还可以像我在此处使用elevate.exeLinux 或 Mac 上的本机 *nix 文件一样运行本机 Windows .exe 文件。

Try doing the same thing with gulp. You'll have to wait for someone to come along and write a gulp-wrapper for the native program you want to use. In addition, you'll likely need to write convoluted code like this: (taken straight from angular2-seedrepo)

尝试用 gulp 做同样的事情。您将不得不等待有人来为您要使用的本机程序编写一个 gulp-wrapper。此外,您可能需要像这样编写复杂的代码:(直接取自angular2-seedrepo)

Gulp Development code

Gulp 开发代码

import * as gulp from 'gulp';
import * as gulpLoadPlugins from 'gulp-load-plugins';
import * as merge from 'merge-stream';
import * as util from 'gulp-util';
import { join/*, sep, relative*/ } from 'path';

import { APP_DEST, APP_SRC, /*PROJECT_ROOT, */TOOLS_DIR, TYPED_COMPILE_INTERVAL } from '../../config';
import { makeTsProject, templateLocals } from '../../utils';

const plugins = <any>gulpLoadPlugins();

let typedBuildCounter = TYPED_COMPILE_INTERVAL; // Always start with the typed build.

/**
 * Executes the build process, transpiling the TypeScript files (except the spec and e2e-spec files) for the development
 * environment.
 */
export = () => {
  let tsProject: any;
  let typings = gulp.src([
    'typings/index.d.ts',
    TOOLS_DIR + '/manual_typings/**/*.d.ts'
  ]);
  let src = [
    join(APP_SRC, '**/*.ts'),
    '!' + join(APP_SRC, '**/*.spec.ts'),
    '!' + join(APP_SRC, '**/*.e2e-spec.ts')
  ];

  let projectFiles = gulp.src(src);
  let result: any;
  let isFullCompile = true;

  // Only do a typed build every X builds, otherwise do a typeless build to speed things up
  if (typedBuildCounter < TYPED_COMPILE_INTERVAL) {
    isFullCompile = false;
    tsProject = makeTsProject({isolatedModules: true});
    projectFiles = projectFiles.pipe(plugins.cached());
    util.log('Performing typeless TypeScript compile.');
  } else {
    tsProject = makeTsProject();
    projectFiles = merge(typings, projectFiles);
  }

  result = projectFiles
    .pipe(plugins.plumber())
    .pipe(plugins.sourcemaps.init())
    .pipe(plugins.typescript(tsProject))
    .on('error', () => {
      typedBuildCounter = TYPED_COMPILE_INTERVAL;
    });

  if (isFullCompile) {
    typedBuildCounter = 0;
  } else {
    typedBuildCounter++;
  }

  return result.js
    .pipe(plugins.sourcemaps.write())
// Use for debugging with Webstorm/IntelliJ
// https://github.com/mgechev/angular2-seed/issues/1220
//    .pipe(plugins.sourcemaps.write('.', {
//      includeContent: false,
//      sourceRoot: (file: any) =>
//        relative(file.path, PROJECT_ROOT + '/' + APP_SRC).replace(sep, '/') + '/' + APP_SRC
//    }))
    .pipe(plugins.template(templateLocals()))
    .pipe(gulp.dest(APP_DEST));
};

Gulp Production code

Gulp 生产代码

import * as gulp from 'gulp';
import * as gulpLoadPlugins from 'gulp-load-plugins';
import { join } from 'path';

import { TMP_DIR, TOOLS_DIR } from '../../config';
import { makeTsProject, templateLocals } from '../../utils';

const plugins = <any>gulpLoadPlugins();

const INLINE_OPTIONS = {
  base: TMP_DIR,
  useRelativePaths: true,
  removeLineBreaks: true
};

/**
 * Executes the build process, transpiling the TypeScript files for the production environment.
 */

export = () => {
  let tsProject = makeTsProject();
  let src = [
    'typings/index.d.ts',
    TOOLS_DIR + '/manual_typings/**/*.d.ts',
    join(TMP_DIR, '**/*.ts')
  ];
  let result = gulp.src(src)
    .pipe(plugins.plumber())
    .pipe(plugins.inlineNg2Template(INLINE_OPTIONS))
    .pipe(plugins.typescript(tsProject))
    .once('error', function () {
      this.once('finish', () => process.exit(1));
    });


  return result.js
    .pipe(plugins.template(templateLocals()))
    .pipe(gulp.dest(TMP_DIR));
};

The actual gulp code is much more complicated that this, as this is only 2 of the several dozen gulp files in the repo.

实际的 gulp 代码比这复杂得多,因为这只是 repo 中几十个 gulp 文件中的 2 个。

So, which one is easier to you?

那么,哪一个对你来说更容易呢?

In my opinion, NPM scripts far surpasses gulp and grunt, in both effectiveness and ease of use, and all front-end developers should consider using it in their workflow because it is a major time saver.

在我看来,NPM 脚本在有效性和易用性方面都远远超过了 gulp 和 grunt,所有前端开发人员都应该考虑在他们的工作流程中使用它,因为它可以节省大量时间。

UPDATE

更新

There is one scenario I've encountered where I wanted to use Gulp in combination with NPM scripts and Webpack.

我遇到过一种情况,我想将 Gulp 与 NPM 脚本和 Webpack 结合使用。

When I need to do remote debuggingon an iPad or Android device for example, I need to start up extra servers. In the past I ran all the servers as separate processes, from within IntelliJ IDEA (Or Webstorm) that is easy with the "Compound" Run Configuration. But if I need to stop and restart them, it was tedious to have to close 5 different server tabs, plus the output was spread across the different windows.

例如,当我需要在 iPad 或 Android 设备上进行远程调试时,我需要启动额外的服务器。过去,我在 IntelliJ IDEA(或 Webstorm)中将所有服务器作为单独的进程运行,这很容易使用“复合”运行配置。但是,如果我需要停止并重新启动它们,则必须关闭 5 个不同的服务器选项卡很乏味,而且输出分布在不同的窗口中。

One of the benefits of gulp is that is can chain all the output from separate independent processes into one console window, which becomes the parent of all the child servers.

gulp 的好处之一是可以将来自不同独立进程的所有输出链接到一个控制台窗口中,该窗口成为所有子服务器的父级。

So I created a very simple gulp task that just runs my NPM scripts or the commands directly, so all the output appears in one window, and I can easily end all 5 servers at once by closing the gulp task window.

所以我创建了一个非常简单的 gulp 任务,它直接运行我的 NPM 脚本或命令,所以所有输出都出现在一个窗口中,我可以通过关闭 gulp 任务窗口轻松地一次结束所有 5 个服务器。

Gulp.js

Gulp.js

/**
 * Gulp / Node utilities
 */
var gulp = require('gulp-help')(require('gulp'));
var utils = require('gulp-util');
var log = utils.log;
var con = utils.colors;

/**
 * Basic workflow plugins
 */
var shell = require('gulp-shell'); // run command line from shell
var browserSync = require('browser-sync');

/**
 * Performance testing plugins
 */
var ngrok = require('ngrok');

// Variables
var serverToProxy1 = "localhost:5000";
var finalPort1 = 8000;


// When the user enters "gulp" on the command line, the default task will automatically be called. This default task below, will run all other tasks automatically.

// Default task
gulp.task('default', function (cb) {
   console.log('Starting dev servers!...');
   gulp.start(
      'devserver:jit',
      'nodemon',
      'browsersync',
      'ios_webkit_debug_proxy'
      'ngrok-url',
      // 'vorlon',
      // 'remotedebug_ios_webkit_adapter'
   );
});

gulp.task('nodemon', shell.task('cd ../backend-nodejs && npm run nodemon'));
gulp.task('devserver:jit', shell.task('npm run devserver:jit'));
gulp.task('ios_webkit_debug_proxy', shell.task('npm run ios-webkit-debug-proxy'));
gulp.task('browsersync', shell.task(`browser-sync start --proxy ${serverToProxy1} --port ${finalPort1} --no-open`));
gulp.task('ngrok-url', function (cb) {
   return ngrok.connect(finalPort1, function (err, url) {
      site = url;
      log(con.cyan('ngrok'), '- serving your site from', con.yellow(site));
      cb();
   });
});
// gulp.task('vorlon', shell.task('vorlon'));
// gulp.task('remotedebug_ios_webkit_adapter', shell.task('remotedebug_ios_webkit_adapter'));

Still quite a bit of code just to run 5 tasks, in my opinion, but it works for the purpose. One caveate is that gulp-shelldoesn't seem to run some commands correctly, such as ios-webkit-debug-proxy. So I had to create an NPM Script that just executes the same command, and then it works.

在我看来,仍然有相当多的代码只是为了运行 5 个任务,但它可以达到目的。一个警告是它gulp-shell似乎没有正确运行某些命令,例如ios-webkit-debug-proxy. 所以我不得不创建一个 NPM 脚本来执行相同的命令,然后它就可以工作了。

So I primarily use NPM Scripts for all my tasks, but occasionally when I need to run a bunch of servers at once, I'll fire up my Gulp task to help out. Pick the right tool for the right job.

所以我主要使用 NPM 脚本来完成我的所有任务,但偶尔当我需要同时运行一堆服务器时,我会启动我的 Gulp 任务来提供帮助。为正确的工作选择正确的工具。

UPDATE 2

更新 2

I now use a script called concurrentlywhich does the same thing as the gulp task above. It runs multiple CLI scripts in parallel and pipes them all to the same console window, and its very simple to use. Once again, no code required (well, the code is inside the node_module for concurrently, but you don't have to concern yourself with that)

我现在使用一个名为concurrently的脚本,它与上面的 gulp 任务做同样的事情。它并行运行多个 CLI 脚本并将它们全部通过管道传送到同一个控制台窗口,并且使用起来非常简单。再一次,不需要代码(好吧,代码在 node_module 中并发,但您不必担心)

// NOTE: If you need to run a command with spaces in it, you need to use 
// double quotes, and they must be escaped (at least on windows).
// It doesn't seem to work with single quotes.

"run:all": "concurrently \"npm run devserver\" nodemon browsersync ios_webkit_debug_proxy ngrok-url"

This runs all 5 scripts in parallel piped out to one terminal. Awesome! So that this point, I rarely use gulp, since there are so many cli scripts to do the same tasks with no code.

这将并行运行所有 5 个脚本,并通过管道输出到一个终端。惊人的!所以这一点,我很少使用 gulp,因为有很多 cli 脚本可以在没有代码的情况下完成相同的任务。

I suggest you read these articles which compare them in depth.

我建议你阅读这些文章,对它们进行深入比较。

回答by R.R

I used both options in my different projects.

我在不同的项目中使用了这两个选项。

Here is one boilerplate that I put together using gulpwith webpack- https://github.com/iroy2000/react-reflux-boilerplate-with-webpack.

这是我gulpwebpack- https://github.com/iroy2000/react-reflux-boilerplate-with-webpack一起使用的一个样板。

I have some other project used only webpackwith npm tasks.

我有一些其他项目仅webpack用于npm tasks.

And they both works totally fine. And I think it burns down to is how complicated your task is, and how much control you want to have in your configuration.

他们都工作得很好。我认为它归结为您的任务有多复杂,以及您希望在配置中拥有多少控制权。

For example, if you tasks is simple, let's say dev, build, test... etc ( which is very standard ), you are totally fine with just simple webpackwith npm tasks.

例如,如果您的任务很简单,比如说dev, build, test... 等(这是非常标准的),那么您只需使用简单webpacknpm tasks.

But if you have very complicated workflow and you want to have more control of your configuration ( because it is coding ), you could go for gulp route.

但是,如果您的工作流程非常复杂,并且希望对配置有更多的控制权(因为它是编码),则可以选择 gulp 路线。

But from my experience, webpack ecosystem provides more than enough plugins and loaders that I will need, and so I love using the bare minimum approach unless there is something you can only do in gulp. And also, it will make your configuration easier if you have one less thing in your system.

但是根据我的经验,webpack 生态系统提供了足够多的插件和加载器,我需要,所以我喜欢使用最低限度的方法,除非有些事情你只能在 gulp 中完成。而且,如果您的系统中少了一件,它将使您的配置更容易。

And a lot of times, nowadays, I see people actually replacing gulp and browsifyall together with webpackalone.

很多时候,如今,我看到人们实际上将gulp and browsify所有人都替换为webpack独自一人。

回答by Maokai

The concepts of Gulp and Webpack are quite different. You tell Gulp howto put front-end code together step-by-step, but you tell Webpack whatyou want through a config file.

Gulp 和 Webpack 的概念完全不同。你告诉 Gulp如何一步一步地把前端代码放在一起,但是你通过一个配置文件告诉 Webpack你想要什么

Here is a short article (5 min read) I wrote explaining my understanding of the differences: https://medium.com/@Maokai/compile-the-front-end-from-gulp-to-webpack-c45671ad87fe

这是我写的一篇短文(阅读 5 分钟),解释了我对差异的理解:https: //medium.com/@Maokai/compile-the-front-end-from-gulp-to-webpack-c45671ad87fe

Our company moved from Gulp to Webpack in the past year. Although it took some time, we figured out how to move all we did in Gulp to Webpack. So to us, everything we did in Gulp we can also do through Webpack, but not the other way around.

我们公司在去年从 Gulp 迁移到了 Webpack。虽然花费了一些时间,但我们想出了如何将我们在 Gulp 中所做的一切迁移到 Webpack。所以对我们来说,我们在 Gulp 中所做的一切都可以通过 Webpack 来完成,但反过来不行。

As of today, I'd suggest just use Webpack and avoid the mixture of Gulp and Webpack so you and your team do not need to learn and maintain both, especially because they are requiring very different mindsets.

到今天为止,我建议只使用 Webpack,避免将 Gulp 和 Webpack 混合使用,这样您和您的团队就不需要学习和维护两者,尤其是因为它们需要非常不同的思维方式。

回答by Max Favilli

Honestly I think the best is to use both.

老实说,我认为最好是同时使用两者。

  • Webpackfor all javascriptrelated.
  • Gulpfor all cssrelated.
  • 用于所有javascript相关的Webpack
  • 吞咽所有与css相关的内容。

I still have to find a decent solution for packaging css with webpack, and so far I am happy using gulp for css and webpack for javascript.

我仍然需要找到一个像样的解决方案来使用 webpack 打包 css,到目前为止我很高兴使用 gulp 来处理 css 和 webpack 来处理 javascript。

I also use npmscripts as @Tetradev as described. Expecially since I am using Visual Studio, and while NPM Task runneris pretty reliableWebpack Task Runneris pretty buggy.

我也使用npm脚本作为@Tetradev,如上所述。Expecially因为我使用的Visual Studio,虽然NPM Task runner是相当可靠Webpack Task Runner是非常马车