Gulp + Webpack ou JUST Webpack?

161

Je vois des gens utiliser gulp avec webpack. Mais alors j'ai lu webpack peut remplacer gulp? Je suis complètement confus ici ... quelqu'un peut-il expliquer?

METTRE À JOUR

à la fin j'ai commencé par gulp. J'étais nouveau dans le front-end moderne et je voulais juste être opérationnel rapidement. Maintenant que j'ai les pieds bien mouillés après plus d'un an, je suis prêt à passer au webpack. Je suggère le même parcours pour les personnes qui partent dans les mêmes chaussures. Ne dites pas que vous ne pouvez pas essayer webpack mais dites simplement si cela semble compliqué, commencez par gulp ... rien de mal à cela.

Si vous ne voulez pas gulp, oui, il y a du grognement, mais vous pouvez aussi simplement spécifier des commandes dans votre package.json et les appeler à partir de la ligne de commande sans un exécuteur de tâches juste pour être opérationnel au départ. Par exemple:

"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"
    },
PositiveGuy
la source
3
Cela m'a aidé à comprendre Webpack mieux que les propres documents de Webpack ou tout autre article: github.com/petehunt/webpack-howto
George Ananda Eman
blog.andrewray.me/webpack-when-to-use-and-why pas besoin d'utiliser gulp avec webpack
Andy Ray
Mon exemple clair et simple serait que je veux que webpack-dev-server gère mes js avec HMR, mais je rencontre des problèmes où je ne peux pas utiliser les générateurs de site statiques et le serveur de développement webpack. Avec une configuration compliquée, je peux y parvenir, mais je peux le faire aussi. La principale différence est donc le temps et la courbe d'apprentissage.
dewwwald
2 ans plus tard, j'ai encore du mal sur des questions similaires ...
Frank Nocke
votre mise à jour devrait être une réponse, +1
Z. Khullah

Réponses:

82

Cette réponse pourrait aider. Task Runners (Gulp, Grunt, etc.) et Bundlers (Webpack, Browserify). Pourquoi utiliser ensemble?

... et voici un exemple d'utilisation de webpack à partir d'une tâche gulp. Cela va plus loin et suppose que votre configuration Webpack est écrite en 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();
            }
        }
    }
}

Je pense que vous constaterez qu'à mesure que votre application se complique, vous voudrez peut-être utiliser gulp avec une tâche Webpack comme dans l'exemple ci-dessus. Cela vous permet de faire quelques choses plus intéressantes dans votre build que les chargeurs et plugins Webpack ne font vraiment pas, c'est-à-dire. création de répertoires de sortie, démarrage de serveurs, etc. Eh bien, pour être succinct, webpack peut réellement faire ces choses, mais vous pourriez les trouver limités pour vos besoins à long terme. L'un des plus grands avantages de gulp -> webpack est que vous pouvez personnaliser la configuration de votre webpack pour différents environnements et laisser gulp faire la bonne tâche au bon moment. Cela dépend vraiment de vous, mais il n'y a rien de mal à exécuter webpack depuis gulp, en fait, il y a des exemples assez intéressants sur la façon de le faire..

4m1r
la source
Mon projet webpack est assez gros - donc je dois également augmenter la mémoire des nœuds via la commande en ligne de commande stackoverflow.com/questions/34727743/... Existe-t-il un moyen de le faire directement via webpack?
Abhinav Singi
Vérifiez ces deux. Vous devrez probablement définir la mémoire v8 avant d'exécuter node ou webpack. stackoverflow.com/questions/7193959/… et webpack.github.io/docs/build-performance.html
4m1r
Je ne sais pas pourquoi j'ai accepté cela comme réponse. Je suppose que c'était probablement dû au premier lien que vous avez partagé. Mais en utilisant webpack de gulp? c'est encore plus un gâchis si vous me demandez maintenant :). Je n'essaierais même pas de recourir à quelque chose comme ça.
PositiveGuy
80

Les scripts NPM peuvent faire la même chose que gulp, mais avec environ 50 fois moins de code. En fait, sans code du tout, uniquement des arguments de ligne de commande.

Par exemple, le cas d'utilisation que vous avez décrit dans lequel vous souhaitez avoir un code différent pour différents environnements.

Avec les scripts Webpack + NPM, c'est aussi simple que cela:

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

Maintenant , vous maintenez simplement deux scripts de configuration de webpack, un pour le mode de développement, webpack.development.jset un pour le mode de production, webpack.production.js. J'utilise également une webpack.common.jsconfiguration qui héberge le Webpack partagé sur tous les environnements, et utilise webpackMerge pour les fusionner.

En raison de la fraîcheur des scripts NPM, il permet un chaînage facile, similaire à la façon dont gulp fait Streams / pipes.

Dans l'exemple ci-dessus, pour construire pour le développement, il vous suffit d'aller sur votre ligne de commande et de l'exécuter npm run build:dev.

  1. NPM s'exécuterait en premier prebuild:dev,
  2. Puis build:dev,
  3. Et enfin postbuild:dev.

Les préfixes preet postindiquent à NPM dans quel ordre s'exécuter.

Si vous remarquez, avec les scripts Webpack + NPM, vous pouvez exécuter des programmes natifs, tels que rimraf , au lieu d'un gulp-wrapper pour un programme natif tel que gulp-rimraf. Vous pouvez également exécuter des fichiers .exe Windows natifs comme je l'ai fait ici avec elevate.exeou des fichiers * nix natifs sur Linux ou Mac.

Essayez de faire la même chose avec gulp. Vous devrez attendre que quelqu'un vienne et rédige un gulp-wrapper pour le programme natif que vous souhaitez utiliser. De plus, vous devrez probablement écrire du code alambiqué comme celui-ci: (tiré directement du repo angular2-seed )

Code de développement 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));
};

Code de production de 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));
};

Le code réel de gulp est beaucoup plus compliqué que celui-ci, car il ne s'agit que de 2 des plusieurs dizaines de fichiers gulp du dépôt.

Alors, lequel est le plus facile pour vous?

À mon avis, les scripts NPM surpassent de loin le goulot et le grognement, à la fois en efficacité et en facilité d'utilisation, et tous les développeurs frontaux devraient envisager de l'utiliser dans leur flux de travail, car c'est un gain de temps majeur.

METTRE À JOUR

Il y a un scénario que j'ai rencontré dans lequel je voulais utiliser Gulp en combinaison avec des scripts NPM et Webpack.

Lorsque je dois effectuer un débogage à distance sur un iPad ou un appareil Android par exemple, je dois démarrer des serveurs supplémentaires. Dans le passé, j'ai exécuté tous les serveurs en tant que processus séparés, à partir d'IntelliJ IDEA (ou Webstorm), ce qui est facile avec la configuration d'exécution "Compound". Mais si je dois les arrêter et les redémarrer, il était fastidieux de devoir fermer 5 onglets de serveurs différents, et la sortie était répartie sur les différentes fenêtres.

L'un des avantages de gulp est qu'il peut enchaîner toutes les sorties de processus indépendants séparés dans une seule fenêtre de console, qui devient le parent de tous les serveurs enfants.

J'ai donc créé une tâche gulp très simple qui exécute simplement mes scripts NPM ou les commandes directement, de sorte que toute la sortie apparaît dans une seule fenêtre, et je peux facilement mettre fin aux 5 serveurs à la fois en fermant la fenêtre de la tâche 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'));

Encore un peu de code juste pour exécuter 5 tâches, à mon avis, mais cela fonctionne pour le but. Une mise en garde est que gulp-shellcela ne semble pas exécuter correctement certaines commandes, telles que ios-webkit-debug-proxy. J'ai donc dû créer un script NPM qui exécute simplement la même commande, puis cela fonctionne.

J'utilise donc principalement des scripts NPM pour toutes mes tâches, mais parfois, lorsque j'ai besoin d'exécuter plusieurs serveurs à la fois, je lance ma tâche Gulp pour m'aider. Choisissez le bon outil pour le bon travail.

MISE À JOUR 2

J'utilise maintenant un script appelé simultanément qui fait la même chose que la tâche gulp ci-dessus. Il exécute plusieurs scripts CLI en parallèle et les dirige tous vers la même fenêtre de console, et c'est très simple à utiliser. Encore une fois, aucun code requis (enfin, le code est à l'intérieur du node_module pour simultanément, mais vous n'avez pas à vous en préoccuper)

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

Cela exécute les 5 scripts en parallèle acheminés vers un terminal. Impressionnant! Pour que ce point, j'utilise rarement gulp, car il y a tellement de scripts cli pour faire les mêmes tâches sans code.

Je vous propose de lire ces articles qui les comparent en profondeur.

TetraDev
la source
14
C'est parce que vos tâches sont relativement faciles. Bonne chance pour les constructions complexes de scripts avec shell :-)
Filip Sobczak
5
Ce ne sont que des exemples. Ma construction est très complexe et comporte de nombreux scripts s'exécutant sur le shell, fonctionne parfaitement et est facile à maintenir. Et, ce que les scripts NPM ne font pas pour moi, webpack le fait, comme uglify, compresser gzip, transformer, etc. Merci. Qu'est-ce qui est si complexe que vous avez besoin de gorgée?
TetraDev
2
(plus d'un an plus tard lol): merci beaucoup, excellente réponse !!
PositiveGuy
1
@ user108471 Bien sûr, le Webpack peut créer un fichier assets.json qui répertorie tous les modules compilés avec les ID associés. De nombreux autres types de fichiers JSON d'informations de construction peuvent être créés avec les bons plugins. À quel genre de chose faites-vous spécifiquement référence que cette gulp peut faire?
TetraDev
1
@GiannosCharalambous Merci pour cette astuce. J'utilise en fait npm-run-alldepuis quelques mois maintenant, mais je n'ai même pas pensé à utiliser le -pdrapeau parallèle! Je vais essayer ça cette semaine
TetraDev
8

J'ai utilisé les deux options dans mes différents projets.

Voici un passe-partout que j'ai assemblé gulpavec webpack- https://github.com/iroy2000/react-reflux-boilerplate-with-webpack .

J'ai un autre projet utilisé uniquement webpackavec npm tasks.

Et ils fonctionnent tous les deux parfaitement bien. Et je pense que cela dépend de la complexité de votre tâche et du contrôle que vous souhaitez avoir dans votre configuration.

Par exemple, si vous les tâches est simple, disons dev, build, test... etc ( ce qui est très standard), vous êtes tout à fait bien avec tout simple webpackavec npm tasks.

Mais si vous avez un flux de travail très compliqué et que vous souhaitez avoir plus de contrôle sur votre configuration (car il s'agit de codage), vous pouvez opter pour la route gulp.

Mais d'après mon expérience, l'écosystème webpack fournit plus que suffisamment de plugins et de chargeurs dont j'aurai besoin, et j'aime donc utiliser l'approche minimale, à moins qu'il n'y ait quelque chose que vous ne pouvez faire qu'en gulp. Et aussi, cela facilitera votre configuration si vous avez un élément de moins dans votre système.

Et souvent, de nos jours, je vois des gens remplacer gulp and browsifytous ensemble par des webpackseuls.

RR
la source
5
Oui, mais Webpack a la mauvaise réputation d'être trop compliqué à comprendre. J'ai tendance à essayer d'utiliser gulp d'abord avec browserify, pas encore prêt à prendre Webpack et en partie je n'ai pas fait beaucoup avec Browserify ou node sur le front-end, donc je veux savoir comment tout le monde le fait avec gulp et browserify d'abord juste pour avoir cette histoire en termes d'expérience
PositiveGuy
1
Webpack n'est compliqué que si vous n'avez pas travaillé avec, tout comme gulp, grunt, browserify, dactylographié et tout le reste. Webpack est extrêmement facile à utiliser une fois que vous avez compris comment configurer le fichier de configuration et travailler avec des chargeurs. En fait, les fichiers de configuration peuvent être aussi courts que 20 à 30 lignes de code pour une version de webpack fonctionnelle, et peuvent être aussi robustes que vous le souhaitez. Sans oublier que le remplacement de module à chaud Webpack est absolument incroyable. Voir: andrewhfarmer.com/understanding-hmr et andrewhfarmer.com/webpack-hmr-tutorial and medium.com/@dabit3/beginner-s-guide-to-webpack-b1f1a3638460
TetraDev
2

Les concepts de Gulp et Webpack sont assez différents. Vous dites à Gulp comment assembler le code frontal étape par étape, mais vous indiquez à Webpack ce que vous voulez via un fichier de configuration.

Voici un court article (5 min de lecture) que j'ai écrit pour expliquer ma compréhension des différences: https://medium.com/@Maokai/compile-the-front-end-from-gulp-to-webpack-c45671ad87fe

Notre société est passée de Gulp à Webpack au cours de la dernière année. Bien que cela ait pris du temps, nous avons trouvé comment déplacer tout ce que nous avons fait de Gulp vers Webpack. Donc, pour nous, tout ce que nous avons fait dans Gulp, nous pouvons également le faire via Webpack, mais pas l'inverse.

À partir d'aujourd'hui, je suggère simplement d'utiliser Webpack et d'éviter le mélange de Gulp et de Webpack afin que vous et votre équipe n'ayez pas besoin d'apprendre et de maintenir les deux, en particulier parce qu'ils nécessitent des mentalités très différentes.

Maokai
la source
2

Honnêtement, je pense que le mieux est d'utiliser les deux.

  • Webpack pour tous les javascript .
  • Gulp pour tous les css liés.

Je dois encore trouver une solution décente pour l'empaquetage de css avec webpack, et jusqu'à présent je suis content d'utiliser gulp pour css et webpack pour javascript.

J'utilise aussi npm scripts comme @Tetradev comme décrit. Surtout que je l'utilise Visual Studio, et même si NPM Task runnerc'est assez fiable, Webpack Task Runner c'est assez bogué .

Max Favilli
la source
J'ai trouvé en utilisant le NPM Task Runner + Gulp la clé. Placez les commandes webpack dans le fichier packange.json et le CSS (SASS) associé dans le fichier gulp. Configurez également le package.json pour avoir une étape de construction qui appelle une tâche gulp dans le cadre de la version de production
Nico