diff --git a/bin/commands/minify.js b/bin/commands/minify.js index f2e4cc3e..bca34010 100644 --- a/bin/commands/minify.js +++ b/bin/commands/minify.js @@ -26,7 +26,10 @@ "use strict"; var path = require('path'), + fs = require('fs'), + wrench = require('wrench'), sdkUtils = require('../lib/utils'), + util = require('../../lib/util'), JavaScriptOptimizer = require('../lib/javascript_optimizer'); /** @@ -48,7 +51,8 @@ function minify() { var projectRoot = sdkUtils.getProjectRoot(process.cwd()), componentsFolder = path.join(projectRoot, 'components'), components = {}, - includedComponents = []; + includedComponents = [], + outputPath; sdkUtils.iterateComponents(componentsFolder, function (config, path, folder) { var fullId = config.id + ';' + config.version; @@ -66,6 +70,11 @@ function minify() { var buildConfig = require(path.join(projectRoot, 'build.json')), additionalProjects = buildConfig.additionalProjects || []; + if (buildConfig.buildPath) { + outputPath = path.resolve(projectRoot, buildConfig.buildPath); + copyProject(projectRoot, outputPath); + } + for (var i = 0, len = additionalProjects.length; i < len; i++) { var folder = path.resolve(projectRoot, additionalProjects[i], 'components'); @@ -84,11 +93,42 @@ function minify() { } var optimizer = new JavaScriptOptimizer({ - out: '/path/to/the/minified/project', // defaults to the current project + outputPath: outputPath, components: components, includedComponents: includedComponents }); optimizer.run(); } +function copyProject(projectPath, minPath) { + wrench.mkdirSyncRecursive(minPath, '0755'); + + var files = fs.readdirSync(projectPath); + + for (var i = 0, len = files.length; i < len; i++) { + var file = files[i], + fromPath = path.join(projectPath, file), + toPath = path.join(minPath, file), + stats = fs.statSync(fromPath); + + if (['.git', '.svn', '.cvs'].indexOf(file) !== -1) { + continue; + } + + if (stats.isDirectory() && fromPath.match(/^.*\/client\/js$/)) { + wrench.mkdirSyncRecursive(toPath, '0755'); + continue; + } + + if (stats.isDirectory()) { + wrench.mkdirSyncRecursive(toPath, '0755'); + copyProject(fromPath, toPath); + } else { + fs.writeFileSync(toPath, fs.readFileSync(fromPath)); + } + + + } +} + module.exports = register; diff --git a/bin/lib/javascript_optimizer.js b/bin/lib/javascript_optimizer.js index 89f5ef28..dff6f10c 100644 --- a/bin/lib/javascript_optimizer.js +++ b/bin/lib/javascript_optimizer.js @@ -31,6 +31,7 @@ var requirejs = require('requirejs'), path = require('path'), util = require('../../lib/util'), fs = require('fs'), + wrench = require('wrench'), extend = require('node.extend'); var excludedModules = ['js/index.min']; @@ -45,6 +46,7 @@ var excludedCoreModules = [ function JsOptimizer(options) { this._components = options.components; this._includedComponents = options.includedComponents; + this._outputPath = options.outputPath; this._baseConfig = { optimize: "none", @@ -57,11 +59,20 @@ function JsOptimizer(options) { JsOptimizer.prototype.run = function () { for (var i = 0, len = this._includedComponents.length; i < len; i++) { var component = this._components[this._includedComponents[i]], - output = path.join(component.path, 'client/js/index.min.js'); + output; + + if (this._outputPath) { + this._copyExcludedFiles(component); + this._modifyMetaJson(component); + output = path.join(this._outputPath, 'components', component.folder, + 'client', 'js', 'index.min.js'); + } else { + output = path.join(component.path, 'client', 'js', 'index.min.js'); + } var options = component.id === 'core' ? - this._generateCoreConfiguration(component, component.path, output) : - this._generateConfiguration(component, component.path, output); + this._generateCoreConfiguration(component, output) : + this._generateConfiguration(component, output); (function (component) { requirejs.optimize(options, function () { @@ -73,8 +84,27 @@ JsOptimizer.prototype.run = function () { } }; -JsOptimizer.prototype._generateConfiguration = function (component, componentPath, outputFile) { +JsOptimizer.prototype._modifyMetaJson = function (component) { + var config = component.config, + configPath = path.join(this._outputPath, 'components', component.folder, 'meta.json'); + + for (var viewName in config.views) { + var view = config.views[viewName], + hasController = view.controller && view.controller.client, + controllerPath = path.join(component.path, 'client', 'js', viewName + '.js'); + + if (!hasController && fs.existsSync(controllerPath)) { + view.controller = view.controller || {}; + view.controller.client = viewName + '.js'; + } + } + + fs.writeFileSync(configPath, JSON.stringify(config), 'utf8'); +}; + +JsOptimizer.prototype._generateConfiguration = function (component, outputFile) { var self = this; + var componentPath = component.path; var coreLocation = path.join(this._components['core;1.0'].path, 'client', 'js'); return extend(true, {}, this._baseConfig, { baseUrl: path.join(componentPath, 'client'), @@ -116,7 +146,9 @@ JsOptimizer.prototype._generateConfiguration = function (component, componentPat }); }; -JsOptimizer.prototype._generateCoreConfiguration = function (component, componentPath, outputFile) { +JsOptimizer.prototype._generateCoreConfiguration = function (component, outputFile) { + var componentPath = component.path; + return { baseUrl: path.join(componentPath, 'client', 'js'), @@ -221,9 +253,25 @@ JsOptimizer.prototype._getModules = function (componentPath, modulePrefix, exclu return modules; }; -JsOptimizer.prototype._getDefineStatement = function (ast) { - // TODO: handle socket.io, promise, step and rain_error +JsOptimizer.prototype._copyExcludedFiles = function (component) { + var jsPath = path.join(component.path, 'client', 'js'), + prefix = component.id === 'core' ? 'raintime' : 'js', + excluded = component.id === 'core' ? excludedCoreModules : excludedModules, + output = path.join(this._outputPath, 'components', component.folder, 'client', 'js'); + + util.walkSync(jsPath, ['.js'], function (filePath) { + var moduleName = filePath.substring(jsPath.length + 1, filePath.length - 3), + destination = path.join(output, path.relative(jsPath, filePath)); + moduleName = prefix + '/' + moduleName.replace('\\', '/'); + + if (excluded.indexOf(moduleName) !== -1) { + wrench.mkdirSyncRecursive(path.dirname(destination)); + fs.writeFileSync(destination, fs.readFileSync(filePath)); + } + }); +}; +JsOptimizer.prototype._getDefineStatement = function (ast) { for (var i = 0, len = ast.body.length; i < len; i++) { var statement = ast.body[i]; diff --git a/build.json b/build.json new file mode 100644 index 00000000..f94c6f2e --- /dev/null +++ b/build.json @@ -0,0 +1,3 @@ +{ + "buildPath": "../min/rainjs" +} diff --git a/components/core/client/templates/bootstrap.html b/components/core/client/templates/bootstrap.html index 73d3b468..f1220730 100644 --- a/components/core/client/templates/bootstrap.html +++ b/components/core/client/templates/bootstrap.html @@ -31,7 +31,12 @@ "name": "raintime", "main": "raintime", "location": "core/js" - }] + }], + "map": { + "*": { + "core/1.0/js": "raintime" + } + } }; var rainContext = { language: '{{language}}', diff --git a/public/instances b/public/instances deleted file mode 120000 index da892003..00000000 --- a/public/instances +++ /dev/null @@ -1 +0,0 @@ -../instances \ No newline at end of file