Gulp + Webpack o JUST Webpack?


161

Vedo persone che usano gulp con webpack. Ma poi ho letto webpack in grado di sostituire gulp? Sono completamente confuso qui ... qualcuno può spiegare?

AGGIORNARE

alla fine ho iniziato con gulp. Ero nuovo al front-end moderno e volevo solo alzarmi e correre veloce. Ora che ho i piedi abbastanza bagnati dopo più di un anno, sono pronto per passare al webpack. Suggerisco lo stesso percorso per le persone che iniziano con le stesse scarpe. Non dire che non puoi provare il webpack, ma dì solo se sembra complicato iniziare prima con gulp ... niente di sbagliato in questo.

Se non vuoi gulp, sì, c'è grugnito ma puoi anche specificare i comandi nel tuo package.json e chiamarli dalla riga di comando senza un task runner solo per iniziare e funzionare inizialmente. Per esempio:

"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"
    },

3
Questo mi ha aiutato a cogliere Webpack meglio dei documenti di Webpack o di qualsiasi altro articolo: github.com/petehunt/webpack-howto
George Ananda Eman,

blog.andrewray.me/webpack-when-to-use-and- perché non c'è bisogno di usare gulp con webpack
Andy Ray

Il mio esempio chiaro e semplice sarebbe che voglio webpack-dev-server per gestire i miei js con HMR, ma sto riscontrando problemi in cui non posso usare generatori di siti statici e server di sviluppo webpack. Con una configurazione complicata posso raggiungere questo obiettivo, ma è un semplice sorso che posso farlo anche io. Quindi la differenza principale è il tempo e la curva di apprendimento.
dewwwald,

2 anni dopo, continuo a lottare su questioni simili ...
Frank Nocke,

il tuo aggiornamento dovrebbe essere una risposta, +1
Z. Khullah,

Risposte:


82

Questa risposta potrebbe aiutare. Task Runner (Gulp, Grunt, ecc.) E Bundlers (Webpack, Browserify). Perché usare insieme?

... ed ecco un esempio dell'uso del webpack all'interno di un'attività gulp. Questo fa un ulteriore passo avanti e presuppone che la configurazione del tuo webpack sia scritta in 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();
            }
        }
    }
}

Penso che scoprirai che man mano che la tua app diventa più complicata, potresti voler usare gulp con un'attività webpack come nell'esempio sopra. Ciò ti consente di fare alcune cose più interessanti nella tua build che caricatori e plugin di webpack non fanno davvero, ad es. creazione di directory di output, avvio di server, ecc. Beh, per essere concisi, il webpack può effettivamente fare queste cose, ma potresti trovarle limitate per le tue esigenze a lungo termine. Uno dei maggiori vantaggi che ottieni da gulp -> webpack è che puoi personalizzare la configurazione del tuo webpack per diversi ambienti e fare in modo che gulp svolga le attività giuste al momento giusto. Sta davvero a te, ma non c'è niente di sbagliato nell'esecuzione di webpack da gulp, in effetti ci sono alcuni esempi piuttosto interessanti su come farlo..


Il mio progetto webpack è piuttosto grande, quindi ho bisogno di aumentare la memoria del nodo anche tramite il comando della riga di comando stackoverflow.com/questions/34727743/… Esiste un modo per farlo direttamente tramite webpack?
Abhinav Singi,

Dai un'occhiata a questi due. Probabilmente devi impostare la memoria v8 prima di eseguire il nodo o il webpack. stackoverflow.com/questions/7193959/... e webpack.github.io/docs/build-performance.html
4m1r

Non sono sicuro del motivo per cui ho accettato questa come risposta. Suppongo che probabilmente sia dovuto al primo link che hai condiviso. Ma usando webpack da gulp? è ancora più un casino se me lo chiedi ora :). Non proverei nemmeno a ricorrere a qualcosa del genere.
Positivo

80

Gli script NPM possono fare lo stesso di gulp, ma con circa 50 volte meno codice. In effetti, senza alcun codice, solo argomenti della riga di comando.

Ad esempio, il caso d'uso descritto in cui si desidera avere un codice diverso per ambienti diversi.

Con gli script Webpack + NPM è facile:

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

Ora gestisci semplicemente due script di configurazione del webpack, uno per la modalità di sviluppo webpack.development.jse uno per la modalità di produzione webpack.production.js. webpack.common.jsUso anche una configurazione webpack condivisa su tutti gli ambienti e utilizzo webpackMerge per unirli.

A causa della freddezza degli script NPM, consente un facile concatenamento, simile a come gulp esegue stream / pipe.

Nell'esempio sopra, per costruire per lo sviluppo, vai semplicemente alla tua riga di comando ed esegui npm run build:dev.

  1. L'NPM verrebbe eseguito per la prima volta prebuild:dev,
  2. poi build:dev,
  3. E infine postbuild:dev.

I prefissi pree postindicano a NPM in quale ordine eseguire.

Se noti, con gli script Webpack + NPM, puoi eseguire un programma nativo, ad esempio rimraf, anziché un gulp-wrapper per un programma nativo come gulp-rimraf. Puoi anche eseguire file .exe di Windows nativi come ho fatto qui con elevate.exeo file * nix nativi su Linux o Mac.

Prova a fare la stessa cosa con gulp. Dovrai aspettare che arrivi qualcuno e scrivere un gulp-wrapper per il programma nativo che vuoi usare. Inoltre, probabilmente dovrai scrivere codice contorto in questo modo: (preso direttamente dal repository angular2-seed )

Codice di sviluppo 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));
};

Codice di produzione 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));
};

L'attuale codice gulp è molto più complicato di questo, poiché si tratta solo di due delle diverse dozzine di file gulp nel repository.

Quindi, quale è più facile per te?

A mio avviso, gli script NPM superano di gran lunga il gulp e il grugnito, sia in termini di efficacia che di facilità d'uso, e tutti gli sviluppatori front-end dovrebbero considerare l'utilizzo nel loro flusso di lavoro perché è un notevole risparmio di tempo.

AGGIORNARE

C'è uno scenario che ho riscontrato in cui volevo usare Gulp in combinazione con script NPM e Webpack.

Ad esempio, quando devo eseguire il debug remoto su un dispositivo iPad o Android, devo avviare server aggiuntivi. In passato ho eseguito tutti i server come processi separati, dall'interno di IntelliJ IDEA (o Webstorm) che è facile con la configurazione di esecuzione "Compound". Ma se ho bisogno di fermarli e riavviarli, è stato noioso dover chiudere 5 diverse schede del server, inoltre l'output è stato distribuito tra le diverse finestre.

Uno dei vantaggi di gulp è che può incatenare tutto l'output da processi indipendenti separati in una finestra della console, che diventa il genitore di tutti i server figlio.

Quindi ho creato un'attività gulp molto semplice che esegue semplicemente i miei script NPM o i comandi direttamente, quindi tutto l'output appare in una finestra e posso facilmente terminare tutti e 5 i server contemporaneamente chiudendo la finestra dell'attività gulp.

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

Ancora un po 'di codice solo per eseguire 5 attività, secondo me, ma funziona allo scopo. Un caveato è che gulp-shellnon sembra eseguire correttamente alcuni comandi, come ad esempio ios-webkit-debug-proxy. Quindi ho dovuto creare uno script NPM che esegue semplicemente lo stesso comando e quindi funziona.

Quindi uso principalmente gli script NPM per tutte le mie attività, ma occasionalmente quando ho bisogno di eseguire un sacco di server contemporaneamente, accendo il mio compito Gulp per dare una mano. Scegli lo strumento giusto per il lavoro giusto.

AGGIORNAMENTO 2

Ora uso uno script chiamato contemporaneamente che fa la stessa cosa del compito gulp sopra. Esegue più script CLI in parallelo e li reindirizza tutti alla stessa finestra della console ed è molto semplice da usare. Ancora una volta, nessun codice richiesto (beh, il codice è all'interno del node_module per allo stesso tempo, ma non devi preoccuparti di quello)

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

Ciò esegue tutti e 5 gli script in parallelo inviati a un terminale. Eccezionale! Quindi, questo punto, uso raramente gulp, dal momento che ci sono così tanti script cli per fare le stesse attività senza codice.

Ti suggerisco di leggere questi articoli che li confrontano in modo approfondito.


14
Ecco perché i tuoi compiti sono relativamente facili. Buona fortuna per lo scripting di build complesse con shell :-)
Filip Sobczak,

5
Questi sono solo esempi. La mia build è molto complessa e ha molti script in esecuzione sulla shell, funziona perfettamente ed è facile da mantenere. E ciò che gli script NPM non fanno per me, lo fa il webpack, come uglify, compress gzip, transform, ecc. Grazie. Che cosa è così complesso che hai bisogno di sorseggiare?
TetraDev,

2
(più di un anno dopo lol): grazie mille, ottima risposta !!
Positivo

1
@ user108471 Certo che il webpack può, può creare un assets.json che elenca tutti i moduli compilati con gli ID associati. Molti altri tipi di file JSON di informazioni in fase di creazione possono essere creati con i plug-in giusti. Di che tipo ti riferisci specificamente a quel sorso?
TetraDev,

1
@GiannosCharalambous Grazie per il suggerimento. In realtà sto usando npm-run-allda alcuni mesi, ma non ho nemmeno pensato di usare la -pbandiera parallela! Lo proverò questa settimana
TetraDev il

8

Ho usato entrambe le opzioni nei miei diversi progetti.

Ecco un testo standard che ho messo insieme usando gulpcon webpack- https://github.com/iroy2000/react-reflux-boilerplate-with-webpack .

Ho qualche altro progetto usato solo webpackcon npm tasks.

Ed entrambi funzionano perfettamente. E penso che il problema sia quanto è complicato il tuo compito e quanto controllo vuoi avere nella tua configurazione.

Ad esempio, se le attività è semplice, diciamo dev, build, test... ecc (che è molto standard), si sono totalmente bene con solo semplice webpackcon npm tasks.

Ma se hai un flusso di lavoro molto complicato e vuoi avere un maggiore controllo della tua configurazione (perché è la codifica), potresti scegliere gulp route.

Ma dalla mia esperienza, l'ecosistema del webpack fornisce plug-in e caricatori più che sufficienti di cui avrò bisogno, e quindi adoro usare l'approccio minimale a meno che non ci sia qualcosa che puoi fare solo in gulp. Inoltre, renderà la tua configurazione più semplice se hai una cosa in meno nel tuo sistema.

E molte volte, al giorno d'oggi, vedo le persone in realtà sostituire gulp and browsifytutto insieme da webpacksole.


5
Sì, ma Webpack ha avuto una brutta reputazione di essere troppo complicato da capire. Tendo a provare a usare gulp prima con browserify, non sono ancora pronto ad affrontare Webpack e in parte non ho fatto molto con Browserify o il nodo sul front-end, quindi voglio imparare come lo fanno tutti con gulp e browserify prima solo così ho quella storia in termini di esperienza
Positivo

1
Il webpack è complicato solo se non ci hai lavorato, proprio come gulp, grunt, browserify, dattiloscritto e qualsiasi altra cosa. Webpack è estremamente facile da usare una volta capito come impostare il file di configurazione e lavorare con i caricatori. In effetti, i file di configurazione possono essere lunghi fino a 20-30 righe di codice per una build di webpack funzionante e possono essere robusti quanto è necessario. Per non parlare della sostituzione del modulo a caldo Webpack è assolutamente sorprendente. Vedi: andrewhfarmer.com/understanding-hmr e andrewhfarmer.com/webpack-hmr-tutorial and medium.com/@dabit3/beginner-s-guide-to-webpack-b1f1a3638460
TetraDev

2

I concetti di Gulp e Webpack sono abbastanza diversi. Spiega a Gulp come mettere insieme il codice front-end, ma dici a Webpack cosa vuoi attraverso un file di configurazione.

Ecco un breve articolo (5 minuti di lettura) che ho scritto spiegando la mia comprensione delle differenze: https://medium.com/@Maokai/compile-the-front-end-from-gulp-to-webpack-c45671ad87fe

La nostra azienda è passata da Gulp a Webpack nell'ultimo anno. Anche se ci è voluto del tempo, abbiamo capito come spostare tutto ciò che abbiamo fatto in Gulp su Webpack. Quindi per noi, tutto ciò che abbiamo fatto in Gulp è possibile anche tramite Webpack, ma non viceversa.

Ad oggi, suggerirei di utilizzare solo Webpack ed evitare la combinazione di Gulp e Webpack in modo che tu e il tuo team non abbiate bisogno di imparare e mantenere entrambi, soprattutto perché richiedono mentalità molto diverse.


2

Onestamente penso che il migliore sia usare entrambi.

  • Webpack per tutti i javascript correlati.
  • Gulp per tutti i CSS correlati.

Devo ancora trovare una soluzione decente per il confezionamento di CSS con Webpack, e finora sono felice di usare Gulp per CSS e Webpack per JavaScript.

Uso anche gli npmscript come @Tetradev come descritto. Soprattutto da quando sto usando Visual Studio, e mentre NPM Task runnerè abbastanza affidabile Webpack Task Runner è piuttosto buggy .


Ho trovato utilizzando NPM Task Runner + Gulp la chiave. Inserisci i comandi webpack nel file packange.json e CSS (SASS) correlati nel file gulp. Installa anche package.json in modo che abbia un passaggio di generazione che chiama un'attività gulp come parte della versione di produzione
Nico,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.