neft
Version:
Universal Platform
157 lines (120 loc) • 3.79 kB
text/coffeescript
'use strict'
fs = require 'fs-extra'
crypto = require 'crypto'
pathUtils = require 'path'
os = require 'os'
moduleCache = require 'lib/module-cache'
{stringify} = JSON
STRING_FILES =
'.pegjs': true
'.txt': true
replaceStr = (str, oldStr, newStr) ->
i = str.indexOf oldStr
unless ~i then return str
r = str.slice 0, i
r += newStr
r += str.slice i + oldStr.length
r
getFile = (path, opts) ->
unless extname = pathUtils.extname(path)
return
file = moduleCache.getFile path, compile: false
if STRING_FILES[extname]
file = "module.exports = #{JSON.stringify(file)}"
file
fileScope = """(function(){
{{before}}
var __modules = {{init}};
var __require = (function(){
var exports = {{declarations}};
var initialized = new Array(__modules.length);
return function (paths, name){
var path = paths[name];
if (path < exports.length) {
if (!initialized[path]) {
initialized[path] = true;
exports[path] = {};
exports[path] = __modules[path](exports[path]);
}
return exports[path];
}
if (typeof require === 'function') {
return require(name);
}
throw new Error("Cannot find module '"+name+"'");
};
})();
var result = __require({index: {{index}}}, 'index');
if(typeof module !== 'undefined'){
return module.exports = result;
} else {
return result;
}
})();"""
moduleScope = '''function(exports){
var module = {exports: exports};
var require = __require.bind(null, {{paths}});
var exports = module.exports;
{{file}}
return module.exports;
}'''
getDeclarations = (modules) ->
r = []
for name in modules
r.push {}
r
getModulesInit = (modules, paths, indexes, opts) ->
inits = []
for name in modules
index = indexes[name]
modulePaths = paths[name]
pathRefs = {}
for req of modulePaths
pathRefs[req] = indexes[modulePaths[req]]
unless func = getFile(name, opts)
continue
name = name.replace /\\/g, '\\\\'
switch pathUtils.extname name
when '.json'
func = "module.exports = #{func};"
module = moduleScope
module = replaceStr module, '{{name}}', name
module = replaceStr module, '{{paths}}', stringify pathRefs
module = replaceStr module, '{{file}}', func
inits[index] = module
"[#{inits}]"
getModulesByPaths = (paths) ->
modules = []
modulesByPaths = Object.create null
for parentPath of paths
parentPaths = paths[parentPath]
for req of parentPaths
path = parentPaths[req]
if modulesByPaths[path]
continue
modulesByPaths[path] = true
modules.push path
modules
getIndexes = (modules) ->
indexes = Object.create null
for module, i in modules
indexes[module] = i
indexes
module.exports = (processData, opts, callback) ->
{paths} = processData
modules = getModulesByPaths paths
indexes = getIndexes modules
declarations = getDeclarations modules
init = getModulesInit modules, paths, indexes, opts
# before
before = ''
if opts.globals
for key, val of opts.globals
val = JSON.stringify val
before += "var #{key} = #{val};\n"
r = fileScope
r = replaceStr r, '{{before}}', before
r = replaceStr r, '{{index}}', indexes[opts.path]
r = replaceStr r, '{{declarations}}', stringify declarations
r = replaceStr r, '{{init}}', init
callback null, r