C#을 통한 Javascript 압축 (한글불가)

2020. 6. 3. 16:29·C#.NET/C#

 

출처 : http://truelogic.org/wordpress/2015/09/18/minify-javascript-with-c/

 

MVC부터는 번들이 있어, 전혀 쓸모가 없지만 구닥다리 웹폼에서는 이것이 필요했다..

결론부터 말하면 한글 깨짐 문제로 사용하지 않는 자료, 영문 압축은 잘 됨

 

1. 윈폼이든 ASP.NET의 IIS 든.. 새로 쓰기 할 경로폴더에 읽기/쓰기 권한이 있어야 함

2. 원 제작자의 의도는, 외쿡인이라 한글을 쓰지 않으니 
   압축로직을 char[] 가 아닌 바이너리 스트림으로 처리하면서 이 부분에서 한글 깨짐이 발생함

3. 해결방법은 byte 비교가 아닌 char 를 비교하며 한글 문자열일때 유니코드 변환을 해야함..

4. 즉 출처의 소스 코드는 인코딩 옵션을 줘바야 그닥 의미가 없음

 

결론은 js 압축 방식의 형태를 구경해보고자 한다면...
적어도 한번은 삽질해봤고.. 학습용으로 보기엔 괜찮은 코드라 올려둠

하지만 실사용은 mvc이상에선 닷넷프레임워크면 기본제공 번들러를
core면 nuget에서 받아 사용하지 않을까 추정..

그리고 구닥다리 웹폼엔 https://www.nuget.org/packages/AjaxMin/ 이걸 써도 되지 않을까 추측
js를 압축해주는 사이트라면  https://closure-compiler.appspot.com/home 와 같은 사이트도 있고
다른 대안의 방법은 많음...

 

주의 : 로컬 IIS 디버깅중 코드 오류 발생하면 iisworker가 물고 있는 경우가 발생하니

iisworker 프로세스를 강제 종료해야 할 수 있음

 

using System;
using System.IO;

namespace JSMinify
{
    public class Minify
    {
        private string mFileName = "";              // file to process
        private string mOriginalData = "";           // data from original file
        private string mModifiedData = "";          // processed data
        private bool mIsError = false;               // becomes true if any error happens
        private string mErr = "";                    // error message 
        private BinaryReader mReader = null;         // stream to process the file byte by byte

        private const int EOF = -1;                 // for end of file

        /// <summary>
        /// Constructor - does all the processing
        /// </summary>
        /// <param name="f">file path</param>
        public Minify(string f) {

            try
            {
                if (File.Exists(f))
                {
                    mFileName = f;
                    
                    //read contents completely. This is only for test purposes. The actual processing is done by another stream
                    StreamReader rdr = new StreamReader(mFileName);
                    mOriginalData = rdr.ReadToEnd();
                    rdr.Close();

                    mReader = new BinaryReader(new FileStream(mFileName, FileMode.Open));
                    doProcess();
                    mReader.Close();

                    //write modified data
                    string outFile = mFileName + ".min";
                    StreamWriter wrt = new StreamWriter(outFile);
                    wrt.Write(mModifiedData);
                    wrt.Close();

                }
                else {
                    mIsError = true;
                    mErr = "File does not exist";
                }

            }
            catch (Exception ex) {
                mIsError = true;
                mErr = ex.Message;
            }
        }

        /// <summary>
        /// Main process
        /// </summary>
        private void doProcess() { 
            int lastChar = 1;                   // current byte read
            int thisChar = -1;                  // previous byte read
            int nextChar = -1;                  // byte read in peek()
            bool endProcess = false;            // loop control
            bool ignore = false;                // if false then add byte to final output
            bool inComment = false;             // true when current bytes are part of a comment
            bool isDoubleSlashComment = false;  // '//' comment


            // main processing loop
            while (!endProcess) {
                endProcess = (mReader.PeekChar() == -1);    // check for EOF before reading
                if (endProcess)
                    break;

                ignore = false;
                thisChar = mReader.ReadByte();
                
                if (thisChar == '\t')
                    thisChar = ' ';
                else if (thisChar == '\t')
                    thisChar = '\n';
                else if (thisChar == '\r')
                    thisChar = '\n';

                if (thisChar == '\n')
                    ignore = true;

                if (thisChar == ' ')
                {
                    if ((lastChar == ' ') || isDelimiter(lastChar) == 1)
                        ignore = true;
                    else {
                        endProcess = (mReader.PeekChar() == -1); // check for EOF
                        if (!endProcess)
                        {
                            nextChar = mReader.PeekChar();
                            if (isDelimiter(nextChar) == 1)
                                ignore = true;
                        }
                    }
                }


                if (thisChar == '/')
                {
                    nextChar = mReader.PeekChar();
                    if (nextChar == '/' || nextChar == '*')
                    {
                        ignore = true;
                        inComment = true;
                        if (nextChar == '/')
                            isDoubleSlashComment = true;
                        else
                            isDoubleSlashComment = false;
                    }


                }

                // ignore all characters till we reach end of comment
                if (inComment) {
                    while (true) {
                        thisChar = mReader.ReadByte();
                        if (thisChar == '*') {
                            nextChar = mReader.PeekChar();
                            if (nextChar == '/')
                            {
                                thisChar = mReader.ReadByte();
                                inComment = false;
                                break;
                            }
                        }
                        if (isDoubleSlashComment && thisChar == '\n') {
                                inComment = false;
                                break;
                        }

                     } // while (true)
                    ignore = true;  
                } // if (inComment) 
                

                if (!ignore)
                    addToOutput(thisChar);
                    
                lastChar = thisChar;
            } // while (!endProcess) 
        }


        /// <summary>
        /// Add character to modified data string
        /// </summary>
        /// <param name="c">char to add</param>
        private void addToOutput(int c)
        {
            mModifiedData += (char) c;
        }


        /// <summary>
        /// Original data from file
        /// </summary>
        /// <returns></returns>
        public string getOriginalData()
        {
            return mOriginalData;
        }

        /// <summary>
        /// Modified data after processing
        /// </summary>
        /// <returns></returns>
        public string getModifiedData()
        {
            return mModifiedData;
        }

        /// <summary>
        /// Check if a byte is alphanumeric
        /// </summary>
        /// <param name="c">byte to check</param>
        /// <returns>retval - 1 if yes. else 0</returns>
        private int isAlphanumeric(int c)
        {
            int retval = 0;

            if ((c >= 'a' && c <= 'z') ||
                (c >= '0' && c <= '9') ||
                (c >= 'A' && c <= 'Z') ||
                c == '_' || c == '$' || c == '\\' || c > 126)
                retval = 1;

            return retval;

        }

        /// <summary>
        /// Check if a byte is a delimiter 
        /// </summary>
        /// <param name="c">byte to check</param>
        /// <returns>retval - 1 if yes. else 0</returns>
        private int isDelimiter(int c)
        {
            int retval = 0;

            if (c == '(' || c == ',' || c == '=' || c == ':' ||
                c == '[' || c == '!' || c == '&' || c == '|' ||
                c == '?' || c == '+' || c == '-' || c == '~' ||
                c == '*' || c == '/' || c == '{' || c == '\n' ||
                c == ',' 
            )
            {
                retval = 1;
            }

            return retval;

        }



    }
}

 

 

'C#.NET > C#' 카테고리의 다른 글

C# 에서 POST로 API 보내기  (0) 2025.07.15
Dapper ORM 사용 예제  (2) 2024.10.22
Spring의 Class ToString 을 비슷하게 구현해보자  (0) 2024.09.20
간단 텍스트 파일 로그 생성  (0) 2024.09.06
c# 권장 코딩 규칙 가이드  (0) 2020.06.09
'C#.NET/C#' 카테고리의 다른 글
  • Dapper ORM 사용 예제
  • Spring의 Class ToString 을 비슷하게 구현해보자
  • 간단 텍스트 파일 로그 생성
  • c# 권장 코딩 규칙 가이드
iyak
iyak
자료 정리
  • iyak
    iyak
    나의 정리 공간

    post | manage
  • 전체
    오늘
    어제
    • 분류 전체보기 (55)
      • C#.NET (30)
        • C# (9)
        • ASP.NET (19)
        • WinForm (0)
        • 설정 (2)
      • JAVA,Spring (0)
        • Spring (0)
      • DB (9)
        • SQLServer (9)
        • MySQL & MaridDB (0)
      • Web (12)
        • JS & jQuery (10)
        • Web개발 관련사이트 (2)
      • 기타 (4)
        • 프로그램 (4)
  • 블로그 메뉴

    • 홈
    • 태그
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
iyak
C#을 통한 Javascript 압축 (한글불가)
상단으로

티스토리툴바