微内核架构

微内核架构

内核不变 core有很强的扩展性 有扩展的时候不能每次都修改内核 微内核去驱动插件运行
在这里插入图片描述
核心原理

const events = [];
const typeEnum = ['bootstrap','mount','remove']
// 一个最简单的微内核
class Core() {
	context = {}

	defaultOpts = {
		beforeBootstrap: () => {
			console.log('beforeBootstrap')
		}
		bootstraped: () => {
			console.log('bootstraped')
		}

		beforeMount: () => {
			console.log('beforeMount')
		}
		mounted: () => {
			console.log('mounted')
		}

		beforeRemove: () => {
			console.log('beforeRemov')
		}
		removed: () => {
			console.log('removed')
		}
	}
	
	constructor(ots){
		this.opts = {...this.defaultOpts, ...opts}
	}
	
	addOlugin({type,run}){
		event[type] = event[type] || []
		event[type].push(run)
	}
	// 调用
	pluginsRun(type){
		events[type]?.forEach(fn => fn(this.context))
	}
	start() { 
		this.opts.beforeBootstrap()
		this.pluginsRun('bootstrap') 
		this.opts.bootstraped()
		
		this.opts.beforeMount()
		this.pluginsRun('mount') 
		this.opts.mounted()

		this.opts.beforeRemove()
		this.pluginsRun('remove') 
		this.opts.removeed()
		// typeEnum.forEach(type => {
		//	pluginsRun(type);
		// })
	}	
	end(){
		this.opts.beforeRemove()
		pluginsRun('remove') 
		this.opts.removeed()
	}
}
export default Core;

// 用户使用
import core form 'Core'

const core = new Core({
	beforeBootstrap: () => {}
})
core.addPlugin({
	type: 'mount',
	run: (context) => {
		console.log('this mount a', context)
	}
})

core.addPlugin({
	type: 'step2',
	run: (context) => {
		console.log('this mount b', context)
	}
})
core.start()

tapable

// 安装:pnpm add tapable
const { SyncHook } = require('tapable');

const hook = new SyncHook(['arg1', 'arg2', 'arg3']);

hook.tap('flag1', (a1, a2, a3) => {
    console.log('flag1', a1, a2, a3)
})

hook.tap('flag2', (a1, a2, a3) => {
    console.log('flag2', a1, a2, a3)
})

hook.call('hello', 'this is', 'luyi')

const emit = new SyncHook();
const afterEmit = new SyncHook();

const hooks = {
    emit
}

webpack
压缩插件

// 安装:pnpm add jszip webpack-source -D --filter --@react-master
const JSzip = require('jszip');
const { RawSource } = require('webpack-sources');

class ZipPlugin {
    constructor(options) {
        this.options = options;
    }

    apply(complier) {
        let context = this;
        complier.hooks.emit.tapAsync('zipPlugin', (compilation, callback) => {
            const zip = new JSzip();
            // 生成的所有的静态文件,我都给你压缩一下
            // emit 阶段,我已经能在 compilation.assets 这里,拿到所有的 要生成的静态文件了。
            Object.keys(compilation.assets).forEach((filename) => {
                const source = compilation.assets[filename].source();
                zip.file(filename, source);
            });

            zip.generateAsync({ type: 'nodebuffer' }).then(res => {
                compilation.assets[context.options.filename] = new RawSource(res);
                callback()
            })
        })
    }
}

module.exports = ZipPlugin;
// 使用:webpack.prod.js: 
// plugins: [ new ZipPlugin({filename: 'text.html'}) ]

在这里插入图片描述

babel 插件:想要改变一些代码的能力的时候
删除代码中的console语句

function sendLog(){

}
// 1. 在外面包一层
const warpSendLog = warpped(sendLog)
const warpped = (fn) => (..rest) => {
	// do sth
	fn(...rest)
}
warpSendLog()

// 2. 对象重写
const originXHR = window.xhr;
window.xhr = function(...rest) {
	// do sth
	originXHR.call(window, ...rest)
}

// 3. consoe.log()
// 工程里面已经写了 但是不想再去修改代码
{
	// ...
	console.log(params)
}

const generate = require('@babel/generator').default;
// 我们想要在调试环境下,把 console.log() 打印出文件的具体的位置 行数、列数。
// parseAST -- traverse -- generator

const consolePlugin = function({ types }) {
    return {
        visitor: {
        // 访问者模式
            CallExpression(path) {
                const name = generate(path.node.callee).code;
                if(['console.log', 'console.info', 'console.error'].includes(name)) {
                    const { line, column } = path.node.loc.start;
                    path.node.arguments.unshift(types.stringLiteral(`filepath: ${line}, ${column}`))
                }
            }
        }
    }
}

module.exports = consolePlugin;

// 使用: .babelrc "plugins": { "console.logPlugin" }

postCss 插件

js -> babel
css -> postCss

// 主题切换 data-theme
// 基于  color: "#000000"
A {
	color: #f3f4f6
}
// 改成: 
html[data-theme = "dark"] {
	A {
		color: #111827
	}
}

// 安装插件: pnpm add postcss-nested@^6.0.1 postcss-nesting@^10.2.0 --filter @react-master
// 修改代码的两个库

// 完整代码:
const postcss = require('postcss');

const defaults = {
    functionName: 'luyi',
    groups: {},
    darkThemeSelector:  'html[data-theme="dark"]',
    nestingPlugin: null,
}

const resolveColor = (options, theme, group, defaultValue) => {
    const [light, dark] = options.groups[group] || [];
    return theme === "dark" ? dark : light;  
}

module.exports = postcss.plugin('postcss-theme-colors', (options) => {
    // 合并一下参数
    options = Object.assign({}, defaults, options);
	// 匹配字符 
    const reGroup = new RegExp(`\\b${options.functionName}\\(([^)]+)\\)`, 'g')

    return (style, result) => {

        const hasPlugin = name => 
            name.replace(/^postcss-/, '') === options.nestingPlugin ||
            result.processor.plugins.some(p => p.postcssPlugin === name)

        const getValue = (value, theme) => {
            // match: luyi(gray50);
            // group: gray50
            // --> 真实的颜色。
            return value.replace(reGroup, (match, group) => {
                return resolveColor(options, theme, group, match)
            })
        }

        style.walkDecls((decl) => {
            const value = decl.value;
            // 我去判断一下,这个 value 上,有没有 luyi(*) 这个东西
            if(!value || !reGroup.test(value)) {
                return; 
            }

            // ##FF0000 color ##0000ff
            // 这里的代码,就是一个匹配到了,value 是 luyi(*)
            // value 是 luyi(gray50); 
            // lightValue:#f9fafb;  darkValue:#030712
            const lightValue = getValue(value, 'light');
            const darkValue = getValue(value, 'dark');

            // decl 就是一个样式。color: #fff, 的 AST
            const darkDecl = decl.clone({ value: darkValue });

            let darkRule;
            // 使用 nest 插件,生成 dark 的样式
            if(hasPlugin('postcss-nesting')) {
                darkRule = postcss.atRule({
                    name: 'nest',
                    params: `${options.darkThemeSelector} &`
                })
            } else if(hasPlugin('postcss-nested')) {
                darkRule = postcss.rule({
                    params: `${options.darkThemeSelector} &`
                })
            } else {
                decl.warn(result, 'no plugins nest find')
            }
 
            if(darkRule) {
                darkRule.append(darkDecl);
                decl.after(darkRule);
            }

            const lightDecl = decl.clone({value: lightValue});
            decl.replaceWith(lightDecl);
        })
    }

})

// 使用: .postcssrc.js  "plugins": [ require(',.themePlugin')({groups})]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值