审查视图

application/admin/command/Min.php 5.8 KB
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
<?php

namespace app\admin\command;

use think\console\Command;
use think\console\Input;
use think\console\input\Option;
use think\console\Output;
use think\Exception;

class Min extends Command
{

    /**
     * 路径和文件名配置
     */
    protected $options = [
        'cssBaseUrl'  => 'public/assets/css/',
        'cssBaseName' => '{module}',
        'jsBaseUrl'   => 'public/assets/js/',
        'jsBaseName'  => 'require-{module}',
    ];

    protected function configure()
    {
        $this
                ->setName('min')
                ->addOption('module', 'm', Option::VALUE_REQUIRED, 'module name(frontend or backend),use \'all\' when build all modules', null)
                ->addOption('resource', 'r', Option::VALUE_REQUIRED, 'resource name(js or css),use \'all\' when build all resources', null)
30
                ->addOption('optimize', 'o', Option::VALUE_OPTIONAL, 'optimize type(uglify|closure|none)', 'none')
31 32 33 34 35
                ->setDescription('Compress js and css file');
    }

    protected function execute(Input $input, Output $output)
    {
Karson authored
36 37
        $module = $input->getOption('module') ?: '';
        $resource = $input->getOption('resource') ?: '';
38
        $optimize = $input->getOption('optimize') ?: 'none';
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55

        if (!$module || !in_array($module, ['frontend', 'backend', 'all']))
        {
            throw new Exception('Please input correct module name');
        }
        if (!$resource || !in_array($resource, ['js', 'css', 'all']))
        {
            throw new Exception('Please input correct resource name');
        }

        $moduleArr = $module == 'all' ? ['frontend', 'backend'] : [$module];
        $resourceArr = $resource == 'all' ? ['js', 'css'] : [$resource];

        $minPath = __DIR__ . DS . 'Min' . DS;
        $publicPath = ROOT_PATH . 'public' . DS;
        $tempFile = $minPath . 'temp.js';
56
        $nodeExec = '';
57 58

        if (!$nodeExec)
59
        {
60
            if (IS_WIN)
61
            {
62 63
                // Winsows下请手动配置配置该值,一般将该值配置为 '"C:\Program Files\nodejs\node.exe"',除非你的Node安装路径有变更
                $nodeExec = '"C:\Program Files\nodejs\node.exe"';
64
            }
65
            else
66
            {
67
                try
68
                {
69 70 71 72 73 74 75 76 77
                    $nodeExec = exec("which node");
                    if (!$nodeExec)
                    {
                        throw new Exception("node environment not found!please install node first!");
                    }
                }
                catch (Exception $e)
                {
                    throw new Exception($e->getMessage());
78
                }
79 80 81 82 83 84 85 86 87 88 89 90 91
            }
        }

        foreach ($moduleArr as $mod)
        {
            foreach ($resourceArr as $res)
            {
                $data = [
                    'publicPath'  => $publicPath,
                    'jsBaseName'  => str_replace('{module}', $mod, $this->options['jsBaseName']),
                    'jsBaseUrl'   => $this->options['jsBaseUrl'],
                    'cssBaseName' => str_replace('{module}', $mod, $this->options['cssBaseName']),
                    'cssBaseUrl'  => $this->options['cssBaseUrl'],
92 93
                    'jsBasePath'  => str_replace(DS, '/', ROOT_PATH . $this->options['jsBaseUrl']),
                    'cssBasePath' => str_replace(DS, '/', ROOT_PATH . $this->options['cssBaseUrl']),
94
                    'optimize'    => $optimize,
95 96 97 98 99 100 101 102 103 104 105 106 107
                    'ds'          => DS,
                ];

                //源文件
                $from = $data["{$res}BasePath"] . $data["{$res}BaseName"] . '.' . $res;
                if (!is_file($from))
                {
                    $output->error("{$res} source file not found!file:{$from}");
                    continue;
                }
                if ($res == "js")
                {
                    $content = file_get_contents($from);
108
                    preg_match("/require\.config\(\{[\r\n]?[\n]?+(.*?)[\r\n]?[\n]?}\);/is", $content, $matches);
109 110 111 112 113 114 115 116 117 118 119 120 121 122
                    if (!isset($matches[1]))
                    {
                        $output->error("js config not found!");
                        continue;
                    }
                    $config = preg_replace("/(urlArgs|baseUrl):(.*)\n/", '', $matches[1]);
                    $data['config'] = $config;
                }
                // 生成压缩文件
                $this->writeToFile($res, $data, $tempFile);

                $output->info("Compress " . $data["{$res}BaseName"] . ".{$res}");

                // 执行压缩
123 124 125 126 127 128
                $command = "{$nodeExec} \"{$minPath}r.js\" -o \"{$tempFile}\" >> \"{$minPath}node.log\"";
                if ($output->isDebug())
                {
                    $output->warning($command);
                }
                echo exec($command);
129 130 131
            }
        }
132 133 134 135
        if (!$output->isDebug())
        {
            @unlink($tempFile);
        }
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171

        $output->info("Build Successed!");
    }

    /**
     * 写入到文件
     * @param string $name
     * @param array $data
     * @param string $pathname
     * @return mixed
     */
    protected function writeToFile($name, $data, $pathname)
    {
        $search = $replace = [];
        foreach ($data as $k => $v)
        {
            $search[] = "{%{$k}%}";
            $replace[] = $v;
        }
        $stub = file_get_contents($this->getStub($name));
        $content = str_replace($search, $replace, $stub);

        if (!is_dir(dirname($pathname)))
        {
            mkdir(strtolower(dirname($pathname)), 0755, true);
        }
        return file_put_contents($pathname, $content);
    }

    /**
     * 获取基础模板
     * @param string $name
     * @return string
     */
    protected function getStub($name)
    {
Karson authored
172
        return __DIR__ . DS . 'Min' . DS . 'stubs' . DS . $name . '.stub';
173 174 175
    }

}