2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

JScript + Closure Compier

Posted at
  • JScript + Closure Compiler(Windows上)で、ファルダ内のJavascriptソースコードを結合、コンパイルする。
  • JREさえインストールされていれば利用可能。
  • 文字コードはUTF-8(BOMなし)LFを想定。
  • 依存関係はgoog.require()とgoog.provide()で指定。
    • 出力ファイルにgoog.require()とgoog.provie()は含まれない。
      • コンパイルの後処理で削除する。
  • Pythonが利用可能なら、素直にそっちを使うべき。
    • 組み込みのAntタスクはサポートしていない実行オプションがあったり、前処理、後処理を差し挟むのが面倒なので、ちょっと微妙。
build.js
var COMPILER         = 'closure-compiler.jar';
var DEST_DEVELOPMENT = '../../dest.js';
var DEST_TEST        = '../qunit/test.js';
var DEST_PRODUCTION  = '../../dest.min.js';
var FOLDER_SOURCES   = '../../sources';
var FOLDER_TESTS     = '../../tests/qunit';
var FOLDER_EXTERNS   = 'externs';
var ENCODING         = 'utf-8';
var TEMPLATE         = '"(function(window) {%output%})(window);"';

// Gets file names in a folder recursively.
var getFileNames = function(fileName) {
	var fileSystem = new ActiveXObject('Scripting.FileSystemObject');
	if (fileSystem.FileExists(fileName)) {
			// If the file is a file (not a directory).
		return [fileName];
	}
	if (!fileSystem.FolderExists(fileName)) {
		return [];
	}

	var filenames = [];

	// Searches a current folder.
	var folder = fileSystem.GetFolder(fileName);
	for (var e = new Enumerator(folder.Files); !e.atEnd(); e.moveNext()) {
		filenames.push(e.item().Path);
	}

	// Seaches child folders.
	for (var e = new Enumerator(folder.SubFolders); !e.atEnd(); e.moveNext()) {
		filenames = filenames.concat(getFileNames(e.item()));
	}
	return filenames;
};

// Reads a file with UTF-8.
var readFile = function(fileName) {
	try {
		var stream = new ActiveXObject('ADODB.Stream');
		stream.Type = 2;
		stream.charset = ENCODING;
		stream.Open();
		stream.LoadFromFile(fileName);
		return stream.ReadText(-1);
	} finally {
		stream.Close();
	}
};

// Writes a text to a file with UTF-8 except a BOM.
var writeFile = function(fileName, text) {
	try {
		// Writes a text to a stream with UTF-8.
		var stream = new ActiveXObject('ADODB.Stream');
		stream.Type = 2;
		stream.Charset = ENCODING;
		stream.Open();
		stream.WriteText(text);

		// Changes a stream type.
		stream.Position = 0;
		stream.Type = 1;

		// Skips a BOM and keeps a text.
		stream.Position = 3;
		var bytes = stream.Read();

		// Resets a stream and writes a text to.
		stream.Position = 0;
		stream.SetEOS();
		stream.Write(bytes);

		// Saves a stream.
		stream.SaveToFile(fileName, 2);
	} finally {
		stream.Close();
	}
};

try {
	// Runs Closure Compiler.
	var runClosureCompiler = function(options) {
		var command = 'java';
		for (var key in options) {
			switch (key) {
				case '--externs':
				case '--formatting':
					for (var i = 0; i < options[key].length; i++) {
						command += ' ' + key + ' ' + options[key][i];
					}
					break;
				case '--js':
					command += ' ' + key;
					for (var i = 0; i < options[key].length; i++) {
						command += ' ' + options[key][i];
					}
					break;
				default:
					command += ' ' + key + ' ' + options[key];
					break;
			}
		}

		var shell = new ActiveXObject('WScript.Shell');
		var exec = shell.Exec(command);

		while (exec.Status === 0) {
			WScript.Sleep(10);
		}

		var errorMessage = '';
		while (!exec.StdErr.AtEndofStream) {
			errorMessage += exec.StdErr.ReadLine() + '\n';
		}
		if (errorMessage !== '') {
			throw {command: command, errorMessage: errorMessage};
		}
	};

	// Generates nx.js.
	runClosureCompiler({
		'-jar'		                    : COMPILER,
		'--charset'                     : ENCODING,
		'--compilation_level'           : 'WHITESPACE_ONLY',
		'--manage_closure_dependencies' : 'true',
		'--js_output_file'              : DEST_DEVELOPMENT,
		'--js'                          : getFileNames(FOLDER_SOURCES),
		'--output_wrapper'              : TEMPLATE,
		'--formatting'                  : [
			'pretty_print',
			'print_input_delimiter'
		]
	});

	// Removes Google directives from nx.js.
	var content = readFile(DEST_DEVELOPMENT)
		.replace(/goog\.require\(.*\);\s?/g, '')
		.replace(/goog\.provide\(.*\);\s?/g, '');
	writeFile(DEST_DEVELOPMENT, content);

	// Generates nx.min.js.
	runClosureCompiler({
		'-jar'		          : COMPILER,
		'--charset'           : ENCODING,
		'--compilation_level' : 'ADVANCED_OPTIMIZATIONS',
		'--js_output_file'    : DEST_PRODUCTION,
		'--js'                : [
			DEST_DEVELOPMENT
		],
		'--externs'           : getFileNames(FOLDER_EXTERNS),
		'--output_wrapper'    : '"(function() {%output%})();"'
	});

	// Generates test.js.
	if (FOLDER_TESTS.length >= 1) {
		runClosureCompiler({
			'-jar'                : COMPILER,
			'--charset'           : ENCODING,
			'--compilation_level' : 'WHITESPACE_ONLY',
			'--js_output_file'    : DEST_TEST,
			'--js'                : getFileNames(FOLDER_TESTS),
			'--formatting'        : [
				'pretty_print',
				'print_input_delimiter'
			]
		});
	}
}  catch (e) {
	WScript.Echo(e.command);
	WScript.Echo(e.errorMessage);
}
2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?