Gulp + Webpack или просто Webpack?

Я вижу, что люди используют gulp с webpack. Но потом я прочитал, что webpack может заменить gulp? Я совершенно запутался...кто-нибудь может объяснить?

обновление

в конце концов я начал с gulp. Я был новичком в современном интерфейсе и просто хотел встать и быстро бежать. Теперь, когда у меня ноги совсем мокрые после более чем года, я готов переехать в webpack. Я предлагаю тот же маршрут для людей, которые начинают в той же обуви. Не говорю, что вы не можете попробовать webpack, но просто говоря, если это кажется сложным, начните с глотка...в этом нет ничего плохого.

Если вы не хотите глотать, да, есть ворчание, но вы также можете просто указать команды в своем пакете.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"
    },

5 ответов


этот ответ может помочь. бегуны задачи (глоток, хрюканье и т. д.) и Бандлеры (Webpack, Browserify). Зачем использовать вместе?

...и вот пример использования webpack из задачи gulp. Это идет дальше и предполагает, что ваша конфигурация 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 для разных сред и выполнить правильную задачу в нужное время. Это действительно зависит от вас, но нет ничего плохого в запуск webpack из gulp, на самом деле есть некоторые довольно интересные примеры как это сделать. Пример выше в основном из jlongster.


НПМ скрипты может сделать то же самое, что и 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. NPM сначала запустится prebuild:dev,
  2. затем build:dev,
  3. и наконец postbuild:dev.

на pre и post префиксы сообщают NPM, какой заказ выполнить.

если вы заметили, с webpack + npm скрипты, вы можете запустить собственные программы, такие как rimraf, вместо gulp-wrapper для родной программы, такой как gulp-rimraf. Можно также запускать собственные окна .EXE файлы, как я сделал здесь с elevate.exe или собственные * nix файлы на Linux или Mac.

попробуйте сделать то же самое с gulp. У тебя будет ждать, пока кто-то придет и напишет оболочку глотка для родной программы, которую вы хотите использовать. Кроме того, вам, вероятно, придется написать такой запутанный код: (взято прямо из angular2-seed РЕПО)

код разработки 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

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 намного сложнее, чем это, так как это только 2 из нескольких десятков файлов gulp в РЕПО.

Итак, какой из них вам легче?

на мой взгляд, сценарии NPM намного превосходят gulp и grunt, как по эффективности, так и по простоте использования, и все интерфейсные разработчики должны рассмотреть возможность использования его в своем рабочем процессе, потому что это большая экономия времени.

обновление

есть один сценарий, с которым я столкнулся, где я хотел использовать Gulp в сочетании со сценариями NPM и Webpack.

когда мне нужно сделать удаленной отладки на устройстве iPad или Android, например, мне нужно запустить дополнительные серверы. В прошлом я запускал все серверы как отдельные процессы, из IntelliJ IDEA (или Webstorm), что легко с конфигурацией запуска "Compound". Но если мне нужно остановить и перезапустить их, было утомительно закрывать 5 разных вкладок сервера, плюс вывод был распространен по разным окнам.

одно из преимуществ глотка что может приковать полностью выход из отдельных независимых процессов в одно окно консоли, которое становится родительским для всех дочерних серверов.

поэтому я создал очень простую задачу gulp, которая просто запускает мои сценарии NPM или команды напрямую, поэтому все выходные данные отображаются в одном окне, и я могу легко завершить все 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 задач, на мой взгляд, но он работает для этой цели. Один caveate заключается в том, что gulp-shell не похоже, что некоторые команды выполняются правильно, например ios-webkit-debug-proxy. Поэтому мне пришлось создать сценарий NPM, который просто выполняет ту же команду, а затем он работает.

поэтому я в основном использую сценарии NPM для всех своих задач, но иногда, когда мне нужно запустить сразу несколько серверов, я запускаю свою задачу Gulp, чтобы помочь. Выбрать правильный инструмент для правильной работы.

Я предлагаю вам прочитать эти статьи, сравните их в глубина.


я использовал оба варианта в разных проектах.

вот один шаблон, который я собрал используя gulp с webpack - https://github.com/iroy2000/react-reflux-boilerplate-with-webpack.

у меня есть другой проект, используемый только webpack С npm tasks.

и они оба отлично работают. И я думаю, все сводится к тому, насколько сложна твоя задача, и насколько ты хочешь контролировать свою жизнь. конфигурация.

например, если у вас задачи простые, скажем dev, build, test ... etc (что очень стандартно), вы полностью в порядке с простоwebpack С npm tasks.

но если у вас очень сложный рабочий процесс, и вы хотите иметь больше контроля над своей конфигурацией ( потому что это кодирование), вы можете пойти на маршрут gulp.

но по моему опыту, экосистема webpack предоставляет более чем достаточно плагинов и загрузчиков, которые я понадобится, и поэтому я люблю использовать минимальный подход, если нет чего-то, что вы можете сделать только залпом. А также, это сделает вашу конфигурацию проще, если у вас есть одна вещь меньше в вашей системе.

и много раз, в настоящее время, я вижу, что люди на самом деле заменяют gulp and browsify вместе с .


честно говоря, я думаю, что лучше использовать оба.

  • Webpack для всех в JavaScript связанные.
  • залпом для всех в CSS связанные.

мне все еще нужно найти достойное решение для упаковки css с webpack, и до сих пор я доволен использованием gulp для css и webpack для javascript.

Я также использую npm скрипты как @Tetradev как описано. Expecially, так как я использую Visual Studio, а NPM Task runner довольно надежный Webpack Task Runner довольно багги.


понятия Gulp и Webpack совершенно разные. Вы скажите Gulp как чтобы собрать интерфейсный код шаг за шагом, но вы говорите Webpack что вы хотите через файл config.

вот короткая статья (5 минут чтения), которую я написал, объясняя свое понимание различий: https://medium.com/@Maokai/compile-the-front-end-from-gulp-to-webpack-c45671ad87fe

наша компания переехала из Gulp в Webpack в прошлом год. Хотя это заняло некоторое время, мы выяснили, как переместить все, что мы сделали в глотке в Webpack. Поэтому для нас все, что мы сделали в Gulp, мы также можем сделать через Webpack, но не наоборот.

на сегодняшний день я бы предложил просто использовать Webpack и избегать смеси Gulp и Webpack, поэтому вам и вашей команде не нужно учиться и поддерживать оба, особенно потому, что они требуют очень разных мыслей.