UNPKG

cheetah-framework

Version:

Cheetah Framework JS used in all our applications

205 lines (170 loc) 6.2 kB
const path = require('path') const mix = require('laravel-mix') const { argv } = require('yargs') const Paths = require('./Paths') const Config = require('./Config') const File = require('./File') const glob = require('glob') const fs = require('fs-extra') global.path = path // make it extend cheetah class class Cheetah { constructor (rootPath) { rootPath = rootPath || process.cwd() this.argv = argv this.config = new Config(rootPath) this.paths = new Paths(rootPath, this) this.moduleAlias = {} this.relativeModuleAlias = {} this.scssModules = [] this.modulesFonts = [] this.modulesImages = [] this.modules = [] } start () { this.loadModules() this.writeSassFile() this.mix() } /** * Create aliases + build main sass file */ loadModules () { // remove existing symlinks if (File.exists(this.paths.symlinkFolder)) { fs.readdirSync(this.paths.symlinkFolder, { withFileTypes: true }).forEach(file => { if (file.isSymbolicLink()) { fs.unlinkSync(this.paths.symlinkFolder + '/' + file.name) } }) } else { console.error('Missing folder: ' + this.paths.symlinkFolder) process.exit() } this.modules = this.config.modules this.modules.push(this.paths.appPath) this.modules.unshift(path.resolve(__dirname, '..')) this.modules.forEach(module => { const configPath = module + '/.cheetah.js' if (!File.exists(configPath)) { throw new Error('Missing .cheetah.js file in ' + module) } this.loadModule(configPath) // Sub modules glob.sync(module + '/js/modules/*/.cheetah.js', {}).forEach(module => this.loadModule(module)) }) } loadModule (configPath) { const folder = path.relative(this.paths.rootPath, path.dirname(configPath)) const scssFile = path.dirname(configPath) + '/sass/_main.scss' const config = require(configPath) // Add alias and symlink on @moduleName if (config.moduleName) { const jsFolder = File.exists(`${folder}/js`) ? `${folder}/js` : folder // prevent infinite symlink recursion if (!this.paths.root(jsFolder).includes(this.paths.appPath)) { fs.symlinkSync(this.paths.root(jsFolder), `${this.paths.symlinkFolder}/${config.moduleName}`) } this.moduleAlias[config.moduleName.replace('@', '@@')] = this.paths.root(jsFolder) this.relativeModuleAlias[config.moduleName] = jsFolder if (File.exists(`${folder}/images`)) { this.modulesImages.push(`${folder}/images`) } if (File.exists(`${folder}/fonts`)) { this.modulesFonts.push(`${folder}/fonts`) } } if (config.sassAutoload !== false && File.exists(scssFile)) { if (config.sassFirst === true) { this.scssModules.unshift(scssFile) } else { this.scssModules.push(scssFile) } } if (config.alias) { Object.keys(config.alias).forEach(aliasName => { this.moduleAlias[aliasName.replace('@', '@@')] = this.paths.root(folder + '/' + config.alias[aliasName]) this.relativeModuleAlias[aliasName] = folder + '/' + config.alias[aliasName] }) } } writeSassFile () { const file = new File(`${this.paths.appPath}/sass/app.scss`) let content = ` /***** * Cheetah auto generated file * DO NOT EDIT/DELETE **/\n\n` // Load framework variables const frameworkVariableFile = this.paths.relative(path.resolve(__dirname, '..') + '/sass/_variables.scss') content += `@import "${frameworkVariableFile}";\n` // Project variables if (File.exists(`${this.paths.appPath}/sass/_variables.scss`)) { content += '@import "_variables";\n' } this.scssModules.forEach(module => { content += `@import "${this.paths.relative(module)}";\n` }) file.write(content) } mix () { const _this = this const modulePaths = this.modules.reverse().map(path => (File.exists(`${path}/js`) ? `${path}/js` : path) + '/') modulePaths.pop() // remove cheetah framework path const relativeModulePaths = modulePaths.map(path => this.paths.relative(path)) for (const key in _this.relativeModuleAlias) { const path = _this.relativeModuleAlias[key] // find modulePath matching start of alias path const match = relativeModulePaths.find(replacePath => replacePath === path.slice(0, replacePath.length)) if (match) { _this.relativeModuleAlias[key] = path.slice(match.length) } } mix.webpackConfig(function (env, argv) { return { resolve: { mainFiles: ['index', 'Index'], modules: [ ...modulePaths, _this.paths.root(), 'node_modules', ], alias: { ..._this.moduleAlias, ..._this.relativeModuleAlias } }, output: { chunkFilename: 'cheetah/js/chunks/[name].[chunkhash].js' } } }) if (!mix.inProduction() && process.env.MIX_SOURCEMAPS === 'true') { mix.sourceMaps() } mix.options({ processCssUrls: false }) mix.js(`${this.paths.appPath}/js/app.js`, 'public/cheetah/js') .sass(`${this.paths.appPath}/sass/app.scss`, 'public/cheetah/css').version() // Copy assets mix.copy([path.resolve(__dirname, '../fonts'), ...this.modulesFonts], 'public/cheetah/fonts') mix.copy([path.resolve(__dirname, '../images'), ...this.modulesImages], 'public/cheetah/images') mix.copy(path.resolve(this.paths.rootPath, 'node_modules/element-ui/lib/theme-chalk/fonts'), 'public/cheetah/css/fonts') /** * Locate and override laravel-mix js Webpack rule * @todo - Should be update in TROC-2472 Pre compile cheetah framework */ mix.override((webpackConfig) => { const jsRule = webpackConfig.module.rules.find(rule => { return rule.test.toString() === /\.jsx?$/.toString() }) if (!jsRule) { console.error('ERROR - Unable to locate laravel-mix js Webpack rule') process.exit() } jsRule.exclude = /node_modules\/(?!(cheetah-framework|@imarcom)\/).*/ }) } } module.exports = Cheetah