【问题标题】:Minify Inline Javascript in PHP Files with Gulp使用 Gulp 缩小 PHP 文件中的内联 Javascript
【发布时间】:2015-02-11 05:44:02
【问题描述】:

我要做的是使用 Gulp 在 php 文件中缩小内联 javascript <script>。原因是因为我试图压缩整体文件大小(这对我来说很重要)。 javascript 包含 php 变量。

我从gulp-minify-inline-scripts 插件开始,但对其进行了更改,使其能够识别php 文件。不幸的是,除非使用 html 文件,否则我无法成功输出 javascript。

我的想法是保留 php 变量并将内容保存回 php 文件。没有编译实际的 php。

插件代码:

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 内联 Javascript:

<?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

?>

【问题讨论】:

  • 一般情况下是无法做到的。
  • 我不得不问...为什么不呢? @zerkms
  • 因为通常结果取决于 php 运行时。
  • 但这需要吗?我在考虑仍然保留 php 变量,只是将内容保存回 php 文件。没有编译实际的 php。
  • 这可能是可能的——但我怀疑 gulp 是否能够处理这个问题。您必须编写自己的版本来“识别” JS 代码中的 PHP 变量,并且知道必须让它们“保持不变”。另外,根据您的 PHP 代码,这可能会引入合理的解析器根本无法处理的复杂性。

标签: javascript php gulp


【解决方案1】:

对于遇到此问题的任何人,我已经根据@Cbroe 在评论中暗示的内容编写了一个解决方案。真的很简单:把php代码包装起来,这样就不会破坏jsminifier,然后在代码缩小之后,去掉包装好的php字符串,释放php变量。您可以通过选择更好的包装字符串来简化这一点。

我会小心你使用它的目的,因为除了我的特定用例之外,我没有测试过其他任何东西。

更新:我已经用了几个月了,它从来没有坏过。只需确保使用您在正则表达式中放置的相同脚本标记模式,否则它可能无法在页面中找到该标记。

新的 Gulp 插件代码:

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 内联 Javascript:

<?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

?>

【讨论】:

  • 您不必要地将缩小的特定实现绑定到修复代码约定,这不是最佳实践。您应该查看 Wordpress 的 codex.wordpress.org/Function_Reference/wp_localize_script 以查看将数据添加到页面以在脚本中使用的示例,而无需将其转换为内联 php 输出。
  • 我想进一步了解这里的代码约定是什么问题?因为如果我将内联脚本中的函数调用到 JS 文件中,则需要加载 JS 文件才能运行该函数。将脚本内联,不需要加载 JS 文件。我也不希望每次请求页面时都必须在 php 中编译内联 JS。
  • 将页面上的每个脚本或 css 放在页面上,而不是单独的文件,也是一种节省加载各种文件的开销的方法,但这不是通常建议,如果您需要那种速度,最好使用闭包编译器或其他东西来组合它。将数据与模型和两种不同的编程语言混合在一个文件中通常也不是最佳实践。
  • 当然。你完全正确。我只是看到一些内联 JS 不会受到伤害的情况。不过,在“最佳实践”与速度方面肯定存在权衡。尤其是考虑到很多大型网站都在做我正在做的事情……谷歌就是其中之一……也就是说,我知道你来自哪里。
  • 是的,Google 发明了 Closure Compiler 和 GWT 来进行优化。 - 我确信他们的开发人员实际上并没有在 JS 中编写那些 2 字母变量或在 Google 主页上输入内联代码 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-03
  • 2012-10-23
  • 2014-06-24
  • 1970-01-01
相关资源
最近更新 更多