diff --git a/components/gulpfile.js b/components/gulpfile.js index fd9e51b..d0351af 100644 --- a/components/gulpfile.js +++ b/components/gulpfile.js @@ -1,177 +1,207 @@ 'use strict'; import plugins from 'gulp-load-plugins'; import yargs from 'yargs'; import browser from 'browser-sync'; import gulp from 'gulp'; import panini from 'panini'; import { rimraf } from 'rimraf'; import yaml from 'js-yaml'; import fs from 'fs'; import webpackStream from 'webpack-stream'; import webpack2 from 'webpack'; import named from 'vinyl-named'; import uncss from 'uncss'; import autoprefixer from 'autoprefixer'; import imagemin from 'gulp-imagemin'; import { gifsicle, mozjpeg, optipng, svgo } from 'gulp-imagemin'; - import * as dartSass from 'sass'; import gulpSass from 'gulp-sass'; + const sass = gulpSass(dartSass); +const localtunnel = require('localtunnel'); // Load all Gulp plugins into one variable const $ = plugins(); // Check for --production flag const PRODUCTION = !!(yargs.argv.production); // Load settings from config.yml const config = loadConfig(); function loadConfig() { const unsafe = require('js-yaml-js-types').all; const schema = yaml.DEFAULT_SCHEMA.extend(unsafe); let ymlFile = fs.readFileSync('config.yml', 'utf8'); return yaml.load(ymlFile, { schema }); } // Build the "dist" folder by running all of the below tasks // Sass must be run later so UnCSS can search for used classes in the others assets. gulp.task('build', gulp.series(clean, gulp.parallel(pages, javascript, images, copy), compileSass)); // Build the site, run the server, and watch for file changes gulp.task('default', gulp.series('build', server, watch)); // Delete the "dist" folder // This happens every time a build starts function clean(done) { rimraf.rimrafSync(config.paths.dist); done(); } // Copy files out of the assets folder // This task skips over the "img", "js", and "scss" folders, which are parsed separately function copy() { return gulp.src(config.paths.assets) .pipe(gulp.dest(config.paths.dist + '/assets')); } // Copy page templates into finished HTML files function pages() { return gulp.src('src/pages/**/*.{html,hbs,handlebars}') .pipe(panini({ root: 'src/pages/', layouts: 'src/layouts/', partials: 'src/partials/', data: 'src/data/', helpers: 'src/helpers/' })) .pipe(gulp.dest(config.paths.dist)); } // Load updated HTML templates and partials into Panini function resetPages(done) { panini.refresh(); done(); } // Compile Sass into CSS // In production, the CSS is compressed function compileSass() { const postCssPlugins = [ autoprefixer(), PRODUCTION && uncss.postcssPlugin(config.tasks.uncss), ].filter(Boolean); return gulp.src('src/assets/scss/app.scss') .pipe($.sourcemaps.init()) .pipe(sass({ includePaths: config.paths.sass }) .on('error', sass.logError)) .pipe($.postcss(postCssPlugins)) .pipe($.if(PRODUCTION, $.cleanCss({ compatibility: 'ie9' }))) .pipe($.if(!PRODUCTION, $.sourcemaps.write())) .pipe(gulp.dest(config.paths.dist + '/assets/css')) .pipe(browser.reload({ stream: true })); } let webpackConfig = { mode: (PRODUCTION ? 'production' : 'development'), module: { rules: [ { test: /\.js$/, use: { loader: 'babel-loader', options: { presets: [ "@babel/preset-env" ], compact: false } } } ] }, devtool: !PRODUCTION && 'source-map' } // Combine JavaScript into one file // In production, the file is minified function javascript() { return gulp.src(config.paths.entries) .pipe(named()) .pipe($.sourcemaps.init()) .pipe(webpackStream(webpackConfig, webpack2)) .pipe($.if(PRODUCTION, $.uglify() .on('error', e => { console.log(e); }) )) .pipe($.if(!PRODUCTION, $.sourcemaps.write())) .pipe(gulp.dest(config.paths.dist + '/assets/js')); } // Copy images to the "dist" folder // In production, the images are compressed function images() { return gulp.src('src/assets/img/**/*') .pipe($.if(PRODUCTION, imagemin([ gifsicle({interlaced: true}), mozjpeg({quality: 85, progressive: true}), optipng({optimizationLevel: 5}), svgo({ plugins: [ {removeViewBox: true}, {cleanupIDs: false} ] }) ]))) .pipe(gulp.dest(config.paths.dist + '/assets/img')); } -// Start a server with BrowserSync to preview the site in +// Start a server with BrowserSync to preview the site function server(done) { browser.init({ - server: config.paths.dist, port: config.dev.port - }, done); + server: config.paths.dist, + port: config.dev.port, + }); + + if (tunnel in config.dev && config.dev.tunnel.enabled) { + setupTunnel().then(() => { + done(); + }); + } else { + done(); + } } // Reload the browser with BrowserSync function reload(done) { browser.reload(); done(); } // Watch for changes to static assets, pages, Sass, and JavaScript function watch() { gulp.watch(config.paths.assets, copy); gulp.watch('src/pages/**/*.html').on('all', gulp.series(pages, browser.reload)); gulp.watch('src/{layouts,partials}/**/*.html').on('all', gulp.series(resetPages, pages, browser.reload)); gulp.watch('src/data/**/*.{js,json,yml}').on('all', gulp.series(resetPages, pages, browser.reload)); gulp.watch('src/helpers/**/*.js').on('all', gulp.series(resetPages, pages, browser.reload)); gulp.watch('src/assets/scss/**/*.scss').on('all', compileSass); gulp.watch('src/assets/js/**/*.js').on('all', gulp.series(javascript, browser.reload)); gulp.watch('src/assets/img/**/*').on('all', gulp.series(images, browser.reload)); } + +async function setupTunnel() { + try { + const tunnelOptions = { port: config.dev.port }; + + if (subdomain in config.dev.tunnel) { + tunnelOptions.subdomain = config.dev.tunnel.subdomain; + } + const tunnel = await localtunnel(tunnelOptions); + + console.log('Tunnel URL:', tunnel.url); + + tunnel.on('close', () => { + console.log('Localtunnel closed'); + }); + } catch (err) { + console.error('Localtunnel setup failed:', err); + throw err; + } +} diff --git a/components/package-template.json b/components/package-template.json index b24e9fa..644258c 100644 --- a/components/package-template.json +++ b/components/package-template.json @@ -1,50 +1,51 @@ { "main": "gulpfile.babel.js", "scripts": { "start": "gulp", "build": "gulp build --production" }, "dependencies": { "foundation-sites": "^6.9.0", "jquery": "^3.6.0", "motion-ui": "^2.0.4", "what-input": "^5.2.12" }, "devDependencies": { "@babel/core": "^7.26.0", "@babel/preset-env": "^7.26.0", "@babel/register": "^7.25.9", "autoprefixer": "^10.4.20", "babel-loader": "^9.2.1", "browser-sync": "^3.0.3", "gulp": "^5.0.0", "gulp-babel": "^8.0.0", "gulp-clean-css": "^4.3.0", "gulp-cli": "^3.0.0", "gulp-concat": "^2.6.1", "gulp-extname": "^0.2.2", "gulp-if": "^3.0.0", "gulp-imagemin": "^7.1.0", "gulp-load-plugins": "^2.0.8", "gulp-postcss": "^10.0.0", "gulp-sass": "^5.1.0", "gulp-sourcemaps": "^3.0.0", "gulp-uglify": "^3.0.2", "js-yaml": "^4.1.0", "js-yaml-js-types": "^1.0.1", + "localtunnel":"^2.0.2", "panini": "^1.7.2", "postcss": "^8.4.49", "rimraf": "^6.0.1", "sass": "^1.80.7", "style-sherpa": "^1.0.2", "uncss": "^0.17.3", "vinyl-named": "^1.1.0", "webpack": "^5.96.1", "webpack-stream": "^7.0.0", "yargs": "^17.7.2" }, "bugs": { "url": "https://devcentral.nasqueron.org/" }, "private": true } diff --git a/config.yml b/config.yml index 457b6d1..fec09e3 100644 --- a/config.yml +++ b/config.yml @@ -1,63 +1,66 @@ # ------------------------------------------------------------- # Static website configuration # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Project: Nasqueron # Site: Upsection testing site # ------------------------------------------------------------- # ------------------------------------------------------------- # Metadata to generate package.json # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - package: name: nasqueron-upsection-test version: 0.1.0 description: Allow to test if we can build a static site repository_name: upsection # ------------------------------------------------------------- # Configuration for Gulp build tasks # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - paths: dist: "dist" # Paths to static assets that aren't images, CSS, or JavaScript assets: - "src/assets/**/*" - "!src/assets/{img,js,scss}{,/**/*}" # Paths to Sass libraries, which can then be loaded with @import sass: - "node_modules/foundation-sites/scss" - "node_modules/motion-ui/src" # Paths to JavaScript entry points for webpack to bundle modules entries: - "src/assets/js/app.js" tasks: # Make sure CSS is compatible with browsers guards prefixes like -moz- autoprefixer: browsers: - last 2 versions - ie >= 9 - ios >= 12 - android >= 7.0 # Remove unused CSS declarations uncss: html: - "src/**/*.html" ignore: - "!!js/regexp .foundation-mq" - '!!js/regexp ^\.is-.*' # ------------------------------------------------------------- # Configuration for development server # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - dev: port: 8000 + tunnel: + enabled: true + subdomain: "upsection" diff --git a/package.json b/package.json index b90c608..e13f2db 100644 --- a/package.json +++ b/package.json @@ -1,57 +1,58 @@ { "main": "gulpfile.babel.js", "scripts": { "start": "gulp", "build": "gulp build --production" }, "dependencies": { "foundation-sites": "^6.9.0", "jquery": "^3.6.0", "motion-ui": "^2.0.4", "what-input": "^5.2.12" }, "devDependencies": { "@babel/core": "^7.26.0", "@babel/preset-env": "^7.26.0", "@babel/register": "^7.25.9", "autoprefixer": "^10.4.20", "babel-loader": "^9.2.1", "browser-sync": "^3.0.3", "gulp": "^5.0.0", "gulp-babel": "^8.0.0", "gulp-clean-css": "^4.3.0", "gulp-cli": "^3.0.0", "gulp-concat": "^2.6.1", "gulp-extname": "^0.2.2", "gulp-if": "^3.0.0", "gulp-imagemin": "^7.1.0", "gulp-load-plugins": "^2.0.8", "gulp-postcss": "^10.0.0", "gulp-sass": "^5.1.0", "gulp-sourcemaps": "^3.0.0", "gulp-uglify": "^3.0.2", "js-yaml": "^4.1.0", "js-yaml-js-types": "^1.0.1", + "localtunnel":"^2.0.2", "panini": "^1.7.2", "postcss": "^8.4.49", "rimraf": "^6.0.1", "sass": "^1.80.7", "style-sherpa": "^1.0.2", "uncss": "^0.17.3", "vinyl-named": "^1.1.0", "webpack": "^5.96.1", "webpack-stream": "^7.0.0", "yargs": "^17.7.2" }, "bugs": { "url": "https://devcentral.nasqueron.org/" }, "private": true, "name": "nasqueron-upsection-test", "version": "0.1.0", "description": "Allow to test if we can build a static site", "repository": { "type": "git", "url": "https://devcentral.nasqueron.org/source/upsection.git" } } diff --git a/template/config.yml.in b/template/config.yml.in index 7c82767..dc7f54f 100644 --- a/template/config.yml.in +++ b/template/config.yml.in @@ -1,63 +1,66 @@ # ------------------------------------------------------------- # Static website configuration # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Project: Nasqueron # Site: https://%%SUBDOMAIN%%.nasqueron.org # ------------------------------------------------------------- # ------------------------------------------------------------- # Metadata to generate package.json # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - package: name: nasqueron-%%SUBDOMAIN%%-www version: 0.1.0 description: Build %%SUBDOMAIN%% site repository_name: %%SUBDOMAIN%%-www # ------------------------------------------------------------- # Configuration for Gulp build tasks # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - paths: dist: "dist" # Paths to static assets that aren't images, CSS, or JavaScript assets: - "src/assets/**/*" - "!src/assets/{img,js,scss}{,/**/*}" # Paths to Sass libraries, which can then be loaded with @import sass: - "node_modules/foundation-sites/scss" - "node_modules/motion-ui/src" # Paths to JavaScript entry points for webpack to bundle modules entries: - "src/assets/js/app.js" tasks: # Make sure CSS is compatible with browsers guards prefixes like -moz- autoprefixer: browsers: - last 2 versions - ie >= 9 - ios >= 12 - android >= 7.0 # Remove unused CSS declarations uncss: html: - "src/**/*.html" ignore: - "!!js/regexp .foundation-mq" - '!!js/regexp ^\.is-.*' # ------------------------------------------------------------- # Configuration for development server # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - dev: port: 8000 + tunnel: + enabled: true + subdomain: %%SUBDOMAIN%%