NPM-Skripte können dasselbe wie gulp tun, jedoch mit etwa 50-mal weniger Code. In der Tat, ohne Code, nur Befehlszeilenargumente.
Beispiel: Der von Ihnen beschriebene Anwendungsfall, in dem Sie unterschiedlichen Code für unterschiedliche Umgebungen verwenden möchten.
Mit Webpack + NPM-Skripten ist das ganz einfach:
"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/*\"",
Jetzt verwalten Sie einfach zwei Webpack-Konfigurationsskripte, eines für den Entwicklungsmodus webpack.development.js
und eines für den Produktionsmodus webpack.production.js
. Ich verwende auch eine webpack.common.js
Webpack-Konfiguration, die in allen Umgebungen gemeinsam genutzt wird, und verwende webpackMerge, um sie zusammenzuführen.
Aufgrund der Coolness von NPM-Skripten ermöglicht es eine einfache Verkettung, ähnlich wie bei gulp Streams / Pipes.
Im obigen Beispiel gehen Sie zum Erstellen für die Entwicklung einfach zu Ihrer Befehlszeile und führen sie aus npm run build:dev
.
- NPM würde zuerst laufen
prebuild:dev
,
- dann
build:dev
,
- Und schließlich
postbuild:dev
.
Die Präfixe pre
und post
teilen NPM mit, in welcher Reihenfolge sie ausgeführt werden sollen.
Wenn Sie feststellen, dass Sie mit Webpack + NPM-Skripten ein natives Programm ausführen können, z. B. rimraf
anstelle eines Gulp-Wrappers für ein natives Programm wie z gulp-rimraf
. Sie können auch native Windows .exe-Dateien wie hier mit elevate.exe
oder native * nix-Dateien unter Linux oder Mac ausführen .
Versuchen Sie, dasselbe mit Schluck zu tun. Sie müssen warten, bis jemand kommt und einen Schluck-Wrapper für das native Programm schreibt, das Sie verwenden möchten. Außerdem müssen Sie wahrscheinlich verschachtelten Code wie folgt schreiben: (direkt aus dem Angular2-Seed- Repo entnommen )
Gulp Entwicklungscode
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));
};
Gulp Produktionscode
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));
};
Der eigentliche Gulp-Code ist viel komplizierter als dieser, da dies nur zwei der mehreren Dutzend Gulp-Dateien im Repo sind.
Welches ist für Sie einfacher?
Meiner Meinung nach übertreffen NPM-Skripte in Bezug auf Effektivität und Benutzerfreundlichkeit das Schlucken und Grunzen bei weitem, und alle Front-End-Entwickler sollten in Betracht ziehen, sie in ihrem Workflow zu verwenden, da dies eine erhebliche Zeitersparnis darstellt.
AKTUALISIEREN
Es gibt ein Szenario, in dem ich Gulp in Kombination mit NPM-Skripten und Webpack verwenden wollte.
Wenn ich beispielsweise ein Remote-Debugging auf einem iPad oder Android-Gerät durchführen muss, muss ich zusätzliche Server starten. In der Vergangenheit habe ich alle Server als separate Prozesse innerhalb von IntelliJ IDEA (oder Webstorm) ausgeführt, was mit der "Compound" -Laufkonfiguration einfach ist. Wenn ich sie jedoch stoppen und neu starten muss, war es mühsam, 5 verschiedene Server-Registerkarten schließen zu müssen, und die Ausgabe wurde auf die verschiedenen Fenster verteilt.
Einer der Vorteile von gulp besteht darin, dass die gesamte Ausgabe von separaten unabhängigen Prozessen in einem Konsolenfenster verkettet werden kann, das zum übergeordneten Element aller untergeordneten Server wird.
Daher habe ich eine sehr einfache Gulp-Aufgabe erstellt, die nur meine NPM-Skripte oder die Befehle direkt ausführt, sodass die gesamte Ausgabe in einem Fenster angezeigt wird und ich alle 5 Server gleichzeitig beenden kann, indem ich das Fenster für die Gulp-Aufgabe schließe.
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'));
Meiner Meinung nach immer noch ziemlich viel Code, um nur 5 Aufgaben auszuführen, aber es funktioniert für diesen Zweck. Eine Einschränkung ist, dass gulp-shell
einige Befehle nicht korrekt ausgeführt werden, z ios-webkit-debug-proxy
. Also musste ich ein NPM-Skript erstellen, das nur den gleichen Befehl ausführt, und dann funktioniert es.
Daher verwende ich hauptsächlich NPM-Skripte für alle meine Aufgaben. Wenn ich jedoch gelegentlich mehrere Server gleichzeitig ausführen muss, starte ich meine Gulp-Aufgabe, um zu helfen. Wählen Sie das richtige Werkzeug für den richtigen Job.
UPDATE 2
Ich verwende jetzt ein Skript, das gleichzeitig aufgerufen wird und dasselbe wie die oben beschriebene Schluckaufgabe ausführt. Es führt mehrere CLI-Skripte parallel aus und leitet sie alle an dasselbe Konsolenfenster weiter. Die Verwendung ist sehr einfach. Auch hier ist kein Code erforderlich (nun, der Code befindet sich gleichzeitig im node_module, aber Sie müssen sich nicht darum kümmern)
// 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"
Dadurch werden alle 5 Skripte parallel an ein Terminal weitergeleitet. Genial! Daher verwende ich an diesem Punkt selten gulp, da es so viele CLI-Skripte gibt, um dieselben Aufgaben ohne Code auszuführen.
Ich schlage vor, Sie lesen diese Artikel, die sie ausführlich vergleichen.