From 5178e8d2c65e7e0caf2f45094aec667ef706ad31 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Fri, 29 Jul 2016 16:55:27 -0600 Subject: [PATCH] Pre-build less cache in build.js before packaging --- build/build.js | 2 + build/config.js | 3 +- build/lib/prebuild-less-cache.js | 78 ++++++++++++++++++++++++++++++++ 3 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 build/lib/prebuild-less-cache.js diff --git a/build/build.js b/build/build.js index 781d9b061..26e49cd76 100755 --- a/build/build.js +++ b/build/build.js @@ -11,6 +11,7 @@ const transpileCoffeeScriptPaths = require('./lib/transpile-coffee-script-paths' const transpileCsonPaths = require('./lib/transpile-cson-paths') const transpilePegJsPaths = require('./lib/transpile-peg-js-paths') const generateModuleCache = require('./lib/generate-module-cache') +const prebuildLessCache = require('./lib/prebuild-less-cache') const generateMetadata = require('./lib/generate-metadata') const packageApplication = require('./lib/package-application') @@ -21,5 +22,6 @@ transpileCoffeeScriptPaths() transpileCsonPaths() transpilePegJsPaths() generateModuleCache() +prebuildLessCache() generateMetadata() packageApplication() diff --git a/build/config.js b/build/config.js index b45ca106f..b92a74e26 100644 --- a/build/config.js +++ b/build/config.js @@ -12,11 +12,12 @@ const repositoryRootPath = path.resolve(__dirname, '..') const buildOutputPath = path.join(repositoryRootPath, 'out') const intermediateAppPath = path.join(buildOutputPath, 'app') const cachePath = path.join(repositoryRootPath, 'cache') +const homeDirPath = process.env.HOME || process.env.USERPROFILE module.exports = { appMetadata, channel, repositoryRootPath, buildOutputPath, intermediateAppPath, - cachePath + cachePath, homeDirPath } function getChannel () { diff --git a/build/lib/prebuild-less-cache.js b/build/lib/prebuild-less-cache.js new file mode 100644 index 000000000..a1119bd6d --- /dev/null +++ b/build/lib/prebuild-less-cache.js @@ -0,0 +1,78 @@ +'use strict' + +const fs = require('fs') +const glob = require('glob') +const path = require('path') +const LessCache = require('less-cache') + +const CONFIG = require('../config') +const LESS_CACHE_VERSION =require('less-cache/package.json').version +const FALLBACK_VARIABLE_IMPORTS = '@import "variables/ui-variables";\n@import "variables/syntax-variables";\n' + +module.exports = function () { + const cacheDirPath = path.join(CONFIG.intermediateAppPath, 'less-compile-cache') + console.log(`Generating pre-built less cache in ${cacheDirPath}`) + + // Group bundled packages into UI themes, syntax themes, and non-theme packages + const uiThemes = [] + const syntaxThemes = [] + const nonThemePackages = [] + for (let packageName in CONFIG.appMetadata.packageDependencies) { + const packageMetadata = require(path.join(CONFIG.intermediateAppPath, 'node_modules', packageName, 'package.json')) + if (packageMetadata.theme === 'ui') { + uiThemes.push(packageName) + } else if (packageMetadata.theme === 'syntax') { + syntaxThemes.push(packageName) + } else { + nonThemePackages.push(packageName) + } + } + + // Warm cache for every combination of the default UI and syntax themes, + // because themes assign variables which may be used in any style sheet. + for (let uiTheme of uiThemes) { + for (let syntaxTheme of syntaxThemes) { + // Build a LessCache instance with import paths based on the current theme combination + const lessCache = new LessCache({ + cacheDir: cacheDirPath, + fallbackDir: path.join(CONFIG.homeDirPath, '.atom', 'compile-cache', 'prebuild-less', LESS_CACHE_VERSION), + syncCaches: true, + resourcePath: CONFIG.intermediateAppPath, + importPaths: [ + path.join(CONFIG.intermediateAppPath, 'node_modules', syntaxTheme, 'styles'), + path.join(CONFIG.intermediateAppPath, 'node_modules', uiTheme, 'styles'), + path.join(CONFIG.intermediateAppPath, 'static', 'variables'), + path.join(CONFIG.intermediateAppPath, 'static'), + ] + }) + + function cacheCompiledCSS(lessFilePath, importFallbackVariables) { + let lessSource = fs.readFileSync(lessFilePath, 'utf8') + if (importFallbackVariables) { + lessSource = FALLBACK_VARIABLE_IMPORTS + lessSource + } + lessCache.cssForFile(lessFilePath, lessSource) + } + + // Cache all styles in static; don't append variable imports + for (let lessFilePath of glob.sync(path.join(CONFIG.intermediateAppPath, 'static', '**', '*.less'))) { + cacheCompiledCSS(lessFilePath, false) + } + + // Cache styles for all bundled non-theme packages + for (let nonThemePackage of nonThemePackages) { + for (let lessFilePath of glob.sync(path.join(CONFIG.intermediateAppPath, 'node_modules', nonThemePackage, '**', '*.less'))) { + cacheCompiledCSS(lessFilePath, true) + } + } + + // Cache styles for this UI theme + const uiThemeMainPath = path.join(CONFIG.intermediateAppPath, 'node_modules', uiTheme, 'index.less') + cacheCompiledCSS(uiThemeMainPath, true) + + // Cache styles for this syntax theme + const syntaxThemeMainPath = path.join(CONFIG.intermediateAppPath, 'node_modules', syntaxTheme, 'index.less') + cacheCompiledCSS(syntaxThemeMainPath, true) + } + } +}