Files
JS/webseite-gulp-ts/frontend/gulpfile.js
Philippe Torrel c548ea97a1
2026-08-05 09:49:28 +02:00

227 lines
6.5 KiB
JavaScript

// import gulp from 'gulp';
import { task, src, dest, watch, parallel, series } from 'gulp';
// Allgemeine Module für Gulp
import plumber from 'gulp-plumber';
import sourcemaps from 'gulp-sourcemaps';
// SERVER =================================
import bs from 'browser-sync';
const browserSync = bs.create();
// https://browsersync.io/docs/gulp
// $ gulp server
task('server', () => {
browserSync.init({
server: {
baseDir: './',
},
// host: '127.0.0.1',
// localhost: false,
open: false,
port: 3000,
});
});
task('reload', (done) => {
browserSync.reload(); // Refresh der Seite
done();
});
// =================================
// CSS ==================================
import * as dartSass from 'sass';
import gulpSass from 'gulp-sass';
import autoPrefixer from 'gulp-autoprefixer';
const sass = gulpSass(dartSass);
// $ gulp css
task('css', (done) => {
// Updated path to look in dev/scss
const sourceFile = './dev/scss/main.scss';
const targetFolder = './assets/css';
src(sourceFile, { allowEmpty: true, sourcemaps: true })
.pipe(plumber()) // Falls ein Fehler entsteht, überspringe Fehlerabbruch
.pipe(
sass({
outputStyle: 'expanded',
sourceMap: false,
debug: true,
quietDeps: true, // Unix
silenceDeprecations: ['color-functions', 'global-builtin', 'import', 'legacy-js-api', 'abs-percent'],
}).on('error', sass.logError),
)
.pipe(autoPrefixer()) // fehlende prefixe im css werden gesetzt (-ms-, -o- -webkit-)
.pipe(dest(targetFolder, { sourcemaps: '../map' }));
done();
});
// ==================================
// JS bzw. TS ==================================
import { spawn } from 'node:child_process';
import { fileURLToPath } from 'node:url';
import path from 'node:path';
import rollupStream from '@rollup/stream';
import { babel } from '@rollup/plugin-babel'; // Plugin für rollup. JS Dateien werden über Babel direkt beim bundlen in "altes" JS über babel kompiliert
import { nodeResolve } from '@rollup/plugin-node-resolve'; // import Kurzschreibweise (suche Module im node_modules Ordner)
import commonJs from '@rollup/plugin-commonjs'; // commonjs module werden module (ES6) kompatibel gemacht
import source from 'vinyl-source-stream';
import buffer from 'vinyl-buffer';
import rollupReplace from '@rollup/plugin-replace'; // Umbenennung von Variablen in den Modulen möglich
import esbuild from 'rollup-plugin-esbuild'; // TypeScript strippen ohne TS-Compiler-API (TS 7+ kompatibel)
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const tscBin = path.join(__dirname, 'node_modules', 'typescript', 'bin', 'tsc');
// declare the cache variable outside of task scopes
let cache;
// $ gulp typecheck — Typen prüfen (tsc CLI, kein Emit)
task('typecheck', (done) => {
const child = spawn(process.execPath, [tscBin, '--noEmit'], {
stdio: 'inherit',
cwd: __dirname,
});
child.on('error', done);
child.on('close', (code) => {
done(code === 0 ? undefined : new Error(`typecheck failed with exit code ${code}`));
});
});
// $ gulp ts — Bundle (esbuild strippt Types, Babel downlevelt für Browser)
task('ts', () => {
// Updated path to look in dev/scripts for a main.ts file
const sourceFile = './dev/scripts/main.ts';
const targetFolder = './assets/js';
return rollupStream({
input: sourceFile,
output: {
format: 'iife',
sourcemap: 'inline', // Enable inline sourcemap for gulp-sourcemaps
},
// define the cache in Rollup options
cache,
plugins: [
esbuild({
include: /\.[jt]sx?$/,
exclude: /node_modules/,
sourceMap: true,
// Babel übernimmt Browser-Downleveling; esbuild nur TS→JS
target: 'esnext',
tsconfig: './tsconfig.json',
}),
rollupReplace({
'process.env.NODE_ENV': JSON.stringify('development'),
preventAssignment: true,
}),
nodeResolve(), // z.B. import _ from 'lodash' <- damit in "node_modules" nach Modul gesucht wird
commonJs({
include: 'node_modules/**',
}), // wenn require - commonJS Schreibweise vorliegt, wird es umgeschrieben, so dass import statement verwendet werden kann
babel({
presets: ['@babel/preset-env'], // ES6+ in altes JS umgewandelt
plugins: ['@babel/plugin-transform-runtime'], // kontrolliert, ob ein Modul bereits eingebunden und bindet es nicht erneut ein
babelHelpers: 'runtime',
compact: true,
extensions: ['.js', '.ts'],
}),
],
})
.on('bundle', (bundle) => {
// update the cache after every new bundle is created
cache = bundle;
})
.pipe(source('build.js'))
.pipe(buffer())
.pipe(sourcemaps.init({ loadMaps: true }))
.pipe(
sourcemaps.write('../map', {
sourceRoot: '../dev/scripts',
}),
)
.pipe(dest(targetFolder));
});
// HTML =================================
import fileInclude from 'gulp-file-include';
task('html', (done) => {
const sourceFiles = ['./dev/html/pages/**/*.html', './dev/html/pages/*.html'];
const targetFolder = './';
src(sourceFiles)
.pipe(plumber())
.pipe(
fileInclude({
prefix: '@@',
basepath: './dev/html/includes',
}),
)
.pipe(dest(targetFolder));
done();
});
// === Watcher ======================
task('watcher', () => {
// Watcher for scss files in dev/scss
watch(['./dev/scss/**/*.+(scss|css)', './dev/scss/*.+(scss|css)'], series('css', 'reload'));
// Watcher for ts/js files in dev/scripts
watch(['./dev/scripts/**/*.ts', './dev/scripts/*.ts'], series('ts', 'reload'));
// Watcher for html files in dev/pages
watch(
[
'./dev/html/pages/**/*.html',
'./dev/html/pages/*.html',
'./dev/html/includes/**/*.html',
'./dev/html/includes/*.html',
],
series('html', 'reload'),
);
});
// ==== DEV MODE ====================
task('dev', series('css', 'ts', 'html', parallel('watcher', 'server')));
task('check', series('typecheck', 'ts'));
// ===================================
task('test', (done) => {
console.log('Test task executed');
done();
});
task('copy', (done) => {
src('package.json')
//.pipe(module())
.pipe(dest('./docs'));
console.log('Copy task executed');
done();
});
// gulp.task('test', (done) => {
// console.log('Test task executed');
// done();
// });
// gulp.task('copy', (done) => {
// gulp
// .src('package.json')
// //.pipe(module())
// .pipe(gulp.dest('./docs'));
// console.log('Copy task executed');
// done();
// });