如何在PHP运行如下JS容易...或者其他什么东西(How to minify JS in PHP

2019-06-25 10:13发布

我做了一些环顾四周,但我仍然困惑了一下。

我试图Crockford的JSMin,但Win XP的不能解压可执行文件的某些原因。

我真正想要的是,虽然使用PHP来缩小JS代码的简单和易于使用的JS minifier - 并返回结果。

究其原因,就是因为:我有2个文件(例如)说我之间的工作:scripts.js中和scripts_template.js

scripts_template的是,我写出来正常码 - 那我也来缩小它并粘贴精缩脚本到scripts.js中 - 这是我在我的网站实际使用的一个。

我想简单地做这样的事情在我的网页,以消除中间人:

<script type="text/javascript" src="scripts.php"></script>

再来说scripts.php的内容:

<?php include("include.inc"); header("Content-type:text/javascript"); echo(minify_js(file_get_contents("scripts_template.js")));

这样一来,每当我更新我的JS,我没有要不断去一个网站来缩小它,它重新粘贴到scripts.js中 - 一切都将自动更新。

是的,我也尝试过Crockford的PHP Minifier,我已经看到了在PHP迅速,但我不明白的PHP类,只是还没有......有什么在那里,猴子可以理解,或许真的与正则表达式?

怎么样,我们让这个更简单?

我只是想删除标签空间 - 我仍然希望我的代码是可读的。

它不是像剧本让我的网站滞后epically,这只是事情是聊胜于无。

标签去除,任何人吗? 如果可能的话,有关删除完全空白行怎么样?

Answer 1:

我已经使用了PHP实现通过JSMin的道格拉斯·克罗克福德相当长的一段时间。 串联文件时,它可以是一个有点冒险,因为可能存在对封尾缺少分号。

这将会是一个明智的想法缓存缩小的输出和回声,只要它比源文件更新什么是缓存。

require 'jsmin.php';

if(filemtime('scripts_template.js') < filemtime('scripts_template.min.js')) {
  read_file('scripts_template.min.js');
} else {
  $output = JSMin::minify(file_get_contents('scripts_template.js'));
  file_put_contents('scripts_template.min.js', $output);
  echo $output;
}

您也可以尝试JShrink 。 我没有以前使用它,因为我还没有困难JSMin过,但下面这段代码应该做的伎俩。 我没有意识到这一点,但JShrink需要PHP 5.3和命名空间。

require 'JShrink/Minifier.php';

if(filemtime('scripts_template.js') < filemtime('scripts_template.min.js')) {
  read_file('scripts_template.min.js');
} else {
  $output = \JShrink\Minifier::minify(file_get_contents('scripts_template.js'));
  file_put_contents('scripts_template.min.js', $output);
  echo $output;
}


Answer 2:

看看Assetic,在PHP中一笔巨大的财富管理库。 大家都用的Symfony2集成和广泛的应用。

https://github.com/kriswallsmith/assetic



Answer 3:

根据您的服务器(例如,不是在运行的限制安全模式 ),也许你也可以超越PHP的minifier和使用运行shell_exec() 举例来说,如果你可以在服务器上运行Java,把副本锐压缩机的服务器上,并直接使用它。

然后scripts.php会是这样的:

<?php 

  $cmd = "java -cp [path-to-yui-dir] -jar [path-to-yuicompressor.jar] [path-to-scripts_template.js]";

  echo(shell_exec($cmd));

?>

其它建议:建立微小一步到您的开发流程,部署到服务器之前。 例如,我建立了我的Eclipse PHP项目的JS和CSS文件压缩为一个“构建”文件夹中。 奇迹般有效。



Answer 4:

使用“PHPWee”: https://github.com/searchturbine/phpwee-php-minifier (也使用JSmin ),我有点进一步推@Robert K溶液。

该解决方案允许涅槃CSS和JS文件。 如果无法找到非缩小的文件,它会返回一个空字符串。 如果缩小的文件比旧的非精缩,它会尝试创建它。 这将创建精缩文件的子文件夹,如果它不存在。 如果该方法可以成功地运行如下的文件,则返回它无论是在一个<script> (JavaScript的)或<link> (CSS)标签。 否则,该方法将在适当的标签返回非minified的版本。

:PHP 7.0.13测试

/**
* Try to minify the JS/CSS file. If we are not able to minify,
*   returns the path of the full file (if it exists).
*
* @param $matches Array
*   0 = Full partial path
*   1 = Path without the file
*   2 = File name and extension
*
* @param $fileType Boolean
*   FALSE: css file.
*   TRUE: js file
*
* @return String
*/
private static function createMinifiedFile(array $matches, bool $fileType)
{
    if (strpos($matches[1], 'shared_code') !== false) {

        $path = realpath(dirname(__FILE__)) . str_replace(
            'shared_code',
            '..',
            $matches[1]
        );

    } else {

        $path = realpath(dirname(__FILE__)) .
            "/../../" . $matches[1];
    }

    if (is_file($path . $matches[2])) {

        $filePath = $link = $matches[0];

        $min = 'min/' . str_replace(
            '.',
            '.min.',
            $matches[2]
        );

        if (!is_file($path . $min) or 
            filemtime($path . $matches[2]) > 
            filemtime($path . $min)
        ) {

            if (!is_dir($path . 'min')) {

                mkdir($path . 'min');   
            }

            if ($fileType) { // JS

                $minified = preg_replace(
                        array(
                            '/(\))\R({)/',
                            '/(})\R/'
                        ),
                        array(
                            '$1$2',
                            '$1'
                        ),
                        Minify::js(
                        (string) file_get_contents(
                            $path . $matches[2]
                        )
                    )
                );

            } else { // CSS

                $minified = preg_replace(
                    '@/\*(?:[\r\s\S](?!\*/))+\R?\*/@', //deal with multiline comments
                    '',
                    Minify::css(
                        (string) file_get_contents(
                            $path . $matches[2]
                        )
                    )
                );
            }

            if (!empty($minified) and file_put_contents(
                    $path . $min, 
                    $minified 
                )
            ) {

                $filePath = $matches[1] . $min;
            }

        } else { // up-to-date

            $filePath = $matches[1] . $min;
        }

    } else { // full file doesn't exists

        $filePath = "";
    }

    return $filePath;
}

/**
* Return the minified version of a CSS file (must end with the .css extension).
*   If the minified version of the file is older than the full CSS file,
*   the CSS file will be shrunk.
*
*   Note: An empty string will be return if the CSS file doesn't exist.
*
*   Note 2: If the file exists, but the minified file cannot be created, 
*       we will return the path of the full file.
*
* @link https://github.com/searchturbine/phpwee-php-minifier Source
*
* @param $path String name or full path to reach the CSS file.
*   If only the file name is specified, we assume that you refer to the shared path.
*
* @return String
*/
public static function getCSSMin(String $path)
{
    $link = "";
    $matches = array();

    if (preg_match(
            '@^(/[\w-]+/view/css/)?([\w-]+\.css)$@',
            $path,
            $matches
        )
    ) {

        if (empty($matches[1])) { // use the default path

            $matches[1] = self::getCssPath();

            $matches[0] = $matches[1] . $matches[2];
        }

        $link = self::createMinifiedFile($matches, false);

    } else {

        $link = "";
    }

    return (empty($link) ?
        '' :
        '<link rel="stylesheet" href="' . $link . '">'
    );
}

/**
* Return the path to fetch CSS sheets.
* 
* @return String
*/
public static function getCssPath()
{
    return '/shared_code/css/' . self::getCurrentCSS() . "/";
}

/**
* Return the minified version of a JS file (must end with the .css extension).
*   If the minified version of the file is older than the full JS file,
*   the JS file will be shrunk.
*
*   Note: An empty string will be return if the JS file doesn't exist.
*
*   Note 2: If the file exists, but the minified file cannot be created, 
*       we will return the path of the full file.
*
* @link https://github.com/searchturbine/phpwee-php-minifier Source
*
* @param $path String name or full path to reach the js file.
*
* @return String
*/
public static function getJSMin(String $path)
{
    $matches = array();

    if (preg_match(
            '@^(/[\w-]+(?:/view)?/js/)([\w-]+\.js)$@',
            $path,
            $matches
        )
    ) {
        $script = self::createMinifiedFile($matches, true);

    } else {

        $script = "";
    }

    return (empty($script) ? 
        '' :
        '<script src="' . $script . '"></script>'
    );
}

在(Smarty的)模板,您可以使用这样的那些方法:

{$PageController->getCSSMin("main_frame.css")}
//Output: <link rel="stylesheet" href="/shared_code/css/default/min/main_frame.min.css">

{$PageController->getCSSMin("/gem-mechanic/view/css/gem_mechanic.css")}
//Output: <link rel="stylesheet" href="/gem-mechanic/view/css/min/gem_mechanic.min.css">

{$PageController->getJSMin("/shared_code/js/control_utilities.js")}
//Output: <script src="/shared_code/js/min/control_utilities.min.js"></script>

{$PageController->getJSMin("/PC_administration_interface/view/js/error_log.js")}
//Output: <script src="/PC_administration_interface/view/js/min/error_log.min.js"></script>

单元测试:

/**
* Test that we can minify CSS files successfully.
*/
public function testGetCSSMin()
{
    //invalid style
    $this->assertEmpty(
        PageController::getCSSMin('doh!!!')
    );


    //shared style
    $path = realpath(dirname(__FILE__)) . '/../css/default/min/main_frame.min.css';

    if (is_file($path)) {

        unlink ($path);
    }

    $link = PageController::getCSSMin("main_frame.css");

    $this->assertNotEmpty($link);

    $this->assertEquals(
        '<link rel="stylesheet" href="/shared_code/css/default/min/main_frame.min.css">',
        $link
    );

    $this->validateMinifiedFile($path);


    //project style
    $path = realpath(dirname(__FILE__)) . '/../../gem-mechanic/view/css/min/gem_mechanic.min.css';

    if (is_file($path)) {

        unlink ($path);
    }

    $link = PageController::getCSSMin("/gem-mechanic/view/css/gem_mechanic.css");

    $this->assertNotEmpty($link);

    $this->assertEquals(
        '<link rel="stylesheet" href="/gem-mechanic/view/css/min/gem_mechanic.min.css">',
        $link
    );

    $this->validateMinifiedFile($path);
}

/**
* Test that we can minify JS files successfully.
*/
public function testGetJSMin()
{
    //invalid script
    $this->assertEmpty(
        PageController::getJSMin('doh!!!')
    );


    //shared script
    $path = realpath(dirname(__FILE__)) . '/../js/min/control_utilities.min.js';

    if (is_file($path)) {

        unlink ($path);
    }

    $script = PageController::getJSMin("/shared_code/js/control_utilities.js");

    $this->assertNotEmpty($script);

    $this->assertEquals(
        '<script src="/shared_code/js/min/control_utilities.min.js"></script>',
        $script
    );

    $this->validateMinifiedFile($path);


    //project script
    $path = realpath(dirname(__FILE__)) . '/../../PC_administration_interface/view/js/min/error_log.min.js';

    if (is_file($path)) {

        unlink ($path);
    }

    $script = PageController::getJSMin("/PC_administration_interface/view/js/error_log.js");

    $this->assertNotEmpty($script);

    $this->assertEquals(
        '<script src="/PC_administration_interface/view/js/min/error_log.min.js"></script>',
        $script
    );

    $this->validateMinifiedFile($path);
}

/**
* Make sure that the minified file exists and that its content is valid.
*
* @param $path String the path to reach the file
*/
private function validateMinifiedFile(string $path)
{
    $this->assertFileExists($path);

    $content = (string) file_get_contents($path);

    $this->assertNotEmpty($content);

    $this->assertNotContains('/*', $content);

    $this->assertEquals(
        0,
        preg_match(
            '/\R/',
            $content
        )
    );
}

其他注意事项

  1. phpwee.php我不得不更换<?<?php
  2. 我曾与命名空间(功能问题class_exists()无法找到类即使他们是在同一个文件)。 我在每一个文件中删除命名空间解决了这个问题。


文章来源: How to minify JS in PHP easily…Or something else