npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@aligov/gov-venom-transformer

v0.0.3

Published

venom dsl transformed to js code

Downloads

18

Readme

@aligov/gov-venom-transformer

Venom DSL code转化为React render。

Example

    const { venomToReact, plugin } = require("@aligov/gov-venom-transformer");

    // class
    const code = `
        <div
            :class={{active : true, current: false}}
        >123</div>
    `;

    const transedCode = venomToReact(code);

转化后的结果:

    // transedCode值:

    import React from 'react';
    import _ from 'lodash';
    export default function () {
        return React.createElement('div', {
            'className': _.transform({
                active: true,
                current: false
            }, function (res, value, key) {
                if (value) {
                    res.push(key);
                }
            }, []).join(' ')
        }, '123');
    }

venom-transformer插件机制

@aligov/gov-venom-transformer库通过提供可扩展的插件机制,为我们实现venom以及可定制的DSL语法提供了便利。

目前,@aligov/gov-venom-transformer库的插件机制提供两种能力的可扩展:标签标签属性

标签属性的插件扩展机制

格式如下:

module.exports = {
    type: "prop",
    name: /\:class|className/,
    func(ctx, { value, node }) {
        // console.log("ctx:", ctx, val);
        value = value || "";

        // 支持表达式范式
        if (/^\{\{.+\}\}$/.test(value)) {
            value = value.slice(1, -1);
        }

        // key: 属性名
        // value: 该属性所对应的实际代码值
        return {
            // 如果是定制的样式,需要维持原来的属性名
            [isCustomElement(node.name)
                ? "class"
                : "className"
            ]: classSetTemplate({ classSet: value })
        };
    }
};

插件最终需要提供一个对象格式,对象里有三个属性:

type

告知transformer库是什么类型的插件,可选值:prop/tag

name

表明是对哪个属性的代码转换插件,支持字符串及正则表达式。

func

func需要是一个方法,transformer库会传对应的内部实现参数给到该方法,该方法需要实现对对应标签属性的转化,并返回一个对象,对象名为转化后的属性名字,对象值为转化后的React标签的属性值,字符串属性。

标签的插件扩展机制

格式如下:

import _ from "lodash";

const ifTemplate = _.template("((<%= condition %>)?(<%= body %>):null)");
const ifAttr = `condition`;

module.exports = {
    type: "tag",
    name: /if/i, // 忽略大小写
    func(ctx, {
        node,
        children,
        VenomCodeError
    }) {
        if(_.startsWith(children, ',')) {
            children = children.slice(1);
        }

        const condStr = node.attribs[ifAttr] || 'false'; // 条件不写默认为false

        const data = {
            condition: condStr.trim(),
            body: children,
        };

        return ifTemplate(data);
    }
};

typename跟标签属性的说明一致,主要是func有点区别:

  • func的参数里会多传一个children过来,代表该标签的children已经被转化成的js代码;
  • func方法不再需要返回对象,而是只需要返回被转化后的代码即可。

同时,在实际的插件书写过程中,可能需要用到内部的,用于方便实现上下文的context的部分机制,比如:

  • 如果需要引入一些第三方模块,那么可以使用context的defines属性,该属性是一个数组,只需要将参数组装成有一定格式的对象,然后被push进该数组,最终会生成类似import {Button} from '@alife/next';之类的代码;
  • 如果需要生成一些辅助性的通用函数,且需要借助于render的上下文环境,则需要用到:context.injectedFunctions数组,将生成的函数代码字符串push进该数组即可。

TODO

  • [x] 1、去this写法支持;
  • [x] 2、else/elseif标签支持;
  • [x] 3、编译出的代码的lodash引用去掉;
  • [x] 4、venom-transformer实现无用代码精简;
  • [ ] 5、styled-components支持;