Gulp + Webpack hoặc JUST Webpack?


161

Tôi thấy mọi người sử dụng gulp với webpack. Nhưng sau đó tôi đọc webpack có thể thay thế gulp? Tôi hoàn toàn bối rối ở đây ... ai đó có thể giải thích?

CẬP NHẬT

cuối cùng tôi bắt đầu với một ngụm Tôi mới làm quen với front-end hiện đại và chỉ muốn thức dậy và chạy nhanh. Bây giờ tôi đã bị ướt chân sau hơn một năm, tôi đã sẵn sàng để chuyển sang webpack. Tôi đề nghị cùng một lộ trình cho những người bắt đầu trong cùng một đôi giày. Không nói rằng bạn không thể thử webpack mà chỉ nói nếu nó có vẻ phức tạp bắt đầu với gulp trước ... không có gì sai với điều đó.

Nếu bạn không muốn nuốt chửng, vâng, có tiếng càu nhàu nhưng bạn cũng có thể chỉ định các lệnh trong gói.json và gọi chúng từ dòng lệnh mà không có trình chạy tác vụ chỉ để khởi động và chạy ban đầu. Ví dụ:

"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
Điều này đã giúp tôi nắm bắt Webpack tốt hơn tài liệu của chính Webpack hoặc bất kỳ bài viết nào: github.com/petehunt/webpack-howto
George Ananda Eman

blog.andrewray.me/webpack-when-to-use-and-why không cần sử dụng gulp với webpack
Andy Ray

Ví dụ đơn giản và đơn giản của tôi là tôi muốn máy chủ webpack-dev xử lý js của tôi với HMR, nhưng tôi gặp vấn đề khi tôi không thể sử dụng trình tạo trang web tĩnh và máy chủ phát triển webpack. Với cấu hình phức tạp, tôi có thể đạt được điều này, nhưng tôi cũng có thể làm được. Vì vậy, sự khác biệt chính là thời gian và đường cong học tập.
dewwwald


bản cập nhật của bạn phải là một câu trả lời, +1
Z. Khullah

Câu trả lời:


82

Câu trả lời này có thể giúp. Người chạy tác vụ (Gulp, Grunt, v.v.) và Bundlers (Webpack, Browserify). Tại sao sử dụng cùng nhau?

... Và đây là một ví dụ về việc sử dụng gói web trong một tác vụ gulp. Điều này tiến thêm một bước và giả định rằng cấu hình webpack của bạn được viết bằng 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();
            }
        }
    }
}

Tôi nghĩ rằng bạn sẽ thấy rằng khi ứng dụng của bạn trở nên phức tạp hơn, bạn có thể muốn sử dụng gulp với tác vụ gói web như ví dụ ở trên. Điều này cho phép bạn thực hiện một số điều thú vị hơn trong bản dựng của mình mà trình tải webpack và plugin thực sự không làm, tức là. tạo thư mục đầu ra, máy chủ khởi động, v.v ... Vâng, thật ngắn gọn, webpack thực sự có thể làm những việc đó, nhưng bạn có thể thấy chúng bị giới hạn cho nhu cầu lâu dài của mình. Một trong những lợi thế lớn nhất bạn có được từ gulp -> webpack là bạn có thể tùy chỉnh cấu hình webpack của mình cho các môi trường khác nhau và để gulp thực hiện đúng nhiệm vụ cho đúng thời điểm. Điều này thực sự tùy thuộc vào bạn, nhưng không có gì sai khi chạy webpack từ gulp, trên thực tế có một số ví dụ khá thú vị về cách thực hiện..


Dự án webpack của tôi khá lớn - vì vậy tôi cũng cần tăng bộ nhớ nút thông qua dòng lệnh stackoverflow.com/questions/34727743/. Có cách nào để thực hiện trực tiếp qua webpack không?
Abhinav Singi

Kiểm tra hai cái này Bạn có thể phải đặt bộ nhớ v8 trước khi chạy nút hoặc gói web. stackoverflow.com/questions/7193959/...webpack.github.io/docs/build-performance.html
4m1r

Tôi không chắc tại sao tôi chấp nhận đây là câu trả lời. Tôi cho rằng có lẽ là do liên kết đầu tiên bạn chia sẻ. Nhưng sử dụng webpack từ gulp? Điều đó thậm chí còn lộn xộn hơn nếu bạn hỏi tôi bây giờ :). Tôi thậm chí sẽ không thử dùng đến một thứ như thế.
Tích cực,

80

Các tập lệnh NPM có thể làm tương tự như gulp, nhưng trong mã ít hơn khoảng 50 lần. Trong thực tế, không có mã nào cả, chỉ có các đối số dòng lệnh.

Ví dụ: trường hợp sử dụng mà bạn mô tả nơi bạn muốn có mã khác nhau cho các môi trường khác nhau.

Với Webpack + NPM ScScript, thật dễ dàng:

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

Bây giờ bạn chỉ cần duy trì hai tập lệnh cấu hình webpack, một cho chế độ phát triển webpack.development.jsvà một cho chế độ sản xuất , webpack.production.js. Tôi cũng sử dụng webpack.common.jscấu hình webpack được chia sẻ trên tất cả các môi trường và sử dụng webpackMerge để hợp nhất chúng.

Do tính mát mẻ của các tập lệnh NPM, nó cho phép dễ dàng xâu chuỗi, tương tự như cách gulp thực hiện Streams / pipe.

Trong ví dụ trên, để xây dựng để phát triển, bạn chỉ cần vào dòng lệnh của mình và thực thi npm run build:dev.

  1. NPM đầu tiên sẽ chạy prebuild:dev,
  2. Sau đó build:dev,
  3. Và cuối cùng postbuild:dev.

Các tiền tố preposttiền tố cho NPM biết thứ tự thực hiện.

Nếu bạn nhận thấy, với các tập lệnh Webpack + NPM, bạn có thể chạy một chương trình gốc, chẳng hạn như rimraf, thay vì một trình bao bọc cho một chương trình gốc, chẳng hạn như gulp-rimraf. Bạn cũng có thể chạy các tệp .exe của Windows như tôi đã làm ở đây với elevate.exehoặc các tệp * nix gốc trên Linux hoặc Mac.

Hãy thử làm điều tương tự với gulp. Bạn sẽ phải đợi ai đó đi cùng và viết một gói bọc cho chương trình gốc mà bạn muốn sử dụng. Ngoài ra, bạn có thể sẽ cần phải viết mã phức tạp như thế này: (lấy trực tiếp từ repo angular2-seed )

Mã phát triển 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));
};

Mã sản xuất 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));
};

Mã gulp thực tế phức tạp hơn nhiều, vì đây chỉ là 2 trong số vài chục tệp gulp trong repo.

Vì vậy, cái nào là dễ dàng hơn với bạn?

Theo tôi, các kịch bản NPM vượt xa gulp và grunt, cả về tính hiệu quả và dễ sử dụng, và tất cả các nhà phát triển front-end nên xem xét sử dụng nó trong quy trình làm việc của họ vì đây là một trình tiết kiệm thời gian chính.

CẬP NHẬT

Có một kịch bản tôi đã gặp phải khi tôi muốn sử dụng Gulp kết hợp với các tập lệnh NPM và Webpack.

Khi tôi cần gỡ lỗi từ xa trên thiết bị iPad hoặc Android chẳng hạn, tôi cần khởi động thêm máy chủ. Trước đây, tôi đã chạy tất cả các máy chủ dưới dạng các quy trình riêng biệt, từ bên trong IntelliJ IDEA (Hoặc Webstorm) rất dễ dàng với Cấu hình chạy "Hợp chất". Nhưng nếu tôi cần dừng và khởi động lại chúng, thật tẻ nhạt khi phải đóng 5 tab máy chủ khác nhau, cộng với đầu ra được trải đều trên các cửa sổ khác nhau.

Một trong những lợi ích của gulp là có thể xâu chuỗi tất cả đầu ra từ các quy trình độc lập riêng biệt vào một cửa sổ giao diện điều khiển, trở thành cha mẹ của tất cả các máy chủ con.

Vì vậy, tôi đã tạo một tác vụ gulp rất đơn giản, chỉ chạy trực tiếp các tập lệnh NPM hoặc các lệnh, vì vậy tất cả đầu ra xuất hiện trong một cửa sổ và tôi có thể dễ dàng kết thúc tất cả 5 máy chủ cùng một lúc bằng cách đóng cửa sổ tác vụ 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'));

Theo tôi, vẫn còn khá nhiều mã chỉ để chạy 5 tác vụ, nhưng nó hoạt động đúng với mục đích. Một điều lưu ý là gulp-shelldường như không chạy một số lệnh chính xác, chẳng hạn như ios-webkit-debug-proxy. Vì vậy, tôi đã phải tạo một NPM Script chỉ thực hiện cùng một lệnh và sau đó nó hoạt động.

Vì vậy, tôi chủ yếu sử dụng Tập lệnh NPM cho tất cả các nhiệm vụ của mình, nhưng thỉnh thoảng khi tôi cần chạy một loạt các máy chủ cùng một lúc, tôi sẽ kích hoạt nhiệm vụ Gulp của mình để giúp đỡ. Chọn công cụ phù hợp cho công việc phù hợp.

CẬP NHẬT 2

Bây giờ tôi sử dụng một tập lệnh được gọi đồng thời , thực hiện tương tự như nhiệm vụ gulp ở trên. Nó chạy song song nhiều tập lệnh CLI và chuyển tất cả chúng vào cùng một cửa sổ giao diện điều khiển và rất đơn giản để sử dụng. Một lần nữa, không yêu cầu mã (tốt, mã nằm trong nút_module đồng thời, nhưng bạn không phải lo lắng về điều đó)

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

Điều này chạy tất cả 5 tập lệnh song song được dẫn đến một thiết bị đầu cuối. Tuyệt vời! Vì vậy, điểm này, tôi hiếm khi sử dụng gulp, vì có rất nhiều tập lệnh cli để thực hiện các nhiệm vụ tương tự mà không có mã.

Tôi đề nghị bạn đọc những bài viết này so sánh chúng sâu sắc.


14
Điều đó khiến cho nhiệm vụ của bạn tương đối dễ dàng. Chúc may mắn xây dựng kịch bản phức tạp với vỏ :-)
Filip Sobczak

5
Đây chỉ là những ví dụ. Bản dựng của tôi rất phức tạp và có nhiều tập lệnh thực thi trên shell, hoạt động hoàn hảo và dễ bảo trì. Và, những gì các kịch bản NPM không làm cho tôi, webpack làm, chẳng hạn như uglify, nén gzip, chuyển đổi, v.v ... Cảm ơn. Điều gì là phức tạp mà bạn cần gulp cho?
TetraDev

2
(hơn một năm sau lol): cảm ơn nhiều, phản hồi tuyệt vời !!
Tích cực,

1
@ user108471 Chắc chắn webpack có thể, nó có thể tạo một property.json liệt kê tất cả các mô-đun được biên dịch với ID liên quan. Nhiều loại tệp JSON thông tin thời gian xây dựng có thể được tạo bằng các plugin phù hợp. Những loại cụ thể mà bạn đang đề cập đến gulp có thể làm gì?
TetraDev

1
@GiannosCharalambous Cảm ơn vì mẹo đó. Tôi thực sự đã sử dụng được npm-run-allmột vài tháng nay, nhưng tôi thậm chí không nghĩ đến việc sử dụng -pcờ song song! Tôi sẽ thử điều đó trong tuần này
TetraDev

8

Tôi đã sử dụng cả hai lựa chọn trong các dự án khác nhau của tôi.

Đây là một cái nồi hơi mà tôi kết hợp sử dụng gulpvới webpack- https://github.com/iroy2000/react-reflux-boilerplate-with-webpack .

Tôi có một số dự án khác chỉ được sử dụng webpackvới npm tasks.

Và cả hai đều hoạt động hoàn toàn tốt. Và tôi nghĩ rằng vấn đề của bạn là phức tạp đến mức nào, và bạn muốn có bao nhiêu quyền kiểm soát trong cấu hình của mình.

Ví dụ, nếu bạn nhiệm vụ là đơn giản, giả sử dev, build, test... vv (mà là rất chuẩn), bạn hoàn toàn tốt với chỉ đơn giản webpackvới npm tasks.

Nhưng nếu bạn có quy trình làm việc rất phức tạp và bạn muốn kiểm soát cấu hình của mình nhiều hơn (vì nó là mã hóa), bạn có thể đi theo lộ trình gulp.

Nhưng từ kinh nghiệm của tôi, hệ sinh thái webpack cung cấp quá nhiều plugin và trình tải mà tôi sẽ cần, và vì vậy tôi thích sử dụng phương pháp tối thiểu trần trừ khi có điều gì đó bạn chỉ có thể làm trong gulp. Ngoài ra, nó sẽ làm cho cấu hình của bạn dễ dàng hơn nếu bạn có một thứ ít hơn trong hệ thống của mình.

Và rất nhiều lần, ngày nay, tôi thấy mọi người thực sự thay thế gulp and browsifytất cả cùng webpackmột mình.


5
Phải, nhưng Webpack đã có tiếng xấu là quá phức tạp để hiểu. Tôi có xu hướng thử sử dụng gulp trước với browserify, chưa sẵn sàng để sử dụng Webpack và một phần là tôi chưa làm được gì nhiều với Browserify hoặc nút ở mặt trước vì vậy tôi muốn tìm hiểu cách mọi người đang làm điều đó với gulp và trình duyệt trước tiên chỉ để tôi có lịch sử đó về mặt kinh nghiệm
positiveGuy

1
Webpack chỉ phức tạp nếu bạn chưa từng làm việc với nó, giống như gulp, grunt, browserify, typcript và bất cứ thứ gì khác. Webpack cực kỳ dễ sử dụng một khi bạn hiểu cách thiết lập tệp cấu hình và làm việc với các trình tải. Trong thực tế, các tệp cấu hình có thể chỉ có 20-30 dòng mã để xây dựng gói webpack hoạt động và có thể mạnh mẽ như bạn cần. Chưa kể Webpack Hot Module thay thế là hoàn toàn tuyệt vời. Xem: andrewhfarmer.com/understanding-hmrandrewhfarmer.com/webpack-hmr-tutorialmedium.com/@dabit3/beginner-s-guide-to-webpack-b1f1a3638460
TetraDev

2

Các khái niệm về Gulp và Webpack khá khác nhau. Bạn nói với Gulp cách đặt mã mặt trước theo từng bước, nhưng bạn nói với Webpack những gì bạn muốn thông qua một tệp cấu hình.

Đây là một bài viết ngắn (5 phút đọc) Tôi đã viết giải thích sự hiểu biết của tôi về sự khác biệt: https://medium.com/@Maokai/compile-the-front-end-from-gulp-to-webpack-c45671ad87fe

Công ty chúng tôi đã chuyển từ Gulp sang Webpack trong năm qua. Mặc dù phải mất một thời gian, chúng tôi đã tìm ra cách chuyển tất cả những gì chúng tôi đã làm trong Gulp sang Webpack. Vì vậy, với chúng tôi, mọi thứ chúng tôi đã làm trong Gulp chúng tôi cũng có thể thực hiện thông qua Webpack, nhưng không phải là cách khác.

Kể từ hôm nay, tôi khuyên bạn chỉ nên sử dụng Webpack và tránh hỗn hợp Gulp và Webpack để bạn và nhóm của bạn không cần phải học và duy trì cả hai, đặc biệt là vì chúng đòi hỏi những suy nghĩ rất khác nhau.


2

Thành thật tôi nghĩ tốt nhất là sử dụng cả hai.

  • Webpack cho tất cả các javascript liên quan.
  • Nuốt cho tất cả các css liên quan.

Tôi vẫn phải tìm một giải pháp hợp lý để đóng gói css với webpack và cho đến nay tôi rất vui khi sử dụng gulp cho css và webpack cho javascript.

Tôi cũng sử dụng npmcác tập lệnh như @Tetradev như được mô tả. Đặc biệt là vì tôi đang sử dụng Visual Studio, và trong khi NPM Task runnerkhá đáng tin cậy Webpack Task Runner là khá lỗi .


Tôi đã tìm thấy bằng cách sử dụng NPM Task Runner + Gulp khóa. Đặt các lệnh webpack trong tệp packange.json và CSS (SASS) liên quan đến tệp gulp. Đồng thời thiết lập gói.json để có bước xây dựng gọi tác vụ gulp như một phần của bản phát hành sản xuất
Nico
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.