postcss插件开发:全局添加namespace

文章目录

      • postcss
      • 开发postcss插件
      • 单元测试
      • 打包上传到npm
      • 结语

好久不见~

postcss插件开发:全局添加namespace_第1张图片

话不多说

postcss

一款css处理的平台,官方文档提供非常全面的api,可以对css的定义,修饰,语句进行定制。

常见很多postcss基础的插件,在官方git仓库中都有提到:https://github.com/postcss/postcss

开发postcss插件

我这边有一个需求,是希望可以全局添加一个namespace。

就想到可以添加postcss插件,为每条选择器添加自己的头部。

话不多说,上代码:

const postcss = require('postcss');

module.exports = postcss.plugin('postcss-global-namespace', opts => {
	
	opts = opts || {};
	let globalClsName = opts.hasOwnProperty('globalClsName') && opts.globalClsName
  return root => {
		root.walk(node => {
			let selectorArr = (node.selector || '').split(',')
			return node.selector = ((selectorArr || []).map((itm) => {
				if (itm.match(/^(\s*)(html|body)(\s*)$/)) {
					return itm
				}
				return globalClsName + ' ' + itm
			}).join(','))
		})

	};

})

usage:

// postcssrc.js

module.exports = {
  "plugins": {
    ...
    "postcss-global-namespace": {
      globalClsName: '.global-name-hahahaha'
    }
  }
}

globalClsName是我在postcss插件定义时,添加的props。传入我的postcss-global-namespace之后,我通过root.walk(node,() => ),拿到每一条选择器定义:

// 这就是一条定义
.banner, .banner1 {
	color: #abccfc #212231;
	font-size: 1.5em/2;
	font-weight: light;
	position: fixed 0 0;
	size: 100% 48px;
}

对每一条定义按照,分割开,依次为每一个原子定义添加头部。

output:

.global-name-hahahaha .banner, .global-name-hahahaha .banner1 {
	color: #abccfc #212231;
	font-size: 1.5em/2;
	font-weight: light;
	position: fixed 0 0;
	size: 100% 48px;
}

本插件还对html和body标签做了进行了不处理

if (itm.match(/^(\s*)(html|body)(\s*)$/)) {
					return itm
				}

默认用户会将.global-name-hahahaha添加到html/body标签,而且业务代码都是从body标签的内部第一个标签开始,所以并没有处理~

单元测试

插件自己最好自带单元测试。

自己写两套css input和output的实例,然后用工具对比就好啦~

var expect = require('chai').expect;

...

describe('test about global classname for css nodes', function() {
  it('test global namespace', function() {
    run(inCase, outCase, {globalClsName: '.global-namespace'})
  });
});

function run(input, output, opts) { 
    return postcss([postcssGlobalNameSpace(opts) ]).process(input) 
    .then(result => { 
     expect(result.css).equal(output); 
     expect(result.warnings().length).equal(0); 
		})
		.catch(err => {
			console.log(err)
		}); 
} 

打包上传到npm

结语

postcss插件开发非常,简单便捷,灵活

实际上不只是去修改某个css语法,还可以根据自身项目要求,校验某个语法,非常好用的一款插件。

你可能感兴趣的:(css)