mirror of
https://github.com/atom/atom.git
synced 2026-01-23 13:58:08 -05:00
Merge pull request #5524 from atom/ks-defer-coffee-script-require
Minimize CoffeeScript requires
This commit is contained in:
11
package.json
11
package.json
@@ -24,8 +24,9 @@
|
||||
"atom-keymap": "^3.1.2",
|
||||
"bootstrap": "git+https://github.com/atom/bootstrap.git#6af81906189f1747fd6c93479e3d998ebe041372",
|
||||
"clear-cut": "0.4.0",
|
||||
"coffee-cash": "0.7.0",
|
||||
"coffee-script": "1.8.0",
|
||||
"coffeestack": "0.8.0",
|
||||
"coffeestack": "^1.1",
|
||||
"color": "^0.7.3",
|
||||
"delegato": "^1",
|
||||
"emissary": "^1.3.1",
|
||||
@@ -35,10 +36,10 @@
|
||||
"fstream": "0.1.24",
|
||||
"fuzzaldrin": "^2.1",
|
||||
"git-utils": "^3.0.0",
|
||||
"grim": "1.1.1",
|
||||
"grim": "1.1.2",
|
||||
"guid": "0.0.10",
|
||||
"jasmine-json": "~0.0",
|
||||
"jasmine-tagged": "^1.1.3",
|
||||
"jasmine-tagged": "^1.1.4",
|
||||
"jquery": "^2.1.1",
|
||||
"less-cache": "0.21",
|
||||
"marked": "^0.3",
|
||||
@@ -57,7 +58,7 @@
|
||||
"scandal": "2.0.0",
|
||||
"scoped-property-store": "^0.16.2",
|
||||
"scrollbar-style": "^2.0.0",
|
||||
"season": "^5.1.2",
|
||||
"season": "^5.1.4",
|
||||
"semver": "~4.2",
|
||||
"serializable": "^1",
|
||||
"service-hub": "^0.4.0",
|
||||
@@ -93,7 +94,7 @@
|
||||
"deprecation-cop": "0.36.0",
|
||||
"dev-live-reload": "0.41.0",
|
||||
"encoding-selector": "0.18.0",
|
||||
"exception-reporting": "0.23.0",
|
||||
"exception-reporting": "0.24.0",
|
||||
"find-and-replace": "0.157.0",
|
||||
"fuzzy-finder": "0.66.0",
|
||||
"git-diff": "0.52.0",
|
||||
|
||||
28
spec/compile-cache-spec.coffee
Normal file
28
spec/compile-cache-spec.coffee
Normal file
@@ -0,0 +1,28 @@
|
||||
path = require 'path'
|
||||
CSON = require 'season'
|
||||
CoffeeCache = require 'coffee-cash'
|
||||
|
||||
to5 = require '../src/6to5'
|
||||
CompileCache = require '../src/compile-cache'
|
||||
|
||||
describe "Compile Cache", ->
|
||||
describe ".addPathToCache(filePath)", ->
|
||||
it "adds the path to the correct CSON, CoffeeScript, or 6to5 cache", ->
|
||||
spyOn(CSON, 'readFileSync').andCallThrough()
|
||||
spyOn(CoffeeCache, 'addPathToCache').andCallThrough()
|
||||
spyOn(to5, 'addPathToCache').andCallThrough()
|
||||
|
||||
CompileCache.addPathToCache(path.join(__dirname, 'fixtures', 'cson.cson'))
|
||||
expect(CSON.readFileSync.callCount).toBe 1
|
||||
expect(CoffeeCache.addPathToCache.callCount).toBe 0
|
||||
expect(to5.addPathToCache.callCount).toBe 0
|
||||
|
||||
CompileCache.addPathToCache(path.join(__dirname, 'fixtures', 'coffee.coffee'))
|
||||
expect(CSON.readFileSync.callCount).toBe 1
|
||||
expect(CoffeeCache.addPathToCache.callCount).toBe 1
|
||||
expect(to5.addPathToCache.callCount).toBe 0
|
||||
|
||||
CompileCache.addPathToCache(path.join(__dirname, 'fixtures', '6to5', 'double-quotes.js'))
|
||||
expect(CSON.readFileSync.callCount).toBe 1
|
||||
expect(CoffeeCache.addPathToCache.callCount).toBe 1
|
||||
expect(to5.addPathToCache.callCount).toBe 1
|
||||
1
spec/fixtures/cson.cson
vendored
Normal file
1
spec/fixtures/cson.cson
vendored
Normal file
@@ -0,0 +1 @@
|
||||
a: 4
|
||||
@@ -89,6 +89,7 @@ create6to5VersionAndOptionsDigest = (version, options) ->
|
||||
updateDigestForJsonValue(shasum, options)
|
||||
shasum.digest('hex')
|
||||
|
||||
cacheDir = null
|
||||
jsCacheDir = null
|
||||
|
||||
getCachePath = (sourceCode) ->
|
||||
@@ -96,8 +97,7 @@ getCachePath = (sourceCode) ->
|
||||
|
||||
unless jsCacheDir?
|
||||
to5Version = require('6to5-core/package.json').version
|
||||
cacheDir = path.join(process.env.ATOM_HOME, 'compile-cache')
|
||||
jsCacheDir = path.join(cacheDir, 'js', '6to5', create6to5VersionAndOptionsDigest(to5Version, defaultOptions))
|
||||
jsCacheDir = path.join(cacheDir, create6to5VersionAndOptionsDigest(to5Version, defaultOptions))
|
||||
|
||||
path.join(jsCacheDir, "#{digest}.js")
|
||||
|
||||
@@ -141,12 +141,19 @@ loadFile = (module, filePath) ->
|
||||
|
||||
register = ->
|
||||
Object.defineProperty(require.extensions, '.js', {
|
||||
enumerable: true
|
||||
writable: false
|
||||
value: loadFile
|
||||
})
|
||||
|
||||
setCacheDirectory = (newCacheDir) ->
|
||||
if cacheDir isnt newCacheDir
|
||||
cacheDir = newCacheDir
|
||||
jsCacheDir = null
|
||||
|
||||
module.exports =
|
||||
register: register
|
||||
setCacheDirectory: setCacheDirectory
|
||||
getCacheMisses: -> stats.misses
|
||||
getCacheHits: -> stats.hits
|
||||
|
||||
|
||||
@@ -15,6 +15,8 @@ process.on 'uncaughtException', (error={}) ->
|
||||
|
||||
start = ->
|
||||
setupAtomHome()
|
||||
setupCoffeeCache()
|
||||
|
||||
if process.platform is 'win32'
|
||||
SquirrelUpdate = require './squirrel-update'
|
||||
squirrelCommand = process.argv[1]
|
||||
@@ -49,9 +51,7 @@ start = ->
|
||||
else
|
||||
path.resolve(pathToOpen)
|
||||
|
||||
setupCoffeeScript()
|
||||
if args.devMode
|
||||
require(path.join(args.resourcePath, 'src', 'coffee-cache')).register()
|
||||
AtomApplication = require path.join(args.resourcePath, 'src', 'browser', 'atom-application')
|
||||
else
|
||||
AtomApplication = require './atom-application'
|
||||
@@ -66,15 +66,6 @@ global.devResourcePath = path.normalize(global.devResourcePath) if global.devRes
|
||||
setupCrashReporter = ->
|
||||
crashReporter.start(productName: 'Atom', companyName: 'GitHub')
|
||||
|
||||
setupCoffeeScript = ->
|
||||
CoffeeScript = null
|
||||
|
||||
require.extensions['.coffee'] = (module, filePath) ->
|
||||
CoffeeScript ?= require('coffee-script')
|
||||
coffee = fs.readFileSync(filePath, 'utf8')
|
||||
js = CoffeeScript.compile(coffee, filename: filePath)
|
||||
module._compile(js, filePath)
|
||||
|
||||
setupAtomHome = ->
|
||||
return if process.env.ATOM_HOME
|
||||
|
||||
@@ -83,6 +74,15 @@ setupAtomHome = ->
|
||||
atomHome = fs.realpathSync(atomHome)
|
||||
process.env.ATOM_HOME = atomHome
|
||||
|
||||
setupCoffeeCache = ->
|
||||
CoffeeCache = require 'coffee-cash'
|
||||
cacheDir = path.join(process.env.ATOM_HOME, 'compile-cache')
|
||||
# Use separate compile cache when sudo'ing as root to avoid permission issues
|
||||
if process.env.USER is 'root' and process.env.SUDO_USER and process.env.SUDO_USER isnt process.env.USER
|
||||
cacheDir = path.join(cacheDir, 'root')
|
||||
CoffeeCache.setCacheDirectory(path.join(cacheDir, 'coffee'))
|
||||
CoffeeCache.register()
|
||||
|
||||
parseCommandLine = ->
|
||||
version = app.getVersion()
|
||||
options = optimist(process.argv[1..])
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
crypto = require 'crypto'
|
||||
path = require 'path'
|
||||
|
||||
CoffeeScript = require 'coffee-script'
|
||||
CSON = require 'season'
|
||||
fs = require 'fs-plus'
|
||||
|
||||
cacheDir = path.join(process.env.ATOM_HOME, 'compile-cache')
|
||||
|
||||
stats =
|
||||
hits: 0
|
||||
misses: 0
|
||||
|
||||
# Use separate compile cache when sudo'ing as root to avoid permission issues
|
||||
if process.env.USER is 'root' and process.env.SUDO_USER and process.env.SUDO_USER isnt process.env.USER
|
||||
cacheDir = path.join(cacheDir, 'root')
|
||||
|
||||
coffeeCacheDir = path.join(cacheDir, 'coffee')
|
||||
CSON.setCacheDir(path.join(cacheDir, 'cson'))
|
||||
|
||||
getCachePath = (coffee) ->
|
||||
digest = crypto.createHash('sha1').update(coffee, 'utf8').digest('hex')
|
||||
path.join(coffeeCacheDir, "#{digest}.js")
|
||||
|
||||
getCachedJavaScript = (cachePath) ->
|
||||
if fs.isFileSync(cachePath)
|
||||
try
|
||||
cachedJavaScript = fs.readFileSync(cachePath, 'utf8')
|
||||
stats.hits++
|
||||
return cachedJavaScript
|
||||
return
|
||||
|
||||
convertFilePath = (filePath) ->
|
||||
if process.platform is 'win32'
|
||||
filePath = "/#{path.resolve(filePath).replace(/\\/g, '/')}"
|
||||
encodeURI(filePath)
|
||||
|
||||
compileCoffeeScript = (coffee, filePath, cachePath) ->
|
||||
{js, v3SourceMap} = CoffeeScript.compile(coffee, filename: filePath, sourceMap: true)
|
||||
stats.misses++
|
||||
# Include source map in the web page environment.
|
||||
if btoa? and JSON? and unescape? and encodeURIComponent?
|
||||
js = "#{js}\n//# sourceMappingURL=data:application/json;base64,#{btoa unescape encodeURIComponent v3SourceMap}\n//# sourceURL=#{convertFilePath(filePath)}"
|
||||
try
|
||||
fs.writeFileSync(cachePath, js)
|
||||
js
|
||||
|
||||
requireCoffeeScript = (module, filePath) ->
|
||||
coffee = fs.readFileSync(filePath, 'utf8')
|
||||
cachePath = getCachePath(coffee)
|
||||
js = getCachedJavaScript(cachePath) ? compileCoffeeScript(coffee, filePath, cachePath)
|
||||
module._compile(js, filePath)
|
||||
|
||||
module.exports =
|
||||
cacheDir: cacheDir
|
||||
|
||||
register: ->
|
||||
Object.defineProperty(require.extensions, '.coffee', {
|
||||
writable: false
|
||||
value: requireCoffeeScript
|
||||
})
|
||||
|
||||
addPathToCache: (filePath) ->
|
||||
switch path.extname(filePath)
|
||||
when '.coffee'
|
||||
content = fs.readFileSync(filePath, 'utf8')
|
||||
cachePath = getCachePath(coffee)
|
||||
compileCoffeeScript(coffee, filePath, cachePath)
|
||||
when '.cson'
|
||||
CSON.readFileSync(filePath)
|
||||
when '.js'
|
||||
require('./6to5').addPathToCache(filePath)
|
||||
|
||||
getCacheMisses: -> stats.misses
|
||||
|
||||
getCacheHits: -> stats.hits
|
||||
26
src/compile-cache.coffee
Normal file
26
src/compile-cache.coffee
Normal file
@@ -0,0 +1,26 @@
|
||||
path = require 'path'
|
||||
CSON = require 'season'
|
||||
CoffeeCache = require 'coffee-cash'
|
||||
to5 = require './6to5'
|
||||
|
||||
# This file is required directly by apm so that files can be cached during
|
||||
# package install so that the first package load in Atom doesn't have to
|
||||
# compile anything.
|
||||
exports.addPathToCache = (filePath, atomHome) ->
|
||||
atomHome ?= process.env.ATOM_HOME
|
||||
cacheDir = path.join(atomHome, 'compile-cache')
|
||||
# Use separate compile cache when sudo'ing as root to avoid permission issues
|
||||
if process.env.USER is 'root' and process.env.SUDO_USER and process.env.SUDO_USER isnt process.env.USER
|
||||
cacheDir = path.join(cacheDir, 'root')
|
||||
|
||||
CoffeeCache.setCacheDirectory(path.join(cacheDir, 'coffee'))
|
||||
CSON.setCacheDir(path.join(cacheDir, 'cson'))
|
||||
to5.setCacheDirectory(path.join(cacheDir, 'js'))
|
||||
|
||||
switch path.extname(filePath)
|
||||
when '.coffee'
|
||||
CoffeeCache.addPathToCache(filePath)
|
||||
when '.cson'
|
||||
CSON.readFileSync(filePath)
|
||||
when '.js'
|
||||
to5.addPathToCache(filePath)
|
||||
@@ -65,12 +65,15 @@ class Task
|
||||
# * `taskPath` The {String} path to the CoffeeScript/JavaScript file that
|
||||
# exports a single {Function} to execute.
|
||||
constructor: (taskPath) ->
|
||||
coffeeCacheRequire = "require('#{require.resolve('./coffee-cache')}').register();"
|
||||
coffeeScriptRequire = "require('#{require.resolve('coffee-script')}').register();"
|
||||
coffeeCacheRequire = "require('#{require.resolve('coffee-cash')}')"
|
||||
coffeeCachePath = require('coffee-cash').getCacheDirectory()
|
||||
coffeeStackRequire = "require('#{require.resolve('coffeestack')}')"
|
||||
stackCachePath = require('coffeestack').getCacheDirectory()
|
||||
taskBootstrapRequire = "require('#{require.resolve('./task-bootstrap')}');"
|
||||
bootstrap = """
|
||||
#{coffeeScriptRequire}
|
||||
#{coffeeCacheRequire}
|
||||
#{coffeeCacheRequire}.setCacheDirectory('#{coffeeCachePath}');
|
||||
#{coffeeCacheRequire}.register();
|
||||
#{coffeeStackRequire}.setCacheDirectory('#{stackCachePath}');
|
||||
#{taskBootstrapRequire}
|
||||
"""
|
||||
bootstrap = bootstrap.replace(/\\/g, "\\\\")
|
||||
|
||||
@@ -1,33 +1,17 @@
|
||||
function registerRuntimeTranspilers() {
|
||||
// This sets require.extensions['.coffee'].
|
||||
require('coffee-script').register();
|
||||
|
||||
// This redefines require.extensions['.js'].
|
||||
require('../src/6to5').register();
|
||||
}
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
|
||||
window.onload = function() {
|
||||
try {
|
||||
var startTime = Date.now();
|
||||
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
|
||||
// Ensure ATOM_HOME is always set before anything else is required
|
||||
if (!process.env.ATOM_HOME) {
|
||||
var home;
|
||||
if (process.platform === 'win32') {
|
||||
home = process.env.USERPROFILE;
|
||||
} else {
|
||||
home = process.env.HOME;
|
||||
}
|
||||
var atomHome = path.join(home, '.atom');
|
||||
try {
|
||||
atomHome = fs.realpathSync(atomHome);
|
||||
} catch (error) {
|
||||
// Ignore since the path might just not exist yet.
|
||||
}
|
||||
process.env.ATOM_HOME = atomHome;
|
||||
setupAtomHome();
|
||||
|
||||
var cacheDir = path.join(process.env.ATOM_HOME, 'compile-cache');
|
||||
// Use separate compile cache when sudo'ing as root to avoid permission issues
|
||||
if (process.env.USER === 'root' && process.env.SUDO_USER && process.env.SUDO_USER !== process.env.USER) {
|
||||
cacheDir = path.join(cacheDir, 'root');
|
||||
}
|
||||
|
||||
// Skip "?loadSettings=".
|
||||
@@ -45,10 +29,7 @@ window.onload = function() {
|
||||
|
||||
var devMode = loadSettings.devMode || !loadSettings.resourcePath.startsWith(process.resourcesPath + path.sep);
|
||||
|
||||
// Require before the module cache in dev mode
|
||||
if (devMode) {
|
||||
registerRuntimeTranspilers();
|
||||
}
|
||||
setupCoffeeCache(cacheDir);
|
||||
|
||||
ModuleCache = require('../src/module-cache');
|
||||
ModuleCache.register(loadSettings);
|
||||
@@ -65,11 +46,9 @@ window.onload = function() {
|
||||
|
||||
require('vm-compatibility-layer');
|
||||
|
||||
if (!devMode) {
|
||||
registerRuntimeTranspilers();
|
||||
}
|
||||
|
||||
require('../src/coffee-cache').register();
|
||||
setupCsonCache(cacheDir);
|
||||
setupSourceMapCache(cacheDir);
|
||||
setup6to5(cacheDir);
|
||||
|
||||
require(loadSettings.bootstrapScript);
|
||||
require('ipc').sendChannel('window-command', 'window:loaded');
|
||||
@@ -78,8 +57,7 @@ window.onload = function() {
|
||||
global.atom.loadTime = Date.now() - startTime;
|
||||
console.log('Window load time: ' + global.atom.getWindowLoadTime() + 'ms');
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
} catch (error) {
|
||||
var currentWindow = require('remote').getCurrentWindow();
|
||||
currentWindow.setSize(800, 600);
|
||||
currentWindow.center();
|
||||
@@ -88,3 +66,41 @@ window.onload = function() {
|
||||
console.error(error.stack || error);
|
||||
}
|
||||
}
|
||||
|
||||
var setupCoffeeCache = function(cacheDir) {
|
||||
var CoffeeCache = require('coffee-cash');
|
||||
CoffeeCache.setCacheDirectory(path.join(cacheDir, 'coffee'));
|
||||
CoffeeCache.register();
|
||||
}
|
||||
|
||||
var setupAtomHome = function() {
|
||||
if (!process.env.ATOM_HOME) {
|
||||
var home;
|
||||
if (process.platform === 'win32') {
|
||||
home = process.env.USERPROFILE;
|
||||
} else {
|
||||
home = process.env.HOME;
|
||||
}
|
||||
var atomHome = path.join(home, '.atom');
|
||||
try {
|
||||
atomHome = fs.realpathSync(atomHome);
|
||||
} catch (error) {
|
||||
// Ignore since the path might just not exist yet.
|
||||
}
|
||||
process.env.ATOM_HOME = atomHome;
|
||||
}
|
||||
}
|
||||
|
||||
var setup6to5 = function(cacheDir) {
|
||||
var to5 = require('../src/6to5');
|
||||
to5.setCacheDirectory(path.join(cacheDir, 'js', '6to5'));
|
||||
to5.register();
|
||||
}
|
||||
|
||||
var setupCsonCache = function(cacheDir) {
|
||||
require('season').setCacheDir(path.join(cacheDir, 'cson'));
|
||||
}
|
||||
|
||||
var setupSourceMapCache = function(cacheDir) {
|
||||
require('coffeestack').setCacheDirectory(path.join(cacheDir, 'coffee', 'source-maps'));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user