'Combining Relative Files in Gulp

I need to combine some HTML files with the CSS that resides in the same directory using Gulp. The file structure of my project is as follows.

- src
    - dir1
        - index.html
        - style.css
    - dir2
        - index.html
        - style.css
    - dir3
        - index.html
        - style.css

So, I'm combining the HTML and CSS from dir1, then the HTML and CSS from dir2, and so on.

I've tried to do this several ways (including the following) but can't get anything to work the way I want.

.pipe(replace('<link rel="stylesheet" href="style.css">', function (match, p1) {
    return '<style>' + fs.readFileSync('src/' + p1, 'utf8') + '</style>';
}))

Is there an easy way to reference relative files in Gulp?



Solution 1:[1]

I assume you are using gulp 4 and gulp-replace, and that your gulpfile.js is located in the project directory, next to the src subdirectory.

Then the task consists of three steps:

  1. read the index.html files
  2. replace the string <link rel="stylesheet" href="style.css"> with a <style> tag with the contents of the file style.css in the same directory as index.html.
  3. write the changed index.html files to a new destination directory.

Steps 1 and 3 are easy to accomplish with gulp.src and gulp.dist, so let's look at step 2. Each style.css (the file we want to read) resides in the same directory as index.html. That directory can be retrieved with this.file.dirname in the gulp-replace callback. If we append "style.css" to that directory, we will get a full path to a CSS file that can be read with readFileSync. The rest is pretty straightforward:

const { readFileSync } = require('fs');
const gulp = require('gulp');
const replace = require('gulp-replace');
const { join } = require('path');

exports.default = () =>
    gulp.src('src/**/index.html')
    .pipe(replace('<link rel="stylesheet" href="style.css">', function () {
        const stylePath = join(this.file.dirname, 'style.css');
        const style = readFileSync(stylePath);
        return `<style>${style}</style>`;
    }))
    .pipe(gulp.dest('dest'));

I really think that the only unobvious part in this process is getting the directory of each index.html/style.css file pair in the gulp-replace callback as this.file.dirname. Here, according to gulp-replace:

The value of this.file will be equal to the vinyl instance for the file being processed.

and file.dirname for a vinyl file

Gets and sets the dirname of file.path. Will always be normalized and have trailing separators removed.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 GOTO 0