Scheinbar aus heiterem Himmel begann die Gulp-Verarbeitung, die ich für diese Website eingerichtet hatte, mit einem Wettlauf-Problem. Ich führte meinen watch-Befehl aus, änderte etwas CSS, und die Verarbeitung hinterließ manchmal einige zusätzliche Dateien, die während der Verarbeitung aufgeräumt werden sollten. Als ob die Bereinigungsaufgaben vor der Landung der Dateien im Dateisystem stattgefunden hätten (oder so ähnlich… ich bin der Sache nie wirklich auf den Grund gegangen).
Vergessen wir die Details dieses Fehlers. Ich dachte, ich würde es lösen, indem ich die Dinge auf Gulp 4.x anstelle von 3.x aktualisiere und die Dinge im integrierten Befehl gulp.series ausführe, was meiner Meinung nach helfen würde (und das tat es auch).
Gulp 4.x zum Laufen zu bringen, war eine ziemliche Reise für mich, die darin bestand, dass ich ein Jahr lang aufgab, dann den Kampf neu entfachte und ihn schließlich behob. Mein Problem war, dass Gulp 4 eine CLI-Version von 2.x benötigt, während Gulp 3 aus irgendeinem Grund eine Version 3.x verwendete. Im Wesentlichen musste ich die Versionen herabstufen, aber nachdem ich unzählige Dinge versucht hatte, schien nichts zu funktionieren, als ob eine Geisterversion von CLI 3.x auf meiner Maschine wäre.
Ich bin sicher, dass versiertere Kommandozeilen-Experten dies schneller als ich herausgefunden hätten, aber es stellt sich heraus, dass die Ausführung von command -v gulp den Dateipfad enthüllt, an dem Gulp installiert ist, was bei mir /usr/local/share/npm/bin/gulp ergab, und das manuelle Löschen von dort vor der Neuinstallation der neuesten Version hat mich wieder auf 2.x zurückgebracht.
Jetzt, wo ich Gulp 4.x verwenden konnte, habe ich meine gulpfile.js in kleinere Funktionen umgeschrieben, die jeweils ziemlich isoliert in ihrer Verantwortung sind. Vieles davon ist **ganz spezifisch für mein Setup** auf dieser Website, daher ist es nicht als generische Vorlage gedacht. Ich veröffentliche es nur, weil es mir bei der Erstellung sicherlich geholfen hätte.
Was mein spezielles Gulpfile tut
- Führt einen Webserver ( Browsersync ) für Stil-Injektion und automatische Aktualisierung aus
- Führt einen Dateibeobachter (native Gulp-Funktion) aus, um die richtigen Aufgaben für die richtigen Dateien auszuführen und die obigen Dinge zu tun
- CSS-Verarbeitung
- Sass > Autoprefixer > Minifizieren
- Bricht den Stylesheet-Cache aus den Vorlagen (z. B.
<link href="style.css?BREAK_CACHE"> - Legt style.css an den richtigen Ort für ein WordPress-Theme und bereinigt Dateien, die nur während der Verarbeitung benötigt werden
- JavaScript-Verarbeitung
- Babel > Verketten > Minifizieren
- Bricht den Browser-Cache für die
<script>s - Bereinigt ungenutzte Dateien, die bei der Verarbeitung erstellt wurden
- SVG-Verarbeitung
- Erstellt einen SVG-Sprite (einen Block von
<symbol>s - Benennt ihn als sprite.php-Datei (damit er in einer Vorlage per PHP-Include eingebunden werden kann) und platziert ihn an einem bestimmten Ort
- Erstellt einen SVG-Sprite (einen Block von
- PHP-Verarbeitung
- Aktualisiert den Ajax-Aufruf im JavaScript, um den Cache zu leeren, wenn die Anzeigen geändert werden
Code-Dump!
const gulp = require("gulp"),
browserSync = require("browser-sync").create(),
sass = require("gulp-sass"),
postcss = require("gulp-postcss"),
autoprefixer = require("autoprefixer"),
cssnano = require("cssnano"),
del = require("del"),
babel = require("gulp-babel"),
minify = require("gulp-minify"),
concat = require("gulp-concat"),
rename = require("gulp-rename"),
replace = require("gulp-replace"),
svgSymbols = require("gulp-svg-symbols"),
svgmin = require("gulp-svgmin");
const paths = {
styles: {
src: ["./scss/*.scss", "./art-direction/*.scss"],
dest: "./css/"
},
scripts: {
src: ["./js/*.js", "./js/libs/*.js", "!./js/min/*.js"],
dest: "./js/min"
},
svg: {
src: "./icons/*.svg"
},
php: {
src: ["./*.php", "./ads/*.php", "./art-direction/*.php", "./parts/**/*.php"]
},
ads: {
src: "./ads/*.php"
}
};
/* STYLES */
function doStyles(done) {
return gulp.series(style, moveMainStyle, deleteOldMainStyle, done => {
cacheBust("./header.php", "./");
done();
})(done);
}
function style() {
return gulp
.src(paths.styles.src)
.pipe(sass())
.on("error", sass.logError)
.pipe(postcss([autoprefixer(), cssnano()]))
.pipe(gulp.dest(paths.styles.dest))
.pipe(browserSync.stream());
}
function moveMainStyle() {
return gulp.src("./css/style.css").pipe(gulp.dest("./"));
}
function deleteOldMainStyle() {
return del("./css/style.css");
}
/* END STYLES */
/* SCRIPTS */
function doScripts(done) {
return gulp.series(
preprocessJs,
concatJs,
minifyJs,
deleteArtifactJs,
reload,
done => {
cacheBust("./parts/footer-scripts.php", "./parts/");
done();
}
)(done);
}
function preprocessJs() {
return gulp
.src(paths.scripts.src)
.pipe(
babel({
presets: ["@babel/env"],
plugins: ["@babel/plugin-proposal-class-properties"]
})
)
.pipe(gulp.dest("./js/babel/"));
}
function concatJs() {
return gulp
.src([
"js/libs/jquery.lazy.js",
"js/libs/jquery.fitvids.js",
"js/libs/jquery.resizable.js",
"js/libs/prism.js",
"js/babel/highlighting-fixes.js",
"js/babel/global.js"
])
.pipe(concat("global-concat.js"))
.pipe(gulp.dest("./js/concat/"));
}
function minifyJs() {
return gulp
.src(["./js/babel/*.js", "./js/concat/*.js"])
.pipe(
minify({
ext: {
src: ".js",
min: ".min.js"
}
})
)
.pipe(gulp.dest(paths.scripts.dest));
}
function deleteArtifactJs() {
return del([
"./js/babel",
"./js/concat",
"./js/min/*.js",
"!./js/min/*.min.js"
]);
}
/* END SCRIPTS */
/* SVG */
function doSvg() {
return gulp
.src(paths.svg.src)
.pipe(svgmin())
.pipe(
svgSymbols({
templates: ["default-svg"],
svgAttrs: {
width: 0,
height: 0,
display: "none"
}
})
)
.pipe(rename("icons/sprite/icons.php"))
.pipe(gulp.dest("./"));
}
/* END SVG */
/* GENERIC THINGS */
function cacheBust(src, dest) {
var cbString = new Date().getTime();
return gulp
.src(src)
.pipe(
replace(/cache_bust=\d+/g, function() {
return "cache_bust=" + cbString;
})
)
.pipe(gulp.dest(dest));
}
function reload(done) {
browserSync.reload();
done();
}
function watch() {
browserSync.init({
proxy: "csstricks.local"
});
gulp.watch(paths.styles.src, doStyles);
gulp.watch(paths.scripts.src, doScripts);
gulp.watch(paths.svg.src, doSvg);
gulp.watch(paths.php.src, reload);
gulp.watch(paths.ads.src, done => {
cacheBust("./js/global.js", "./js/");
done();
});
}
gulp.task("default", watch);
Probleme / Fragen
- Das Schlimmste ist, dass der Cache nicht sehr intelligent geleert wird. Wenn sich CSS ändert, wird der Cache aller Stylesheets geleert, nicht nur der relevanten.
- Ich würde SVG-Icons in Zukunft wahrscheinlich einfach mit PHP
include()s direkt einbetten, anstatt mich mit Sprites zu befassen. - Der SVG-Prozessor bricht ab, wenn die ursprünglichen SVGs
widthundheightAttribute haben, was falsch erscheint. - Würde gulp-changed eine Geschwindigkeitssteigerung bringen? Also nur Dateien betrachten, die sich geändert haben, anstatt alle Dateien? Oder ist es nicht mehr nötig?
- Sollte ich Gulp neu starten bei Änderungen an der gulpfile.js?
- Es wäre schön, wenn alle von mir verwendeten Bibliotheken ES6-kompatibel wären, damit ich Dinge
importieren könnte, anstatt sie manuell verketten zu müssen.
Es gibt immer so viel mehr, das getan werden kann. Idealerweise würde ich diese gesamte Website einfach Open-Source machen, aber dazu bin ich noch nicht gekommen.
Unsere Gulp-Datei ist tatsächlich ziemlich ähnlich, mit Ausnahme der Cache-Leerung. Da wir die Skripte und Stile in PHP (WordPress) registrieren, fügen wir einfach den Änderungszeitstempel der Datei als Cache-Buster hinzu. Funktioniert ziemlich gut, der Cache wird nur geleert, wenn sich die Datei tatsächlich ändert.
Die wp_enqueue_functions nehmen $ver als vierten Parameter, wie folgt:
wp_enqueue_style( 'handle', './pathtofile/style.css', 'dep', filetime('./pathtofile/style.css') );Ah, ich sollte klarstellen, der zweite Parameter der Registrierung ist die URL zur Datei, und die Funktion filetime ist der Dateisystempfad zur Datei.
Ich gehe davon aus, dass
filetime()für den Server trivial ist, dies bei jeder Anfrage zu berechnen? Ich bin nicht server-kundig genug, um das zu wissen.Mein Freund, ich muss dir leider sagen, dass gulp-cli noch keine 3.0 erreicht hat (es hat aber 0.3.0 erreicht).
Aber CLI ist nicht einmal erforderlich.
Alles, was es tut, ist, dir zu erlauben, deine lokale (Node-Module oder ähnliches) Version von Gulp auszuführen, indem du sie global aufrufst (im richtigen Projekt), was verschiedene Projekte mit unterschiedlichen Versionen von Gulp ermöglicht, aber nur ein globales Gulp.
filetime()ist wirklich clever, Jakob. Es scheint sehr performant zu sein und ist wahrscheinlich vernachlässigbar für eine Handvoll Dateien.Für Websites, die sich in der Produktion nicht zu oft ändern, ist ein granularerer Ansatz das Anhängen der Theme-Version:
wp_get_theme()->get('Version'). Dies hat den zusätzlichen Vorteil, dass wir die Nummer auf dem neuesten Stand halten müssen :)Ich habe eine universellere, ultimative Lösung gefunden
https://gist.github.com/marsjaninzmarsa/038ce27f1e76b90edd5773532e48520b
So in etwa für Ihre Gulp-Cache-Leerung. Es berechnet alles im Filter für jeden Build, aktualisiert den Hash aber nur, wenn sich die Datei geändert hat.
// Installieren Sie gulp-rev, gulp-rev-replace
var revisionFilter = gulp.filter([‘/*’, ‘!/index.html’], { restore: true });
gulp.src(…)
.pipe(revisionFilter)
.pipe(gulp.rev()) // berechnet den Hash der Dateien
.pipe(revisionFilter.restore)
Ich verwende 'gulp-rev' zur Versionierung basierend auf einem Content-Hash, der konstant bleiben sollte, es sei denn, eine Datei hat sich tatsächlich geändert. Aufgrund der Struktur unseres Projekts (gibt eine Reihe von CSS-Dateien für verschiedene Themes aus, die in unserem CMS ausgewählt werden können) und dann verwenden wir es, um ein Manifest zu generieren, um alle Dateinamen für unseren Backend-Code zu erhalten. Das heißt, ich habe dies noch nicht in Gulp 4 ausprobiert. Da Gulp 3 in den neuesten Versionen von Node nicht funktioniert, ist dies eine Hürde, die wir bald überwinden müssen.
Nur mein 2 Cent für
gulp-rev– ich benutze es seit Jahren mit großem Erfolg, zusammen mitgulp-rev-rewriteundgulp-rev-delete-original.Zach – Ich hatte damit keine Probleme mit Gulp 4 :)
Ich habe auch eine Gulp 4-Datei erstellt, die öffentlich ist: https://github.com/jenstornell/gulpfile-style-script. Ein schöner Vorteil meines Repos ist, dass Sie es installieren können, indem Sie einfach eine Zeile in die Eingabeaufforderung kopieren und einfügen.
Ich mag gulp-load-plugins sehr. Es erlaubt Ihnen im Grunde, die meisten der erforderlichen Dinge am Anfang zu überspringen.
let $ = require('gulp-load-plugins')();Dann, wann immer Sie etwas brauchen, wie z. B. Autoprefixer
.pipe($.autoprefixer())Es weiß einfach, wie es es aus Ihrer package.json abrufen kann.
Ah, das habe ich vorher nicht bemerkt
Leider hatte ich Probleme mit Gulp + WordPress + Browser-Sync.
Gulp stürzte oft ab.
Ich habe alles auf Webpack umgeschrieben, es funktioniert jetzt hervorragend.
Dafür funktioniert die gesamte Umgebung auf Docker-Containern zusammen mit Xdebug für WordPress.
Jede Änderung an JS/CSS-Dateien erstellt separate Hash-Dateien.
Die dynamisch in PHP geladen werden.
CSS wird als Inline geliefert, es gibt kein Problem mit der Größe, da jede Unterseite ihr eigenes CSS und JS hat.
Wenn jemand interessiert ist, empfehle ich https://github.com/tomik23/docker-wordpress-xdebug
Natürlich ist die Vorlage selbst ziemlich dürftig, dies ist eine abgespeckte Version und nur als Beispiel.
Wow, mein aktueller Gulp-Workflow ist Ihrem sehr ähnlich
Nur PHP-bezogene Aufgaben fehlen in meinem Workflow
Für die Cache-Leerung verwendete ich das aktuelle Datum/Uhrzeit und verwendete Regex, um es in HTML-Dateien zu ersetzen
Um zu vermeiden, dass Gulp aufgrund von Dateänderungen neu gestartet werden muss, habe ich zwei Dinge implementiert:
– Fügen Sie
watchEvents: [ 'change', 'add', 'unlink', 'addDir', 'unlinkDir' ]zur BrowserSync-Konfiguration hinzu.– gulp-include, damit ich die Quellcodedateien für JS nicht in der Gulp-Datei definieren muss, sondern verschiedene Dateien basierend auf ihrem Speicherort im Verzeichnis
./src/verketten und erstellen.Wenn Sie interessiert sind, hier ist ein Gist mit dem vollständigen Gulp-Setup.
Ich bin dabei, von sass-lint zu stylelint zu wechseln, da sass-lint nicht mehr gepflegt wird.
Mini Gulp-bezogener Link-Dump…
November 2019 – Kieran Barkers So minimieren Sie JavaScript- und CSS-Dateien mit Gulp
Dezember 2019 – Ethan Marcotttes Setup
Dezember 2019 – Jason Pamentals Setup