1 (изменено: RUVATA, 2012-07-16 11:47:13)

Тема: JScriptInclude Gear - Механизм каскадного импорта скриптов/библиотек.

Дабы по 10 раз не переписывать одно и тоже, прошу Вас ознакомится с очередной редакцией опубликованной мной на хабрахабре
(где его вобщем-то не очень радушно восприняли но видимо есть на то причины)
Здесь же оставлю ссылку на пример. (В нем теперь "худо-бедно", но все же есть справка JScriptInclude.chm)
Для успешного запуска примера предварительно ознакомитесь с разделом Example прилагаемой справки.

Желающих обсудить что либо, высказать свои замечания/предложения с нетерпением ожидаю в комментария к данному посту, а так же в обсуждении вышеуказанного поста на хабре.

Ничто не помогает писать код больше чем Stevie Ray Vaughan And Double Trouble в наушниках.

2

Re: JScriptInclude Gear - Механизм каскадного импорта скриптов/библиотек.

Пока только придирка по именам переменных. Сделайте замену по схеме:

s/Tagert/Target/g

s/AllredyLoded/AlreadyLoaded/g

Далее посерьезнее.

1. Это совершенно излишне и крайне не рекомендуется

var AllredyLoded = new Boolean(false);

достаточно написать

var AllredyLoded = false;

2. ошибка!!!
typeof  include !== "object"

typeof функция == 'function'
функция, но никак не объект

3. eval(...)
Выполнится в контексте (области видимости) функции include, то есть все объявленные сущности внешнему скрипту видны не будут.

( 2 * b ) || ! ( 2 * b )

3 (изменено: RUVATA, 2012-06-01 10:43:14)

Re: JScriptInclude Gear - Механизм каскадного импорта скриптов/библиотек.

Rumata, спасибо ... но все же не все ваши замечания "в яблочко", особенно про область видимости, но об этом отдельно.
за "Вражеский язык" - стыдно, все поправил, и в коде и в посте.

3.И самый интересный момент
Да, действительно eval() отработает в контексте include() и все объявленное через ключевое слово var
умрет вместе с include.[[scope]]... ну так никто и не говорил что Вы не можете объявляться в библиотеках глобально
Я собственно именно это и имел в виду... Я немного переработал пример, чтобы этот момент уточнить.

Ничто не помогает писать код больше чем Stevie Ray Vaughan And Double Trouble в наушниках.

4

Re: JScriptInclude Gear - Механизм каскадного импорта скриптов/библиотек.

RUVATA пишет:

<...> ну так никто и не говорил что Вы не можете объявляться в библиотеках глобально

Я не понял этой фразы.

Какой смысл в функции include('external.js') если все импортируемые файлом сущности "умрут"? Рекомендую к прочтению статью Global eval. What are the options?. Статья большая, но очень полезная. В контексте этой темы вывод единственный и печальный - глобальный eval в JScript не работает.

( 2 * b ) || ! ( 2 * b )

5

Re: JScriptInclude Gear - Механизм каскадного импорта скриптов/библиотек.

То, что эта проблема не решается средствами языка, это понятно. В этом случае советую делать предобработку используемого кода. Это означает всякие придуманные фишки (инклуды, лямбды, LinQ и т.п.) заменять родным скриптом.

Например, сначала надо провести анализ какие библиотеки требуются для выполнения кода, затем просто все соединить в один файл. А далее по желанию: LibName.InnerVariable или - Variable in Global Context.

6

Re: JScriptInclude Gear - Механизм каскадного импорта скриптов/библиотек.

Rumata,

Какой смысл в функции include('external.js'), если все импортируемые файлом сущности "умрут"

Я же обновил пример использования вот сейчас ссылочку повторю вот, напоминаю - запускаем mainScript.js из MainDir
Если вы в подключаемых скриптах будете объявлять сущности без ключевого слова var, то они будут даже при eval в контексте include, объявлены в Global.[[scope]]

PS: сейчас переработаю механизм, и мы избавимся от этого неудобства "глобального объявления сущностей",
но нам необходимо будет после "инклудов" произвести принудительную инициализацию через eval в основном контексте
например:


jsImport.include("\\EmbeddedDir\\EmbeddedScript.js")
jsImport.include("\\SecondIncludeTest.js")
eval(jsImport.initialization)

смысл таков, что функция пробежится по всем файлам каскадом, выловит все jsImport.include(...) и соберет сорцы
в свойстве глобального объекта jsImport.initialization, ну и собственно... всё
минуточку терпения бьюсь с регулярками (ох я их не люблю, но без них никуда)

Ничто не помогает писать код больше чем Stevie Ray Vaughan And Double Trouble в наушниках.

7 (изменено: RUVATA, 2012-06-03 00:28:45)

Re: JScriptInclude Gear - Механизм каскадного импорта скриптов/библиотек.

Ура, Ура, Ура !!!
Возрадуйтесь товарищи
готово - вот Вам пример, новой инкарнации моего механизма JScriptInclude... распаковываем => заходим в MainDir => стартуем mainScript.js (наслаждаемся )
Теперь все подключаемое импортируется прямо в глобальный [[scope]](это скрытый объект-хранилище доступных сущностей "область видимости", для тех кто ECMA не читал ),
Как и обещал - победил неудобство "инкогнито" объявления сущностей без ключевого слова var в основной стек
цена сией победы, требование к выполнению eval(jsImport.initialization), после описания подключений в вызывающем скрипте.
Есть лишь определенные требования к описанию относительных путей:
1) если необходимо подключить скрипт из той-же директории, то вид должен быть следующий
"\\имя_скрипта.js"
2) вглубь по лесу(древу каталогов), соответсвенно вида
"\\каталог_вглубь\\имя_скрипта.js"
3) вверх по лесу(древу каталогов), обозначается добавлением предшествующих точек, количество точек прямо пропорционально количеству шагов вверх по дереву каталогов, т.е.
...\\имя_скрипта.js выводит нас на три каталога вверх от родительского, например при
расположении вызывающего jsImport.include("...\\test.js") расположенного в D:\1\2\3\4\5\
механизм будет пытаться импортировать D:\1\2\test.js

Желательно описывать сам механизм имменно в вызывающем скрипте, хотя если вы заметили написан он таким образом,
что даже если он и будет в подключаемом скрипте, ничего не произойдет.

Прошу Вас протестировать, сие ноу-хау ну и соответственно, если все "бэнч!", то переписываю первый пост в теме.

Вот листинг mainScript.js, код механизма в таком виде занимает 2,8 Кб


if (typeof jsImport == "undefined"){var jsImport = new Object(); jsImport.initialization = "";};
if (typeof fso == "undefined"){var fso = new ActiveXObject("Scripting.FileSystemObject")};
if (typeof LoadedLibs == "undefined"){var LoadedLibs = []};
if (typeof SourseBuffer == "undefined"){SourseBuffer = [];}
 
 if(typeof  jsImport.include !== "function"){
        jsImport.include = function (TargetScript, ParentDir){
			if (typeof ParentDir == "undefined"){ParentDir = WScript.ScriptFullName.replace(/[^\\]+$/, '');};
		 
			PathValidation(ParentDir)		
 
            for (i in LoadedLibs){
                if(i == TargetScript){AlreadyLoaded = true}
            };
 
            if(typeof AlreadyLoaded == 'undefined' || AlreadyLoaded !== true){
                if(fso.FileExists(TargetScript)){				
                    var SourseBuffer = fso.OpenTextFile(TargetScript).ReadAll();
					var includeArray = includePharser()
					jsImport.initialization =  jsImport.initialization + SourseBuffer 										
						if(includeArray.length != 0){					
							for(i in includeArray){	
								jsImport.include(includeArray[i].replace(/\\\\/, "\\"), TargetScript.replace(/[^\\]+$/,""))						
							};
						};					
					LoadedLibs.push(TargetScript)
					AlreadyLoaded = false;
                } else { 				
                    WScript.Echo("Target " + TargetScript + " not found")					
                };
 
                 function StepOutside(outside){
                    return outside.substring(0, outside.lastIndexOf("\\"))
                };				
				
				function includePharser(){
					var pattern =  /jsImport.include\("(.*?)"\)/g;
					var result;
					var includeArray = [];					
						while ( (result = pattern.exec(SourseBuffer)) != null) {
							includeArray.push(result[1])
							SourseBuffer = SourseBuffer.replace(result[0],"")
							pattern.lastIndex = 0
						};
					return includeArray;
				};
				
				function PathValidation(ParentDir){		
					if(TargetScript.charAt(1) !== ":"){
						var dot = TargetScript.charAt(0)					   
						if(dot  == "."){
							var OutsidePath = ParentDir, counter= -1;                    		 
								while(dot == "."){
									counter++
									dot = TargetScript.charAt(counter);
									OutsidePath = StepOutside(OutsidePath);
								};		 
							TargetScript = OutsidePath + TargetScript.substring(counter);
							dot = "undefined"; counter = "undefined"; OutsidePath = "undefined"; AlreadyLoaded = 'undefined';
						} else {
							TargetScript = ParentDir + TargetScript.substring(1)
						};
					};
				};
				
            };
 
        };
    };
 
jsImport.include("\\EmbeddedDir\\EmbeddedScript.js")
jsImport.include("\\SecondIncludeTest.js")
eval(jsImport.initialization)
 
SecondIncludeFunction()
OutsideFunction()
EmbeddedFunction()
WScript.Echo(Embedded.Constant)
WScript.Echo(Embedded3)

И минимизированный вариант кода механизма (для тех кому глаз режет ) код механизма в таком виде занимает 2,05 Кб


if(typeof jsImport=="undefined"){var jsImport=new Object();jsImport.initialization=""};if(typeof fso=="undefined"){var fso=new ActiveXObject("Scripting.FileSystemObject")};if(typeof LoadedLibs=="undefined"){var LoadedLibs=[]};if(typeof SourseBuffer=="undefined"){SourseBuffer=[]}if(typeof jsImport.include!=="function"){jsImport.include=function(TargetScript,ParentDir){if(typeof ParentDir=="undefined"){ParentDir=WScript.ScriptFullName.replace(/[^\\]+$/,'')};PathValidation(ParentDir);for(i in LoadedLibs){if(i==TargetScript){AlreadyLoaded=true}};if(typeof AlreadyLoaded=='undefined'||AlreadyLoaded!==true){if(fso.FileExists(TargetScript)){var SourseBuffer=fso.OpenTextFile(TargetScript).ReadAll();var includeArray=includePharser();jsImport.initialization=jsImport.initialization+SourseBuffer;if(includeArray.length!=0){for(i in includeArray){jsImport.include(includeArray[i].replace(/\\\\/,"\\"),TargetScript.replace(/[^\\]+$/,""))}};LoadedLibs.push(TargetScript);AlreadyLoaded=false}else{WScript.Echo("Target "+TargetScript+" not found")};function StepOutside(outside){return outside.substring(0,outside.lastIndexOf("\\"))};function includePharser(){var pattern=/jsImport.include\("(.*?)"\)/g;var result;var includeArray=[];while((result=pattern.exec(SourseBuffer))!=null){includeArray.push(result[1]);SourseBuffer=SourseBuffer.replace(result[0],"");pattern.lastIndex=0};return includeArray};function PathValidation(ParentDir){if(TargetScript.charAt(1)!==":"){var dot=TargetScript.charAt(0);if(dot=="."){var OutsidePath=ParentDir,counter=-1;while(dot=="."){counter++;dot=TargetScript.charAt(counter);OutsidePath=StepOutside(OutsidePath)};TargetScript=OutsidePath+TargetScript.substring(counter);dot="undefined";counter="undefined";OutsidePath="undefined";AlreadyLoaded='undefined'}else{TargetScript=ParentDir+TargetScript.substring(1)}}}}}};

ну и для совсем минималисов-параноиков минимализированный и обфусцированный, код механизма в таком виде занимает - 1,66 Кб

eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('3(7 6=="5"){4 6=D O();6.o=""};3(7 k=="5"){4 k=D V("M.G")};3(7 l=="5"){4 l=[]};3(7 8=="5"){8=[]}3(7 6.j!=="d"){6.j=d(2,a){3(7 a=="5"){a=u.F.h(/[^\\\\]+$/,\'\')};x(a);C(i y l){3(i==2){f=w}};3(7 f==\'5\'||f!==w){3(k.H(2)){4 8=k.I(2).J();4 9=s();6.o=6.o+8;3(9.E!=0){C(i y 9){6.j(9[i].h(/\\\\\\\\/,"\\\\"),2.h(/[^\\\\]+$/,""))}};l.A(2);f=R}z{u.S("T "+2+" U Q")};d t(n){B n.r(0,n.P("\\\\"))};d s(){4 p=/6.j\\("(.*?)"\\)/g;4 m;4 9=[];v((m=p.L(8))!=K){9.A(m[1]);8=8.h(m[0],"");p.N=0};B 9};d x(a){3(2.q(1)!==":"){4 e=2.q(0);3(e=="."){4 c=a,b=-1;v(e=="."){b++;e=2.q(b);c=t(c)};2=c+2.r(b);e="5";b="5";c="5";f=\'5\'}z{2=a+2.r(1)}}}}}};',58,58,'||TargetScript|if|var|undefined|jsImport|typeof|SourseBuffer|includeArray|ParentDir|counter|OutsidePath|function|dot|AlreadyLoaded||replace||include|fso|LoadedLibs|result|outside|initialization|pattern|charAt|substring|includePharser|StepOutside|WScript|while|true|PathValidation|in|else|push|return|for|new|length|ScriptFullName|FileSystemObject|FileExists|OpenTextFile|ReadAll|null|exec|Scripting|lastIndex|Object|lastIndexOf|found|false|Echo|Target|not|ActiveXObject'.split('|'),0,{}))
Ничто не помогает писать код больше чем Stevie Ray Vaughan And Double Trouble в наушниках.

8 (изменено: Rumata, 2012-06-02 01:31:47)

Re: JScriptInclude Gear - Механизм каскадного импорта скриптов/библиотек.

Очень много кода и много мусора (LoadedLibs, AlreadyLoaded и прочие глобальные объекты) для такой простой задачи как прочитать внешний файл и выполнить его.

( 2 * b ) || ! ( 2 * b )

9 (изменено: RUVATA, 2012-06-02 01:50:20)

Re: JScriptInclude Gear - Механизм каскадного импорта скриптов/библиотек.

Rumata, согласен
можете предложить более лаконичный вариант ? я был бы рад... (и наверное не один я)

PS: код действительно сыроват... но с поставленной задачей справляется, не так ли ?
Если у меня дойдут руки - перепишу, нет, так может кто ни будь другой подсобит...
Тем более за неимением альтернатив - и в таком виде штука вполне пригодная (ИМХО)
Я ее реализовывал в первую очередь для собственных нужд, меня собственно и первый
вариант вполне себе устраивал...

PPS:

для такой простой задачи как прочитать внешний файл и выполнить его

ИМХО - излишне критично, и предвзято...
просто прочитать файл и выполнить - это две строки кода


var Sourse = fso.OpenTextFile("какой-то файл").ReadAll();
eval(Sourse)

а раз я использовал 60 - строк, наверное на то есть причины... мне не хочется верить что здесь
меня принимают совсем за дурака
код не подвергался ни оптимизации, ни адаптации... в основном для удобства отладки писался
более развернуто... (вменяемого дебагера для WSH-скриптов кроме как тащить себе монстра VisualStudio
я не нашел, хотя и не искал особо).

Оправдываюсь как маленький, честное слово, но я тут у Вас человек новый... маленьким можно

Ничто не помогает писать код больше чем Stevie Ray Vaughan And Double Trouble в наушниках.

10 (изменено: Rumata, 2012-06-02 02:23:54)

Re: JScriptInclude Gear - Механизм каскадного импорта скриптов/библиотек.


/**
 * Функция эмуляции подключения файлов. Читает содержимое заданного файла. 
 * Если такой файл уже был "подключен", то повторно чтение не производится. 
 *
 * В случае отсутствия файла вызывается встроенная функция require.error, 
 * которая (по умолчанию) бросает исключение с текстом об ошибке. При 
 * необходимости эту функцию можно переопределить. 
 *
 * Содержимое файла кешируется в переменной require.cache и передается 
 * функции eval для окончательного подключения всех загруженных файлов. 
 *
 * Пример:
 * require('A.js');
 * require('B.js');
 * eval(require.cache);
 *
 * @param  String   имя файла	
 * @param  Integer  формат открываемого файла
 *                  -2 - открыть используя системные настройки
 *                  -1 - открыть файл как Unicode
 *                   0 - открыть файл как ASCII (по умолчанию)
 */
function require(filespec, format)
{
	var fso = require.fso = require.fso || new ActiveXObject('Scripting.FileSystemObject');

	var filespec = fso.GetAbsolutePathName(filespec);

	if ( require.files.hasOwnProperty(filespec) ) {
		return;
	}

	if ( ! fso.FileExists(filespec) ) {
		require.error('File not found: "' + filespec + '"');
		return;
	}

	var content;
	
	var e;
	try {
		var h = fso.OpenTextFile(filespec, 1, false, format || 0);
		content = h.ReadAll();
		h.Close();
	} catch (e) {
		require.error(e.message);
		return;
	}

	require.files[filespec] = 1;
	require.cache = [require.cache, '//!required: ' + filespec, content].join('\n');
};

/**
 * Функция бросает исключение. Вызывается при созникновении ошибок. 
 *
 * @param  String   текст ошибки
 */
require.error = function(msg)
{
	throw new Error(msg);
};

/**
 * Хэш, хранит список подключенных файлов. Используется для внутренних целей 
 * функцией require. 
 *
 * @var  Object
 */
require.files = {};

/**
 * Строковая переменная, хранит содержимое всех подключенных файлов. 
 * Значение переменной передается функции eval для окончательного подключения 
 * всех загруженных файлов. 
 *
 * @var  String
 */
require.cache = '';
( 2 * b ) || ! ( 2 * b )

11

Re: JScriptInclude Gear - Механизм каскадного импорта скриптов/библиотек.

Отлично, давайте бадаться... (по доброму, кодо-дескутировать)

Давайте же сравнивать... да начнется шоу!

1) Строк кода (без пустых строк, с построчно раскрытыми блоками)
     JScriptInclude  - 60 строк               
     "функция эмуляции подключения..." - 24 строки
JScriptInclude - 0 баллов
"функция эмуляции подключения..." - 5 баллов (я бы даже 10 дал, но мы же по честному)

2.1) Возможность использования абсолютного пути
Запускаем скрипт в каталоге D:\Main\test.js пытаемся подключить D:\Main\Embedded\Embedded.js с содержимым

var WOW = "WOW it's work"

JScriptInclude  - Да   

jsImport.include("D:\\MainDir\\Embedded\\Embedded.js")
eval(jsImport.initialization)
WScript.Echo(WOW)

"функция эмуляции подключения..." - Судя по всему  - Да, но толку нет

reqire("D:\\MainDir\\Embedded\\Embedded.js")
eval(reqire.cache)
WScript.Echo(WOW)

- получаем ошибку "WOW - определение отсутствует"
JScriptInclude - 5 баллов
"функция эмуляции подключения..." - 0 баллов

2.2) Возможность подключения скриптов из родительского каталога
Запускаем скрипт в каталоге D:\Main\test.js пытаемся подключить D:\Main\Embedded.js с содержимым

var WOW = "WOW it's work"

JScriptInclude  - Да   

jsImport.include("\\Embedded.js")
eval(jsImport.initialization)
WScript.Echo(WOW)

"функция эмуляции подключения..." - Судя по всему  - Да, но толку нет

reqire("Embedded.js")
eval(reqire.cache)
WScript.Echo(WOW)

- получаем ошибку "WOW - определение отсутствует"
JScriptInclude - 5 баллов
"функция эмуляции подключения..." - 0 баллов

2.3) Возможность подключения скриптов из дочернего каталога (вверх по лесу/древу каталогов)
Запускаем скрипт в каталоге D:\Main\test.js пытаемся подключить D:\Main\Embedded\Embedded.js с содержимым

var WOW = "WOW it's work"

JScriptInclude  - Да   

jsImport.include("\\Embedded\\Embedded.js")
eval(jsImport.initialization)
WScript.Echo(WOW)

"функция эмуляции подключения..." - Судя по всему НЕТ

reqire("Embedded.js")
eval(reqire.cache)
WScript.Echo(WOW)

- пробовал и "\\Embedded\\Embedded.js" и "Embedded\\Embedded.js" и все равно ошибка "File not found D:\Embedded\Embedded.js"
ладно, не удивляемся идем дальше.
JScriptInclude - 5 баллов
"функция эмуляции подключения..." - 0 баллов

2.3) Возможность подключения скриптов из родительских каталогов (вниз по лесу/древу каталогов)
Запускаем скрипт в каталоге D:\Main\test.js пытаемся подключить D:\Embedded.js с содержимым

var WOW = "WOW it's work"

JScriptInclude  - Да   

jsImport.include(".\\Embedded.js")
eval(jsImport.initialization)
WScript.Echo(WOW)

"функция эмуляции подключения..." - НЕТ, она такую плюшку даже не предусматривает.
JScriptInclude - 5 баллов
"функция эмуляции подключения..." - 0 баллов

3) Возможность каскадного импорта библиотек, т.е. импорт скриптов, которые подключаю другие скрипты через тот-же синтаксис, и механизм
Запускаем скрипт в каталоге D:\Main\test.js пытаемся подключить D:\Embedded.js с содержимым

jsImport.include("\\Embedded\\Embedded2.js") // D:\Main\Embedded\Embedded2.js - содержимое var WOW2 = "WOW2 it's work"
var WOW = "WOW it's work"

JScriptInclude  - Да   

jsImport.include(".\\Embedded.js")
eval(jsImport.initialization)
WScript.Echo(WOW)
WScript.Echo(WOW2)

JScriptInclude - 5 баллов
"функция эмуляции подключения..." - 0 баллов

примеры обоих скриптов с окружением для теста - дабы не быть голословным

итак подведем итоги:
JScriptInclude - 25 баллов
"функция эмуляции подключения..." - 5 баллов (Учитывая что вообще ни разу не сделала то для чего предназначалась)

С нетерпением жду РЕВАНШ !

Ничто не помогает писать код больше чем Stevie Ray Vaughan And Double Trouble в наушниках.

12

Re: JScriptInclude Gear - Механизм каскадного импорта скриптов/библиотек.

RUVATA пишет:

С нетерпением жду РЕВАНШ

Реванша не будет. Я не ставил цель сделать полноценный скрипт лучше чем у Вас. Я хотел показать, что можно было писать проще, понятнее и компактнее. То что я написал, это всего лишь сырой набросок того, что надо еще исправлять, улучшать и усложнять. В настоящее время функция может подгружать (на самом деле эмулировать, так же как и Ваша) внешний файл только на первом уровне. Вложенные (каскадные) подключения не реализованы. С чем Ваш скрипт оригинально справляется в рамках заданных правил кодирования. Но он пасует, когда (и не только !!!) скрипт будет подключен так (одинарные кавычки вместо двойных):

jsImport.include('\\Embedded\\Embedded2.js')

Ваш скрипт реализует сложную систему обращения к внешним ресурсам:

RUVATA пишет:

1) если необходимо подключить скрипт из той-же директории, то вид должен быть следующий
"\\имя_скрипта.js"
...

На самом деле - это обращение к файлу,, расположенному в корневой директории текущего диска. Стандартно это выглядит так:

файл из текущего каталога
filename.ext
.\filename.ext

файл из дочернего каталога
child\filename.ext

файл из родительского каталога
..\filename.ext

прямой доступ к файлу по абсолютному пути (без указания имени диска - значит в пределах текущего диска)
c:\dir1\dir2\filename.ext
\dir1\dir2\filename.ext

прямой доступ к файлу по относительному пути
..\dir2\filename.ext

Выдуманный Вами способ доступа к объектам ФС сложный и запутанный. Полагаю, что Вы сами запутались в своих тестах. Полагаю, что Вам следует лучше готовится к подобного рода тестам и тщательно проверять сообщения об ошибках.

RUVATA пишет:

получаем ошибку "WOW - определение отсутствует"

такой ошибки не получите, потому что скрипт завершился с ошибкой, возникшей выше по тексту. Исправьте s/reqire/require/g и повторите свои тесты.

( 2 * b ) || ! ( 2 * b )

13 (изменено: RUVATA, 2012-06-04 00:24:10)

Re: JScriptInclude Gear - Механизм каскадного импорта скриптов/библиотек.

Полностью согласен с Вами, по поводу относительных путей...
это я обязательно переделаю... вы абсолютно правы, что я реализовал
не очевидный способ... (будем делать так как общепринято)
Вы конечно уже поправили, но не reqire, я взял из секции "Пример", предыдущей версии
ну и о главном

То что я написал, это всего лишь сырой набросок того, что надо еще исправлять, улучшать и усложнять.

я почти то же самое говорил постом ранее

код не подвергался ни оптимизации, ни адаптации... в основном для удобства отладки писался более развернуто...

Извиняюсь за резкий ответ на критику (обоснованную)... мой вариант был не из  лучших, и тут собственно Ваш код... ну меня и понесло

PS: я просмотрел Ваш вариант, кое что подало парочку идей... спасибо.

Ничто не помогает писать код больше чем Stevie Ray Vaughan And Double Trouble в наушниках.

14

Re: JScriptInclude Gear - Механизм каскадного импорта скриптов/библиотек.

Ну мне кажется, что можно проще код написать. Например так:

var FSO = new ActiveXObject("Scripting.FileSystemObject");
var WshShell = new ActiveXObject("WScript.Shell");

var SC = WScript.CreateObject("ScriptControl");
SC.Language = "JScript";
SC.AddObject("WScript", WScript);
SC.AddObject("__Global", this);

function require(Path)
{
  var ResultPath=Path;
  if (Path.indexOf(":")==-1) ResultPath = WshShell.CurrentDirectory+"\\"+Path;
  var F=FSO.OpenTextFile(ResultPath, 1, 0);
  var Code = F.ReadAll();
  F.Close();
  
  SC.AddCode(Code);
}
SC.AddCode("var require=function(Path){__Global.require(Path);}");

WshShell.CurrentDirectory = WScript.Arguments(0).replace(/\\[^\\]+$/,"");
require(WScript.Arguments(0));

Думаю лучше ScriptControl использовать, чтобы не мусорить глобальное пространство. Плюс удобный контроль ошибок.

15

Re: JScriptInclude Gear - Механизм каскадного импорта скриптов/библиотек.

JSman пишет:

не мусорить глобальное пространство. Плюс удобный контроль ошибок.

Сомнительно. Файл подключается ради тех самых сущностей, которые в нем описаны. А вот ошибки времени выполнения скрипта в eval - абсолютно не информативны, так как покажут номер строки родительского файла, где описан вызов функции eval. Что значит, что таким способом подключаемые скрипты не отладишь.

Поэтому функции, подобно описанным в этой теме считаю, малополезными и ненадежными. В крайнем случае, один скрипт можно подключить по схеме open/read/eval. Если Вам необходимо много файлов - пишите wsf-файл.

( 2 * b ) || ! ( 2 * b )

16

Re: JScriptInclude Gear - Механизм каскадного импорта скриптов/библиотек.

Rumata пишет:

А вот ошибки времени выполнения скрипта в eval - абсолютно не информативны, так как покажут номер строки родительского файла, где описан вызов функции eval. Что значит, что таким способом подключаемые скрипты не отладишь.

Поэтому функции, подобно описанным в этой теме считаю, малополезными и ненадежными. В крайнем случае, один скрипт можно подключить по схеме open/read/eval. Если Вам необходимо много файлов - пишите wsf-файл.

Вот оцените отладчик на JS (лучше смотреть в cscript либо отображать диалоговые окна моноширинным шрифтом). Думаю понравится .

var FSO = new ActiveXObject("Scripting.FileSystemObject");
var WshShell = new ActiveXObject("WScript.Shell");

var SC = WScript.CreateObject("ScriptControl");
SC.Language = "JScript";
SC.AddObject("WScript", WScript);
SC.AddObject("__Global", this);

var CodeCache="", CurrentLib=WScript.ScriptFullName, CurrentAddCode="var require=function(Path){__Global.require(Path);}";

function ParseError()
{
  WScript.Echo(["\nОшибка: «", SC.Error.Description, "»\nв строке:\n", CurrentAddCode.split(/\r?\n/g)[SC.Error.Line-1], "\n", new Array(SC.Error.Column).join("—")+"^\n\n", "Line: ", SC.Error.Line, "; Column: ", SC.Error.Column, "\n\nLib: "+CurrentLib].join(""));
  WScript.Echo(CurrentAddCode);
}

function require(Path)
{
  var ResultPath=Path;
  if (Path.indexOf(":")==-1) ResultPath = WshShell.CurrentDirectory+"\\"+Path;
  CurrentLib = ResultPath;
  var F=FSO.OpenTextFile(ResultPath, 1, 0);
  var Code = F.ReadAll();
  F.Close();
  CodeCache+="\n"+ResultPath+"\n"+Code;
  SC.AddCode(CurrentAddCode=Code.replace(/\r?\n\r?\n/g,"\n \n"));
}
SC.AddCode(CurrentAddCode);

try {
  WshShell.CurrentDirectory = WScript.Arguments(0).replace(/\\[^\\]+$/,"");
  SC.AddCode("require(WScript.Arguments(0));");  
} catch(e) {
  ParseError();
}

17

Re: JScriptInclude Gear - Механизм каскадного импорта скриптов/библиотек.

Механизм переработан с учетом сделанных замечаний см. первый пост в топике.

Ничто не помогает писать код больше чем Stevie Ray Vaughan And Double Trouble в наушниках.

18 (изменено: RUVATA, 2012-07-16 11:38:44)

Re: JScriptInclude Gear - Механизм каскадного импорта скриптов/библиотек.

Подготовлена очередная редакция.
Милости прошу на хабрахабр
подробнее см. первый пост в теме.

Ничто не помогает писать код больше чем Stevie Ray Vaughan And Double Trouble в наушниках.

19

Re: JScriptInclude Gear - Механизм каскадного импорта скриптов/библиотек.

Решение коллеги JSman лучше.

( 2 * b ) || ! ( 2 * b )

20

Re: JScriptInclude Gear - Механизм каскадного импорта скриптов/библиотек.

Re: Решение коллеги JSman лучше.

А ссылочку можно... поиск не помог.

Ничто не помогает писать код больше чем Stevie Ray Vaughan And Double Trouble в наушниках.

21

Re: JScriptInclude Gear - Механизм каскадного импорта скриптов/библиотек.

Да вот же она, да и чуть выше пост был.