JavaScriptMinifier C#压缩Javascript

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text;
using System.IO;

/// <summary>
/// 提供压缩 JavaScript 代码的能力。
/// </summary>
public sealed class JavaScriptMinifier
{
    #region 私有字段

    private const int EOF = -1;

    private readonly StringBuilder _JsBuilder;
    private readonly TextReader _JsReader;
    private int _TheA = Convert.ToInt32(‘\n‘);
    private int _TheB;
    private int _TheLookahead = EOF;

    #endregion

    #region 构造函数

    /// <summary>
    /// 初始化 <see cref="JavaScriptMinifier"/> 类的新实例。
    /// </summary>
    /// <param name="jsReader">包含要压缩的 JavaScript 代码的 <see cref="TextReader"/>。</param>
    private JavaScriptMinifier(TextReader jsReader)
    {
        if (jsReader == null) throw new ArgumentNullException("jsReader");

        this._JsReader = jsReader;
        this._JsBuilder = new StringBuilder();
    }

    #endregion

    #region 静态方法

    /// <summary>
    /// 压缩指定的 JavaScript 代码。
    /// </summary>
    /// <param name="js">包含要压缩的 JavaScript 代码的 <see cref="StringBuilder"/>。</param>
    /// <returns>返回包含压缩后的 JavaScript 代码的 <see cref="StringBuilder"/>。</returns>
    public static StringBuilder Minify(StringBuilder js) { return Minify(new StringReader(js.ToString())); }

    /// <summary>
    /// 压缩指定的 JavaScript 代码。
    /// </summary>
    /// <param name="jsCode">要压缩的 JavaScript 代码。</param>
    /// <returns>返回包含压缩后的 JavaScript 代码的 <see cref="StringBuilder"/>。</returns>
    public static StringBuilder Minify(string jsCode) { return Minify(new StringReader(jsCode)); }

    /// <summary>
    /// 压缩指定的 JavaScript 代码。
    /// </summary>
    /// <param name="jsReader">包含要压缩的 JavaScript 代码的 <see cref="TextReader"/>。</param>
    /// <returns>返回包含压缩后的 JavaScript 代码的 <see cref="StringBuilder"/>。</returns>
    public static StringBuilder Minify(TextReader jsReader)
    {
        JavaScriptMinifier jsmin = new JavaScriptMinifier(jsReader);

        jsmin._Jsmin();

        return jsmin._JsBuilder;
    }

    #endregion

    #region 私有方法

    private void _Jsmin()
    {
        this._Action(3);

        while (this._TheA != EOF)
        {
            switch ((Char)this._TheA)
            {
                case ‘ ‘:
                    if (_IsAlphanum(this._TheB)) this._Action(1);
                    else this._Action(2);

                    break;
                case ‘\n‘:
                    switch ((Char)this._TheB)
                    {
                        case ‘{‘:
                        case ‘[‘:
                        case ‘(‘:
                        case ‘+‘:
                        case ‘-‘:
                            this._Action(1);

                            break;
                        case ‘ ‘:
                            this._Action(3);

                            break;
                        default:
                            if (_IsAlphanum(this._TheB)) this._Action(1);
                            else this._Action(2);

                            break;
                    }

                    break;
                default:
                    switch ((Char)this._TheB)
                    {
                        case ‘ ‘:
                            if (_IsAlphanum(this._TheA))
                            {
                                this._Action(1);

                                break;
                            }

                            this._Action(3);

                            break;
                        case ‘\n‘:
                            switch ((Char)this._TheA)
                            {
                                case ‘}‘:
                                case ‘]‘:
                                case ‘)‘:
                                case ‘+‘:
                                case ‘-‘:
                                case ‘"‘:
                                case ‘\‘‘:
                                    this._Action(1);

                                    break;
                                default:
                                    if (_IsAlphanum(this._TheA)) this._Action(1);
                                    else this._Action(3);

                                    break;
                            }

                            break;
                        default:
                            this._Action(1);

                            break;
                    }

                    break;
            }
        }
    }

    private void _Action(int d)
    {
        if (d <= 1) this._Put(this._TheA);
        if (d <= 2)
        {
            this._TheA = this._TheB;

            if (this._TheA == ‘\‘‘ || this._TheA == ‘"‘)
            {
                for (; ; )
                {
                    this._Put(this._TheA);
                    this._TheA = this._Get();

                    if (this._TheA == this._TheB) break;
                    if (this._TheA <= ‘\n‘) throw new Exception(string.Format("Error: JSMIN unterminated string literal: {0}", this._TheA));
                    if (this._TheA != ‘\\‘) continue;

                    this._Put(this._TheA);
                    this._TheA = this._Get();
                }
            }
        }

        if (d > 3) return;

        this._TheB = this._Next();

        if (this._TheB != ‘/‘ || ((((((((((((this._TheA != ‘(‘ && this._TheA != ‘,‘) && this._TheA != ‘=‘) && this._TheA != ‘[‘) && this._TheA != ‘!‘) && this._TheA != ‘:‘) && this._TheA != ‘&‘) && this._TheA != ‘|‘) && this._TheA != ‘?‘) && this._TheA != ‘{‘) && this._TheA != ‘}‘) && this._TheA != ‘;‘) && this._TheA != ‘\n‘)) return;

        this._Put(this._TheA);
        this._Put(this._TheB);

        for (; ; )
        {
            this._TheA = this._Get();

            if (this._TheA == ‘/‘) break;

            if (this._TheA == ‘\\‘)
            {
                this._Put(this._TheA);
                this._TheA = this._Get();
            }
            else if (this._TheA <= ‘\n‘) throw new Exception(string.Format("Error: JSMIN unterminated Regular Expression literal : {0}.", this._TheA));

            this._Put(this._TheA);
        }

        this._TheB = this._Next();
    }

    private int _Next()
    {
        int c = this._Get();
        const int s = (int)‘*‘;

        if (c == ‘/‘)
        {
            switch ((Char)this._Peek())
            {
                case ‘/‘:
                    for (; ; )
                    {
                        c = this._Get();

                        if (c <= ‘\n‘) return c;
                    }
                case ‘*‘:
                    this._Get();

                    for (; ; )
                    {
                        switch (this._Get())
                        {
                            case s:
                                if (this._Peek() == ‘/‘)
                                {
                                    this._Get();

                                    return Convert.ToInt32(‘ ‘);
                                }

                                break;
                            case EOF:
                                throw new Exception("Error: JSMIN Unterminated comment.");
                        }
                    }
                default:
                    return c;
            }
        }

        return c;
    }

    private int _Peek()
    {
        this._TheLookahead = this._Get();

        return this._TheLookahead;
    }

    private int _Get()
    {
        int c = this._TheLookahead;
        this._TheLookahead = EOF;

        if (c == EOF) c = this._JsReader.Read();

        return c >= ‘ ‘ || c == ‘\n‘ || c == EOF ? c : (c == ‘\r‘ ? ‘\n‘ : ‘ ‘);
    }

    private void _Put(int c) { this._JsBuilder.Append((char)c); }

    private static bool _IsAlphanum(int c) { return ((c >= ‘a‘ && c <= ‘z‘) || (c >= ‘0‘ && c <= ‘9‘) || (c >= ‘A‘ && c <= ‘Z‘) || c == ‘_‘ || c == ‘$‘ || c == ‘\\‘ || c > 126); }

    #endregion
}

JavaScriptMinifier

时间: 2024-10-11 05:47:22

JavaScriptMinifier C#压缩Javascript的相关文章

压缩 javascript 和 css

www.iwangzheng.com 目前我们项目中的 CSS/JS 文件比较多, 由于RAILS 3.0 没有提供asset pipeline功能,所以这样会制约我们的访问速度. 例如:  目前,我们的布局( origin.html.erb )页面有 19 个JS文件,15个CSS文件. 每次打开都需要发送 34个 request,严重影响体验. 所以,我们要把这些js, css 分别打包压缩成一个文件. 参考: http://stackoverflow.com/questions/71122

Spring Mvc + Maven + yuicompressor 使用 profile 来压缩 javascript ,css 文件; (十)

profile相关知识点: 在开发项目时,设想有以下场景: 你的Maven项目存放在一个远程代码库中(比如github),该项目需要访问数据库,你有两台电脑,一台是Linux,一台是Mac OS X,你希望在两台电脑上都能做项目开发.但是,安装Linux的电脑上安装的是MySQL数据库,而Mac OS X的电脑安装的是PostgreSQL数据库.此时你需要找到一种简单的方法在两种数据库连接中进行切换,你会怎么做? 此外,你的项目需要部署.为了调试,在开发时我们在Java编译结果中加入了调试信息(

YUI Compressor 压缩 JavaScript 原理-《转载》

YUI Compressor 压缩 JavaScript 的内容包括: 移除注释 移除额外的空格 细微优化 标识符替换(Identifier Replacement) YUI Compressor包括哪些细微优化呢? object["property"] ,如果属性名是合法的 JavaScript 标识符(注:合法的 JavaScript 标识符——由一个字母开头,其后选择性地加上一个或者多个字母.数字或下划线)且不是保留字,将优化为: object.property . {"

使用Google的Closure Compiler,在本机上压缩javascript

2011-12-05 13:47:39 1.JAVA JDK下载地址: http://download.oracle.com/otn-pub/java/jdk/7u1-b08/jdk-7u1-windows-i586.exe 2.WIN7下JAVA环境配置: (1)用鼠标右击“计算机”—–>属性—–>选择左边导航的“高级系统设置”选项—>选择右下角的“环境变量”选项(2)进行win7下Java环境变量配置 在”系统变量”下进行如下配置:A.新建->变量名:JAVA_HOME 变量值

【Java】通过移除空行和注释来压缩 JavaScript 代码

1. [代码]JavaScriptCompressor.java/** * This file is part of the Echo Web Application Framework (hereinafter "Echo"). * Copyright (C) 2002-2009 NextApp, Inc. * * Compresses a String containing JavaScript by removing comments and whitespace. */publ

gzip压缩JavaScript

为了提高客户端的体验效果,RIA开发逐渐兴起.这样会项目中会充斥的大量的JavaScript代码,与此同时会消耗客户端浏览器性能.对于 Ext 实现的 one page one application ,对于外网访问也就产生了噩梦似的加载(除非你的网速足够快).为了缓解(不是解决,从代码加载方面考虑)加载慢的问题可以对JavaScript进行压缩.JavaScript的gzip静态压缩方法 一.将js格式文件压缩成gzjs格式.使用gzip.exe打包压缩后的JS文件,最后生成xx.js.gz,

压缩javascript文件方法

写在前面的话:正式部署前端的时候,javascript文件一般需要压缩,并生成相应的sourcemap文件,对于一些小型的项目开发,这里提供一个简单的办法. ======正文开始====== 1.下载google-closure-compiler文件: 从这里下载:download 2.复制压缩包中的compiler.jar到需要压缩的javascript文件目录. 3.打开命令行cmd,cd到该目录,运行如下命令: java -jar compiler.jar --js test.js --j

使用Google Closure Compiler高级压缩Javascript代码注意的几个地方

介绍 GCC(Google Closure Compiler)是由谷歌发布的Js代码压缩编译工具.它可以做到分析Js的代码,移除不需要的代码(dead code),并且去重写它,最后再进行压缩. 三种压缩模式 GCC提供三种压缩模式: 1)Whitespace only 2)Simple 3)Advanced 我们以这段简单的代码为例 function sayHello(name) { alert('Hello, ' + name); } sayHello('binnng'); 分别使用这三种压

gulp-uglify 压缩javascript文件

1.安装gulp-uglify 命令行输入npm install gulp-uglify --save-dev ; 2.配置文件 2.1基本使用 var gulp = require('gulp'), uglify = require('gulp-uglify'); //获取uglify插件 gulp.task('jsmin', function () { gulp.src('src/js/index.js') //引入js文件 .pipe(uglify()) .pipe(gulp.dest('