Skrypty NPM mogą robić to samo, co gulp, ale zawierają około 50 razy mniej kodu. W rzeczywistości bez żadnego kodu, tylko argumenty wiersza poleceń.
Na przykład opisany przypadek użycia, w którym chcesz mieć inny kod dla różnych środowisk.
Dzięki skryptom Webpack + NPM jest to takie proste:
"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/*\"",
Teraz po prostu utrzymać dwa skrypty WebPack config, po jednym dla trybu rozwoju, webpack.development.js
i jeden dla trybu produkcyjnego webpack.production.js
. Używam również pliku, webpack.common.js
który zawiera konfigurację pakietu webpack udostępnioną we wszystkich środowiskach i używam webpackMerge do ich scalania.
Ze względu na fajność skryptów NPM pozwala na łatwe łączenie w łańcuch, podobnie jak gulp robi Strumienie / rury.
W powyższym przykładzie, aby zbudować do programowania, po prostu przejdź do wiersza poleceń i wykonaj npm run build:dev
.
- NPM będzie najpierw uruchamiany
prebuild:dev
,
- następnie
build:dev
,
- I wreszcie
postbuild:dev
.
pre
I post
prefiksy powiedzieć KMP jakiej kolejności wykonywać w.
Jeśli zauważysz, dzięki skryptom Webpack + NPM możesz uruchamiać programy natywne, takie jak rimraf
, zamiast opakowania gulp dla programu natywnego, takiego jak gulp-rimraf
. Możesz także uruchamiać natywne pliki .exe systemu Windows, tak jak tutaj, elevate.exe
lub natywne pliki * nix w systemie Linux lub Mac.
Spróbuj zrobić to samo z łykiem. Będziesz musiał poczekać, aż ktoś przyjdzie i napisze opakowanie dla natywnego programu, którego chcesz użyć. Ponadto prawdopodobnie będziesz musiał napisać zawiły kod w następujący sposób: (pobrany bezpośrednio z repozytorium angular2-seed )
Kod programistyczny 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));
};
Kod produkcji 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));
};
Rzeczywisty kod gulp jest znacznie bardziej skomplikowany, ponieważ to tylko 2 z kilkudziesięciu plików gulp w repozytorium.
Więc który z nich jest dla Ciebie łatwiejszy?
Moim zdaniem skrypty NPM znacznie przewyższają łyk i chrząknięcie, zarówno pod względem skuteczności, jak i łatwości użycia, a wszyscy programiści front-end powinni rozważyć użycie go w swoim przepływie pracy, ponieważ jest to duża oszczędność czasu.
AKTUALIZACJA
Jest jeden scenariusz, z którym się spotkałem, w którym chciałem użyć Gulp w połączeniu ze skryptami NPM i Webpack.
Kiedy muszę przeprowadzić zdalne debugowanie na przykład na iPadzie lub urządzeniu z Androidem, muszę uruchomić dodatkowe serwery. W przeszłości uruchamiałem wszystkie serwery jako oddzielne procesy z poziomu IntelliJ IDEA (lub Webstorm), co jest łatwe dzięki „złożonej” konfiguracji uruchamiania. Ale jeśli muszę je zatrzymać i ponownie uruchomić, zamknięcie 5 różnych kart serwera było żmudne, a dane wyjściowe były rozproszone w różnych oknach.
Jedną z zalet gulp jest to, że można połączyć wszystkie dane wyjściowe z oddzielnych niezależnych procesów w jednym oknie konsoli, które staje się nadrzędnym dla wszystkich serwerów podrzędnych.
Stworzyłem więc bardzo proste zadanie typu „łyk”, które po prostu uruchamia moje skrypty NPM lub polecenia bezpośrednio, dzięki czemu wszystkie dane wyjściowe pojawiają się w jednym oknie i mogę łatwo zamknąć wszystkie 5 serwerów jednocześnie, zamykając okno zadania „łyk”.
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'));
Wciąż całkiem sporo kodu tylko do wykonania 5 zadań, moim zdaniem, ale działa w tym celu. Jedynym zastrzeżeniem jest to, że gulp-shell
niektóre polecenia, takie jakios-webkit-debug-proxy
. Musiałem więc stworzyć skrypt NPM, który po prostu wykonuje to samo polecenie, a potem działa.
Dlatego przede wszystkim używam skryptów NPM do wszystkich moich zadań, ale czasami, gdy potrzebuję uruchomić kilka serwerów jednocześnie, uruchamiam zadanie Gulp, aby pomóc. Wybierz odpowiednie narzędzie do odpowiedniej pracy.
AKTUALIZACJA 2
Teraz używam skryptu o nazwie concurrently, który robi to samo, co powyższe zadanie łyka. Uruchamia równolegle wiele skryptów CLI i przesyła je wszystkie do tego samego okna konsoli i jest bardzo prosty w użyciu. Ponownie, nie jest wymagany żaden kod (cóż, kod znajduje się w module node_module do jednoczesnego, ale nie musisz się tym przejmować)
// 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"
To uruchamia wszystkie 5 skryptów równolegle do jednego terminala. Niesamowite! Dlatego rzadko używam łyka, ponieważ jest tak wiele skryptów CLI do wykonywania tych samych zadań bez kodu.
Proponuję przeczytać te artykuły, które szczegółowo je porównują.