mirror of
				https://github.com/NodeBB/NodeBB.git
				synced 2025-10-31 11:05:54 +01:00 
			
		
		
		
	Use less memory to build translation files (#6070)
* Change languages build to use less memory Add graceful-fs so no ned to worry about fs limits * Specify encoding for fs.readFile Use eachLimit since graceful-fs handles that now
This commit is contained in:
		
				
					committed by
					
						 Barış Soner Uşaklı
						Barış Soner Uşaklı
					
				
			
			
				
	
			
			
			
						parent
						
							f5385e38bf
						
					
				
				
					commit
					c47c47f7e3
				
			| @@ -40,6 +40,7 @@ | |||||||
|     "express": "^4.16.2", |     "express": "^4.16.2", | ||||||
|     "express-session": "^1.15.6", |     "express-session": "^1.15.6", | ||||||
|     "express-useragent": "1.0.8", |     "express-useragent": "1.0.8", | ||||||
|  |     "graceful-fs": "^4.1.11", | ||||||
|     "html-to-text": "3.3.0", |     "html-to-text": "3.3.0", | ||||||
|     "ipaddr.js": "^1.5.4", |     "ipaddr.js": "^1.5.4", | ||||||
|     "jimp": "0.2.28", |     "jimp": "0.2.28", | ||||||
|   | |||||||
| @@ -63,12 +63,11 @@ var fallbackCacheInProgress = {}; | |||||||
| var fallbackCache = {}; | var fallbackCache = {}; | ||||||
|  |  | ||||||
| function initFallback(namespace, callback) { | function initFallback(namespace, callback) { | ||||||
| 	fs.readFile(path.resolve(nconf.get('views_dir'), namespace + '.tpl'), function (err, file) { | 	fs.readFile(path.resolve(nconf.get('views_dir'), namespace + '.tpl'), 'utf8', function (err, template) { | ||||||
| 		if (err) { | 		if (err) { | ||||||
| 			return callback(err); | 			return callback(err); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		var template = file.toString(); |  | ||||||
| 		var title = nsToTitle(namespace); | 		var title = nsToTitle(namespace); | ||||||
|  |  | ||||||
| 		var translations = sanitize(template); | 		var translations = sanitize(template); | ||||||
|   | |||||||
| @@ -45,16 +45,16 @@ function renderEmail(req, res, next) { | |||||||
|  |  | ||||||
| 						async.waterfall([ | 						async.waterfall([ | ||||||
| 							function (next) { | 							function (next) { | ||||||
| 								fs.readFile(email, next); | 								fs.readFile(email, 'utf8', next); | ||||||
| 							}, | 							}, | ||||||
| 							function (original, next) { | 							function (original, next) { | ||||||
| 								var text = meta.config['email:custom:' + path] ? meta.config['email:custom:' + path] : original.toString(); | 								var text = meta.config['email:custom:' + path] ? meta.config['email:custom:' + path] : original; | ||||||
|  |  | ||||||
| 								next(null, { | 								next(null, { | ||||||
| 									path: path, | 									path: path, | ||||||
| 									fullpath: email, | 									fullpath: email, | ||||||
| 									text: text, | 									text: text, | ||||||
| 									original: original.toString(), | 									original: original, | ||||||
| 								}); | 								}); | ||||||
| 							}, | 							}, | ||||||
| 						], next); | 						], next); | ||||||
|   | |||||||
| @@ -23,7 +23,7 @@ themesController.get = function (req, res, next) { | |||||||
| 				return next(Error('invalid-data')); | 				return next(Error('invalid-data')); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			fs.readFile(themeConfigPath, next); | 			fs.readFile(themeConfigPath, 'utf8', next); | ||||||
| 		}, | 		}, | ||||||
| 		function (themeConfig, next) { | 		function (themeConfig, next) { | ||||||
| 			try { | 			try { | ||||||
|   | |||||||
| @@ -7,9 +7,12 @@ var winston = require('winston'); | |||||||
| var jimp = require('jimp'); | var jimp = require('jimp'); | ||||||
| var mkdirp = require('mkdirp'); | var mkdirp = require('mkdirp'); | ||||||
| var mime = require('mime'); | var mime = require('mime'); | ||||||
|  | var graceful = require('graceful-fs'); | ||||||
|  |  | ||||||
| var utils = require('./utils'); | var utils = require('./utils'); | ||||||
|  |  | ||||||
|  | graceful.gracefulify(fs); | ||||||
|  |  | ||||||
| var file = module.exports; | var file = module.exports; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|   | |||||||
| @@ -120,9 +120,7 @@ image.size = function (path, callback) { | |||||||
| }; | }; | ||||||
|  |  | ||||||
| image.convertImageToBase64 = function (path, callback) { | image.convertImageToBase64 = function (path, callback) { | ||||||
| 	fs.readFile(path, function (err, data) { | 	fs.readFile(path, 'base64', callback); | ||||||
| 		callback(err, data ? data.toString('base64') : null); |  | ||||||
| 	}); |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| image.mimeFromBase64 = function (imageData) { | image.mimeFromBase64 = function (imageData) { | ||||||
|   | |||||||
| @@ -371,7 +371,7 @@ function createCategories(next) { | |||||||
|  |  | ||||||
| 		process.stdout.write('No categories found, populating instance with default categories\n'); | 		process.stdout.write('No categories found, populating instance with default categories\n'); | ||||||
|  |  | ||||||
| 		fs.readFile(path.join(__dirname, '../', 'install/data/categories.json'), function (err, default_categories) { | 		fs.readFile(path.join(__dirname, '../', 'install/data/categories.json'), 'utf8', function (err, default_categories) { | ||||||
| 			if (err) { | 			if (err) { | ||||||
| 				return next(err); | 				return next(err); | ||||||
| 			} | 			} | ||||||
| @@ -402,7 +402,7 @@ function createWelcomePost(next) { | |||||||
|  |  | ||||||
| 	async.parallel([ | 	async.parallel([ | ||||||
| 		function (next) { | 		function (next) { | ||||||
| 			fs.readFile(path.join(__dirname, '../', 'install/data/welcome.md'), next); | 			fs.readFile(path.join(__dirname, '../', 'install/data/welcome.md'), 'utf8', next); | ||||||
| 		}, | 		}, | ||||||
| 		function (next) { | 		function (next) { | ||||||
| 			db.getObjectField('global', 'topicCount', next); | 			db.getObjectField('global', 'topicCount', next); | ||||||
| @@ -421,7 +421,7 @@ function createWelcomePost(next) { | |||||||
| 				uid: 1, | 				uid: 1, | ||||||
| 				cid: 2, | 				cid: 2, | ||||||
| 				title: 'Welcome to your NodeBB!', | 				title: 'Welcome to your NodeBB!', | ||||||
| 				content: content.toString(), | 				content: content, | ||||||
| 			}, next); | 			}, next); | ||||||
| 		} else { | 		} else { | ||||||
| 			next(); | 			next(); | ||||||
| @@ -473,7 +473,7 @@ function setCopyrightWidget(next) { | |||||||
| 	var db = require('./database'); | 	var db = require('./database'); | ||||||
| 	async.parallel({ | 	async.parallel({ | ||||||
| 		footerJSON: function (next) { | 		footerJSON: function (next) { | ||||||
| 			fs.readFile(path.join(__dirname, '../', 'install/data/footer.json'), next); | 			fs.readFile(path.join(__dirname, '../', 'install/data/footer.json'), 'utf8', next); | ||||||
| 		}, | 		}, | ||||||
| 		footer: function (next) { | 		footer: function (next) { | ||||||
| 			db.getObjectField('widgets:global', 'footer', next); | 			db.getObjectField('widgets:global', 'footer', next); | ||||||
| @@ -484,7 +484,7 @@ function setCopyrightWidget(next) { | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if (!results.footer && results.footerJSON) { | 		if (!results.footer && results.footerJSON) { | ||||||
| 			db.setObjectField('widgets:global', 'footer', results.footerJSON.toString(), next); | 			db.setObjectField('widgets:global', 'footer', results.footerJSON, next); | ||||||
| 		} else { | 		} else { | ||||||
| 			next(); | 			next(); | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -29,7 +29,7 @@ Languages.listCodes = function (callback) { | |||||||
| 		return callback(null, codeCache); | 		return callback(null, codeCache); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	fs.readFile(path.join(languagesPath, 'metadata.json'), function (err, buffer) { | 	fs.readFile(path.join(languagesPath, 'metadata.json'), 'utf8', function (err, file) { | ||||||
| 		if (err && err.code === 'ENOENT') { | 		if (err && err.code === 'ENOENT') { | ||||||
| 			return callback(null, []); | 			return callback(null, []); | ||||||
| 		} | 		} | ||||||
| @@ -39,7 +39,7 @@ Languages.listCodes = function (callback) { | |||||||
|  |  | ||||||
| 		var parsed; | 		var parsed; | ||||||
| 		try { | 		try { | ||||||
| 			parsed = JSON.parse(buffer.toString()); | 			parsed = JSON.parse(file); | ||||||
| 		} catch (e) { | 		} catch (e) { | ||||||
| 			return callback(e); | 			return callback(e); | ||||||
| 		} | 		} | ||||||
| @@ -64,7 +64,7 @@ Languages.list = function (callback) { | |||||||
| 		async.map(codes, function (folder, next) { | 		async.map(codes, function (folder, next) { | ||||||
| 			var configPath = path.join(languagesPath, folder, 'language.json'); | 			var configPath = path.join(languagesPath, folder, 'language.json'); | ||||||
|  |  | ||||||
| 			fs.readFile(configPath, function (err, buffer) { | 			fs.readFile(configPath, 'utf8', function (err, file) { | ||||||
| 				if (err && err.code === 'ENOENT') { | 				if (err && err.code === 'ENOENT') { | ||||||
| 					return next(); | 					return next(); | ||||||
| 				} | 				} | ||||||
| @@ -72,7 +72,7 @@ Languages.list = function (callback) { | |||||||
| 					return next(err); | 					return next(err); | ||||||
| 				} | 				} | ||||||
| 				try { | 				try { | ||||||
| 					var lang = JSON.parse(buffer.toString()); | 					var lang = JSON.parse(file); | ||||||
| 					next(null, lang); | 					next(null, lang); | ||||||
| 				} catch (e) { | 				} catch (e) { | ||||||
| 					next(e); | 					next(e); | ||||||
|   | |||||||
| @@ -31,18 +31,18 @@ exports.read = function read(callback) { | |||||||
| 		return callback(null, cached); | 		return callback(null, cached); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	fs.readFile(filePath, function (err, buffer) { | 	fs.readFile(filePath, 'utf8', function (err, buster) { | ||||||
| 		if (err) { | 		if (err) { | ||||||
| 			winston.warn('[cache-buster] could not read cache buster', err); | 			winston.warn('[cache-buster] could not read cache buster', err); | ||||||
| 			return callback(null, generate()); | 			return callback(null, generate()); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if (!buffer || buffer.toString().length !== 11) { | 		if (!buster || buster.length !== 11) { | ||||||
| 			winston.warn('[cache-buster] cache buster string invalid: expected /[a-z0-9]{11}/, got `' + buffer + '`'); | 			winston.warn('[cache-buster] cache buster string invalid: expected /[a-z0-9]{11}/, got `' + buster + '`'); | ||||||
| 			return callback(null, generate()); | 			return callback(null, generate()); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		cached = buffer.toString(); | 		cached = buster; | ||||||
| 		callback(null, cached); | 		callback(null, cached); | ||||||
| 	}); | 	}); | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -106,7 +106,7 @@ function minifyModules(modules, fork, callback) { | |||||||
| 		return prev; | 		return prev; | ||||||
| 	}, []); | 	}, []); | ||||||
|  |  | ||||||
| 	async.eachLimit(moduleDirs, 1000, mkdirp, function (err) { | 	async.each(moduleDirs, mkdirp, function (err) { | ||||||
| 		if (err) { | 		if (err) { | ||||||
| 			return callback(err); | 			return callback(err); | ||||||
| 		} | 		} | ||||||
| @@ -126,7 +126,7 @@ function minifyModules(modules, fork, callback) { | |||||||
| 				minifier.js.minifyBatch(filtered.minify, fork, cb); | 				minifier.js.minifyBatch(filtered.minify, fork, cb); | ||||||
| 			}, | 			}, | ||||||
| 			function (cb) { | 			function (cb) { | ||||||
| 				async.eachLimit(filtered.skip, 500, function (mod, next) { | 				async.each(filtered.skip, function (mod, next) { | ||||||
| 					linkIfLinux(mod.srcPath, mod.destPath, next); | 					linkIfLinux(mod.srcPath, mod.destPath, next); | ||||||
| 				}, cb); | 				}, cb); | ||||||
| 			}, | 			}, | ||||||
| @@ -137,7 +137,7 @@ function minifyModules(modules, fork, callback) { | |||||||
| function linkModules(callback) { | function linkModules(callback) { | ||||||
| 	var modules = JS.scripts.modules; | 	var modules = JS.scripts.modules; | ||||||
|  |  | ||||||
| 	async.eachLimit(Object.keys(modules), 1000, function (relPath, next) { | 	async.each(Object.keys(modules), function (relPath, next) { | ||||||
| 		var srcPath = path.join(__dirname, '../../', modules[relPath]); | 		var srcPath = path.join(__dirname, '../../', modules[relPath]); | ||||||
| 		var destPath = path.join(__dirname, '../../build/public/src/modules', relPath); | 		var destPath = path.join(__dirname, '../../build/public/src/modules', relPath); | ||||||
|  |  | ||||||
| @@ -183,7 +183,7 @@ function getModuleList(callback) { | |||||||
| 	modules = modules.concat(coreDirs); | 	modules = modules.concat(coreDirs); | ||||||
|  |  | ||||||
| 	var moduleFiles = []; | 	var moduleFiles = []; | ||||||
| 	async.eachLimit(modules, 1000, function (module, next) { | 	async.each(modules, function (module, next) { | ||||||
| 		var srcPath = module.srcPath; | 		var srcPath = module.srcPath; | ||||||
| 		var destPath = module.destPath; | 		var destPath = module.destPath; | ||||||
|  |  | ||||||
| @@ -255,7 +255,7 @@ JS.linkStatics = function (callback) { | |||||||
| 		if (err) { | 		if (err) { | ||||||
| 			return callback(err); | 			return callback(err); | ||||||
| 		} | 		} | ||||||
| 		async.eachLimit(Object.keys(plugins.staticDirs), 1000, function (mappedPath, next) { | 		async.each(Object.keys(plugins.staticDirs), function (mappedPath, next) { | ||||||
| 			var sourceDir = plugins.staticDirs[mappedPath]; | 			var sourceDir = plugins.staticDirs[mappedPath]; | ||||||
| 			var destDir = path.join(__dirname, '../../build/public/plugins', mappedPath); | 			var destDir = path.join(__dirname, '../../build/public/plugins', mappedPath); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -13,7 +13,7 @@ var Plugins = require('../plugins'); | |||||||
| var buildLanguagesPath = path.join(__dirname, '../../build/public/language'); | var buildLanguagesPath = path.join(__dirname, '../../build/public/language'); | ||||||
| var coreLanguagesPath = path.join(__dirname, '../../public/language'); | var coreLanguagesPath = path.join(__dirname, '../../public/language'); | ||||||
|  |  | ||||||
| function getTranslationTree(callback) { | function getTranslationMetadata(callback) { | ||||||
| 	async.waterfall([ | 	async.waterfall([ | ||||||
| 		// generate list of languages and namespaces | 		// generate list of languages and namespaces | ||||||
| 		function (next) { | 		function (next) { | ||||||
| @@ -49,42 +49,51 @@ function getTranslationTree(callback) { | |||||||
| 		// save a list of languages to `${buildLanguagesPath}/metadata.json` | 		// save a list of languages to `${buildLanguagesPath}/metadata.json` | ||||||
| 		// avoids readdirs later on | 		// avoids readdirs later on | ||||||
| 		function (ref, next) { | 		function (ref, next) { | ||||||
| 			async.waterfall([ | 			async.series([ | ||||||
| 				function (next) { | 				function (next) { | ||||||
| 					mkdirp(buildLanguagesPath, next); | 					mkdirp(buildLanguagesPath, next); | ||||||
| 				}, | 				}, | ||||||
| 				function (x, next) { | 				function (next) { | ||||||
| 					fs.writeFile(path.join(buildLanguagesPath, 'metadata.json'), JSON.stringify({ | 					fs.writeFile(path.join(buildLanguagesPath, 'metadata.json'), JSON.stringify({ | ||||||
| 						languages: ref.languages, | 						languages: ref.languages, | ||||||
| 						namespaces: ref.namespaces, | 						namespaces: ref.namespaces, | ||||||
| 					}), next); | 					}), next); | ||||||
| 				}, | 				}, | ||||||
| 				function (next) { | 			], function (err) { | ||||||
| 					next(null, ref); | 				next(err, ref); | ||||||
| 				}, | 			}); | ||||||
| 			], next); |  | ||||||
| 		}, | 		}, | ||||||
|  | 	], callback); | ||||||
|  | } | ||||||
|  |  | ||||||
| 		// for each language and namespace combination, | function writeLanguageFile(language, namespace, translations, callback) { | ||||||
| 		// run through core and all plugins to generate | 	var dev = global.env === 'development'; | ||||||
| 		// a full translation hash | 	var filePath = path.join(buildLanguagesPath, language, namespace + '.json'); | ||||||
| 		function (ref, next) { |  | ||||||
| 			var languages = ref.languages; | 	async.series([ | ||||||
|  | 		async.apply(mkdirp, path.dirname(filePath)), | ||||||
|  | 		async.apply(fs.writeFile, filePath, JSON.stringify(translations, null, dev ? 2 : 0)), | ||||||
|  | 	], callback); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // for each language and namespace combination, | ||||||
|  | // run through core and all plugins to generate | ||||||
|  | // a full translation hash | ||||||
|  | function buildTranslations(ref, next) { | ||||||
| 	var namespaces = ref.namespaces; | 	var namespaces = ref.namespaces; | ||||||
|  | 	var languages = ref.languages; | ||||||
| 	var plugins = _.values(Plugins.pluginsData).filter(function (plugin) { | 	var plugins = _.values(Plugins.pluginsData).filter(function (plugin) { | ||||||
| 		return typeof plugin.languages === 'string'; | 		return typeof plugin.languages === 'string'; | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| 			var tree = {}; | 	async.each(namespaces, function (namespace, next) { | ||||||
|  | 		async.each(languages, function (lang, next) { | ||||||
| 			async.eachLimit(languages, 10, function (lang, next) { |  | ||||||
| 				async.eachLimit(namespaces, 10, function (namespace, next) { |  | ||||||
| 			var translations = {}; | 			var translations = {}; | ||||||
|  |  | ||||||
| 			async.series([ | 			async.series([ | ||||||
| 				// core first | 				// core first | ||||||
| 				function (cb) { | 				function (cb) { | ||||||
| 							fs.readFile(path.join(coreLanguagesPath, lang, namespace + '.json'), function (err, buffer) { | 					fs.readFile(path.join(coreLanguagesPath, lang, namespace + '.json'), 'utf8', function (err, file) { | ||||||
| 						if (err) { | 						if (err) { | ||||||
| 							if (err.code === 'ENOENT') { | 							if (err.code === 'ENOENT') { | ||||||
| 								return cb(); | 								return cb(); | ||||||
| @@ -93,7 +102,7 @@ function getTranslationTree(callback) { | |||||||
| 						} | 						} | ||||||
|  |  | ||||||
| 						try { | 						try { | ||||||
| 									Object.assign(translations, JSON.parse(buffer.toString())); | 							Object.assign(translations, JSON.parse(file)); | ||||||
| 							cb(); | 							cb(); | ||||||
| 						} catch (err) { | 						} catch (err) { | ||||||
| 							cb(err); | 							cb(err); | ||||||
| @@ -106,7 +115,7 @@ function getTranslationTree(callback) { | |||||||
| 					//  2. old language string (en_GB) | 					//  2. old language string (en_GB) | ||||||
| 					//  3. corrected plugin defaultLang (en-US) | 					//  3. corrected plugin defaultLang (en-US) | ||||||
| 					//  4. old plugin defaultLang (en_US) | 					//  4. old plugin defaultLang (en_US) | ||||||
| 							async.eachLimit(plugins, 20, function (pluginData, done) { | 					async.each(plugins, function (pluginData, done) { | ||||||
| 						var pluginLanguages = path.join(__dirname, '../../node_modules/', pluginData.id, pluginData.languages); | 						var pluginLanguages = path.join(__dirname, '../../node_modules/', pluginData.id, pluginData.languages); | ||||||
| 						var defaultLang = pluginData.defaultLang || 'en-GB'; | 						var defaultLang = pluginData.defaultLang || 'en-GB'; | ||||||
|  |  | ||||||
| @@ -116,7 +125,7 @@ function getTranslationTree(callback) { | |||||||
| 							lang.replace('-', '_').replace('-x-', '@'), | 							lang.replace('-', '_').replace('-x-', '@'), | ||||||
| 							lang, | 							lang, | ||||||
| 						], function (language, next) { | 						], function (language, next) { | ||||||
| 									fs.readFile(path.join(pluginLanguages, language, namespace + '.json'), function (err, buffer) { | 							fs.readFile(path.join(pluginLanguages, language, namespace + '.json'), 'utf8', function (err, file) { | ||||||
| 								if (err) { | 								if (err) { | ||||||
| 									if (err.code === 'ENOENT') { | 									if (err.code === 'ENOENT') { | ||||||
| 										return next(null, false); | 										return next(null, false); | ||||||
| @@ -125,7 +134,7 @@ function getTranslationTree(callback) { | |||||||
| 								} | 								} | ||||||
|  |  | ||||||
| 								try { | 								try { | ||||||
| 											Object.assign(translations, JSON.parse(buffer.toString())); | 									Object.assign(translations, JSON.parse(file)); | ||||||
| 									next(null, true); | 									next(null, true); | ||||||
| 								} catch (err) { | 								} catch (err) { | ||||||
| 									next(err); | 									next(err); | ||||||
| @@ -138,40 +147,15 @@ function getTranslationTree(callback) { | |||||||
| 						} | 						} | ||||||
|  |  | ||||||
| 						if (Object.keys(translations).length) { | 						if (Object.keys(translations).length) { | ||||||
| 									tree[lang] = tree[lang] || {}; | 							writeLanguageFile(lang, namespace, translations, cb); | ||||||
| 									tree[lang][namespace] = translations; | 							return; | ||||||
| 						} | 						} | ||||||
| 						cb(); | 						cb(); | ||||||
| 					}); | 					}); | ||||||
| 				}, | 				}, | ||||||
| 			], next); | 			], next); | ||||||
| 		}, next); | 		}, next); | ||||||
| 			}, function (err) { | 	}, next); | ||||||
| 				next(err, tree); |  | ||||||
| 			}); |  | ||||||
| 		}, |  | ||||||
| 	], callback); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // write translation hashes from the generated tree to language files |  | ||||||
| function writeLanguageFiles(tree, callback) { |  | ||||||
| 	// iterate over languages and namespaces |  | ||||||
| 	async.eachLimit(Object.keys(tree), 100, function (language, cb) { |  | ||||||
| 		var namespaces = tree[language]; |  | ||||||
| 		async.eachLimit(Object.keys(namespaces), 10, function (namespace, next) { |  | ||||||
| 			var translations = namespaces[namespace]; |  | ||||||
|  |  | ||||||
| 			var filePath = path.join(buildLanguagesPath, language, namespace + '.json'); |  | ||||||
|  |  | ||||||
| 			mkdirp(path.dirname(filePath), function (err) { |  | ||||||
| 				if (err) { |  | ||||||
| 					return next(err); |  | ||||||
| 				} |  | ||||||
|  |  | ||||||
| 				fs.writeFile(filePath, JSON.stringify(translations), next); |  | ||||||
| 			}); |  | ||||||
| 		}, cb); |  | ||||||
| 	}, callback); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| exports.build = function buildLanguages(callback) { | exports.build = function buildLanguages(callback) { | ||||||
| @@ -179,7 +163,7 @@ exports.build = function buildLanguages(callback) { | |||||||
| 		function (next) { | 		function (next) { | ||||||
| 			rimraf(buildLanguagesPath, next); | 			rimraf(buildLanguagesPath, next); | ||||||
| 		}, | 		}, | ||||||
| 		getTranslationTree, | 		getTranslationMetadata, | ||||||
| 		writeLanguageFiles, | 		buildTranslations, | ||||||
| 	], callback); | 	], callback); | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -11,6 +11,7 @@ var autoprefixer = require('autoprefixer'); | |||||||
| var clean = require('postcss-clean'); | var clean = require('postcss-clean'); | ||||||
|  |  | ||||||
| var fork = require('./debugFork'); | var fork = require('./debugFork'); | ||||||
|  | require('../file'); // for graceful-fs | ||||||
|  |  | ||||||
| var Minifier = module.exports; | var Minifier = module.exports; | ||||||
|  |  | ||||||
| @@ -139,12 +140,12 @@ function executeAction(action, fork, callback) { | |||||||
| function concat(data, callback) { | function concat(data, callback) { | ||||||
| 	if (data.files && data.files.length) { | 	if (data.files && data.files.length) { | ||||||
| 		async.mapLimit(data.files, 1000, function (ref, next) { | 		async.mapLimit(data.files, 1000, function (ref, next) { | ||||||
| 			fs.readFile(ref.srcPath, function (err, buffer) { | 			fs.readFile(ref.srcPath, 'utf8', function (err, file) { | ||||||
| 				if (err) { | 				if (err) { | ||||||
| 					return next(err); | 					return next(err); | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				next(null, buffer.toString()); | 				next(null, file); | ||||||
| 			}); | 			}); | ||||||
| 		}, function (err, files) { | 		}, function (err, files) { | ||||||
| 			if (err) { | 			if (err) { | ||||||
| @@ -163,18 +164,18 @@ function concat(data, callback) { | |||||||
| actions.concat = concat; | actions.concat = concat; | ||||||
|  |  | ||||||
| function minifyJS_batch(data, callback) { | function minifyJS_batch(data, callback) { | ||||||
| 	async.eachLimit(data.files, 1000, function (ref, next) { | 	async.each(data.files, function (ref, next) { | ||||||
| 		var srcPath = ref.srcPath; | 		var srcPath = ref.srcPath; | ||||||
| 		var destPath = ref.destPath; | 		var destPath = ref.destPath; | ||||||
| 		var filename = ref.filename; | 		var filename = ref.filename; | ||||||
|  |  | ||||||
| 		fs.readFile(srcPath, function (err, buffer) { | 		fs.readFile(srcPath, 'utf8', function (err, file) { | ||||||
| 			if (err) { | 			if (err) { | ||||||
| 				return next(err); | 				return next(err); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			var scripts = {}; | 			var scripts = {}; | ||||||
| 			scripts[filename] = buffer.toString(); | 			scripts[filename] = file; | ||||||
|  |  | ||||||
| 			try { | 			try { | ||||||
| 				var minified = uglifyjs.minify(scripts, { | 				var minified = uglifyjs.minify(scripts, { | ||||||
| @@ -203,7 +204,7 @@ function minifyJS(data, callback) { | |||||||
| 		var srcPath = ref.srcPath; | 		var srcPath = ref.srcPath; | ||||||
| 		var filename = ref.filename; | 		var filename = ref.filename; | ||||||
|  |  | ||||||
| 		fs.readFile(srcPath, function (err, buffer) { | 		fs.readFile(srcPath, 'utf8', function (err, file) { | ||||||
| 			if (err) { | 			if (err) { | ||||||
| 				return next(err); | 				return next(err); | ||||||
| 			} | 			} | ||||||
| @@ -211,7 +212,7 @@ function minifyJS(data, callback) { | |||||||
| 			next(null, { | 			next(null, { | ||||||
| 				srcPath: srcPath, | 				srcPath: srcPath, | ||||||
| 				filename: filename, | 				filename: filename, | ||||||
| 				source: buffer.toString(), | 				source: file, | ||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
| 	}, function (err, files) { | 	}, function (err, files) { | ||||||
|   | |||||||
| @@ -59,7 +59,7 @@ function preserveExtraneousPlugins() { | |||||||
| 		}) | 		}) | ||||||
| 		// reduce to a map of package names to package versions | 		// reduce to a map of package names to package versions | ||||||
| 		.reduce(function (map, pkgName) { | 		.reduce(function (map, pkgName) { | ||||||
| 			var pkgConfig = JSON.parse(fs.readFileSync(path.join(modulesPath, pkgName, 'package.json'))); | 			var pkgConfig = JSON.parse(fs.readFileSync(path.join(modulesPath, pkgName, 'package.json'), 'utf8')); | ||||||
| 			map[pkgName] = pkgConfig.version; | 			map[pkgName] = pkgConfig.version; | ||||||
| 			return map; | 			return map; | ||||||
| 		}, {}); | 		}, {}); | ||||||
|   | |||||||
| @@ -32,12 +32,11 @@ Templates.compile = function (callback) { | |||||||
|  |  | ||||||
| 		var partial = '/' + matches[1]; | 		var partial = '/' + matches[1]; | ||||||
| 		if (paths[partial] && relativePath !== partial) { | 		if (paths[partial] && relativePath !== partial) { | ||||||
| 			fs.readFile(paths[partial], function (err, file) { | 			fs.readFile(paths[partial], 'utf8', function (err, partialSource) { | ||||||
| 				if (err) { | 				if (err) { | ||||||
| 					return callback(err); | 					return callback(err); | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				var partialSource = file.toString(); |  | ||||||
| 				source = source.replace(regex, partialSource); | 				source = source.replace(regex, partialSource); | ||||||
|  |  | ||||||
| 				processImports(paths, relativePath, source, callback); | 				processImports(paths, relativePath, source, callback); | ||||||
| @@ -58,10 +57,9 @@ Templates.compile = function (callback) { | |||||||
| 			async.each(Object.keys(paths), function (relativePath, next) { | 			async.each(Object.keys(paths), function (relativePath, next) { | ||||||
| 				async.waterfall([ | 				async.waterfall([ | ||||||
| 					function (next) { | 					function (next) { | ||||||
| 						fs.readFile(paths[relativePath], next); | 						fs.readFile(paths[relativePath], 'utf8', next); | ||||||
| 					}, | 					}, | ||||||
| 					function (file, next) { | 					function (source, next) { | ||||||
| 						var source = file.toString(); |  | ||||||
| 						processImports(paths, relativePath, source, next); | 						processImports(paths, relativePath, source, next); | ||||||
| 					}, | 					}, | ||||||
| 					function (source, next) { | 					function (source, next) { | ||||||
|   | |||||||
| @@ -42,7 +42,7 @@ Themes.get = function (callback) { | |||||||
| 			async.map(themes, function (theme, next) { | 			async.map(themes, function (theme, next) { | ||||||
| 				var config = path.join(themePath, theme, 'theme.json'); | 				var config = path.join(themePath, theme, 'theme.json'); | ||||||
|  |  | ||||||
| 				fs.readFile(config, function (err, file) { | 				fs.readFile(config, 'utf8', function (err, file) { | ||||||
| 					if (err) { | 					if (err) { | ||||||
| 						if (err.code === 'ENOENT') { | 						if (err.code === 'ENOENT') { | ||||||
| 							return next(null, null); | 							return next(null, null); | ||||||
| @@ -50,7 +50,7 @@ Themes.get = function (callback) { | |||||||
| 						return next(err); | 						return next(err); | ||||||
| 					} | 					} | ||||||
| 					try { | 					try { | ||||||
| 						var configObj = JSON.parse(file.toString()); | 						var configObj = JSON.parse(file); | ||||||
|  |  | ||||||
| 						// Minor adjustments for API output | 						// Minor adjustments for API output | ||||||
| 						configObj.type = 'local'; | 						configObj.type = 'local'; | ||||||
| @@ -96,9 +96,9 @@ Themes.set = function (data, callback) { | |||||||
| 				}); | 				}); | ||||||
| 			}, | 			}, | ||||||
| 			function (next) { | 			function (next) { | ||||||
| 				fs.readFile(path.join(nconf.get('themes_path'), data.id, 'theme.json'), function (err, config) { | 				fs.readFile(path.join(nconf.get('themes_path'), data.id, 'theme.json'), 'utf8', function (err, config) { | ||||||
| 					if (!err) { | 					if (!err) { | ||||||
| 						config = JSON.parse(config.toString()); | 						config = JSON.parse(config); | ||||||
| 						next(null, config); | 						next(null, config); | ||||||
| 					} else { | 					} else { | ||||||
| 						next(err); | 						next(err); | ||||||
|   | |||||||
| @@ -218,11 +218,11 @@ middleware.templatesOnDemand = function (req, res, next) { | |||||||
| 				return next(); | 				return next(); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			fs.readFile(filePath.replace(/\.js$/, '.tpl'), cb); | 			fs.readFile(filePath.replace(/\.js$/, '.tpl'), 'utf8', cb); | ||||||
| 		}, | 		}, | ||||||
| 		function (source, cb) { | 		function (source, cb) { | ||||||
| 			Benchpress.precompile({ | 			Benchpress.precompile({ | ||||||
| 				source: source.toString(), | 				source: source, | ||||||
| 				minify: global.env !== 'development', | 				minify: global.env !== 'development', | ||||||
| 			}, cb); | 			}, cb); | ||||||
| 		}, | 		}, | ||||||
|   | |||||||
| @@ -33,10 +33,10 @@ Data.getPluginPaths = getPluginPaths; | |||||||
| function loadPluginInfo(pluginPath, callback) { | function loadPluginInfo(pluginPath, callback) { | ||||||
| 	async.parallel({ | 	async.parallel({ | ||||||
| 		package: function (next) { | 		package: function (next) { | ||||||
| 			fs.readFile(path.join(pluginPath, 'package.json'), next); | 			fs.readFile(path.join(pluginPath, 'package.json'), 'utf8', next); | ||||||
| 		}, | 		}, | ||||||
| 		plugin: function (next) { | 		plugin: function (next) { | ||||||
| 			fs.readFile(path.join(pluginPath, 'plugin.json'), next); | 			fs.readFile(path.join(pluginPath, 'plugin.json'), 'utf8', next); | ||||||
| 		}, | 		}, | ||||||
| 	}, function (err, results) { | 	}, function (err, results) { | ||||||
| 		if (err) { | 		if (err) { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user