pulsar/script/lib/prebuild-less-cache.js
Wliu 33cd8b87dc 👕
2017-03-24 11:38:11 -04:00

120 lines
5.5 KiB
JavaScript

'use strict'
const fs = require('fs')
const klawSync = require('klaw-sync')
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)
}
}
CONFIG.snapshotAuxiliaryData.lessSourcesByRelativeFilePath = {}
function saveIntoSnapshotAuxiliaryData (absoluteFilePath, content) {
const relativeFilePath = path.relative(CONFIG.intermediateAppPath, absoluteFilePath)
if (!CONFIG.snapshotAuxiliaryData.lessSourcesByRelativeFilePath.hasOwnProperty(relativeFilePath)) {
CONFIG.snapshotAuxiliaryData.lessSourcesByRelativeFilePath[relativeFilePath] = {
content: content,
digest: LessCache.digestForContent(content)
}
}
}
CONFIG.snapshotAuxiliaryData.importedFilePathsByRelativeImportPath = {}
// 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.atomHomeDirPath, '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')
]
})
// Store file paths located at the import paths so that we can avoid scanning them at runtime.
for (const absoluteImportPath of lessCache.getImportPaths()) {
const relativeImportPath = path.relative(CONFIG.intermediateAppPath, absoluteImportPath)
if (!CONFIG.snapshotAuxiliaryData.importedFilePathsByRelativeImportPath.hasOwnProperty(relativeImportPath)) {
CONFIG.snapshotAuxiliaryData.importedFilePathsByRelativeImportPath[relativeImportPath] = []
for (const importedFile of klawSync(absoluteImportPath, {nodir: true})) {
CONFIG.snapshotAuxiliaryData.importedFilePathsByRelativeImportPath[relativeImportPath].push(
path.relative(CONFIG.intermediateAppPath, importedFile.path)
)
}
}
}
// Cache all styles in static; don't append variable imports
for (let lessFilePath of glob.sync(path.join(CONFIG.intermediateAppPath, 'static', '**', '*.less'))) {
cacheCompiledCSS(lessCache, 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(lessCache, lessFilePath, true)
}
}
// Cache styles for this UI theme
const uiThemeMainPath = path.join(CONFIG.intermediateAppPath, 'node_modules', uiTheme, 'index.less')
cacheCompiledCSS(lessCache, uiThemeMainPath, true)
for (let lessFilePath of glob.sync(path.join(CONFIG.intermediateAppPath, 'node_modules', uiTheme, '**', '*.less'))) {
if (lessFilePath !== uiThemeMainPath) {
saveIntoSnapshotAuxiliaryData(lessFilePath, fs.readFileSync(lessFilePath, 'utf8'))
}
}
// Cache styles for this syntax theme
const syntaxThemeMainPath = path.join(CONFIG.intermediateAppPath, 'node_modules', syntaxTheme, 'index.less')
cacheCompiledCSS(lessCache, syntaxThemeMainPath, true)
for (let lessFilePath of glob.sync(path.join(CONFIG.intermediateAppPath, 'node_modules', syntaxTheme, '**', '*.less'))) {
if (lessFilePath !== syntaxThemeMainPath) {
saveIntoSnapshotAuxiliaryData(lessFilePath, fs.readFileSync(lessFilePath, 'utf8'))
}
}
}
}
for (let lessFilePath of glob.sync(path.join(CONFIG.intermediateAppPath, 'node_modules', 'atom-ui', '**', '*.less'))) {
saveIntoSnapshotAuxiliaryData(lessFilePath, fs.readFileSync(lessFilePath, 'utf8'))
}
function cacheCompiledCSS (lessCache, lessFilePath, importFallbackVariables) {
let lessSource = fs.readFileSync(lessFilePath, 'utf8')
if (importFallbackVariables) {
lessSource = FALLBACK_VARIABLE_IMPORTS + lessSource
}
lessCache.cssForFile(lessFilePath, lessSource)
saveIntoSnapshotAuxiliaryData(lessFilePath, lessSource)
}
}