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.js
e uno per la modalità di produzione webpack.production.js
. webpack.common.js
Uso 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
.
- L'NPM verrebbe eseguito per la prima volta
prebuild:dev
,
- poi
build:dev
,
- E infine
postbuild:dev
.
I prefissi pre
e post
indicano 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.exe
o 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-shell
non 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.