Skip to content

Instantly share code, notes, and snippets.

@edoves
Created October 30, 2024 14:42
Show Gist options
  • Save edoves/29353e147803a65f17f9805e7cceee4e to your computer and use it in GitHub Desktop.
Save edoves/29353e147803a65f17f9805e7cceee4e to your computer and use it in GitHub Desktop.
Gulp Questions

Question 1?

Can you help with gulp rendering my css and js during production and development current html files is on the root folder. the src folder includes scss and js files and directory the problem is how I am going to set up my <script src=""></script> that it will in both production and development

Answer

To handle CSS and JavaScript rendering in both production and development environments using Gulp, you can follow these steps:

1. Folder Structure

Let's assume your folder structure is something like this:

root/
│
├── src/
│   ├── scss/
│   │   └── styles.scss
│   ├── js/
│   │   └── scripts.js
│   └── index.html
├── dist/  (for production)
│   ├── css/
│   │   └── styles.min.css
│   ├── js/
│   │   └── scripts.min.js
└── gulpfile.js

2. Setting Up Gulp Tasks

You already have tasks for SCSS compilation, JS minification, and file watching. We'll make slight adjustments to them to ensure they work for both environments.

Here’s an example setup for your gulpfile.js:

const gulp = require('gulp');
const sass = require('gulp-sass')(require('sass'));
const cleanCSS = require('gulp-clean-css');
const uglify = require('gulp-uglify');
const rename = require('gulp-rename');
const browserSync = require('browser-sync').create();

// Paths
const paths = {
  scss: './src/scss/**/*.scss',
  js: './src/js/**/*.js',
  html: './*.html'
};

// SCSS to CSS
function styleTask() {
  return gulp.src(paths.scss)
    .pipe(sass().on('error', sass.logError))
    .pipe(gulp.dest('./dist/css'))
    .pipe(cleanCSS())
    .pipe(rename({ suffix: '.min' }))
    .pipe(gulp.dest('./dist/css'))
    .pipe(browserSync.stream());
}

// Minify JS
function jsTask() {
  return gulp.src(paths.js)
    .pipe(gulp.dest('./dist/js'))
    .pipe(uglify())
    .pipe(rename({ suffix: '.min' }))
    .pipe(gulp.dest('./dist/js'))
    .pipe(browserSync.stream());
}

// HTML task
function htmlTask() {
  return gulp.src(paths.html)
    .pipe(gulp.dest('./dist'))
    .pipe(browserSync.stream());
}

// BrowserSync
function browsersyncServe(cb) {
  browserSync.init({
    server: {
      baseDir: './'
    }
  });
  cb();
}

function browsersyncReload(cb) {
  browserSync.reload();
  cb();
}

// Watch files
function watchTask() {
  gulp.watch(paths.scss, styleTask);
  gulp.watch(paths.js, jsTask);
  gulp.watch(paths.html, browsersyncReload);
}

// Default Gulp task
exports.default = gulp.series(
  gulp.parallel(styleTask, jsTask, htmlTask),
  browsersyncServe,
  watchTask
);

3. Setting Up Your HTML

In your HTML file (index.html), set up the paths depending on the environment:

For Development

When working in development, you'll likely want to include the unminified versions of your CSS and JS:

<link rel="stylesheet" href="dist/css/styles.css">
<script src="dist/js/scripts.js"></script>

For Production

In production, you'll want to include the minified versions:

<link rel="stylesheet" href="dist/css/styles.min.css">
<script src="dist/js/scripts.min.js"></script>

4. Managing Environment-Specific Links

To automate this, you can use environment variables in Gulp to differentiate between production and development.

Gulp with Environment Variables

First, install gulp-if and yargs to help manage environments:

npm install gulp-if yargs --save-dev

Now, modify your gulpfile.js:

const gulp = require('gulp');
const sass = require('gulp-sass')(require('sass'));
const cleanCSS = require('gulp-clean-css');
const uglify = require('gulp-uglify');
const rename = require('gulp-rename');
const browserSync = require('browser-sync').create();
const gulpIf = require('gulp-if');
const yargs = require('yargs');

const argv = yargs.argv;
const production = !!argv.production;  // Check if --production flag is used

// Paths
const paths = {
  scss: './src/scss/**/*.scss',
  js: './src/js/**/*.js',
  html: './*.html'
};

// SCSS to CSS
function styleTask() {
  return gulp.src(paths.scss)
    .pipe(sass().on('error', sass.logError))
    .pipe(gulpIf(production, cleanCSS()))  // Minify CSS in production
    .pipe(gulpIf(production, rename({ suffix: '.min' })))
    .pipe(gulp.dest('./dist/css'))
    .pipe(browserSync.stream());
}

// Minify JS
function jsTask() {
  return gulp.src(paths.js)
    .pipe(gulpIf(production, uglify()))  // Minify JS in production
    .pipe(gulpIf(production, rename({ suffix: '.min' })))
    .pipe(gulp.dest('./dist/js'))
    .pipe(browserSync.stream());
}

// BrowserSync
function browsersyncServe(cb) {
  browserSync.init({
    server: {
      baseDir: './'
    }
  });
  cb();
}

function browsersyncReload(cb) {
  browserSync.reload();
  cb();
}

// Watch files
function watchTask() {
  gulp.watch(paths.scss, styleTask);
  gulp.watch(paths.js, jsTask);
  gulp.watch(paths.html, browsersyncReload);
}

// Default Gulp task
exports.default = gulp.series(
  gulp.parallel(styleTask, jsTask),
  gulpIf(!production, browsersyncServe),
  gulpIf(!production, watchTask)
);

// Build task for production
exports.build = gulp.series(
  gulp.parallel(styleTask, jsTask)
);

Now, when you run Gulp without flags, it assumes development mode:

gulp

And for production:

gulp --production

This setup allows you to have the correct CSS and JS files linked depending on the environment you’re working in. During development, it will use the unminified versions, and in production, it will automatically switch to the minified versions.

Question 2?

what I want is when in production I wan to render <link rel="stylesheet" href="css/style.css" /> and in development i want this <link rel="stylesheet" href="dist/css/style.css" />

Answer:

To handle different paths for production and development environments in your HTML files, you'll need a way to inject the correct paths based on the environment. Here’s how you can achieve this using Gulp:

1. Install Required Packages

You need gulp-replace to replace placeholders in your HTML with the correct paths:

npm install gulp-replace --save-dev

2. Modify gulpfile.js

Update your gulpfile.js to handle HTML file path replacements based on the environment:

const gulp = require('gulp');
const sass = require('gulp-sass')(require('sass'));
const cleanCSS = require('gulp-clean-css');
const uglify = require('gulp-uglify');
const rename = require('gulp-rename');
const browserSync = require('browser-sync').create();
const gulpIf = require('gulp-if');
const yargs = require('yargs');
const replace = require('gulp-replace');

const argv = yargs.argv;
const production = !!argv.production;  // Check if --production flag is used

// Paths
const paths = {
  scss: './src/scss/**/*.scss',
  js: './src/js/**/*.js',
  html: './*.html'
};

// SCSS to CSS
function styleTask() {
  return gulp.src(paths.scss)
    .pipe(sass().on('error', sass.logError))
    .pipe(gulpIf(production, cleanCSS()))  // Minify CSS in production
    .pipe(gulpIf(production, rename({ suffix: '.min' })))
    .pipe(gulp.dest('./dist/css'))
    .pipe(browserSync.stream());
}

// Minify JS
function jsTask() {
  return gulp.src(paths.js)
    .pipe(gulpIf(production, uglify()))  // Minify JS in production
    .pipe(gulpIf(production, rename({ suffix: '.min' })))
    .pipe(gulp.dest('./dist/js'))
    .pipe(browserSync.stream());
}

// HTML task
function htmlTask() {
  return gulp.src(paths.html)
    .pipe(replace(/href="css\/style\.css"/g, 'href="dist/css/style.css"')) // Update paths for development
    .pipe(replace(/src="js\/scripts\.js"/g, 'src="dist/js/scripts.js"')) // Update paths for development
    .pipe(gulpIf(production,
      replace(/href="dist\/css\/style\.css"/g, 'href="css/style.css"')) // Update paths for production
    )
    .pipe(gulpIf(production,
      replace(/src="dist\/js\/scripts\.js"/g, 'src="js/scripts.js"'))
    )
    .pipe(gulp.dest('./dist'))
    .pipe(browserSync.stream());
}

// BrowserSync
function browsersyncServe(cb) {
  browserSync.init({
    server: {
      baseDir: './'
    }
  });
  cb();
}

function browsersyncReload(cb) {
  browserSync.reload();
  cb();
}

// Watch files
function watchTask() {
  gulp.watch(paths.scss, styleTask);
  gulp.watch(paths.js, jsTask);
  gulp.watch(paths.html, htmlTask);
}

// Default Gulp task
exports.default = gulp.series(
  gulp.parallel(styleTask, jsTask, htmlTask),
  gulpIf(!production, browsersyncServe),
  gulpIf(!production, watchTask)
);

// Build task for production
exports.build = gulp.series(
  gulp.parallel(styleTask, jsTask, htmlTask)
);

3. Update HTML File

Ensure that your HTML files use placeholders for the paths. For example:

<!-- Development Paths -->
<link rel="stylesheet" href="dist/css/style.css">
<script src="dist/js/scripts.js"></script>

<!-- Production Paths (Comment out the lines above and uncomment the lines below in production) -->
<!-- <link rel="stylesheet" href="css/style.css"> -->
<!-- <script src="js/scripts.js"></script> -->

4. Running Gulp

  • For development, run:

    gulp

    This will use the paths suitable for development.

  • For production, run:

    gulp --production

    This will use the paths suitable for production.

This setup will automatically replace the paths in your HTML files based on the environment you're working in, ensuring the correct files are linked.

Question 3?

how about the image path in both production an development can be conditional

Answer:

To conditionally manage image paths in both production and development environments using Gulp, you can use the same approach as for CSS and JavaScript paths. Here's how you can do it:

1. Update Gulp to Handle Image Paths

You'll follow the same pattern with gulp-replace to conditionally replace image paths based on the environment.

2. Modify Your gulpfile.js

Extend the htmlTask in your gulpfile.js to handle image paths:

const gulp = require('gulp');
const sass = require('gulp-sass')(require('sass'));
const cleanCSS = require('gulp-clean-css');
const uglify = require('gulp-uglify');
const rename = require('gulp-rename');
const browserSync = require('browser-sync').create();
const gulpIf = require('gulp-if');
const yargs = require('yargs');
const replace = require('gulp-replace');

const argv = yargs.argv;
const production = !!argv.production;  // Check if --production flag is used

// Paths
const paths = {
  scss: './src/scss/**/*.scss',
  js: './src/js/**/*.js',
  html: './*.html',
  images: './src/images/**/*'
};

// SCSS to CSS
function styleTask() {
  return gulp.src(paths.scss)
    .pipe(sass().on('error', sass.logError))
    .pipe(gulpIf(production, cleanCSS()))  // Minify CSS in production
    .pipe(gulpIf(production, rename({ suffix: '.min' })))
    .pipe(gulp.dest('./dist/css'))
    .pipe(browserSync.stream());
}

// Minify JS
function jsTask() {
  return gulp.src(paths.js)
    .pipe(gulpIf(production, uglify()))  // Minify JS in production
    .pipe(gulpIf(production, rename({ suffix: '.min' })))
    .pipe(gulp.dest('./dist/js'))
    .pipe(browserSync.stream());
}

// Handle Images
function imageTask() {
  return gulp.src(paths.images)
    .pipe(gulp.dest('./dist/images'))
    .pipe(browserSync.stream());
}

// HTML task
function htmlTask() {
  return gulp.src(paths.html)
    .pipe(replace(/href="css\/style\.css"/g, 'href="dist/css/style.css"')) // Update paths for development
    .pipe(replace(/src="js\/scripts\.js"/g, 'src="dist/js/scripts.js"')) // Update paths for development
    .pipe(replace(/src="images\//g, 'src="dist/images/')) // Update image paths for development
    .pipe(gulpIf(production,
      replace(/href="dist\/css\/style\.css"/g, 'href="css/style.css"')) // Update paths for production
    )
    .pipe(gulpIf(production,
      replace(/src="dist\/js\/scripts\.js"/g, 'src="js/scripts.js"'))
    )
    .pipe(gulpIf(production,
      replace(/src="dist\/images\//g, 'src="images/')) // Update image paths for production
    )
    .pipe(gulp.dest('./dist'))
    .pipe(browserSync.stream());
}

// BrowserSync
function browsersyncServe(cb) {
  browserSync.init({
    server: {
      baseDir: './'
    }
  });
  cb();
}

function browsersyncReload(cb) {
  browserSync.reload();
  cb();
}

// Watch files
function watchTask() {
  gulp.watch(paths.scss, styleTask);
  gulp.watch(paths.js, jsTask);
  gulp.watch(paths.html, htmlTask);
  gulp.watch(paths.images, imageTask);
}

// Default Gulp task
exports.default = gulp.series(
  gulp.parallel(styleTask, jsTask, htmlTask, imageTask),
  gulpIf(!production, browsersyncServe),
  gulpIf(!production, watchTask)
);

// Build task for production
exports.build = gulp.series(
  gulp.parallel(styleTask, jsTask, htmlTask, imageTask)
);

3. Update Your HTML File

In your HTML files, use placeholders for the image paths just like you did for CSS and JavaScript:

Example:

<!-- Development Paths -->
<img src="dist/images/logo.png" alt="Logo">

<!-- Production Paths (Comment out the lines above and uncomment the lines below in production) -->
<!-- <img src="images/logo.png" alt="Logo"> -->

4. Running Gulp

  • For development:

    gulp

    This will use the paths suitable for development.

  • For production:

    gulp --production

    This will use the paths suitable for production.

Summary

This setup will automatically adjust the image paths based on whether you're working in a production or development environment. When in development, it will point to dist/images/, and in production, it will point to images/. This ensures that the correct paths are used without needing manual intervention in your HTML files.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment