CSS und JavaScript mit NPM und Gulp organisieren

Bei den meisten Web-Projekten setze ich auf verschiedene externe Projekte und Frameworks. Sei es Bootstrap, JQuery oder FontAwesome und weitere Klassen oder Plugins. Meistens ist es dann ein Problem, die verschiedenen Versionen und externen Scripts auf einem aktuellen Stand zu halten, zu organisieren oder kontrollieren, welche Version untereinander notwendig ist, um alle Abhängigkeiten (auch die des eigenen Projekts) zu erfüllen.
Um die jeweils aktuellen oder selbst gesetzten festen Versionen von Bootstrap & Co. zu halten, gibt es Nodejs/NPM. Sämtliche Pakete werden dabei in ein Verzeichnis „node_modules“ installiert. Doch wie sieht eine praktikable Lösung aus, mittels welcher diese Bibliotheken im eigenen Web-Projekt gehalten werden?
Genau hier kommt der „Workflow-Enhancer“ Gulp.js ins Spiel. Gulp sorgt dafür, dass die entscheidenden Scripts aus dem Verzeichnis node_modules in das eigene Web-Verzeichnis geführt werden (beispielsweise /js, /css, /fonts, etc.) und ggf. SASS–Code aus Bootstrap und eigenem Code in CSS kompiliert wird. Dazu ist in der DEV-Umgebung ein File-Watcher aktiv, welcher in Echtzeit geschriebenen SASS-Code kompiliert und ins CSS-Verzeichnis schreibt.
Im Anschluss (nicht Teil dieses Beitrags) kann über eine Aufgabe via Gulp der gesamte JS- und CSS-Code für die Produktiv-Umgebung komprimiert werden. Perfekt!

Ausgangslage (Beispiel)

Grundvoraussetzung für den nachfolgend beschriebenen Einsatz von gulp ist, dass bereits NodeJS und npm (oder yarn) in der Entwicklungsumgebung installiert sind.

Ein PHP-Web-Projekt sieht bei mir meistens so aus, dass ich im obersten Verzeichnis alle Umgebungs-Tools ablege (Dateien für Docker, Vagrant, etc.). Dort ist dann auch ein Verzeichnis „www“, in welchem das eigentliche Projekt liegt. In diesem Verzeichnis sind in der Wurzel dann die Dateien für die DEV-Tools (Composer, Node, Gulp, etc.), ein „app“-Verzeichnis, in welchem die PHP-Aktionen sind (MVC) und ein „public“-Verzeichnis, welches die „htdocs“ für die Webroot bereithält. Hier ist meistens nur eine index.php-Datei, welche die Core-Klasse(autoload) aus dem app-Verzeichnis lädt und eben die statischen Frontend-Dateien (js,css, scss, assets, fonts, etc.).

In der Übersicht sieht das dann so aus:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
├── app ->
│   ├── init.php
│   ├── config ->
│   ├── controller ->
│   ├── library ->
│   ├── model ->
│   └── view ->
├── composer.json
├── composer.lock
├── composer.phar
├── gulpfile.js
(├── node_modules -> # wird erst mit "npm install" automatisch angelegt!)
├── package.json
├── package-lock.json
├── public ->
│   ├── css ->
│   ├── js ->
│   ├── fonts ->
│   ├── scss ->
│   └── index.php
└── Readme.md

Das Ziel ist hier also, dass die benötigten JS- und CSS-Dateien aus node_modules in das Frontend-Verzeichnis nach public/js und public/css überführt werden und die selbst geschriebenen SASS-Scripts aus public/scss mit den Scripts aus node_modules zusammen in public/css kompiliert werden (letzteres inkl. FileWatcher in Echtzeit.

Als Basis-Beispiel eine package.json-Datei, die bereits Gulp lokal via npm (oder yarn) installiert:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
  "name": "n73-test",
  "version": "0.1.0",
  "description": "Test-Projekt zur gulp-Demonstration",
  "main": "public/index.php",
  "scripts": {
    "test": "echo "Error: no test specified" && exit 1"
  },
  "author": "Pixel64",
  "license": "MIT",
  "dependencies": {
    "bootstrap": "^4.4.1",
    "jquery": "^3.4.1",
    "popper.js": "^1.16.1"
  },
  "devDependencies": {
    "browser-sync": "^2.26.7",
    "gulp": "^4.0.2",
    "gulp-sass": "^4.0.2"
  }
}

In diesem Projekt werden also die Pakete Bootstrap, JQuery und Popper gezogen und in das Verzeichnis node_modules gelegt.

GULP.JS

Mit der obigen Verzeichnisstruktur werden die Module via „npm install“ installiert (im Root-Verzeichnis, in welchem sich auch die package.json-Datei befindet).

Ist der Vorgang ausgeführt ist gulp _lokal_ installiert! Eine globale Installation von gulp(-cli) kann über den Paketmanager oder mit dem Schalter „-g“ erreicht werden (npm install -g gulp).

Die lokale Projekt-Installation reicht allerdings i.d.R. aus. Die installierte Version kann wie folgt geprüft werden:


1
2
3
./node_modules/.bin/gulp --version
CLI version: 2.2.0
Local version: 4.0.2

gulpfile.js

Die Anweisungen, was gulp im Verzeichnis erledigen soll, werden in der Datei gulpfile.js festgehalten. Eine Beispieldatei für das Test-Projekt sieht so aus:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
var gulp        = require('gulp');
var browserSync = require('browser-sync').create();
var sass        = require('gulp-sass');

// SASS kompilieren, nach public/css verschieben und in browsersync aufnehmen
gulp.task('sass', function(){
    return gulp.src(['node_modules/bootstrap/scss/bootstrap.scss', 'public/scss/*.scss'])
        .pipe(sass())
        .pipe(gulp.dest('public/css'))
        .pipe(browserSync.stream());
});

//JS nach public/js verschieben
gulp.task('js', function(){
    return gulp.src([
        'node_modules/bootstrap/dist/js/bootstrap.min.js',
        'node_modules/jquery/dist/jquery.min.js',
        'node_modules/popper.js/dist/umd/popper.min.js'])
        .pipe(gulp.dest('public/js'))
        .pipe(browserSync.stream());
});



//Fonts nach public/fonts schieben
gulp.task('fonts', function(){
    return gulp.src('node_modules/font-awesome/fonts/*')
        .pipe(gulp.dest('public/fonts'));
});

//fontawesome nach public/css verschieben
gulp.task('fa', ()=>{
    return gulp.src('node_modules/font-awesome/css/font-awesome.min.css')
        .pipe(gulp.dest('public/css'))
        .pipe(browserSync.stream());
});

// SASS ueberwachen und bei Veraenderungen kompilieren
gulp.task('serve', gulp.series('sass', function() {
    browserSync.init({
        proxy: 'http://localhost/',
        notify: true,
    });

    gulp.watch(['node_modules/bootstrap/scss/bootstrap.scss', 'scss/*.scss'], gulp.series('sass'))
    gulp.watch('*.php').on('change', browserSync.reload);
}));


gulp.task('default', gulp.series('js', 'serve', 'fa', 'fonts'));%

Ist diese Datei erstellt, reicht ein einfacher Aufruf von ./node_modules/.bin/gulp und der Vorgang startet. Jetzt werden die entsprechenden Scripts kopiert und ein aktiver FileWatcher überwacht SASS und kompiliert bei Veränderungen scss nach css. Zudem werden die Veränderungen an den definierten Dateien im www-Verzeichnis über einen lokalen Server (Port 3000) angezeigt (index.php oder index.html, je nach Projekt). Letzteres wird durch den gulp-task „server“ organisiert und kann bei Bedarf oder Nutzung anderer Entwicklungsumgebungen deaktiviert werden (Docker- oder Vagrant-Umgebung?).

Zusatz

Natürlich kann gulp auch in komplett statischen Umgebungen eingesetzt werden. Generell müssen jeweils nur die Verzeichnisse an die eigene Projektstruktur angepasst werden.

Über die package.json-Datei kann jeweils kontrolliert werden, welche Versionen von Bootstrap, JQuery & Co. geladen werden sollen und den Weg ins eigene Web-Projekt finden. Die so erstellten CSS- und JS-Dateien können dann wie gewohnt aus dem /js- und /css-Verzeichnis in die eigenen Web-Dateien (PHP->Views, oder HTML-Dateien->statisch) eingebunden werden.

Für das Deployment im Produktiv-Betrieb ist somit auch kein einzelnes Zusammensuchen der Bibliotheken notwendig und auch kein Überwachen der statisch eingebundenen CDN-Links im Projekt notwendig (kann man trotzdem parallel nutzen).

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Durch die Abgabe eines Kommentars akzeptieren sie die Datenschutzerklärung von net73.de

ähnliche Beiträge