UNPKG

csmall-theme

Version:

自用资源,不负责对外的使用解答

119 lines (109 loc) 4.06 kB
const fs = require('fs'); const path = require('path'); const {ConcatSource} = require("webpack-sources"); const pluginName = 'ThemeSwitchPlugin'; let themePathPlace = ''; let themeDir = ''; let themeUriPath = ''; function SwitchTheme(config){ if(config.theme.exists){ themePathPlace = config.themePathPlace; } themeDir = config.publicPath + config.cssDir; themeUriPath = themeDir.slice(1); this.distPath = config.path.dist; this.themeKey = config.theme.key; this.version = config.version; this.onlyBuildTheme = config.onlyBuildTheme; this.cleanExpiredCompiled = config.cleanExpiredCompiled; this.comitBlacklist = ['.htm', '.js']; this.themeExists = config.theme.exists; } function rewriteCssLink(html, version){ const collected = []; const cssFiles = []; let matchCss; const regCss = new RegExp('<link [^>]*href="/?' + themeUriPath + themePathPlace + '/([^>]*).css"[^>]*>', 'g'); while((matchCss = regCss.exec(html))){ collected.push(matchCss); } for(let l = collected.length, i = 0; i < l; i++){ let item = collected[i]; html = html.replace(item[0], ''); cssFiles.push(item[1].replace('-' + version, '')); } let headPos = html.indexOf('<title>'); return html.slice(0, headPos) + '<meta name="css-keys" path="' + themeUriPath.slice(0, -1) + '" keys="' + cssFiles.join(',') + '">' + html.slice(headPos); } //同步删除指定目录下的所前目录和文件,包括当前目录 function rmdirSync(targetPath){ try{ let files = []; if(fs.existsSync(targetPath)){ files = fs.readdirSync(targetPath); files.forEach(function(file){ let curPath = targetPath + "/" + file; if(fs.statSync(curPath).isDirectory()){ // recurse if(!rmdirSync(curPath)){ return false; } }else{ // delete file fs.unlinkSync(curPath); } }); fs.rmdirSync(targetPath); } }catch(e){ console.error(" Remove director fail! path=" + targetPath + " errorMsg:" + e); process.exit(1); } return true; } SwitchTheme.prototype = { apply(compiler){ compiler.hooks.emit.tap(pluginName, compilation => { if(this.onlyBuildTheme){ this.removeOtherAssets(compilation.assets); } if(this.themeExists){ this.rewriteAsyncLoadCssPath(compilation.assets); } //清除掉旧文件 if(this.cleanExpiredCompiled){ console.info('\n===clear old compiled==='); }else{ console.info('\n===clear old theme==='); } rmdirSync(this.distPath + (this.cleanExpiredCompiled? '': '/' + themeDir + '/' + this.themeKey)); }); }, removeOtherAssets(assets){ Object.keys(assets).map(fn => { if(this.comitBlacklist.includes(path.extname(fn))){ delete assets[fn]; } }); }, rewriteAsyncLoadCssPath(assets){ Object.keys(assets).map(fn => { switch(fn.slice(fn.lastIndexOf('.') + 1)){ case 'js': let regExp = new RegExp('\/' + themePathPlace + '\/', 'g'); assets[fn] = new ConcatSource( assets[fn].source().replace(regExp, '\/"+window[\'_THEME_PATH\']+"\/') ); break; case 'css': let js = assets[fn]; delete assets[fn]; fn = fn.replace('/' + themePathPlace + '/', '/' + this.themeKey + '/'); assets[fn] = js; break; case 'htm': assets[fn] = new ConcatSource(rewriteCssLink(assets[fn].source(), this.version)); break; } }); } }; module.exports = SwitchTheme;