Gulp + Webpack还是仅Webpack?

juud5qan  于 2022-11-13  发布在  Webpack
关注(0)|答案(5)|浏览(143)

我看到有人用webpack来代替gulp。但是后来我看到webpack可以代替gulp?我完全搞不懂了...有人能解释一下吗?
更新
最后,我开始了吞咽。我是新的现代前端,只是想尽快开始运行。现在,我已经得到了我的脚相当湿了一年多,我准备转移到webpack。我建议同样的路线,为人民谁开始在相同的鞋。不是说你不能尝试webpack,但只是说,如果它似乎复杂开始吞咽第一...这没有错。
如果你不想使用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"
    },
hwamh0ep

hwamh0ep1#

这个答案可能会有帮助。Task Runners (Gulp, Grunt, etc) and Bundlers (Webpack, Browserify). Why use together?
...这里有一个在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();
            }
        }
    }
}

我想你会发现,随着你的应用程序变得越来越复杂,你可能会想像上面的例子一样使用gulp和webpack任务。这允许你在你的构建中做一些webpack加载器和插件真正不做的更有趣的事情,比如创建输出目录,启动服务器等等。嗯,简单地说,webpack实际上可以做这些事情,但是你可能会发现它们对于你的长期需求来说是有限的。你从gulp -〉webpack得到的最大的好处之一是你可以为不同的环境定制你的webpack配置,并且让gulp在正确的时间做正确的任务。这真的取决于你,但是从gulp运行webpack没有什么错,实际上,有一些很好的interesting例子来说明如何做到这一点。

2wnc66cl

2wnc66cl2#

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

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

使用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/*\"",

现在,您只需维护两个webpack配置脚本,一个用于开发模式webpack.development.js,一个用于生产模式webpack.production.js。我还利用了一个webpack.common.js,其中包含在所有环境中共享的webpack配置,并使用webpackMerge合并它们。
由于NPM脚本的酷,它允许轻松链接,类似于gulp如何处理流/管道。
在上面的示例中,要为开发进行构建,只需转到命令行并执行npm run build:dev
1.国家预防机制将首先运行prebuild:dev
1.然后build:dev
1.最后是postbuild:dev
prepost前缀告诉NPM执行的顺序。
如果您注意到,使用Webpack + NPM脚本,您可以运行本地程序(如rimraf),而不是运行本地程序(如gulp-rimraf)的gulp-wrapper。您还可以运行本地Windows .exe文件,就像我在Linux或Mac上运行elevate.exe或本地 *nix文件时所做的那样。
尝试用gulp做同样的事情。你必须等待有人沿着为你想使用的本机程序写一个gulp-wrapper。另外,你可能需要写如下复杂的代码:(直接取自angular2-seed存储库)

吞咽开发代码

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生产代码

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));
};

实际的gulp代码要复杂得多,因为这只是repo中几十个gulp文件中的两个。
那么,哪一个对你来说更容易呢?
在我看来,NPM脚本在有效性和易用性方面都远远超过了gulp和grunt,所有的前端开发人员都应该考虑在他们的工作流中使用它,因为它可以节省大量的时间。

更新

我曾经遇到过一个场景,我想将Gulp与NPM脚本和Webpack结合使用。
例如,当我需要在iPad或Android设备上进行 * 远程调试 * 时,我需要启动额外的服务器。(或Webstorm)这是很容易与“复合”运行配置。但如果我需要停止和重新启动他们,这是繁琐的必须关闭5个不同的服务器选项卡,加上输出分布在不同的窗口上。
gulp的好处之一是它可以将来自各个独立进程的所有输出链接到一个控制台窗口中,该窗口将成为所有子服务器的父级。
因此,我创建了一个非常简单的gulp任务,它只运行我的NPM脚本或直接运行命令,因此所有输出都显示在一个窗口中,并且我可以通过关闭gulp任务窗口轻松地一次结束所有5个服务器。
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'));

在我看来,仅仅运行5个任务仍然需要相当多的代码,但它可以达到这个目的。一个警告是gulp-shell似乎不能正确地运行一些命令,比如ios-webkit-debug-proxy。所以我不得不创建一个NPM脚本,它只执行相同的命令,然后它就可以工作了。
所以我主要使用NPM脚本来完成我所有的任务,但偶尔当我需要同时运行一堆服务器时,我会启动我的Gulp任务来帮助完成。

更新2

我现在使用一个名为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"

这将并行运行所有5个脚本,并将其发送到一个终端。太棒了!因此,在这一点上,我很少使用Gulp,因为有这么多CLI脚本可以在没有代码的情况下完成相同的任务。

我建议您阅读这些深入比较它们的文章。

5lhxktic

5lhxktic3#

我在不同的项目中使用了这两种选项。
下面是我使用gulpwebpack-https://github.com/iroy2000/react-reflux-boilerplate-with-webpack组合在一起的一个样板文件。
我有一些其他的项目只使用webpacknpm tasks
它们都工作得很好。我认为这归结为你的任务有多复杂,以及你想在你的配置中拥有多少控制权。
例如,如果你的任务很简单,比如devbuildtest...等等(这是非常标准的),你完全可以只使用简单的webpacknpm tasks
但是如果你有非常复杂的工作流程,并且你想对你的配置有更多的控制(因为它是编码),你可以选择吞咽路线。
但根据我的经验,webpack生态系统提供了足够多的插件和加载器,我将需要,所以我喜欢使用最低限度的方法,除非有什么你只能在大口做。而且,它会使您的配置更容易,如果你有一个在您的系统中少一件事。
现在,我经常看到人们将gulp and browsify全部替换为单独的webpack

xoshrz7s

xoshrz7s4#

Gulp和Webpack的概念是完全不同的,你告诉Gulp * 如何 * 一步一步地把前端代码放在一起,但是你通过一个配置文件告诉Webpack * 你想要什么 *。
下面是一篇短文(5分钟阅读),我写了解释我对差异的理解:https://medium.com/@Maokai/compile-the-front-end-from-gulp-to-webpack-c45671ad87fe
在过去的一年里,我们的公司从Gulp转移到Webpack。虽然花了一些时间,但我们找到了如何将我们在Gulp中所做的一切转移到Webpack中。所以对我们来说,我们在Gulp中所做的一切也可以通过Webpack来做,而不是相反。
从今天开始,我建议你只使用Webpack,避免Gulp和Webpack的混合使用,这样你和你的团队就不需要学习和维护这两种工具,特别是因为它们需要非常不同的思维模式。

zzoitvuj

zzoitvuj5#

老实说,我认为最好的是两者都用。

*Webpack适用于所有javascript相关内容。
*大口所有css相关。

我仍然必须找到一个体面的解决方案, Package css与webpack,到目前为止,我很高兴使用gulp为css和webpack为javascript。
我也使用npm脚本作为@Tetradev。特别是因为我使用Visual Studio,而NPM Task runner相当可靠Webpack Task Runner相当有缺陷

相关问题