สคริปต์ NPMสามารถทำเช่นเดียวกันกับอึก แต่ในรหัสน้อยกว่าประมาณ 50x ในความเป็นจริงไม่มีรหัสเลยอาร์กิวเมนต์บรรทัดคำสั่งเท่านั้น
ตัวอย่างเช่นกรณีการใช้งานที่คุณอธิบายซึ่งคุณต้องการให้มีรหัสที่แตกต่างกันสำหรับสภาพแวดล้อมที่แตกต่างกัน
ด้วย Webpack + NPM Scripts มันเป็นเรื่องง่าย:
"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/*\"",
ตอนนี้คุณเพียงแค่รักษาสองสคริปต์การกำหนดค่า webpack หนึ่งสำหรับโหมดการพัฒนา, และหนึ่งสำหรับโหมดการผลิตwebpack.development.js
webpack.production.js
ฉันยังใช้การwebpack.common.js
กำหนดค่า webpack ที่แชร์ในทุกสภาพแวดล้อมและใช้ webpackMerge เพื่อรวมเข้าด้วยกัน
เนื่องจากความเย็นของสคริปต์ NPM จะช่วยให้ผูกมัดง่ายคล้ายกับวิธีอึก Streams / ท่อ
ในตัวอย่างข้างต้นเพื่อสร้างสำหรับ Developement npm run build:dev
คุณเพียงแค่ไปที่บรรทัดคำสั่งของคุณและดำเนินการ
- NPM แรกจะวิ่ง
prebuild:dev
,
- จากนั้น
build:dev
,
postbuild:dev
และในที่สุดก็
pre
และpost
คำนำหน้าบอก NPM ซึ่งเพื่อที่จะดำเนินการใน
ถ้าคุณสังเกตเห็นมีสคริปต์ Webpack + NPM คุณสามารถเรียกใช้โปรแกรมพื้นเมืองเช่นแทนที่จะอึกกระดาษห่อสำหรับโปรแกรมพื้นเมืองเช่นrimraf
gulp-rimraf
นอกจากนี้คุณยังสามารถเรียกใช้ไฟล์. exe Windows แบบเดิมที่ฉันทำที่นี่ด้วยelevate.exe
หรือไฟล์เนทีฟ * บน Linux หรือ Mac
ลองทำสิ่งเดียวกันกับอึก คุณจะต้องรอให้ใครบางคนเข้ามาและเขียนโปรแกรมห่อหุ้มอึกสำหรับโปรแกรมเนทีฟที่คุณต้องการใช้ นอกจากนี้คุณอาจต้องเขียนโค้ดที่ซับซ้อนเช่นนี้: (ถ่ายโดยตรงจากrepo angular2-seed )
รหัสพัฒนาอึก
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));
};
รหัสการผลิตอึก
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));
};
รหัส gulp ที่แท้จริงนั้นซับซ้อนกว่านี้มากเนื่องจากเป็นเพียง 2 ในไฟล์ gulp หลายโหลใน repo
แล้วอันไหนง่ายกว่ากันสำหรับคุณ
ในความคิดของฉันสคริปต์ NPM มีประสิทธิภาพเหนือกว่าทั้งอึกทึกและเสี้ยงฮึดฮัดแสดงความไม่พอใจทั้งในประสิทธิภาพและความสะดวกในการใช้งานและนักพัฒนาส่วนหน้าทั้งหมดควรพิจารณาใช้ในเวิร์กโฟลว์ของพวกเขาเพราะมันเป็นโปรแกรมประหยัดเวลาที่สำคัญ
UPDATE
มีสถานการณ์หนึ่งที่ฉันพบว่าฉันต้องการใช้ Gulp ร่วมกับสคริปต์ NPM และ Webpack
เมื่อฉันต้องทำการดีบักแบบรีโมทบนอุปกรณ์ iPad หรือ Android เช่นฉันต้องเริ่มต้นเซิร์ฟเวอร์เพิ่มเติม ในอดีตที่ผ่านมาฉันรันเซิร์ฟเวอร์ทั้งหมดเป็นกระบวนการที่แยกจากภายใน IntelliJ IDEA (หรือ Webstorm) ซึ่งเป็นเรื่องง่ายด้วยการเรียกใช้ "Compound" Run Configuration แต่ถ้าฉันต้องหยุดและรีสตาร์ทมันก็น่าเบื่อที่จะต้องปิดแท็บเซิร์ฟเวอร์ 5 แท็บต่าง ๆ รวมทั้งเอาต์พุตก็กระจายไปทั่วหน้าต่างอื่น
ข้อดีอย่างหนึ่งของ gulp ก็คือสามารถเชื่อมโยงเอาต์พุตทั้งหมดจากกระบวนการอิสระแยกกันในหน้าต่างคอนโซลเดียวซึ่งกลายเป็นพาเรนต์ของเซิร์ฟเวอร์ลูกทั้งหมด
ดังนั้นฉันจึงสร้างงานอึกง่าย ๆ ที่เพิ่งรันสคริปต์ NPM หรือคำสั่งโดยตรงดังนั้นผลลัพธ์ทั้งหมดที่ปรากฏในหน้าต่างเดียวและฉันสามารถจบเซิร์ฟเวอร์ทั้ง 5 ได้พร้อมกันโดยการปิดหน้าต่างงานอึก
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'));
ยังคงเป็นโค้ดเพียงเล็กน้อยเพื่อให้ทำงาน 5 อย่างในความคิดของฉัน แต่มันใช้งานได้ตามวัตถุประสงค์ หนึ่ง caveate คือว่าดูเหมือนจะไม่เรียกใช้คำสั่งบางอย่างถูกต้องเช่นgulp-shell
ios-webkit-debug-proxy
ดังนั้นฉันต้องสร้างสคริปต์ NPM ที่เพิ่งรันคำสั่งเดียวกันจากนั้นก็ใช้งานได้
ดังนั้นฉันจึงใช้ NPM Scripts เป็นหลักสำหรับงานทั้งหมดของฉัน แต่บางครั้งเมื่อฉันต้องการเรียกใช้เซิร์ฟเวอร์จำนวนมากในคราวเดียวฉันจะเริ่มภารกิจ Gulp ของฉันเพื่อช่วยเหลือ เลือกเครื่องมือที่เหมาะสมสำหรับงานที่เหมาะสม
อัพเดท 2
ตอนนี้ฉันใช้สคริปต์ที่เรียกว่าพร้อมกันซึ่งทำสิ่งเดียวกันกับงานอึกข้างต้น มันรันสคริปต์ CLI หลายตัวพร้อมกันและวางสคริปต์ทั้งหมดลงในหน้าต่างคอนโซลเดียวกันและใช้งานง่ายมาก อีกครั้งไม่จำเป็นต้องใช้รหัส (เช่นกันรหัสอยู่ใน node_module สำหรับพร้อมกัน แต่คุณไม่ต้องกังวลกับเรื่องนั้น)
// 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"
สิ่งนี้จะเรียกใช้สคริปต์ทั้งหมด 5 สคริปต์ในแบบขนานไปป์ไลน์หนึ่งเทอร์มินัล ! น่ากลัว ดังนั้นจุดนี้ฉันไม่ค่อยใช้อึกเนื่องจากมีสคริปต์ cli จำนวนมากเพื่อทำงานเดียวกันโดยไม่มีรหัส
ฉันขอแนะนำให้คุณอ่านบทความเหล่านี้ซึ่งเปรียบเทียบพวกเขาในเชิงลึก