Created
June 22, 2015 18:08
-
-
Save kastermester/4dff3a76c4ab25c5049b to your computer and use it in GitHub Desktop.
Example RequireJS module
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
###* | |
* RequireJS component plugin | |
* @author Brian K. Christensen, Secoya A/S <[email protected]> | |
* @version 0.9.1 | |
* @license BSD | |
### | |
define [], () -> | |
class ComponentModule | |
_config: | |
appBasePath: 'app/extensions' | |
componentBasePath: 'core/modules' | |
relativeModuleOverridePath: 'base' | |
moduleInterface: 'public' | |
textExtensions: [] | |
jsonExtensions: ['json'] | |
extensionsWithCustomLoaders: ['hbs','css'] | |
buildMap = {} | |
TYPE_COMPONENT_BASE = 0 | |
TYPE_COMPONENT_NON_EXTENDABLE = 1 | |
TYPE_COMPONENT_EXTENDABLE = 2 | |
inArray: (needle, haystack) -> | |
for n in haystack | |
return true if n is needle | |
return false | |
_extendConfig: (source, target) -> | |
source ?= {} | |
for k, v of source | |
target[k] ?= v | |
return target | |
resolveComponent: (name, componentConfig) -> | |
# when using #! as sepearator, you get the base component. | |
if name.indexOf('#!') isnt -1 | |
type = TYPE_COMPONENT_BASE | |
[component, module] = name.split '#!' | |
# when using % you get the none extendable component files of a core module. | |
else if name.indexOf('#') isnt -1 | |
type = TYPE_COMPONENT_EXTENDABLE | |
[component, module] = name.split '#' | |
# else we you the 'normal' extendable behavior | |
# if there exist a # then the module is the part on the right side | |
# else the module fallsback to componentConfig['moduleInterface'] | |
else | |
type = TYPE_COMPONENT_NON_EXTENDABLE | |
[component, module] = name.split '%' | |
# the default file to load in. | |
module = componentConfig['moduleInterface'] unless module? | |
return [component, module, type] | |
resolveComponentUrl: (url) -> | |
componentConfig = @_config | |
[component, module, type] = @resolveComponent url.replace('com!', ''), componentConfig | |
specficPath = null | |
if type is TYPE_COMPONENT_BASE | |
modulePath = "#{componentConfig['componentBasePath']}/#{component}/#{componentConfig['relativeModuleOverridePath']}/#{module}" | |
else if type is TYPE_COMPONENT_NON_EXTENDABLE | |
modulePath = "#{componentConfig['componentBasePath']}/#{component}/#{module}" | |
else if type is TYPE_COMPONENT_EXTENDABLE | |
specificPath = "#{componentConfig['appBasePath']}/#{component}/#{module}" | |
modulePath = "#{componentConfig['componentBasePath']}/#{component}/#{componentConfig['relativeModuleOverridePath']}/#{module}" | |
return {modulePath, specificPath} | |
load: (name, req, load, config) -> | |
# we might wanna the extension stuff so we get all the right values on @_config. (remember to fix in hbs plugin) | |
componentConfig = config.component ? {} | |
@_extendConfig @_config, componentConfig | |
[component, module, type] = @resolveComponent name, componentConfig | |
if (idx = module.lastIndexOf('.')) isnt -1 | |
ext = module[(idx+1)..] | |
if ext? | |
if @inArray ext, componentConfig['extensionsWithCustomLoaders'] | |
plugin = ext+"!" | |
else if @inArray ext, componentConfig['textExtensions'] | |
plugin = "text!" | |
else if @inArray ext, componentConfig['jsonExtensions'] | |
plugin = "json!" | |
if type is TYPE_COMPONENT_BASE | |
modulePath = "#{componentConfig['componentBasePath']}/#{component}/#{componentConfig['relativeModuleOverridePath']}/#{module}" | |
@loadNonExtendable req, load, modulePath, plugin, name, config | |
else if type is TYPE_COMPONENT_NON_EXTENDABLE | |
modulePath = "#{componentConfig['componentBasePath']}/#{component}/#{module}" | |
@loadNonExtendable req, load, modulePath, plugin, name, config | |
else if type is TYPE_COMPONENT_EXTENDABLE | |
specificPath = "#{componentConfig['appBasePath']}/#{component}/#{module}" | |
modulePath = "#{componentConfig['componentBasePath']}/#{component}/#{componentConfig['relativeModuleOverridePath']}/#{module}" | |
@loadExtendable req, load, specificPath, modulePath, plugin, name, config | |
loadNonExtendable: (req, load, modulePath, plugin, name, config) -> | |
modulePath = plugin+modulePath if plugin? | |
#console.log "trying to load non extendable module: #{modulePath}" | |
req [modulePath], (module) -> | |
#console.log "loaded non extendable module: #{modulePath}" | |
buildMap[name] = modulePath if config.isBuild | |
load module | |
loadExtendable: (req, load, specificPath, modulePath, plugin, name, config) -> | |
if config.isBuild | |
if typeof(process) == 'undefined' | |
throw new Error("Require Component only supports rjs in node mode") | |
fs = require.nodeRequire 'fs' | |
path = require.nodeRequire 'path' | |
ext = '' | |
if !plugin? | |
ext = '.js' | |
specificFilePath = path.join(config.dirBaseUrl, specificPath) + ext | |
specificExists = fs.existsSync specificFilePath | |
if plugin? | |
specificPath = plugin+specificPath | |
modulePath = plugin+modulePath | |
if specificExists | |
buildMap[name] = specificPath | |
req [specificPath], load | |
else | |
buildMap[name] = modulePath | |
req [modulePath], load | |
else | |
if plugin? | |
specificPath = plugin+specificPath | |
modulePath = plugin+modulePath | |
# loading application overriden files. | |
req [specificPath], (module) -> | |
#console.log "loaded specific module: #{specificPath}" | |
load module | |
, (err) -> | |
# loading modules files if application specific wasn't there. | |
req [modulePath], (module) -> | |
#console.log "loaded base module: #{modulePath}" | |
load module | |
normalize: (name, normalize) -> | |
normalize name | |
write: (pluginName, moduleName, write) -> | |
if typeof(buildMap[moduleName] != 'undefined') | |
path = buildMap[moduleName] | |
write('define(' + JSON.stringify(pluginName + '!' + moduleName) + ', [' + JSON.stringify(path) + '], function(module){ return module; });') | |
return new ComponentModule |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment