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.js
et un pour le mode de production, webpack.production.js
. J'utilise également une webpack.common.js
configuration 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
.
- NPM s'exécuterait en premier
prebuild:dev
,
- Puis
build:dev
,
- Et enfin
postbuild:dev
.
Les préfixes pre
et post
indiquent à 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.exe
ou 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-shell
cela 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.