@a-la/jsx 中文文档教程

发布于 5年前 浏览 22 项目主页 更新于 3年前

@a-la/jsx

npm 版本构建状态Node.js CI

@a-la/jsx< /code> 是 ÀLamode 和其他包的 JSX 转换。

yarn add @a-la/jsx
npm i @a-la/jsx

Table Of Contents

API

该包可通过导入其默认函数获得:

import jsx from '@a-la/jsx'

<ins>jsx</ins>(
  string: string,
  config=: !Config,
): <i>string</i>

将转译后的 JSX 代码返回到 h pragma 调用中。

  • string* string: The code to transform.
  • config <a href="#type-config" title="Options for the program.">!Config</a> (optional): Configuration object.

Config:程序的选项。

NameTypeDescriptionDefault
quoteProps(boolean | string)Whether to surround property names with quotes. When the dom string is passed, it will only quote props for invoking html components, i.e. those that start with a lowercase letter (this is required for Closure Compiler when not providing externs to elements).false
prop2classbooleanIf a property name starts with a capital letter, the className of the VNode will be updated.false
classNames(!Array<string> | !Object)The list of properties to put into the className property.-
renameMap!Object<string, string>How to rename classes (only applies to prop2class and classNames).-
styles!Object<string, string>Rename these properties into styles, e.g., <el border-top="1px"> will become &lt;el style="border-top:1px">. The keys must be property names, and the values are either booleans, or a string that should be used for renaming of the CSS property, such as { borderTop: 'border-top' }. Check out @a-la/styles that provides such a map.-
warn(warning: string) => ?The function to receive warnings, e.g., when destructuring of properties is used on dom elements (for Closure Compiler).-
import { readFileSync } from 'fs'
import jsx from '@a-la/jsx'

const code = readFileSync('example/Component.jsx', 'utf8')
const res = jsx(code)
console.log(res)

给定组件的源代码:

import RichTextArea from 'richtext'

const Title = <title>Example</title>

export const Component = ({
  align = 'right', tabs, img,
}) => {
  const props = {
    class: 'example',
    id: 'id',
  }
  return <div onClick={(e) => {
    e.preventDefault()
    alert('Hello World')
    return false
  }} role="aria-button">
    <Title/>
    <RichTextArea dynamic />
    {tabs.map((tab, i) => <span key={i}>{tab}</span>)}
    <p {...props} align={align}>
      Hello World!
      {img && <img src={img}/>}
    </p>
  </div>
}

得到以下结果:

import RichTextArea from 'richtext'

const Title = h('title',{},`Example`)

export const Component = ({
  align = 'right', tabs, img,
}) => {
  const props = {
    class: 'example',
    id: 'id',
  }
  return h('div',{onClick:(e) => {
    e.preventDefault()
    alert('Hello World')
    return false
  }, role:"aria-button"},
    h(Title),
    h(RichTextArea,{dynamic:true}),
    tabs.map((tab, i) => h('span',{key:i},tab)),
    h('p',{...props,align:align},
      `Hello World!`
      ,img && h('img',{src:img}),
    ),
  )
}

The Transform

transform 是 Babel 实现 JSX transform 的 Reg-Exp 替代品。 我们不知道任何其他替代方案,但是这种方法提供了一个轻量级的解决方案,用于转换 JSX 语法以进行前端和后端渲染以及静态网站生成。 lit-html 基于模板字符串,不提供在 .jsx 文件中启用的 html 高亮显示。 这使得 JSX 成为现代 HTML 模板的标准。 使用 JSX 的服务不一定是反应页面,因此转换可用于服务器端呈现,这将始终需要使用模板提供 HTML。 要在 Node.js 中实现这一点,可以使用 ÀLaMode 转译器,而这个包只导出一个函数来执行代码的翻译。

importexport 语句将在转译时暂时被注释掉,否则 V8 会在尝试检测 JSX 语法开始的位置时抛出错误(请参阅方法)。

Classes

可以让转译器提取属性名称并将它们添加到 className 属性中。 如果这样的属性已经存在,它将被更新。 如果没有,它将被创建。 此外,当 prop2class 属性被设置时,任何以大写字母开头的属性也将被添加到类列表中。 最后,如果您传递重命名映射,类将根据它进行更新。

要转换的组件:

export default function Classes() {
  return (<div Example hello world />)
}

设置:

import { readFileSync } from 'fs'
import jsx from '../src'

const code = readFileSync('example/classes.jsx', 'utf8')
const res = jsx(code, {
  prop2class: true,
  classNames: ['hello', 'world'],
  renameMap: {
    hello: 'hi',
  },
})
console.log(res)

输出:

export default function Classes() {
  return (h('div',{  className:'Example hi world' }))
}

The Dynamic Method

这个包将尝试创建一个新脚本(从 vm 模块导入)来找出 JSX 语法失败的地方(第一个 <)。 因此找到开始标签的位置并提取标签的名称。 通过标签名,可以找到结束标签名,解析里面的内容。

/Users/zavr/a-la/jsx/test/fixture/Component.jsx:2
  <div className={className}>
  ^

SyntaxError: Unexpected token <
    at createScript (vm.js:80:10)
    at Object.runInThisContext (vm.js:139:10)
    at Module._compile (module.js:617:28)
    at Object.Module._extensions..js (module.js:664:10)
    at Module.load (module.js:566:32)
    at tryModuleLoad (module.js:506:12)
    at Function.Module._load (module.js:498:3)
    at Function.Module.runMain (module.js:694:10)
    at startup (bootstrap_node.js:204:16)
    at bootstrap_node.js:625:3

Limitations

  • [ ] Cannot use <> in functions, and {} in comments e.g., js const C = ({ items }) => <div> {items.map((i, j) => { // stop when { 10 }: if (j > 10) return return <span>{i}</span> })} </div>
  • [ ] Cannot define components in export default { }, or use anything with }, e.g., js export default { 'my-component'() { return <div>Hello World</div> }, nested: { val: true }, } </div>

Art Deco© Art Deco™ for À La Mode 2020

@a-la/jsx

npm versionBuild statusNode.js CI

@a-la/jsx is The JSX transform For ÀLamode And Other Packages.

yarn add @a-la/jsx
npm i @a-la/jsx

Table Of Contents

API

The package is available by importing its default function:

import jsx from '@a-la/jsx'

<ins>jsx</ins>(
  string: string,
  config=: !Config,
): <i>string</i>

Returns the transpiled JSX code into h pragma calls.

  • string* string: The code to transform.
  • config <a href="#type-config" title="Options for the program.">!Config</a> (optional): Configuration object.

Config: Options for the program.

NameTypeDescriptionDefault
quoteProps(boolean | string)Whether to surround property names with quotes. When the dom string is passed, it will only quote props for invoking html components, i.e. those that start with a lowercase letter (this is required for Closure Compiler when not providing externs to elements).false
prop2classbooleanIf a property name starts with a capital letter, the className of the VNode will be updated.false
classNames(!Array<string> | !Object)The list of properties to put into the className property.-
renameMap!Object<string, string>How to rename classes (only applies to prop2class and classNames).-
styles!Object<string, string>Rename these properties into styles, e.g., <el border-top="1px"> will become &lt;el style="border-top:1px">. The keys must be property names, and the values are either booleans, or a string that should be used for renaming of the CSS property, such as { borderTop: 'border-top' }. Check out @a-la/styles that provides such a map.-
warn(warning: string) => ?The function to receive warnings, e.g., when destructuring of properties is used on dom elements (for Closure Compiler).-
import { readFileSync } from 'fs'
import jsx from '@a-la/jsx'

const code = readFileSync('example/Component.jsx', 'utf8')
const res = jsx(code)
console.log(res)

Given the component's source code:

import RichTextArea from 'richtext'

const Title = <title>Example</title>

export const Component = ({
  align = 'right', tabs, img,
}) => {
  const props = {
    class: 'example',
    id: 'id',
  }
  return <div onClick={(e) => {
    e.preventDefault()
    alert('Hello World')
    return false
  }} role="aria-button">
    <Title/>
    <RichTextArea dynamic />
    {tabs.map((tab, i) => <span key={i}>{tab}</span>)}
    <p {...props} align={align}>
      Hello World!
      {img && <img src={img}/>}
    </p>
  </div>
}

The following result is achieved:

import RichTextArea from 'richtext'

const Title = h('title',{},`Example`)

export const Component = ({
  align = 'right', tabs, img,
}) => {
  const props = {
    class: 'example',
    id: 'id',
  }
  return h('div',{onClick:(e) => {
    e.preventDefault()
    alert('Hello World')
    return false
  }, role:"aria-button"},
    h(Title),
    h(RichTextArea,{dynamic:true}),
    tabs.map((tab, i) => h('span',{key:i},tab)),
    h('p',{...props,align:align},
      `Hello World!`
      ,img && h('img',{src:img}),
    ),
  )
}

The Transform

The transform is the Reg-Exp alternative to Babel's implementation of the JSX transform. We're not aware of any other alternatives, however this approach provides a light-weight solution for transforming JSX syntax for front-end and back-end rendering and static website generation. The lit-html is based on template strings, and does not provide html highlighting which is enabled in .jsx files. This makes JSX the standard of modern HTML templating. The service using the JSX does not have to be a react page, so that the transform can be used to server-side rendering which will always require serving HTML using a template. To achieve this in Node.js, the ÀLaMode transpiler can be used, whereas this package just exports a single function to perform the translation of the code.

The import and export statements will be temporally commented out when transpiling, otherwise V8 will throw an error when trying to detect where JSX syntax starts (see the method).

Classes

It's possible to make the transpiler extract property names and add them into the className property. If such property already exists, it will be updated. If it doesn't, it will be created. Moreover, when prop2class property is set, any property that starts with a capital letter will also be added to the class list. Finally, if you pass a rename map, the classes will be updated according to it.

The component to transpile:

export default function Classes() {
  return (<div Example hello world />)
}

The setup:

import { readFileSync } from 'fs'
import jsx from '../src'

const code = readFileSync('example/classes.jsx', 'utf8')
const res = jsx(code, {
  prop2class: true,
  classNames: ['hello', 'world'],
  renameMap: {
    hello: 'hi',
  },
})
console.log(res)

The output:

export default function Classes() {
  return (h('div',{  className:'Example hi world' }))
}

The Dynamic Method

This package will try to create a new Script (an import from the vm module) to find out where JSX syntax failed (first <). The location of the opening tag is therefore found out and the name of the tag extracted. With the name of the tag, the closing tag name can be found, and the contents inside parsed.

/Users/zavr/a-la/jsx/test/fixture/Component.jsx:2
  <div className={className}>
  ^

SyntaxError: Unexpected token <
    at createScript (vm.js:80:10)
    at Object.runInThisContext (vm.js:139:10)
    at Module._compile (module.js:617:28)
    at Object.Module._extensions..js (module.js:664:10)
    at Module.load (module.js:566:32)
    at tryModuleLoad (module.js:506:12)
    at Function.Module._load (module.js:498:3)
    at Function.Module.runMain (module.js:694:10)
    at startup (bootstrap_node.js:204:16)
    at bootstrap_node.js:625:3

Limitations

  • [ ] Cannot use <> in functions, and {} in comments e.g., js const C = ({ items }) => <div> {items.map((i, j) => { // stop when { 10 }: if (j > 10) return return <span>{i}</span> })} </div>
  • [ ] Cannot define components in export default { }, or use anything with }, e.g., js export default { 'my-component'() { return <div>Hello World</div> }, nested: { val: true }, } </div>

Art Deco© Art Deco™ for À La Mode 2020

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文