kopia lustrzana https://github.com/c9/core
410 wiersze
14 KiB
JavaScript
410 wiersze
14 KiB
JavaScript
"use strict";
|
|
|
|
main.consumes = ["Plugin", "connect.static"];
|
|
main.provides = ["cdn.build"];
|
|
module.exports = main;
|
|
|
|
function main(options, imports, register) {
|
|
var Plugin = imports.Plugin;
|
|
var connectStatic = imports["connect.static"];
|
|
|
|
var os = require("os");
|
|
var fs = require("fs");
|
|
var path = require("path");
|
|
var error = require("http-error");
|
|
|
|
var build = function() {
|
|
// delay loading of architect build for faster startup
|
|
// todo should we disable this plugin on local instead?
|
|
build = require("architect-build/build");
|
|
build.apply(null, arguments);
|
|
};
|
|
var cache;
|
|
|
|
/***** Initialization *****/
|
|
|
|
var compress = options.compress || false;
|
|
var obfuscate = options.obfuscate || false;
|
|
var keepLess = options.keepLess || false;
|
|
var config = options.config || "ide";
|
|
var settings = options.settings || "devel";
|
|
var cacheDir = path.resolve(options.cache || os.tmpdir() + "/cdn");
|
|
var staticsConfig;
|
|
|
|
var plugin = new Plugin("Ajax.org", main.consumes);
|
|
|
|
/***** Register and define API *****/
|
|
|
|
function init(callback) {
|
|
if (!options.link)
|
|
return callback();
|
|
|
|
var dir = path.join(cacheDir, options.version);
|
|
var rjsConfigPath = path.join(dir, "/static/requirejs-config.json");
|
|
fs.exists(rjsConfigPath, function(exists) {
|
|
if (!exists)
|
|
getStaticsConfig(callback);
|
|
else
|
|
callback();
|
|
});
|
|
}
|
|
|
|
function readConfig(config) {
|
|
if (config == "full") {
|
|
var plugins = [];
|
|
["default-local", "ssh", "default"].forEach(function(n) {
|
|
plugins.push.apply(plugins, readConfig(n).config);
|
|
});
|
|
return {config: plugins};
|
|
}
|
|
|
|
if (config[0] != "/")
|
|
config = path.join(__dirname, "/../../configs/client-" + config);
|
|
|
|
if (config.slice(-3) !== ".js")
|
|
config += ".js";
|
|
|
|
var settings;
|
|
try {
|
|
settings = require("../../settings/standalone");
|
|
config = require(config);
|
|
} catch (e) {
|
|
if (e.code == "MODULE_NOT_FOUND")
|
|
e = new error.NotFound();
|
|
return {error: e};
|
|
}
|
|
settings = settings();
|
|
settings.packaging = true;
|
|
return {config: config(settings)};
|
|
}
|
|
|
|
function buildConfig(config, pathConfig, callback, onReadConfig) {
|
|
var data = readConfig(config);
|
|
if (data.error)
|
|
return callback(data.error);
|
|
|
|
if (onReadConfig && onReadConfig(config, data.config))
|
|
return;
|
|
|
|
var plugins = data.config.concat(sharedModules());
|
|
|
|
var moduleLoadUrl = (options.virtual
|
|
? pathConfig.baseUrl + "/" + pathConfig.hash
|
|
: options.baseUrl) + "/modules";
|
|
|
|
build(plugins, {
|
|
cache: cache,
|
|
pathConfig: pathConfig,
|
|
enableBrowser: true,
|
|
includeConfig: false,
|
|
noArchitect: true,
|
|
compress: compress,
|
|
filter: [],
|
|
ignore: ["amdefine", "plugins/c9.ide.ui/lib_less1.5"],
|
|
withRequire: true,
|
|
stripLess: !keepLess,
|
|
moduleLoadUrl: moduleLoadUrl,
|
|
basepath: pathConfig.root
|
|
}, callback);
|
|
}
|
|
|
|
function buildSkin(config, color, pathConfig, callback) {
|
|
var data = readConfig(config);
|
|
if (data.error)
|
|
return callback(data.error);
|
|
|
|
var plugins = data.config.concat(sharedModules());
|
|
var lessLibs = [];
|
|
|
|
fs.readFile(path.join(pathConfig.root, "plugins/c9.ide.layout.classic/less/lesshat.less"), "utf8", function(err, lesshat) {
|
|
if (err) return callback(err);
|
|
|
|
lessLibs.push(lesshat);
|
|
|
|
fs.readFile(path.join(pathConfig.root, "plugins/c9.ide.layout.classic/themes/default-" + color + ".less"), "utf8", function(err, theme) {
|
|
if (err) return callback(err);
|
|
|
|
lessLibs.push(theme);
|
|
|
|
lessLibs.staticPrefix = "plugins/c9.ide.layout.classic";
|
|
|
|
var themeCss = [{
|
|
id: "text!" + "plugins/c9.ide.layout.classic/themes/" + color + ".less",
|
|
parent: {}
|
|
}];
|
|
|
|
build(plugins, {
|
|
cache: cache,
|
|
pathConfig: pathConfig,
|
|
enableBrowser: true,
|
|
includeConfig: false,
|
|
noArchitect: true,
|
|
compress: compress,
|
|
filter: [],
|
|
ignore: [],
|
|
withRequire: false,
|
|
compileLess: true,
|
|
lessLibs: lessLibs,
|
|
lessLibCacheKey: color,
|
|
basepath: pathConfig.root,
|
|
additional: themeCss
|
|
}, callback);
|
|
});
|
|
});
|
|
}
|
|
|
|
function buildAce(module, pathConfig, callback, aceModuleIgnores) {
|
|
if (!aceModuleIgnores && cache && cache.aceModuleIgnores)
|
|
aceModuleIgnores = cache.aceModuleIgnores;
|
|
|
|
if (aceModuleIgnores) {
|
|
if (aceModuleIgnores.indexOf(module) != -1)
|
|
aceModuleIgnores = []; // allow building default themes
|
|
|
|
return build([module], {
|
|
cache: cache,
|
|
pathConfig: pathConfig,
|
|
enableBrowser: true,
|
|
includeConfig: false,
|
|
noArchitect: true,
|
|
compress: compress,
|
|
quiet: true,
|
|
filter: [],
|
|
ignore: aceModuleIgnores,
|
|
withRequire: false,
|
|
basepath: pathConfig.root
|
|
}, callback);
|
|
}
|
|
|
|
var ignoreRoots = sharedModules().concat([
|
|
"ace/editor",
|
|
"ace/multi_select"
|
|
]);
|
|
|
|
build(ignoreRoots, {
|
|
cache: cache,
|
|
pathConfig: pathConfig,
|
|
enableBrowser: true,
|
|
includeConfig: false,
|
|
noArchitect: true,
|
|
compress: false,
|
|
quiet: true,
|
|
}, function(err, result) {
|
|
var deps = Object.create(null);
|
|
result.sources.forEach(function(pkg) {
|
|
pkg.deps && pkg.deps.forEach(function(p) {
|
|
if (!deps[p]) deps[p] = 1;
|
|
});
|
|
deps[pkg.id] = 1;
|
|
});
|
|
aceModuleIgnores = Object.keys(deps);
|
|
if (cache)
|
|
cache.aceModuleIgnores = aceModuleIgnores;
|
|
buildAce(module, pathConfig, callback, aceModuleIgnores);
|
|
});
|
|
}
|
|
|
|
function sharedModules() {
|
|
return [
|
|
"lib/architect/architect"
|
|
];
|
|
}
|
|
|
|
function buildModule(module, pathConfig, callback) {
|
|
if (/^(ace\/|plugins\/c9.ide.ace)/.test(module))
|
|
return buildAce(module, pathConfig, callback);
|
|
|
|
build([], {
|
|
cache: cache,
|
|
pathConfig: pathConfig,
|
|
enableBrowser: true,
|
|
includeConfig: false,
|
|
noArchitect: true,
|
|
compress: compress,
|
|
filter: [],
|
|
ignore: [],
|
|
additional: [{
|
|
id: module,
|
|
noDeps: true
|
|
}],
|
|
withRequire: false,
|
|
basepath: pathConfig.root
|
|
}, callback);
|
|
}
|
|
|
|
function buildWorker(module, pathConfig, callback) {
|
|
var modules = [module];
|
|
if (module == "plugins/c9.ide.language/worker") {
|
|
// jsonalyzer is missing in built version of local
|
|
var jsonalyzer = require("../c9.ide.language.jsonalyzer/default_plugins");
|
|
var extraPackages = ["plugins/@smartface/smartface.language/loadInclude"];
|
|
try {
|
|
extraPackages = extraPackages.concat(require("lib/salesforce.language/__worker__"));
|
|
} catch(e) {}
|
|
// TODO find a saner method for managing files loaded in language worker
|
|
modules = [
|
|
"plugins/c9.ide.language/worker",
|
|
"plugins/c9.ide.language.generic/local_completer",
|
|
"plugins/c9.ide.language.generic/snippet_completer",
|
|
"plugins/c9.ide.language.generic/mode_completer",
|
|
"plugins/c9.ide.language.generic/open_files_local_completer",
|
|
"plugins/c9.ide.language.generic/simple/make",
|
|
"plugins/c9.ide.language.generic/simple/shell",
|
|
"plugins/c9.ide.language.generic/simple/php",
|
|
"plugins/c9.ide.language.javascript/parse",
|
|
"plugins/c9.ide.language.javascript/scope_analyzer",
|
|
"plugins/c9.ide.language.javascript/debugger",
|
|
"plugins/c9.ide.language.javascript/outline",
|
|
"plugins/c9.ide.language.javascript/jumptodef",
|
|
"plugins/c9.ide.language.javascript.immediate/immediate_complete",
|
|
"plugins/c9.ide.language.javascript.immediate/immediate_complete_static",
|
|
"plugins/c9.ide.language.javascript.infer/infer_jumptodef",
|
|
"plugins/c9.ide.language.javascript.infer/infer_tooltip",
|
|
"plugins/c9.ide.language.javascript.infer/infer_completer",
|
|
"plugins/c9.ide.language.html/html_completer",
|
|
"plugins/c9.ide.language.css/css_handler",
|
|
"plugins/c9.ide.language.javascript.tern/worker/tern_worker",
|
|
"plugins/c9.ide.language.javascript.tern/worker/architect_resolver_worker",
|
|
"plugins/c9.ide.language.javascript.eslint/worker/eslint_worker",
|
|
]
|
|
.concat(jsonalyzer.handlersWorker)
|
|
.concat(jsonalyzer.helpersWorker)
|
|
.concat(extraPackages);
|
|
}
|
|
|
|
build(modules, {
|
|
cache: cache,
|
|
pathConfig: pathConfig,
|
|
enableBrowser: true,
|
|
includeConfig: false,
|
|
noArchitect: true,
|
|
compress: compress,
|
|
obfuscate: obfuscate,
|
|
filter: [],
|
|
ignore: [],
|
|
additional: [{
|
|
id: "ace/worker/worker",
|
|
order: -1000,
|
|
noRequire: true
|
|
}],
|
|
withRequire: false,
|
|
basepath: pathConfig.root
|
|
}, callback);
|
|
}
|
|
|
|
function getStaticsConfig(callback) {
|
|
if (staticsConfig)
|
|
return callback(null, staticsConfig);
|
|
|
|
tryGetConfig(null, connectStatic);
|
|
|
|
if (staticsConfig)
|
|
return callback(null, staticsConfig);
|
|
|
|
var dir = path.join(cacheDir, options.version);
|
|
console.log("Linking static files to ", dir, settings);
|
|
require("../../scripts/makestatic.js")(config, settings, {
|
|
dest: dir + "/static",
|
|
symlink: false,
|
|
compress: options.compress,
|
|
getMounts: !options.link,
|
|
saveRjsConfig: false,
|
|
}, function(err, connectStatic) {
|
|
tryGetConfig(err, connectStatic);
|
|
return callback(err, staticsConfig);
|
|
});
|
|
|
|
function tryGetConfig(err, connectStatic) {
|
|
if (!connectStatic || options.link)
|
|
return;
|
|
|
|
var mounts = connectStatic.getMounts();
|
|
var rjsConfig = connectStatic.getRequireJsConfig();
|
|
|
|
if (!mounts || !mounts[0] || !mounts[0].mount)
|
|
return;
|
|
|
|
var pathMap = Object.create(null);
|
|
mounts.forEach(function(mount) {
|
|
pathMap[mount.mount] = mount.path;
|
|
});
|
|
|
|
staticsConfig = {
|
|
pathMap: pathMap,
|
|
rjsConfig: JSON.parse(JSON.stringify(rjsConfig))
|
|
};
|
|
}
|
|
}
|
|
|
|
function getPathConfig(hash, callback) {
|
|
if (!options.link) {
|
|
getStaticsConfig(function(err, config) {
|
|
if (err) return callback(err);
|
|
|
|
var pathMap = config.pathMap;
|
|
var pathConfig = config.rjsConfig;
|
|
|
|
pathConfig.hash = hash;
|
|
pathConfig.root = path.resolve(path.join(__dirname, "../../"));
|
|
var baseUrl = pathConfig.baseUrl || "";
|
|
for (var p in pathConfig.paths) {
|
|
var url = pathConfig.paths[p];
|
|
if (typeof url === "string" && url.substring(0, baseUrl.length) == baseUrl)
|
|
pathConfig.paths[p] = url.substring(baseUrl.length);
|
|
}
|
|
pathConfig.pathMap = pathMap;
|
|
callback(null, pathConfig);
|
|
});
|
|
} else {
|
|
var root = path.resolve(path.join(cacheDir, hash));
|
|
var rjsConfigPath = path.join(root, "/static/requirejs-config.json");
|
|
fs.readFile(rjsConfigPath, "utf8", function(err, pathConfig) {
|
|
if (err) {
|
|
if (err.code == "ENOENT")
|
|
return callback(new error.NotFound());
|
|
else
|
|
return callback(err);
|
|
}
|
|
|
|
try {
|
|
pathConfig = JSON.parse(pathConfig);
|
|
} catch (e) {
|
|
return callback(e);
|
|
}
|
|
|
|
pathConfig.root = path.join(root, pathConfig.baseUrl);
|
|
for (var p in pathConfig.paths) {
|
|
pathConfig.paths[p] = path.join(root, pathConfig.paths[p]);
|
|
}
|
|
callback(null, pathConfig);
|
|
});
|
|
}
|
|
}
|
|
|
|
function setCache(cacheObj) {
|
|
cache = cacheObj;
|
|
}
|
|
|
|
/**
|
|
*
|
|
**/
|
|
plugin.freezePublicAPI({
|
|
buildAce: buildAce,
|
|
setCache: setCache,
|
|
buildSkin: buildSkin,
|
|
buildConfig: buildConfig,
|
|
buildModule: buildModule,
|
|
buildWorker: buildWorker,
|
|
getPathConfig: getPathConfig,
|
|
get cacheDir() { return cacheDir; },
|
|
get version() { return options.version; }
|
|
});
|
|
|
|
init(function(err) {
|
|
if (err) return register(err);
|
|
|
|
console.log("CDN: version " + options.version + " initialized", cacheDir);
|
|
register(null, { "cdn.build" : plugin });
|
|
});
|
|
}
|