ashaffer/gulp-inline

Duplicate CSS

jvdub opened this issue · 16 comments

When inlining multiple CSS files, one of them gets duplicated for all of them.

gulpfile:

gulp.task('inline', function () {
    return gulp.src('src/test.html')
        .pipe(inline({
            base: 'src/',
            css: minifyCss()
        }))
        .pipe(gulp.dest(paths.dest));
});

test.html:

<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" type="text/css" href="css/default.css" />
    <link rel="stylesheet" type="text/css" href="css/print.css" media="print" />
    <!-- ... -->
</head>
<body>
    <!-- ... -->
</body>

default.css

.showOnPrint {
    display: none;
}

print.css

.showOnPrint {
    display: block;
}

output

<!DOCTYPE html>
<html>
<head>
    <style>
    .showOnPrint {display: block;}
    </style>
    <style>
    .showOnPrint {display: block;}
    </style>
    <!-- ... -->
</head>
<body>
    <!-- ... -->
</body>

It consistently duplicates one of the files, but it's not consistent in which one it duplicates. I imagine this issue is similar to Issue #7 just for CSS.

@jvdub Hmm... not sure what's going on there. I added some test fixtures copied from your post, and they seem to pass. Can you elaborate or provide a failing test case?

I just tested this again and was able to duplicate the issue. Here's what I have:

test.html (I realize this isn't complete HTML, but the project I'm working on takes a template that looks like this)

<link rel="stylesheet" type="text/css" href="css/test.css" />
<link rel="stylesheet" type="text/css" href="css/mine.css" media="print" />
<form>
    <p>Test</p>
</form>
<script language="javascript" type="text/javascript" src="js/test.js"></script>

test.js

(function () {
    console.log('test');
}());

test.css

.test {
    color: red;
}

mine.css

.mine {
    color: blue;
}

gulpfile.js

var gulp = require('gulp'),
    uglify = require('gulp-uglify'),
    jshint = require('gulp-jshint'),
    inline = require('gulp-inline'),
    minifyCss = require('gulp-minify-css'),
    paths = {
        scripts: 'src/js/*.js',
        dest: 'Code/files/'
    };

gulp.task('inlineMine', function () {
    return gulp.src('src/test.html')
        .pipe(inline({
            base: 'src/',
            css: minifyCss()
        }))
        .pipe(gulp.dest(paths.dest));
});

Running gulp inlineMine gives me the following output:

<style>
.mine{color:#00f}
</style>
<style media="print">
.mine{color:#00f}
</style>
<form>
    <p>Test</p>
</form>
<script type="text/javascript">
(function () {
    console.log('test');
}());
</script>

I hope this helps. Looking at the code, I haven't quite figured out why it would do this. It feels like a scoping issue, but I can't see where it's happening.

I found that if I take out the css: minifyCss() option that I don't observe this behavior. This workaround resolves the issue for me as far as I'm concerned. It would be nice to be able to minify it and put it into two different link tags, but that's not something I need at this time.

I encountered the same problem, but with my Javascript. When I take out js: uglify() it works again. So similar to what @jvdub says. It is a workaround for the moment, but would love a proper solution.

Same here. Get this issue with JS. Basically what seems to happen is that all JS is concatenated, but then every script tag is replaced with the full version of the concatenated JS. So for every script tag you get a full copy of all combined JS.

Sorry for the lack of progress on this issue. I'll try to address it some time this week.

jltrv commented

This is due to mishandling of streams. I'm working on a fix.

PzYon commented

I have the same issue using uglify - any news when this will be fixed/released? As far as I unterstand there also seems to be a hotfix related to this issue.

I merged in the hotfix. The issue should be resolved now. Closing this issue for now, let me know if you're still seeing it.

PzYon commented

Great, I can confirm, that it works now. Thank you very much. I now have the next question: Is there a possibility to create sourcemaps when uglifying (e.g. using gulp-sourcemaps) or is this not supported by gulp-inline?

Had the same issue with the current version 0.1.2 trying to set parameters for the JS and CSS functions.

I fixed the problem for now using a lambda expression
key: () => func({opt1: 'value'}) instead of key: func({opt1: 'value'})
since uglify seems to work and only uglify() causes problems.

Working example:

const gulp = require('gulp'),
    inline = require('gulp-inline'),
    htmlmin = require('gulp-htmlmin'),
    cssmin = require('gulp-minify-css'),
    pump = require('pump'),
    babel = require('gulp-babel'),
    inlinemin = require('gulp-minify-inline');

gulp.task('mininline', (cb) => {
    pump([
        gulp.src(paths.html),
        htmlmin({
            collapseWhitespace: true,
            removeComments: true
        }),
        inlinemin(),
        inline({
            base: './',
            js: () => babel({
                presets: ['babili'],
                comments: false
            }),
            css: () => cssmin({
                collapseWhitespace: true,
                removeComments: true
            })
        }),
        gulp.dest('./dist')
        ],
        cb
    );
});

Having the same problem with the latest 0.1.3. Any solution to this bug? I'm using gulp-clean-css for my css minification.

I fixed the problem for now using a lambda expression
key: () => func({opt1: 'value'}) instead of key: func({opt1: 'value'})
since uglify seems to work and only uglify() causes problems.

@mamrehn why would that solve the issue?

Having the issue with exactly same template as the suggested on the fist post by @jvdub

<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" type="text/css" href="css/styles.css" />
    <link rel="stylesheet" type="text/css" href="css/responsive.css" media="print" />
    <!-- ... -->
</head>
<body>
    <!-- ... -->
</body>

Then in the gulpfile:

gulp.task('inline-css', function(){
    gulp.src('index_raw.html')
        .pipe(inline({
            base: 'css/',
            js: uglify({
                preserveComments: 'license'
            }),
            css: [
                minifyCss({
                    compatibility: 'ie8',
                    advanced: false,
                    keepSpecialComments: '1'
                })
            ],
            disabledTypes: ['svg', 'img'], // Only inline css files
            ignore: [
                'dist/js/mixin.js',
                'dist/js/build.js',
            ]
        }))
        .pipe(rename('index.html'))
        .pipe(gulp.dest('./'));
});

And again, working all fine when removing minifyCss module within the CSS option.

@alvarotrigo because with lambdas they are two different functions instead of just one that gets reused.
Have you tried the workaround?

@mamrehn what do you mean by "with lambdas"? I've no idea what's that.

Have you tried the workaround?

Didn't find any solution so far. I guess I'll have to manually do it myself using the gulp-replace module. Quite annoying :(