简体   繁体   中英

Minify Inline Javascript in PHP Files with Gulp

What I'm trying to do is minify inline javascript <script> within php files using Gulp. The reason why is because I'm trying to condense the overall file size (It does matter in my case). The javascript contains php variables.

I've started with the gulp-minify-inline-scripts plugin, but changed it so that it recognizes php files. Unfortunately I haven't successfully been able to output the javascript unless using html files.

My thinking is to keep the php variables and just save the contents back to the php file. Not compiling the actual php.

Plugin code:

var path = require('path');

var gutil = require('gulp-util');
var uglify = require('uglify-js');
var through = require('through2');

var PLUGIN_NAME = 'gulp-minify-inline-scripts';

module.exports = function (options) {
    return through.obj(function (file, enc, cb) {
        var self = this;

        if (file.isNull()) {
            this.push(file);
            return cb();
        }

        if (file.isStream()) {
            this.emit('error', new gutil.PluginError(PLUGIN_NAME, 'Streaming not supported'));
            return cb();
        }

        var fileName = file.path.split(path.sep).pop();

        //html file only
        if (!/^\.php?$/.test(path.extname(file.path))) {
            gutil.log(gutil.colors.red('[WARN] file ' + fileName + ' is not a html file'));
            this.push(file);
            return cb();
        }

        gutil.log("uglify inline scripts in html file: " + file.path);

        var html = file.contents.toString('utf8');
        var reg = /(<script(?![^>]*?\b(type=['"]text\/template['"]|src=["']))[^>]*?>)([\s\S]*?)<\/script>/g;


        html = html.replace(reg, function (str, tagStart, attr, script) {
            try {
                var result = uglify.minify(script, { fromString: true });

                return tagStart + result.code + '</script>';
            } catch (e) {
                self.emit('error', new gutil.PluginError(PLUGIN_NAME, 'uglify inline scripts error: ' + (e && e.stack)));
            }
        });


        file.contents = new Buffer(html);
        this.push(file);
        cb();
    });
};

PHP Inline Javascript to compress:

<?php 

/* Start: This is a php file

?>

<script>
    <?php $var = 'test'; ?>    
    A.config = {
        test: '<?php echo $var; ?>'
    };


    a.visible = function (image, distance) {
        var viewportWidth  = window.innerWidth || document.documentElement.clientWidth;
        var viewportHeight = window.innerHeight || document.documentElement.clientHeight;
        var bounds;
        var gap;

        if (!image.getBoundingClientRect) {
            return false;   
        }
    };
</script>

<?php 

/* End: This is a php file

?>

For anyone that comes across this, I've written up a solution based on what @Cbroe hints at in a comment. It's really simple: wrap php code so it doesn't break jsminifier, then after the code is minified, remove the wrapped php strings to release the php variables. You could simplify this a little more by choosing better wrap strings.

I'd just be careful of what you use this for because I haven't tested for anything other than my specific use case.

UPDATE : I've been using this for several months and it has never broken. Just make sure to use the same script tag pattern that you place in the regex or else it may not find the tag in the page.

New Gulp Plugin Code:

var path = require('path');
var gutil = require('gulp-util');
var uglify = require('uglify-js');
var through = require('through2');
var PLUGIN_NAME = 'gulp-minify-inline-scripts';

module.exports = function(options) {
    return through.obj(function(file, enc, cb) {
        var self = this;

        if (file.isNull()) {
            this.push(file);
            return cb();
        }

        if (file.isStream()) {
            this.emit('error', new gutil.PluginError(PLUGIN_NAME, 'Streaming not supported'));
            return cb();
        }

        var fileName = file.path.split(path.sep).pop();

        //html file only
        if (!/^\.php?$/.test(path.extname(file.path))) {
            gutil.log(gutil.colors.red('[WARN] file ' + fileName + ' is not a html file'));
            this.push(file);
            return cb();
        }

        gutil.log("uglify inline scripts in html file: " + file.path);

        var html = file.contents.toString('utf8');
        var reg = /(<script(?![^>]*?\b(type=['"]text\/template['"]|src=["']))[^>]*?>)([\s\S]*?)<\/script>/g;

        html = html.replace(reg, function(str, tagStart, attr, script) {
            try {
                var result = uglify.minify(script, {
                    fromString: true
                });

                var code = result.code;

                code = code.split("STRIP__>\"").join('');
                code = code.split("\"<__STRIP").join('');

                return tagStart + code + '</script>';
            } catch (e) {
                self.emit('error', new gutil.PluginError(PLUGIN_NAME, 'uglify inline scripts error: ' + (e && e.stack)));
            }
        });

        file.contents = new Buffer(html);

        this.push(file);

        cb();
    });
};

PHP Inline Javascript to compress:

<?php 

/* Start: This is a php file

?>

<script>
    <?php $var = 'test'; ?>    
    A.config = {
        test: "<__STRIP'<?php echo $var; ?>'STRIP__>"
    };

    a.visible = function (image, distance) {
        var viewportWidth  = window.innerWidth || document.documentElement.clientWidth;
        var viewportHeight = window.innerHeight || document.documentElement.clientHeight;
        var bounds;
        var gap;

        if (!image.getBoundingClientRect) {
            return false;   
        }
    };
</script>

<?php 

/* End: This is a php file

?>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM