Set up the site to load its logic and templates piecemeal rather than in one giant app.js file.

This commit is contained in:
Scott Erickson 2014-11-28 16:38:50 -08:00
parent 12b3428aee
commit b698745e05
15 changed files with 399 additions and 95 deletions

107
app/ModuleLoader.coffee Normal file
View file

@ -0,0 +1,107 @@
CocoClass = require 'lib/CocoClass'
locale = require 'locale/locale'
LOG = true
module.exports = ModuleLoader = class ModuleLoader extends CocoClass
@WADS = [
'lib/world'
'lib/surface'
'views/play'
'views/game-menu'
'views/editor'
]
constructor: ->
super()
@loaded = {}
@queue = new createjs.LoadQueue()
@queue.on('fileload', @onFileLoad, @)
load: (path, first=true) ->
if first
$('#module-loading-list ul').empty()
@recentPaths = []
@recentLoadedBytes = 0
originalPath = path
wad = _.find ModuleLoader.WADS, (wad) -> _.string.startsWith(path, wad)
path = wad if wad
return false if @loaded[path]
$('#module-loading-list').modal('show') if first
@loaded[path] = true
@recentPaths.push(path)
li = $("<li class='list-group-item loading' data-path='#{path}'>#{path}</li>")
.prepend($("<span class='glyphicon glyphicon-minus'></span>"))
.prepend($("<span class='glyphicon glyphicon-ok'></span>"))
ul = $('#module-loading-list ul')
ul.append(li).scrollTop(ul[0].scrollHeight)
console.debug 'Loading js file:', "/javascripts/app/#{path}.js" if LOG
@queue.loadFile({
id: path
src: "/javascripts/app/#{path}.js"
type: createjs.LoadQueue.JAVASCRIPT
})
return true
loadLanguage: (langCode) ->
loading = @load("locale/#{langCode}")
firstBit = langCode[...2]
return loading if firstBit is langCode
return loading unless locale[firstBit]?
return @load("locale/#{firstBit}", false) or loading
onFileLoad: (e) =>
$("#module-loading-list li[data-path='#{e.item.id}']").removeClass('loading').addClass('success')
have = window.require.list()
console.group('Dependencies', e.item.id) if LOG
@recentLoadedBytes += e.rawResult.length
dependencies = @parseDependencies(e.rawResult)
console.groupEnd() if LOG
missing = _.difference dependencies, have
@load(module, false) for module in missing
locale.update() if _.string.startsWith(e.item.id, 'locale')
$(e.result).remove()
if @queue.progress is 1
$('#module-loading-list').modal('hide')
@recentPaths.sort()
console.log @recentPaths.join('\n')
console.log 'loaded', @recentPaths.length, 'files,', parseInt(@recentLoadedBytes/1024), 'KB'
@trigger 'load-complete'
parseDependencies: (raw) ->
bits = raw.match(/(require\(\'([^)]+)\')|(register\(\".+\")/g) or []
rootFolder = null
dependencies = []
for bit in bits
if _.string.startsWith(bit, 'register')
root = bit.slice(10, bit.length-1) # remove 'register("' and final double quote
console.groupEnd() if rootFolder if LOG
rootFolder = (root.match('.+/')[0] or '')[...-1]
console.group('register', rootFolder, "(#{bit})") if LOG
else
dep = bit.slice(9, bit.length-1) # remove "require('" and final single quote
dep = dep[1...] if dep[0] is '/'
dep = @expand(rootFolder, dep)
continue if dep is 'memwatch'
continue if _.string.startsWith(dep, 'ace/')
dependencies.push(dep)
console.log dep if LOG
console.groupEnd() if LOG
return dependencies
expand: (root, name) ->
results = []
if /^\.\.?(\/|$)/.test(name)
parts = [root, name].join('/').split('/')
else
parts = name.split('/')
for part in parts
if part is '..'
results.pop()
else if (part isnt '.' and part isnt '')
results.push(part)
return results.join('/')

View file

@ -105,8 +105,12 @@ module.exports = class CocoRouter extends Backbone.Router
window.location.href = window.location.href
routeDirectly: (path, args) ->
path = "views/#{path}"
path = "views/#{path}" if not _.str.startsWith(path, 'views/')
ViewClass = @tryToLoadModule path
if not ViewClass and application.moduleLoader.load(path)
@listenToOnce application.moduleLoader, 'load-complete', ->
@routeDirectly(path, args)
return
return @openView @notFoundView() if not ViewClass
view = new ViewClass({}, args...) # options, then any path fragment args
view.render()
@ -148,11 +152,9 @@ module.exports = class CocoRouter extends Backbone.Router
initializeSocialMediaServices: ->
return if application.testing or application.demoing
services = [
'./lib/services/facebook'
'./lib/services/google'
'./lib/services/twitter'
]
require('./lib/services/facebook')()
require('./lib/services/google')()
require('./lib/services/twitter')()
for service in services
service = require service

View file

@ -1,10 +1,10 @@
FacebookHandler = require 'lib/FacebookHandler'
GPlusHandler = require 'lib/GPlusHandler'
GitHubHandler = require 'lib/GitHubHandler'
locale = require 'locale/locale' # TODO: don't require all of these? Might be slow. (Haven't checked.)
ModuleLoader = require 'ModuleLoader'
locale = require 'locale/locale'
{me} = require 'lib/auth'
Tracker = require 'lib/Tracker'
CocoView = require 'views/kinds/CocoView'
marked.setOptions {gfm: true, sanitize: true, smartLists: true, breaks: false}
@ -43,6 +43,8 @@ Application = initialize: ->
@facebookHandler = new FacebookHandler()
@gplusHandler = new GPlusHandler()
@githubHandler = new GitHubHandler()
@moduleLoader = new ModuleLoader()
@moduleLoader.loadLanguage(me.get('preferredLanguage', true))
$(document).bind 'keydown', preventBackspace
preload(COMMON_FILES)
$.i18n.init {

View file

@ -28,23 +28,46 @@
<link rel="shortcut icon" href="/images/favicon.ico">
<link rel="stylesheet" href="/stylesheets/app.css">
<script src="/lib/ace/ace.js"></script>
<script src="/lib/ace/ace.js" defer></script>
<!--[if IE 9]><script src="/javascripts/box2d.js"></script><![endif]-->
<script src="/javascripts/vendor.js"></script>
<script src="/javascripts/aether.js"></script>
<script src="/javascripts/app.js"></script> <!-- it's all Backbone! -->
<script>$(function() { FastClick.attach(document.body); });</script>
<script src="/javascripts/vendor.js" defer></script>
<script src="/javascripts/aether.js" defer></script>
<script src="/javascripts/app.js" defer></script> <!-- it's all Backbone! -->
<script>
window.userObject = "userObjectTag";
onLoad = function() {
FastClick.attach(document.body);
window.userObject = "userObjectTag";
require('initialize');
}
</script>
<script>require('initialize');</script>
</head>
<body class="nano clearfix">
<body class="nano clearfix" onload="onLoad();">
<div id="fb-root"></div>
<div id="page-container" class="nano-content"></div>
<div id="page-container" class="nano-content">
</div>
<div id="modal-wrapper" class="modal-content"></div>
<div class="modal fade" id="module-loading-list">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">LOADING</h4>
</div>
<div class="modal-body">
<ul class="list-group"></ul>
</div>
</div>
</div>
</div>
<!--<div class="panel panel-primary" id="module-loading-list">-->
<!--<div class="panel-heading">-->
<!--<div class="panel-title">LOADING</div>-->
<!--</div>-->
<!--<ul class="list-group"></ul>-->
<!--</div>-->
</body>
</html>

View file

@ -4,54 +4,62 @@
# http://en.wikipedia.org/wiki/Languages_used_on_the_Internet
module.exports =
en: require './en' # English - English
'en-US': require './en-US' # English (US), English (US)
'en-GB': require './en-GB' # English (UK), English (UK)
'en-AU': require './en-AU' # English (AU), English (AU)
ru: require './ru' # русский язык, Russian
'de-DE': require './de-DE' # Deutsch (Deutschland), German (Germany)
'de-AT': require './de-AT' # Deutsch (Österreich), German (Austria)
'de-CH': require './de-CH' # Deutsch (Schweiz), German (Switzerland)
'es-419': require './es-419' # español (América Latina), Spanish (Latin America)
'es-ES': require './es-ES' # español (ES), Spanish (Spain)
'zh-HANS': require './zh-HANS' # , Chinese (Simplified)
'zh-HANT': require './zh-HANT' # , Chinese (Traditional)
'zh-WUU-HANS': require './zh-WUU-HANS' # , Wuu (Simplified)
'zh-WUU-HANT': require './zh-WUU-HANT' # , Wuu (Traditional)
fr: require './fr' # français, French
ja: require './ja' # , Japanese
ar: require './ar' # العربية, Arabic
'pt-BR': require './pt-BR' # português do Brasil, Portuguese (Brazil)
'pt-PT': require './pt-PT' # Português (Portugal), Portuguese (Portugal)
pl: require './pl' # język polski, Polish
it: require './it' # italiano, Italian
tr: require './tr' # Türkçe, Turkish
'nl-BE': require './nl-BE' # Nederlands (België), Dutch (Belgium)
'nl-NL': require './nl-NL' # Nederlands (Nederland), Dutch (Netherlands)
fa: require './fa' # فارسی, Persian
cs: require './cs' # čeština, Czech
sv: require './sv' # Svenska, Swedish
id: require './id' # Bahasa Indonesia, Indonesian
el: require './el' # ελληνικά, Greek
ro: require './ro' # limba română, Romanian
vi: require './vi' # Tiếng Việt, Vietnamese
hu: require './hu' # magyar, Hungarian
th: require './th' # , Thai
da: require './da' # dansk, Danish
ko: require './ko' # , Korean
sk: require './sk' # slovenčina, Slovak
sl: require './sl' # slovenščina, Slovene
fi: require './fi' # suomi, Finnish
bg: require './bg' # български език, Bulgarian
no: require './no' # Norsk, Norwegian
nn: require './nn' # Norwegian (Nynorsk), Norwegian Nynorsk
nb: require './nb' # Norsk Bokmål, Norwegian (Bokmål)
he: require './he' # עברית, Hebrew
lt: require './lt' # lietuvių kalba, Lithuanian
sr: require './sr' # српски, Serbian
uk: require './uk' # українська мова, Ukrainian
hi: require './hi' # ि, Hindi
ur: require './ur' # اُردُو, Urdu
ms: require './ms' # Bahasa Melayu, Bahasa Malaysia
ca: require './ca' # Català, Catalan
gl: require './gl' # Galego, Galician
update: ->
localesLoaded = (s for s in window.require.list() when _.string.startsWith(s, 'locale/'))
for path in localesLoaded
continue if path is 'locale/locale'
code = path.replace('locale/', '')
@[code] = require(path)
'en': { nativeDescription: 'English', englishDescription: 'English' }
'en-US': { nativeDescription: 'English (US)', englishDescription: 'English (US)' }
'en-GB': { nativeDescription: 'English (UK)', englishDescription: 'English (UK)' }
'en-AU': { nativeDescription: 'English (AU)', englishDescription: 'English (AU)' }
'ru': { nativeDescription: 'русский', englishDescription: 'Russian' }
'de-DE': { nativeDescription: 'Deutsch (Deutschland)', englishDescription: 'German (Germany)' }
'de-AT': { nativeDescription: 'Deutsch (Österreich)', englishDescription: 'German (Austria)' }
'de-CH': { nativeDescription: 'Deutsch (Schweiz)', englishDescription: 'German (Switzerland)' }
'es-419': { nativeDescription: 'español (América Latina)', englishDescription: 'Spanish (Latin America)' }
'es-ES': { nativeDescription: 'español (ES)', englishDescription: 'Spanish (Spain)' }
'zh-HANS': { nativeDescription: '简体中文', englishDescription: 'Chinese (Simplified)' }
'zh-HANT': { nativeDescription: '繁体中文', englishDescription: 'Chinese (Traditional)' }
'zh-WUU-HANS': { nativeDescription: '吴语', englishDescription: 'Wuu (Simplified)' }
'zh-WUU-HANT': { nativeDescription: '吳語', englishDescription: 'Wuu (Traditional)' }
'fr': { nativeDescription: 'français', englishDescription: 'French' }
'ja': { nativeDescription: '日本語', englishDescription: 'Japanese' }
'ar': { nativeDescription: 'العربية', englishDescription: 'Arabic' }
'pt-BR': { nativeDescription: 'português do Brasil', englishDescription: 'Portuguese (Brazil)' }
'pt-PT': { nativeDescription: 'Português (Portugal)', englishDescription: 'Portuguese (Portugal)' }
'pl': { nativeDescription: 'język polski', englishDescription: 'Polish' }
'it': { nativeDescription: 'Italiano', englishDescription: 'Italian' }
'tr': { nativeDescription: 'Türkçe', englishDescription: 'Turkish' }
'nl-BE': { nativeDescription: 'Nederlands (België)', englishDescription: 'Dutch (Belgium)' }
'nl-NL': { nativeDescription: 'Nederlands (Nederland)', englishDescription: 'Dutch (Netherlands)' }
'fa': { nativeDescription: 'فارسی', englishDescription: 'Persian' }
'cs': { nativeDescription: 'čeština', englishDescription: 'Czech' }
'sv': { nativeDescription: 'Svenska', englishDescription: 'Swedish' }
'id': { nativeDescription: 'Bahasa Indonesia', englishDescription: 'Indonesian' }
'el': { nativeDescription: 'Ελληνικά', englishDescription: 'Greek' }
'ro': { nativeDescription: 'limba română', englishDescription: 'Romanian' }
'vi': { nativeDescription: 'Tiếng Việt', englishDescription: 'Vietnamese' }
'hu': { nativeDescription: 'magyar', englishDescription: 'Hungarian' }
'th': { nativeDescription: 'ไทย', englishDescription: 'Thai' }
'da': { nativeDescription: 'dansk', englishDescription: 'Danish' }
'ko': { nativeDescription: '한국어', englishDescription: 'Korean' }
'sk': { nativeDescription: 'slovenčina', englishDescription: 'Slovak' }
'sl': { nativeDescription: 'slovenščina', englishDescription: 'Slovene' }
'fi': { nativeDescription: 'suomi', englishDescription: 'Finnish' }
'bg': { nativeDescription: 'български език', englishDescription: 'Bulgarian' }
'no': { nativeDescription: 'Norsk', englishDescription: 'Norwegian' }
'nn': { nativeDescription: 'Norwegian Nynorsk', englishDescription: 'Norwegian' }
'nb': { nativeDescription: 'Norsk Bokmål', englishDescription: 'Norwegian (Bokmål)' }
'he': { nativeDescription: 'עברית', englishDescription: 'Hebrew' }
'lt': { nativeDescription: 'lietuvių kalba', englishDescription: 'Lithuanian' }
'sr': { nativeDescription: 'српски', englishDescription: 'Serbian' }
'uk': { nativeDescription: 'українська мова', englishDescription: 'Ukrainian' }
'hi': { nativeDescription: 'मानक हिन्दी', englishDescription: 'Hindi' }
'ur': { nativeDescription: 'اُردُو', englishDescription: 'Urdu' }
'ms': { nativeDescription: 'Bahasa Melayu', englishDescription: 'Bahasa Malaysia' }
'ca': { nativeDescription: 'Català', englishDescription: 'Catalan' }
'gl': { nativeDescription: 'Galego', englishDescription: 'Galician' }

View file

@ -292,3 +292,27 @@ html.no-borderimage
body > iframe[src^="https://apis.google.com"]
display: none
#module-loading-list
.modal-content
background: white
border-shadow: 2px 2px 10px black
ul
max-height: 500px
overflow: scroll
li
padding: 2px 15px
font-size: 10px
.glyphicon
margin-right: 10px
&.loading
.glyphicon-ok
display: none
&.success
font-weight: bold
.glyphicon-minus
display: none

View file

@ -1,10 +1,5 @@
RootView = require 'views/kinds/RootView'
template = require 'templates/home'
WizardLank = require 'lib/surface/WizardLank'
ThangType = require 'models/ThangType'
Simulator = require 'lib/simulator/Simulator'
{me} = require '/lib/auth'
module.exports = class HomeView extends RootView
id: 'home-view'
@ -47,10 +42,6 @@ module.exports = class HomeView extends RootView
afterInsert: ->
super(arguments...)
@$el.addClass 'hour-of-code' if @explainsHourOfCode
if me.isAdmin() and me.get('slug') is 'nick'
LevelSetupManager = require 'lib/LevelSetupManager'
setupManager = new LevelSetupManager levelID: 'dungeons-of-kithgard', hadEverChosenHero: true, parent: @
setupManager.open()
setUpHourOfCode: ->
elapsed = (new Date() - new Date(me.get('dateCreated')))

View file

@ -6,6 +6,10 @@ World = require 'lib/world/world'
DocumentFiles = require 'collections/DocumentFiles'
LevelLoader = require 'lib/LevelLoader'
# in the template, but need to require them to load them
require 'views/modal/RevertModal'
require 'views/editor/level/modals/GenerateTerrainModal'
ThangsTabView = require './thangs/ThangsTabView'
SettingsTabView = require './settings/SettingsTabView'
ScriptsTabView = require './scripts/ScriptsTabView'

View file

@ -6,6 +6,9 @@ LayerAdapter = require 'lib/surface/LayerAdapter'
Camera = require 'lib/surface/Camera'
DocumentFiles = require 'collections/DocumentFiles'
# in the template, but need to require to load them
require 'views/modal/RevertModal'
RootView = require 'views/kinds/RootView'
ThangComponentsEditView = require 'views/editor/component/ThangComponentsEditView'
ThangTypeVersionsModal = require './ThangTypeVersionsModal'

View file

@ -4,6 +4,9 @@ Patch = require 'models/Patch'
template = require 'templates/i18n/i18n-edit-model-view'
deltasLib = require 'lib/deltas'
# in the template, but need to require to load them
require 'modal/RevertModal'
module.exports = class I18NEditModelView extends RootView
className: 'editor i18n-edit-model-view'
template: template

View file

@ -139,8 +139,16 @@ module.exports = class RootView extends CocoView
newLang = $('.language-dropdown').val()
$.i18n.setLng(newLang, {})
@saveLanguage(newLang)
loading = application.moduleLoader.loadLanguage(me.get('preferredLanguage', true))
if loading
@listenToOnce application.moduleLoader, 'load-complete', @onLanguageLoaded
else
@onLanguageLoaded()
onLanguageLoaded: ->
@render()
unless newLang.split('-')[0] is 'en'
unless me.get('preferredLanguage').split('-')[0] is 'en'
DiplomatModal = require 'views/modal/DiplomatSuggestionModal'
@openModalView(new DiplomatModal())

View file

@ -1,5 +1,5 @@
RootView = require 'views/kinds/RootView'
template = require 'templates/play'
template = require 'templates/main-play-view'
LevelSession = require 'models/LevelSession'
CocoCollection = require 'collections/CocoCollection'

View file

@ -1,21 +1,109 @@
#- Imports, helpers
_ = require 'lodash'
_.str = require 'underscore.string'
sysPath = require 'path'
startsWith = (string, substring) ->
string.lastIndexOf(substring, 0) is 0
fs = require('fs')
commonjsHeader = fs.readFileSync('node_modules/brunch/node_modules/commonjs-require-definition/require.js', {encoding: 'utf8'})
regJoin = (s) -> new RegExp(s.replace(/\//, '[\\\/\\\\]'))
#- Find all .coffee and .jade files in /app
dirStack = ['./app']
coffeeFiles = []
jadeFiles = []
while dirStack.length
dir = dirStack.pop()
contents = fs.readdirSync(dir)
for file in contents
fullPath = "#{dir}/#{file}"
stat = fs.statSync(fullPath)
if stat.isDirectory()
dirStack.push(fullPath)
else
if _.str.endsWith(file, '.coffee')
coffeeFiles.push(fullPath)
else if _.str.endsWith(file, '.jade')
jadeFiles.push(fullPath)
console.log "Got #{coffeeFiles.length} coffee files and #{jadeFiles.length} jade files."
#- Build the config
exports.config =
paths:
public: 'public'
watched: ['app', 'vendor', 'test/app', 'test/demo']
conventions:
ignored: (path) -> startsWith(sysPath.basename(path), '_')
sourceMaps: true
ignored: (path) -> _.str.startsWith(sysPath.basename(path), '_')
sourceMaps: 'absoluteUrl'
overrides:
production:
sourceMaps: true
sourceMaps: 'absoluteUrl'
files:
javascripts:
defaultExtension: 'coffee'
joinTo:
#- app.js, the first file that is loaded. These modules are required to initialize the client.
'javascripts/app.js': [
# IMPORTANT: if you add to this, make sure you also add any other dependencies
regJoin('^app/schemas')
regJoin('^app/models')
regJoin('^app/collections')
'app/locale/locale.coffee'
'app/application.coffee'
'app/initialize.coffee'
'app/Router.coffee'
'app/ModuleLoader.coffee'
'app/treema-ext.coffee'
'app/collections/NewAchievementCollection.coffee'
'app/collections/CocoCollection.coffee'
'app/lib/FacebookHandler.coffee'
'app/lib/GPlusHandler.coffee'
'app/lib/GitHubHandler.coffee'
'app/lib/auth.coffee'
'app/lib/Tracker.coffee'
'app/lib/CocoClass.coffee'
'app/lib/errors.coffee'
'app/lib/storage.coffee'
'app/lib/utils.coffee'
'app/lib/forms.coffee'
'app/lib/deltas.coffee'
'app/lib/contact.coffee'
'app/lib/sprites/SpriteBuilder.coffee'
'app/lib/SystemNameLoader.coffee'
regJoin('^app/lib/services')
regJoin('^app/views/kinds')
'app/views/NotFoundView.coffee'
'app/views/achievements/AchievementPopup.coffee'
'app/views/modal/ContactModal.coffee'
'app/views/modal/NewModelModal.coffee'
'app/views/modal/RevertModal.coffee'
'app/views/modal/DiplomatSuggestionModal.coffee'
]
#- Wads. Groups of modules by folder which are loaded as a group when needed.
'javascripts/app/lib/surface.js': regJoin('^app/lib/surface')
'javascripts/app/lib/world.js': regJoin('^app/lib/world')
'javascripts/app/views/play.js': regJoin('^app/views/play')
'javascripts/app/views/game-menu.js': regJoin('^app/views/game-menu')
'javascripts/app/views/editor.js': regJoin('^app/views/editor')
#- world.js, used by the worker to generate the world in game
'javascripts/world.js': ///^(
(app[\/\\]lib[\/\\]world(?![\/\\]test))
|(app[\/\\]lib[\/\\]CocoClass.coffee)
@ -24,11 +112,14 @@ exports.config =
|(vendor[\/\\]scripts[\/\\]string_score.js)
|(bower_components[\/\\]underscore.string)
)///
'javascripts/app.js': /^app/
#- vendor.js, all the vendor libraries
'javascripts/vendor.js': ///^(
vendor[\/\\](?!scripts[\/\\]Box2d)
|bower_components[\/\\](?!aether)
)///
#- Other vendor libraries in separate bunches
'javascripts/box2d.js': ///^(
# Include box2dweb for profiling and IE9
# Vector renamed to Box2DVector to avoid name collisions
@ -41,6 +132,8 @@ exports.config =
'javascripts/aether.js': ///^(
(bower_components[\/\\]aether[\/\\]build[\/\\]aether.js)
)///
#- test, demo libraries
'javascripts/test-app.js': /^test[\/\\]app/
'javascripts/demo-app.js': /^test[\/\\]demo/
@ -66,6 +159,7 @@ exports.config =
'vendor/scripts/async.js'
'vendor/scripts/jquery-ui-1.11.1.js.custom.js'
]
stylesheets:
defaultExtension: 'sass'
joinTo:
@ -75,9 +169,28 @@ exports.config =
'app/styles/bootstrap/*'
'vendor/styles/nanoscroller.scss'
]
templates:
defaultExtension: 'jade'
joinTo: 'javascripts/app.js'
joinTo:
'javascripts/app.js': [
'app/templates/modal/error.jade'
'app/templates/not_found.jade'
'app/templates/achievements/achievement-popup.jade'
'app/templates/loading.jade'
'app/templates/loading_error.jade'
'app/templates/modal/contact.jade'
'app/templates/modal/modal_base.jade'
'app/templates/kinds/search.jade'
'app/templates/modal/new_model.jade'
'app/templates/modal/revert.jade'
'app/templates/kinds/user.jade'
'app/templates/modal/diplomat_suggestion.jade'
]
'javascripts/app/views/play.js': regJoin('^app/templates/play')
'javascripts/app/views/game-menu.js': regJoin('^app/templates/game-menu')
'javascripts/app/views/editor.js': regJoin('^app/templates/editor')
framework: 'backbone'
plugins:
@ -85,6 +198,7 @@ exports.config =
delay: 300
coffeelint:
pattern: /^app\/.*\.coffee$/
# pattern: /^dne/ # use this pattern instead if you want to speed compilation
options:
line_endings:
value: 'unix'
@ -102,11 +216,21 @@ exports.config =
mode: 'ruby'
allowCache: true
onCompile: (files) ->
exec = require('child_process').exec
regexFrom = '\\/\\/# sourceMappingURL=([^\\/].*)\\.map'
regexTo = '\\/\\/# sourceMappingURL=\\/javascripts\\/$1\\.map'
regex = "s/#{regexFrom}/#{regexTo}/g"
for file in files
c = "perl -pi -e '#{regex}' #{file.path}"
exec c
modules:
definition: (path, data) ->
needHeaders = [
'public/javascripts/app.js'
'public/javascripts/world.js'
]
defn = if path in needHeaders then commonjsHeader else ''
return defn
for file in coffeeFiles
inputFile = file.replace('./app', 'app')
outputFile = file.replace('.coffee', '.js').replace('./app', 'javascripts/app')
exports.config.files.javascripts.joinTo[outputFile] = inputFile
for file in jadeFiles
inputFile = file.replace('./app', 'app')
outputFile = file.replace('.jade', '.js').replace('./app', 'javascripts/app')
exports.config.files.templates.joinTo[outputFile] = inputFile

View file

@ -112,9 +112,14 @@ exports.setupMiddleware = (app) ->
setupTrailingSlashRemovingMiddleware app
setupRedirectMiddleware app
setupErrorMiddleware app
setupJavascript404s app
###Routing function implementations###
setupJavascript404s = (app) ->
app.get '/javascripts/*', (req, res) ->
res.status(404).send('Not found')
setupFallbackRouteToIndex = (app) ->
app.all '*', (req, res) ->
if req.user