예전에 JSMin을 사용했을 때는 http://fmarcia.info/jsmin/에서 실행 페이지를 열고 거기에 내 코드를 붙여 넣은 다음 가중치가 적용된 코드를 다시 텍스트 편집 도구에 복사하여 저장하곤 했습니다.
시간이 지나면서 이게 정말 귀찮은 일이라는 걸 깨달았어요! 우리는 프로그래머이기 때문에 스스로 일을 더 간단하게 만들어 보는 것은 어떨까요?
그래서 '친절한' JSMin 작업을 시작하게 됐어요.
'친근하게' 작업하는 과정에서 '의외로' 예상치 못한 문제가 발생했고, 결국 어떤 문제가 발생했는지, 어떻게 해결해야 할지 이야기해보겠습니다.
근데 문제를 다 해결한 후에야 기사를 쓸 생각이라 이번에는 "사진도 없고 진실도 없다"는 게 아쉽네요.
설명을 시작하기 전에 이 질문과 관련된 몇 가지 기술적 지식을 설명하겠습니다. Windows 스크립트 호스트에 대한 프로그래밍 경험이 있다면 이 부분을 건너뛸 수 있습니다. 귀하는 ASP에 대한 경험이 있으므로 이 섹션에는 이미 알고 있는 일부 내용이 있을 수 있습니다.
Windows 스크립트 호스트(WSH)는 일부 실행 파일(wscript.exe 및 cscript.exe)로 나타나는 Windows 스크립트 호스트입니다. 해당 기능은 인터넷 보안 정책이나 작업의 제한을 받지 않고 JScript를 실행하는 것입니다. 일부 시스템 관리 작업을 수행하기 위해 VBScript로 작성된 파일입니다. 기본적으로 Windows에서 .js 확장자를 가진 파일은 WSH 파일로 간주됩니다. .js 파일을 두 번 클릭하면 일부 오류 메시지가 나타나거나 바이러스 백신 소프트웨어에 의해 차단될 수 있습니다.
HTML 응용 프로그램은 이름에서 알 수 있듯이 "HTML 응용 프로그램"입니다. Windows 스크립트 호스트와 같이 상당히 느슨한 보안 조건에서 스크립트를 실행합니다. 더 나은 그래픽 인터페이스를 가지고 있습니다. 본질적으로 HTA 파일은 실제로 특별한 확장자를 가진 HTM 파일입니다. 인터페이스를 만드는 데 너무 많은 에너지를 소비하고 싶지 않고 HTML과 WSH 모두에 대한 경험이 있다면 HTML 응용 프로그램을 사용하여 문제를 해결하십시오. 문제는 상당히 나쁜 선택이 아닙니다. HTML 응용 프로그램은 종종 WPF 기술의 전신으로 간주됩니다. 대상 환경이 WPF를 지원하는 경우(예: .NET Framework 3.0) WPF를 사용하는 것이 더 적합할 수 있습니다. HTA 파일은 생성하기 쉽기 때문에 한때 트로이 목마 다운로더로 사용되었습니다. 오늘날까지도 일부 바이러스 백신 소프트웨어는 여전히 HTA 파일을 트로이 목마 다운로더로 대략적으로 판단할 수 있습니다. .exe와 같은 이진 실행 파일과 마찬가지로 HTA 파일의 유해 여부는 파일 형식이 아닌 자체 설계에 따라 결정됩니다.
FSO라고 하는 FileSystemObject는 파일 시스템 작업을 수행하는 스크립트를 용이하게 하기 위해 Windows 스크립팅 기술에 제공되는 구성 요소 개체입니다. 이는 ASP 프로그래밍에서도 매우 일반적입니다.
WshShell은 Shell 관련 개체를 작동하기 위한 스크립트를 용이하게 하기 위해 WSH 실행 환경에서 제공하는 구성 요소 개체입니다.
ADODB.Stream("ADO 스트림"이라고도 함)은 바이너리 데이터 스트림의 작업을 용이하게 하기 위해 ADO에서 제공하는 구성 요소 개체이지만 파일 작업과 같은 데이터베이스 이외의 장소에서도 자주 사용됩니다.
"파일 아이콘을 마우스로 클릭하기만 하면 된다"와 같은 기능적 기능을 "쉘 연관"이라고 부르는 경우가 많으며, 쉘 연관에 대한 사람들의 이해는 "마우스와 연관됨"입니다. 클릭" 또는 뭔가. 하지만 조금 더 주의를 기울이면 마우스 오른쪽 버튼을 클릭하면 나타나는 바로가기 메뉴에 기본 명령 외에 "편집", "인쇄" 등의 다른 명령도 있다는 것을 알 수 있습니다.
이번에 해야 할 일은 .js 파일에 "Minimize" 명령을 추가하는 것입니다. 이 명령을 클릭하면 JSMin이 ECMAScript 코드의 무게를 줄이기 위해 시작됩니다.
여기서 첫 번째 문제가 발생했습니다.
.js 파일(실제로는 WSH 작업 파일)을 작성하여 "설치"를 "자동화"하는 데 사용했습니다.
Windows에서 .js 파일에 파일 연결을 추가하려면 "JSFile" 아래의 Shell 키에 하위 키를 추가해야 합니다. HKCR.js 레지스트리의 "기본" 값에 해당하는 HKCRJSFile 키 키와 Command라는 종속 하위 키가 있습니다.
HKCRJSFileShell 아래에 최소화 항목을 추가하고 명령 하위 키에 대해 "내 hta 파일 경로 "%1"" 값을 설정한 후 이 최소화 명령을 사용하면 "적법한 실행 파일이 아님" 오류가 발생하는 것으로 나타났습니다. , 그리고 앞에 시작 명령을 추가하면 "다음으로 열기" 대화상자가 뜹니다...
쉘 항목 아래에서는 그렇게 기회적일 수는 없는 것 같아서 읽어보게 되었습니다. 먼저 htafile 파일 형식 설정을 한 다음 새로 추가된 Minimize 명령으로 설정합니다. .js 파일은 다음과 같이 작성됩니다.
view sourceprint?1 var asocCommand = wshShell.RegRead("HKEY_CLASSES_ROOT\htafile\Shell\Open\Command\").replace("%1 " , instPath "\" appExec).replace("%*", '"%1"');
셸 관련 문제는 방금 해결되었지만 명령줄 매개변수 구문 분석 문제가 있습니다.
처음에는 WSH 작업 파일을 이 가젯의 전달자로 사용할 계획이었지만 곧 WSH 파일이 기본적으로 부족하다는 사실을 발견했습니다. UI 지원 - VBScript의 InputBox와 HTML의 프롬프트는 JScript로 작성된 WSH 작업 파일에 존재하지 않습니다. WSH 사용을 고집하는 경우 Windows 콘솔을 통해서만 사용자 입력을 얻을 수 있습니다. 그리고 콘솔을 통해 사용자 입력을 받은 경우, 이 도구의 표준 사용 프로세스는 일련의 마우스 조작에서 "마우스로 파일 아이콘 클릭 - 바로가기 메뉴 - 최소화 - 키보드로 문자 입력"이 됩니다(물론, 키보드 조작도 가능합니다) 그러다가 갑자기 키보드로 전환하면 안되는 것 같습니다.
그래서 이 도구를 구현하는 방법으로 풍부한 인터페이스를 제공할 수 있는 파일 형식인 HTA를 사용하기로 결정했습니다.
HTA를 선택하면 명령줄 매개 변수를 구문 분석하는 데 사용되는 "인수" 개체가 없는 등 WSH의 "외부 전송 없음" 기능 중 일부도 잃게 됩니다.
제 생각에는 -level 매개변수를 통해 JSMin의 코드 축소 수준을 지정하고, -silent 매개변수를 통해 프롬프트 정보를 끄는 것이 가능해야 한다고 생각합니다. 이러한 매개변수를 명령줄에서 해석할 수 없는 경우 해당 기능은 구현되지 않습니다.
그래서 두 가지 함수를 작성했습니다.
//========//========
// 명령줄 정보 구문 분석
// HTA의 명령줄에서 해석 환경 실행된 HTA의 실제 경로 및 추가 매개변수
// 코드의 이 부분은 원래 NanaLich에서 생성되었으며 어떤 상황에서도 서면 허가 없이 직접 사용할 수 있습니다. 귀하는 귀하 또는 귀하의 기관이 승인 없이 코드를 생성했다고 주장해서는 안 되며, 승인 없이 NanaLich 이름으로 수정된 버전을 게시해서는 안 됩니다.
//========//========
functionnamedOrNot(args) {
varnamed={},not=[],c; >for(var i = 0; i < args.length; i ) {
c = args[i]
switch(c.charAt(0)) {
case "-":
case "/":
c = c.substring(1);
if(c.indexOf("=") > 0) {
c = c.split("=") ;
named[c.shift()] = c.join("=");
} else if(c.indexOf(":") > 0) {
c = c.split (":");
named[c.shift()] = c.join(":");
} else {
// 명명된 매개변수도 허용하는지 여부를 확인할 수 없습니다. 추가 매개변수입니다.
//i;
named[c] = args[i 1]
break
not.push( c)
break;
}
}
args.named = 명명됨;
args.unnamed = not;
}
var a = [], q = false, c = "", $ = "";
function mit() {
if(c)
a.push(c)
}
for (var i = 0; i < str.length; i ) {
$ = str.charAt(i)
if($ == '"') {
q = ! q;
} else {
if($ == " " && !q) {
mit()
c = ""
} else {
c = $ ;
}
}
}
namedOrNot(a)
return a; =// ========
이런 방식으로 HTA:Application 개체의 commandLine 속성이 이 함수에 전달되는 한 구문 분석 후 명명된 매개 변수와 명명되지 않은 매개 변수를 사용할 수 있습니다. 얻을 수 있습니다.
명령줄 매개변수 문제를 해결한 후 다음 단계는 파일 인코딩입니다.
실제 웹 개발 과정에서는 "유니코드(UTF-16)" 등 다양한 이유로 "유니코드가 아닌 지역 인코딩", "유니코드(UTF-16) 인코딩" 이외의 다른 인코딩 형식을 사용할 수 있습니다. ) Big Endian" 및 "UTF-8" 인코딩 방법.
기존 텍스트 편집 도구를 통해 코드를 복사하여 붙여넣을 경우 파일 저장 시 인코딩 유형만 선택하면 되었지만 이제는 "열기-복사-붙여넣기" 작업이 필요 없는 방식을 설계하고 있습니다. -복사-붙여넣기-저장"은 매우 지루한 작업 단계를 포함하는 도구입니다. 인코딩 유형에 자동으로 적응하는 이 도구의 기능을 설계해야 합니다.
불행히도 내 테스트에서는 FSO나 ADODB.Stream 모두 텍스트 인코딩을 자동으로 식별하는 기능이 없습니다. 다른 방법을 찾아야 합니다. 다행히도 VBScript는 HTA에서 기본적으로 지원되지 않습니다. 바이트 그룹에서 직접 작동하는 기능이지만 VBScript의 문자열로 바이트 그룹에서 작동하는 기능은 여전히 우리의 요구 사항을 어느 정도 충족할 수 있습니다.
그래서 다음 함수를 작성했습니다.
코드 복사
코드는 다음과 같습니다.
함수 vbDetectFileEncoding(fn)
Dim Stream, B3
Set Stream = CreateObject("ADODB.Stream")
Stream.Type = 1
Stream.Open() 호출
Stream.LoadFromFile(fn) 호출
B3 = CStr(Stream.Read(3))
Stream.Close() 호출
Stream = Nothing
Dim L1
L1 = 왼쪽(B3, 1)
If (L1 = ChrW(&hFEFF)) Then
vbDetectFileEncoding = "unicode"
함수 종료
Elseif (L1 = ChrW(&hFFFE)) Then
vbDetectFileEncoding = "unicodeFEFF"
함수 종료
Elseif B3 = (ChrB(&hEF) & ChrB(&hBB) & ChrB(&hBF)) Then
vbDetectFileEncoding = "utf-8"
종료 함수
End If
vbDetectFileEncoding = defEncoding
함수 종료
이 함수는 파일에 존재할 수 있는 BOM을 기반으로 텍스트 파일에 사용된 인코딩을 유추합니다.
여기서 주목해야 할 점은 다음과 같습니다.
ADODB.Stream 관련 문서에서는 허용되는 값이 인터페이스를 통해 인터넷 문자 집합 이름으로 전달되는 일반적인 문자열(예: "iso")이라고 기록합니다. -8859 -1", "Windows-1252" 등). 시스템에 알려진 문자 세트 이름 목록은 Windows 레지스트리에서 HKEY_CLASSES_ROOTMIMEDatabaseCharset의 하위 키 및 "Unicode Big Endian"( Encoding 1201) 해당 항목은 "unicodeFFFE"입니다. 이 정보를 통해 ADO Stream에서 "Unicode Big Endian" 인코딩을 사용할 경우 Charset 속성을 "unicodeFFFE"로 지정해야 함을 유추할 수 있습니다. 혼동의 구현은 다음과 같습니다. BOM 문자의 유니코드 번호는 U FEFF이고 "일반" "유니코드 인코딩"은 실제로 "Unicode Little Endian"입니다. BOM 문자는 두 개의 "FF FE"로 작성됩니다. 바이트이며 " Unicode Big Endian"에서는 "FE FF"로 기록됩니다.
여기서 문제가 발생합니다. "unicodeFFFE"의 반대말이 "unicodeFEFF"인 경우 여기서 "FEFF"는 BOM 문자의 유니코드 번호라는 것을 이해할 수 있습니다. "Unicode Big Endian"을 의미하는 "unicodeFFFE"의 "FFFE"는 무엇을 의미합니까? 분명히 이는 "유니코드 번호가 U FFFE인 문자"를 의미할 수 없습니다.
실제로 Charset 속성에 "unicode" 또는 "unicodeFFFE"가 설정되어 있어도 출력 파일은 "유니코드(리틀 엔디안)"로 인코딩되는 것을 발견했습니다. . 일치하지 않습니다.
추가로 시도한 결과 "Unicode Big Endian"으로 인코딩된 파일을 출력하려면 Charset 속성을 "unicodeFEFF"로 설정해야 한다는 사실을 발견했습니다. "FEFF"가 정확히 일치하는 것을 쉽게 찾을 수 있습니다. BOM 파일의 문자 바이트 순서는 Charset 속성에 대해 "unicodeFXFX"를 설정하는 것이 실제로 "FXFX와 같은 바이트 순서로 인코딩"과 동일하다는 것을 알 수 있습니다. 이는 작성된 대로 완전히 일치하지 않습니다. 레지스트리.
지금까지 가젯은 "유니코드", "유니코드 빅 엔디안", "UTF-8" 및 "유니코드가 아닌 지역 인코딩"으로 파일을 읽고 쓸 수 있었지만 아직 생각해 본 적이 없습니다. 서류와 등록양식에 왜 부정확하거나 전혀 쓸모없는 정보가 들어 있는지 이해해 보세요...
위의 문제들을 하나씩 해결하고 나면 더 이상 공부할 만한 문제는 없는 것 같습니다. .
그런데 JSMin을 사용하는 과정에서 또 다른 문제점을 발견했습니다.
나 같은 일부 사람들은 Windows에서 주로 텍스트 파일의 줄 구분 기호를 LF로 사용합니다. 오른쪽.
JSMin은 모든 CR을 LF로 대체하므로 CR LF 쌍은 두 개의 LF로 구성된 "LF LF" 쌍이 됩니다.
JSMin의 원래 디자인에 따르면 제어 문자 LF는 일반적으로 줄어들기 때문에 두 개의 연속된 LF는 문제가 되지 않지만 jsmin.js에는 특정 특성(/*! ... */), 그리고 이러한 "중요 코멘트"에 CR LF 쌍이 있으면 결국 제거할 수 없는 두 개의 LF 제어 문자가 되어 좋지 않습니다.
이 문제를 해결하기 위해 jsmin.js를 일부 수정했는데... 그런데 JSMin은 제가 이해하기에는 좀 부족해서 CR을 공백으로만 바꿀 수 있었는데 다행히 다음에서는 가능합니다. Windows에는 몇 가지 장점이 있습니다(대부분의 Windows 버전에서는 LF 제어 문자만으로는 메모장 프로그램에서 거의 관찰할 수 없으며, 이로 구분된 두 줄의 텍스트가 서로 붙어 있는 것처럼 보입니다). 그냥 사용하세요... 이러한 수정 사항을 별도로 나열하지 않겠습니다.
이 글에 언급된 모든 코드는 이 압축 패키지에서 찾을 수 있습니다.
압축된 패키지에는 세 가지 파일이 포함되어 있습니다. install.js는 등록 파일과 관련된 "설치" 스크립트이고, jsmin.hta는 "Minimize" 명령을 사용할 때 실제로 실행되는 "애플리케이션"이며, jsmin.js입니다. 나중에 jsmin.js를 수정합니까?
동일한 폴더에 세 개의 파일을 추출한 후 install.js를 두 번 클릭하여 이 도구를 설치합니다. 운영 체제를 다시 설치한 경우 개인 폴더에 도구가 여전히 남아 있는 경우 개인 폴더에 남아 있는 install.js를 두 번 클릭하면 도구를 다시 사용할 수 있습니다.
참고: Windows XP부터 최신 버전의 Windows에서는 인터넷에서 다운로드한 파일에 대해 플래그를 설정합니다. 이 플래그로 인해 HTA 파일이 정상적으로 실행되지 않을 수 있습니다. 이 플래그를 제거하려면 파일 속성 대화 상자에서 "잠금 해제" 버튼을 클릭하십시오.
업데이트: install.js를 수정했습니다. 이제 64비트 Windows 7에 올바르게 설치할 수 있습니다. 설치 후 수동으로 "잠금 해제"할 필요가 없습니다.
비밀은 여기에 있습니다:
코드 복사 코드는 다음과 같습니다
var appsPath = wshShell.ExpandEnvironmentStrings(wshShell.RegRead(regUSF "Personal")) "\Scriptlet";
try{
fso.OpenTextFile(instPath "\" appExec ": Zone.Identifier", 1).Close();
fso.OpenTextFile(instPath "\" appExec ":Zone.Identifier", 2).Close();
}catch(ex){ }
파일 패키지 다운로드 파일 이름이 변경된 jse로 첨부되어 있어 js를 자주 개발하는 친구들이 혼동을 피하기에 편리합니다.
제 친구들 중 상당수가 개발에 win2003을 사용하기 때문에 .js 파일은 일반 텍스트로 열리게 되는데, 앞으로는 js로 실행이 불가능합니다. 그냥 install.jse로 변경하면 실행됩니다.
이런 좋은 자료를 올려주신 작가님께 감사드립니다. 작가 블로그 주소
http://www.cnblogs.com/NanaLich