org node.js webpack gulp

node.js - webpack org js



Gulp+Webpack o JUST Webpack? (5)

Veo personas que usan trago con webpack. Pero luego leí webpack puede reemplazar gulp? Estoy completamente confundido aquí ... ¿alguien puede explicar?

ACTUALIZAR

Al final empecé con trago. Era nuevo en el front-end moderno y solo quería ponerme en marcha rápidamente. Ahora que tengo los pies bastante mojados después de más de un año, estoy listo para pasar a la webpack. Sugiero la misma ruta para las personas que comienzan con los mismos zapatos. No digo que no puedas probar el paquete web, solo di que si parece complicado, comienza con un trago primero ... no hay nada de malo en eso.

Si no quiere tragar, sí, hay gruñidos, pero también puede especificar comandos en su package.json y llamarlos desde la línea de comandos sin un corredor de tareas solo para comenzar a funcionar inicialmente. Por ejemplo:

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


Esta respuesta podría ayudar. Task Runners (Gulp, Grunt, etc.) y Bundlers (Webpack, Browserify). ¿Por qué usar juntos?

... y aquí hay un ejemplo del uso de webpack desde una tarea de trago. Esto va un paso más allá y supone que la configuración de su paquete web está escrita 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(); } } } }

Creo que encontrará que a medida que su aplicación se vuelve más complicada, es posible que desee usar trago con una tarea de paquete web como se muestra en el ejemplo anterior. Esto le permite hacer algunas cosas más interesantes en su compilación que los cargadores de paquetes web y los complementos realmente no hacen, es decir. crear directorios de salida, iniciar servidores, etc. Bueno, para ser sucinto, el paquete web en realidad puede hacer esas cosas, pero puede encontrarlas limitadas para sus necesidades a largo plazo. Una de las mayores ventajas que obtienes de gulp -> webpack es que puedes personalizar la configuración de tu webpack para diferentes entornos y hacer que gulp haga la tarea correcta en el momento adecuado. Realmente depende de usted, pero no hay nada de malo en ejecutar webpack desde Gulp, de hecho, hay algunos ejemplos bastante interesting de cómo hacerlo. El ejemplo anterior es básicamente de jlongster .


Honestamente, creo que lo mejor es usar ambos.

  • Webpack para todos los javascript relacionados.
  • Gulp para todos los css relacionados.

Todavía tengo que encontrar una solución decente para empaquetar css con webpack, y hasta ahora estoy feliz de usar gulp para css y webpack para javascript.

También uso scripts npm como @Tetradev como se describe. Especialmente desde que estoy usando Visual Studio , y aunque NPM Task runner es bastante confiable, Webpack Task Runner es bastante defectuoso.


Los conceptos de Gulp y Webpack son bastante diferentes. Le dice a Gulp cómo armar el código de front-end, paso a paso, pero le dice a Webpack lo que quiere a través de un archivo de configuración.

Aquí hay un breve artículo (5 minutos de lectura) que escribí explicando mi comprensión de las diferencias: https://medium.com/@Maokai/compile-the-front-end-from-gulp-to-webpack-c45671ad87fe

Nuestra empresa se mudó de Gulp a Webpack el año pasado. Aunque tomó algo de tiempo, descubrimos cómo mover todo lo que hicimos en Gulp a Webpack. Entonces, para nosotros, todo lo que hicimos en Gulp también lo podemos hacer a través de Webpack, pero no al revés.

A partir de hoy, sugiero usar Webpack y evitar la combinación de Gulp y Webpack para que usted y su equipo no necesiten aprender y mantener ambos, especialmente porque requieren mentalidades muy diferentes.


Usé ambas opciones en mis diferentes proyectos.

Aquí hay una plantilla que webpack usando gulp con webpack : https://github.com/iroy2000/react-reflux-boilerplate-with-webpack .

Tengo otro proyecto que solo usa webpack con npm tasks .

Y ambos funcionan totalmente bien. Y creo que se reduce a cuán complicada es su tarea y cuánto control desea tener en su configuración.

Por ejemplo, si sus tareas son simples, digamos dev , build , test ... etc (que es muy estándar), está totalmente bien con un simple webpack con npm tasks .

Pero si tiene un flujo de trabajo muy complicado y desea tener un mayor control de su configuración (porque está codificando), podría optar por la ruta de trago.

Pero desde mi experiencia, el ecosistema webpack proporciona complementos y cargadores más que suficientes que necesitaré, por lo que me encanta usar el enfoque mínimo básico a menos que haya algo que solo pueda hacer en trago. Y también, facilitará su configuración si tiene una cosa menos en su sistema.

Y muchas veces, hoy en día, veo personas que en realidad reemplazan gulp and browsify todo junto con webpack solo.


Los scripts de NPM pueden hacer lo mismo que gulp, pero en aproximadamente 50 veces menos código. De hecho, sin ningún código, solo argumentos de línea de comando.

Por ejemplo, el caso de uso que describió donde desea tener un código diferente para diferentes entornos.

Con Webpack + NPM Scripts, es así de fácil:

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

Ahora simplemente mantiene dos scripts de configuración de webpack, uno para el modo de desarrollo, webpack.development.js , y otro para el modo de producción, webpack.production.js . También utilizo un webpack.common.js que aloja la configuración de webpack compartida en todos los entornos, y uso webpackMerge para fusionarlos.

Debido a la frescura de los scripts de NPM, permite un encadenamiento fácil, similar a la forma en que Gulp hace Streams / pipe.

En el ejemplo anterior, para compilar para el desarrollo, simplemente vaya a su línea de comando y ejecute npm run build:dev .

  1. NPM primero correría prebuild:dev ,
  2. Luego build:dev ,
  3. Y finalmente postbuild:dev .

Los prefijos pre y post dicen a NPM en qué orden ejecutar.

Si observa que, con los scripts Webpack + NPM, puede ejecutar programas nativos, como rimraf , en lugar de un gulp-wrapper para un programa nativo como gulp-rimraf . También puede ejecutar archivos .exe nativos de Windows como lo hice aquí con elevate.exe o archivos nativos * nix en Linux o Mac.

Intenta hacer lo mismo con trago. Tendrá que esperar a que alguien venga y escriba un envoltorio para el programa nativo que desea usar. Además, es probable que deba escribir un código complicado como este: (tomado directamente del angular2-seed )

Código de desarrollo de 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)); };

Código de producción 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)); };

El código gulp real es mucho más complicado que esto, ya que esto es solo 2 de las varias docenas de archivos gulp en el repositorio.

Entonces, ¿cuál es más fácil para ti?

En mi opinión, los scripts de NPM superan con creces el trago y el gruñido, tanto en efectividad como en facilidad de uso, y todos los desarrolladores front-end deberían considerar usarlo en su flujo de trabajo porque es un gran ahorro de tiempo.

ACTUALIZAR

Hay un escenario que he encontrado en el que quería usar Gulp en combinación con scripts NPM y Webpack.

Cuando necesito hacer una depuración remota en un dispositivo iPad o Android, por ejemplo, necesito iniciar servidores adicionales. En el pasado, ejecuté todos los servidores como procesos separados, desde IntelliJ IDEA (o Webstorm) que es fácil con la Configuración de ejecución "Compuesta". Pero si necesito detenerlos y reiniciarlos, fue tedioso tener que cerrar 5 pestañas de servidor diferentes, además la salida se extendió por las diferentes ventanas.

Uno de los beneficios de Gulp es que puede encadenar toda la salida de procesos independientes separados en una ventana de consola, que se convierte en el padre de todos los servidores secundarios.

Así que creé una tarea gulp muy simple que solo ejecuta mis scripts NPM o los comandos directamente, de modo que toda la salida aparece en una ventana, y puedo finalizar fácilmente los 5 servidores a la vez cerrando la ventana de la tarea 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''));

Todavía un poco de código solo para ejecutar 5 tareas, en mi opinión, pero funciona para ese propósito. Una advertencia es que gulp-shell no parece ejecutar algunos comandos correctamente, como ios-webkit-debug-proxy . Así que tuve que crear un script NPM que solo ejecuta el mismo comando, y luego funciona.

Así que principalmente uso los Scripts NPM para todas mis tareas, pero ocasionalmente cuando necesito ejecutar un montón de servidores a la vez, enciendo mi tarea Gulp para ayudar. Elija la herramienta adecuada para el trabajo correcto.

ACTUALIZACIÓN 2

Ahora uso un script llamado concurrently que hace lo mismo que la tarea anterior. Ejecuta múltiples scripts de CLI en paralelo y los canaliza a todos a la misma ventana de consola, y es muy fácil de usar. Una vez más, no se requiere código (bueno, el código está dentro del nodo_módulo al mismo tiempo, pero no tiene que preocuparse por eso)

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

Esto ejecuta los 5 scripts en paralelo canalizados a un terminal. ¡Increíble! Para este punto, rara vez uso trago, ya que hay muchos cli scripts para hacer las mismas tareas sin código.

Le sugiero que lea estos artículos que los comparan en profundidad.