Skip to content

Instantly share code, notes, and snippets.

@kastermester
Created June 22, 2015 18:08
Show Gist options
  • Save kastermester/4dff3a76c4ab25c5049b to your computer and use it in GitHub Desktop.
Save kastermester/4dff3a76c4ab25c5049b to your computer and use it in GitHub Desktop.
Example RequireJS module
###*
* 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