var createTypeScriptPreprocessor = function(args, config, logger, helper) {
	config = config || {};

	var log = logger.create('preprocessor.typescript');
	var defaultOptions = {};

	var transformPath = args.transformPath || config.transformPath || function(filepath) {
		return filepath.replace(/\.ts$/, '.js');
	};

	// compiler options
	var options = helper.merge(defaultOptions, args.options || {}, config.options || {});
	var compiler = new tss.TypeScriptSimple(options, false);

	return function(content, file, done) {
		log.debug('Processing "%s".', file.originalPath);
		file.path = transformPath(file.originalPath);

		try {
			var output = compiler.compile(content, file.originalPath);
			done(null, output);
		} catch(e) {
			log.error('%s\n at %s\n%s', e.message, file.originalPath, e.stack);
			return done(e, null);
		}
	};
};
Example #2
0
;(function(){
  'use strict'

  const fs = require('fs')
  const ts = require('typescript')
  const { TypeScriptSimple } = require('typescript-simple')

  const DEFAULT_COMPILER_OPTIONS = {
    declaration: false
    // , emitDecoratorMetadata: true
    // , experimentalDecorators: true
    , module: ts.ModuleKind.CommonJS
    , moduleResolution: ts.ModuleResolutionKind.NodeJs
    , noEmitOnError: true
    , noEmit: false

    , noImplicitAny: false
    , target: ts.ScriptTarget.ES6
    , sourceMap: true
    , inlineSources: true
    // , inlineSourceMap: true
  }

  const compilerOptions = Object.assign({}
    , DEFAULT_COMPILER_OPTIONS
    , {
    // TODO: --dev & --prod settings switcher
  })

  delete compilerOptions.outDir

  const tss = new TypeScriptSimple(compilerOptions)

  function pureTypeScript(module, fileName) {
    const ts = fs.readFileSync(fileName, 'utf8')
    let js
    try {
      js = tss.compile(ts, fileName)
    } catch (e) {
      throw new Error(`Syntax error in ${fileName}: ${e.message}`)
    }
    // console.log(js)
    module._compile(js, fileName)
  }

  // require('source-map-support').install({
  //     environment: 'node'
  //   , hookRequire: true
  // })

  require.extensions['.ts'] = pureTypeScript

  module.exports = pureTypeScript.default = pureTypeScript.pureTypeScript = pureTypeScript

})()
Example #3
0
 function pureTypeScript(module, fileName) {
   const ts = fs.readFileSync(fileName, 'utf8')
   let js
   try {
     js = tss.compile(ts, fileName)
   } catch (e) {
     throw new Error(`Syntax error in ${fileName}: ${e.message}`)
   }
   // console.log(js)
   module._compile(js, fileName)
 }
	return function(content, file, done) {
		log.debug('Processing "%s".', file.originalPath);
		file.path = transformPath(file.originalPath);

		try {
			var output = compiler.compile(content, file.originalPath);
			done(null, output);
		} catch(e) {
			log.error('%s\n at %s\n%s', e.message, file.originalPath, e.stack);
			return done(e, null);
		}
	};
Example #5
0
File: index.js Project: Gaubee/jhs
//通用文件处理
/*
 * file_paths 目录或者目录列表
 * res_pathname 真正要返回的文件
 * pathname URL请求的文件,不代表最后要返回的文件
 */
function _route_to_file(file_paths, res_pathname, type, pathname, params, req, res) {
	//有大量异步操作,所以要把options缓存起来
	var jhs_options = jhs.getOptions(req);
	//统一用数组
	Array.isArray(file_paths) || (file_paths = [file_paths]);

	console.log(("[ " + type.placeholder(5) + "]").colorsHead(), "=>", pathname.placeholder(60, "\n\t"), "=>", file_paths, res_pathname, "\n")

	//如果是取MAP,直接取出
	var map_md5 = req.query._MAP_MD5_;
	var map_from = req.query._MAP_FROM_;
	if (map_md5 && map_from) {
		res.body = temp.get(map_from, map_md5);
		return
	}

	if (!fss.existsFileInPathsSync(file_paths, pathname)) {
		res.status(404);
		var _404file_name = jhs_options["404"] || "404.html";
		if (!fss.existsFileInPathsSync(file_paths, _404file_name)) {
			res.set('Content-Type', mime.contentType("html"));
			res.body = _get_404_file();
			return;
		}
		res_pathname = _404file_name;
	}

	var file_path = file_paths.map(function(folder_path) {
		return folder_path + "/" + res_pathname;
	});

	var content_type = mime.contentType(type);
	res.set('Content-Type', content_type);
	var fileInfo = cache.getFileCache(file_path, cache.options.file_cache_time, jhs_options);
	res.body = fileInfo.source_content;

	if (fileInfo.is_text) {
		var _path_info = path.parse(res_pathname);
		var _extname = _path_info.ext;
		var _filename = _path_info.base;
		var _basename = _path_info.name;
		res.is_text = true;
		res.text_file_info = {
			filename: _filename,
			basename: _basename,
			extname: _extname,
		};
	}

	(jhs_options.common_filter_handle instanceof Function) && jhs_options.common_filter_handle(pathname, params, req, res);

	jhs.emit("*." + type, pathname, params, req, res);

	/*
	 * 用户自定义的处理完成后再做最后的处理,避免nunjucks的include、import指令导入的内容没有处理
	 */
	if (fileInfo.is_text) {
		res.body = res.body.replaceAll("__pathname__", pathname)
			.replaceAll("__res_pathname__", res_pathname)
			.replaceAll("__filename__", _filename)
			.replaceAll("__basename__", _basename)
			.replaceAll("__extname__", _extname);
		var _lower_case_extname = _extname.toLowerCase();
		var _lower_case_compile_to = req.query.compile_to;
		_lower_case_compile_to = (_lower_case_compile_to || "").toLowerCase();
		var _temp_body;
		/* TYPESCRIPT编译 */
		if (_lower_case_extname === ".ts" && /js|\.js/.test(_lower_case_compile_to)) {
			if (fileInfo.compile_tsc_content) {
				res.body = fileInfo.compile_tsc_content;
			} else {
				if (_temp_body = temp.get("typescript", fileInfo.source_md5)) {
					res.body = fileInfo.compile_tsc_content = _temp_body.toString(); //Buffer to String
				} else {
					var tss = new TypeScriptSimple({
						sourceMap: jhs_options.tsc_sourceMap
					});
					res.type('js');
					try {
						var tsc_compile_resule = tss.compile(res.body, path.parse(fileInfo.filepath).dir);
						res.body = tsc_compile_resule;
						temp.set("typescript", fileInfo.source_md5, res.body);
					} catch (e) {
						console.log(e.stack)
							// res.status(500);
						res.body = '((window.console&&console.error)||alert).call(window.console,' + JSON.stringify(e.message) + ')';
					}
				}
			}
		}
		/* Babel编译 */
		if (((_lower_case_extname === ".bb" || _filename.endWith(".bb.js")) && /js|\.js/.test(_lower_case_compile_to)) || /bb_to_\.js/.test(_lower_case_compile_to)) {
			if (fileInfo.compile_bb_content) {
				res.body = fileInfo.compile_bb_content;
			} else {
				if (_temp_body = temp.get("babel-core", fileInfo.source_md5)) {
					res.body = fileInfo.compile_bb_content = _temp_body.toString(); //Buffer to String
				} else {
					res.type('js');
					try {
						console.time("Babel:" + _filename);
						console.log(req.query);
						var sourceMaps = $$.boolean_parse(req.query.debug)
						var bb_compile_resule = BabelCore.transform(res.body, {
							filename: __dirname + "/babel/" + _filename,
							ast: false,
							sourceMaps: sourceMaps,
							babelrc: false,
							code: true,
							presets: ['es2015'],
							ignore: ["node_modules/**/*.js"],
							// plugins: ["syntax-async-generators"]
						});

						var code = bb_compile_resule.code;
						if (sourceMaps) {
							code += "\n//# sourceMappingURL=" + res_pathname +
								"?_MAP_MD5_=" + fileInfo.source_md5 +
								"&_MAP_FROM_=babel-core-map";
							fileInfo.compile_bb_content_map = JSON.stringify(bb_compile_resule.map);
							temp.set("babel-core-map", fileInfo.source_md5, fileInfo.compile_bb_content_map);
						}

						console.timeEnd("Babel:" + _filename);

						res.body = fileInfo.compile_bb_content = code;
						temp.set("babel-core", fileInfo.source_md5, res.body);
					} catch (e) {
						console.log(e.stack)
							// res.status(500);
						res.body = '((window.console&&console.error)||alert).call(window.console,' + JSON.stringify(e.message) + ')';
					}
				}
			}
		}
		/* SASS编译 */
		if (_lower_case_extname === ".scss" && /css|\.css/.test(_lower_case_compile_to)) {
			if (fileInfo.compile_sass_content) {
				res.body = fileInfo.compile_sass_content;
			} else {
				if (_temp_body = temp.get("sass", fileInfo.source_md5)) {
					// console.log("使用缓存,无需编译!!")
					res.body = fileInfo.compile_sass_content = _temp_body.toString(); //Buffer to String
				} else {
					var fiber = Fiber.current;
					sass.render({
						data: res.body,
						includePaths: [path.parse(fileInfo.filepath).dir]
					}, function(e, result) {
						process.nextTick(function() {
							if (e) {
								res.status(500);
								fiber.run({
									css: (e && e.stack) || String(e)
								})
								return
							}
							fiber.run(result)
						});
					});
					var sass_compile_result = Fiber.yield();
					res.body = fileInfo.compile_sass_content = sass_compile_result.css.toString();
					temp.set("sass", fileInfo.source_md5, res.body);
				}
			}
			//文件内容变为CSS了,所以可以参与CSS文件类型的处理
			extname = ".css";
		}
		/* LESS编译 */
		if (_lower_case_extname === ".less" && /css|\.css/.test(_lower_case_compile_to)) {
			if (fileInfo.compile_less_content) {
				res.body = fileInfo.compile_less_content;
			} else {
				if (_temp_body = temp.get("less", fileInfo.source_md5)) {
					// console.log("使用缓存,无需编译!!")
					res.body = fileInfo.compile_less_content = _temp_body.toString(); //Buffer to String
				} else {
					var fiber = Fiber.current;
					less.render(res.body, {
						paths: [path.parse(fileInfo.filepath).dir],
						filename: _filename
					}, function(e, output) {
						process.nextTick(function() {
							if (e) {
								// console.error(e instanceof Error)
								// fiber.throwInto(e);
								res.status(500);
								fiber.run({
									css: (e && e.stack) || String(e)
								})
								return
							}
							console.log("output:::::", output)
							fiber.run(output)
						});
					});
					var less_compile_result = Fiber.yield();
					res.body = fileInfo.compile_less_content = less_compile_result.css.toString();
					temp.set("less", fileInfo.source_md5, res.body);
				}
			}
			//文件内容变为CSS了,所以可以参与CSS文件类型的处理
			extname = ".css";
		}
		/* CSS压缩 */
		if (jhs_options.css_minify && _lower_case_extname === ".css") {
			if (fileInfo.minified_css_content) {
				res.body = fileInfo.minified_css_content;
			} else {
				if (_temp_body = temp.get("css_minify", fileInfo.source_md5)) {
					res.body = fileInfo.minified_css_content = _temp_body.toString(); //Buffer to String
				} else {
					var fiber = Fiber.current;
					new CleanCSS().minify(res.body, function(err, minified) {
						if (err) {
							console.log("[CleanCSS Minify Error]".colorsHead(), "=>", err);
						}
						res.body = fileInfo.minified_css_content = minified.styles;
						if (minified.errors.length + minified.warnings.length) {
							minified.errors.forEach(function(err) {
								console.log("[CSS Error]".colorsHead(), "=>", err);
							});
							minified.warnings.forEach(function(war) {
								console.log("[CSS Warn]".colorsHead(), "=>", war);
							});
						}
						fiber.run();
					});
					Fiber.yield();
					temp.set("css_minify", fileInfo.source_md5, res.body);
				}
			}
		}
		/* JS压缩 */
		if (jhs_options.js_minify && _lower_case_extname === ".js" || $$.boolean_parse(req.query.min)) {
			if (fileInfo.minified_js_content) {
				res.body = fileInfo.minified_js_content;
			} else {
				if (_temp_body = temp.get("js_minify", fileInfo.source_md5)) {
					res.body = fileInfo.minified_js_content = _temp_body.toString(); //Buffer to String
				} else {
					var js_minify_result = UglifyJS.minify(res.body, {
						fromString: true
					});
					res.body = fileInfo.minified_js_content = js_minify_result.code;
					temp.set("js_minify", fileInfo.source_md5, res.body);
				}
			}
		}
		/* HTML压缩 */
		if (jhs_options.html_minify && _lower_case_extname === ".html") {

		}
	}
};