omil

📝Webpack loader for Omi.js React.js and Rax.js components 基于 Omi.js,React.js 和 Rax.js 单文件组件的 Webpack 模块加载器

Downloads
185
Stars
180

English |

Omil

omil webpack loader(SFCs) Omi

<template lang="html" name="component-name">
  <header onClick="${this.test}">${this.data.title}</header>
</template>
<script>
export default class {
  test(){ console.log('Hello Eno!') }
  install() {
    this.data = { title: 'Omi' }
  }
}
</script>
<style>
header { color: #58bc58; }
</style>

Omil

  • Omi webpack loader<style> Sass <template> jsx
  • .omi loader
  • webpack loader <style>``<template>

webpack Omi Loader Omi.js

Omi CLI

webpack Omi CLI Omi CLI

Omi CLI webpack

Omil

npm install -D omil

Visual Studio Code Omi Snippets VSC omi Omi Snippets

Omil``Omi Snippets

webpack

Omi Loader loader

// webpack.config.js
module.exports = {
  module: {
    rules: [
      // ... 
      {
        test: /\.omi|eno$/,
        loader: 'omil'
      }
    ]
  }
}

webpack

module.exports = {
  mode: 'development',
  module: {
    rules: [{
      test: /\.omi|eno$/,
      use: [{
        loader: require.resolve('omil'),
        options: {
          // Use in development, You should remove in production
          sourceMaps: 'both',
          // Config babel plugins for async, await and other many features
          plugins: [
            [
              "@babel/plugin-transform-runtime",
              {
                "absoluteRuntime": false,
                "corejs": false,
                "helpers": true,
                "regenerator": true,
                "useESModules": false
              }
            ]
          ]
        }
      }],
      // Or you can use eno-loader or omil directly
      // use: ['eno-loader']
      // use: ['omil']
    }]
  }
}

Omi Snippets

Omil VS Code Omi Snippets .omi .eno webpack .js omil JS webpack

webpack .omi Omi Snippets .js

  • src
    • Hello.omi
    • Hello.js
Hello.omi
Hello.js Hello.omijs

.omi Omi Snippets .js

  • <template> JSX name="my-test" JSX <my-text>;
  • <script> export default class { // }``export default HOC(class { // });
  • <style>
<template name="my-test">
  <div class="example">
    { this.data.msg }
  </div>
</template>

<script>
export default class {
  install () {
    this.data = {
      msg: 'Hello world!'
    }
  }
}
</script>

<style>
.example {
  color: red;
}
</style>

Omi Snippets .js omil

import { WeElement, define, h } from "omi";
class MyTest extends WeElement {
  render() {
    return h(
      "div",
      {
        class: "example"
      },
      this.data.msg
    );
  }
  install() {
    this.data = {
      msg: "Hello world!"
    };
  }
}
MyTest.css = `
.example {
  color: red;
}
`;
define("my-test", MyTest);

React

React

npm install create-react-app
# 
create-react-app my-project
# 
cd my-project
# 
npm install
#  styled-components   React 
npm install styled-components --save
#  omil React .omi  .eno  JS
npm install omil --save-dev

Omil VS Code Omi Snippets .omi .eno webpack .js omil JS webpack

React

  • name React ;
  • <template>``<script>``<style>
<template name="Component-name">
    <div>
        <p>{this.state.title}</p>
    </div>
</template>
<script>
export default class {
    constructor(props) {
        super(props)
        this.state = {
            title: "react"
        }
    }
    componentDidMount(){
        console.log('')
    }
}

</script>
<style>
p {color: #58bc58};
</style>

Omil

import { Component as WeElement, createElement as h } from "react";
import styled from "styled-components";
const StyledComponents = styled.div`
  /* CSS */
  p {
    color: #58bc58;
  }
`;

class ComponentName extends WeElement {
  render() {
    return h(
      StyledComponents,
      null,
      h("div", null, h("p", null, this.state.title))
    );
  }

  constructor(props) {
    super(props);
    this.state = {
      title: "react"
    };
  }

  componentDidMount() {
    console.log("");
  }
}

ComponentName.css = `
/* CSS */
p {color: #58bc58};
`;
export default ComponentName;

.omi HTML Omi .omi <template>``<script> <style>:

<template name="my-test">
  <div class="example">
    { this.data.msg }
  </div>
</template>

<script>
export default class {
  install () {
    this.data = {
      msg: 'Hello world!'
    }
  }
}
</script>

<style>
.example {
  color: red;
}
</style>

Omil loader ES Module Omi.js

Omil CSS HTML lang Sass

<style lang="sass">
  /* write Sass! */
</style>

<template>

.omi <template>

JSX html <script> render

name = "xxx-xxx"(Omi)

name="xxx-xxx" omi define('xxx-xxx', xxxXxx) <xxx-xxx></xxx-xxx>


  • name omi -;
  • <template>``<script>``<style>
<template name="my-test">
  <div class="example">
    { this.data.msg }
  </div>
</template>
<my-test/>
<my-test></my-test>

name = "XxxXxx"(React)

name="XxxXxx" React React.Component <XxxXxx></XxxXxx>


  • name React ;
  • <template>``<script>``<style>
<template name="MyTest">
  <div class="example">
    { this.data.msg }
  </div>
</template>
<MyTest/>
<MyTest></MyTest>

lang = "html"(Omi)

<template> JSX lang = "html"html ES6 html <div>${ this.data.msg }<div>Omil Omi-Snippets Omi.html()

<template name="my-test" lang="html">
  <div class="example">
    ${ this.data.msg }
  </div>
</template>

<script>

.omi <script>

react Omil export default class { // }``module.exports = class { // }


  • export default class { // }``class MyText {} ; export default MyText Omil Omil Snippets export default class
export default class { // }
module.exports = class { // }
class MyText { // }export default MyText
class MyText { // }module.export = MyText
<script>
export default class {
  install () {
    this.data = {
      msg: 'Hello world!'
    }
  }
}
</script>

(React)

export default HOC(class { // })
module.exports = HOC(class { // })
class MyText { // }export default HOC(MyText)
class MyText { // }module.export = HOC(MyText)
<script>
export default HOC(class {
  install () {
    this.data = {
      msg: 'Hello world!'
    }
  }
})
</script>
<template name="MyTest">
    <div><p>{this.state.title}</p></div>
</template>
<script>
// 
const HOC = (props) => {
    return (WraooedComponent) => {
        return class HOC extends WeElement {
            render() {
                return (<div><WraooedComponent name={{ ...this.props }} /></div>)
            }
        }
    }
}
export default HOC({
    age: 18
})(class {
    install () {
        this.data = {
            msg: 'Hello world!'
        }
    }
})
</script>
<style lang="scss">
p { color: #58bc58; }
</style>
<template name="MyTest">
    {HOC(<div><p>{this.state.title}</p></div>)}
</template>
<script>
// 
const HOC = (props) => {
    return (WraooedComponent) => {
        return class HOC extends WeElement {
            render() {
                return (<div><WraooedComponent name={{ ...this.props }} /></div>)
            }
        }
    }
}
export default class {
    install () {
        this.data = {
            msg: 'Hello world!'
        }
    }
}
</script>
<style lang="scss">
p { color: #58bc58; }
</style>

type="text/babel"

ES6staticES5type="text/babel"

<script>
export default class {
  static name = 'Eno Yao'
  install () {
    this.data = {
      msg: 'Hello world!'
    }
  }
}
</script>

<style>

.omi <style>

<style> Omi Web Components Vue scoped

<style>
.example {
  color: red;
}
</style>

lang = "scss"

lang = "scss" scss css

<style lang = "scss">
$color: red;
.example {
  color: $color;
}
</style>

VS Code Omi Snippets Omi .omi HTML

(HTMLCSSJavaScript )

JSX {/* comment contents here */}
HTML <!-- comment contents here -->

JSX

<template name="component-name">
  <header onClick={this.test}>{this.data.title}</header>
</template>

HTML

JSX JavaScript Omi JSXJSX UI JSX JavaScript

js

import { WeElement, define, h } from "omi";
class ComponentName extends WeElement {
  render() {
    return h(
      "div",
      {
        onClick: this.testClick
      },
      this.data.title
    );
  }
}
define("component-name", ComponentName);

JSX

Omi React JSX JavaScript JSX UI

Omi React Omil Omi Snippets

OmilOmi SnippetsOmiReact<template>``nameReactOmi-

React Omi
<template name="ComponentName"> <template name="component-name">
-

JSX

title JSX

<template name="component-name">
    <div>
        {this.data.title}
    </div>
</template>
<script>
    export default class {
        install() {
            this.data = {
                title: "Eno Yao !"
            }
        }
    }
</script>

JSX JavaScript 2 + 2user.firstName formatName(user) JavaScript

<template name="component-name">
    <div>
        <p>Name: {this.formatName(user)}</p>
        <p>Age: {9+9}</p>
    </div>
</template>
<script>
    const user = {
        firstName: 'Eno',
        lastName: 'Yao'
    };
    export default class {
        formatName(user) {
            return user.firstName + ' ' + user.lastName;
        }
    }
</script>
<template name="component-name">
    <div>
        { !0 ? '' : <p></p> }
        <h1>{ user.age > 18 && <div></div> }<h1></h1>
    </div>
</template>
<template name="component-name">
    <ul>
        {
            ['a','b','c'].map((item,index) => {
                return <li key={index}>{item}</li>
            })
        }
    </ul>
</template>

JSX

JSX JavaScript JavaScript

if for JSX JSX JSX JSX

<template name="component-name">
    <div>
        <p>{this.getGreeting(user)}</p>
        <p>{this.getGreeting()}</p>
    </div>
</template>
<script>
    const user = {
        firstName: 'Eno',
        lastName: 'Yao'
    };
    export default class {
        formatName(user) {
            return user.firstName + ' ' + user.lastName;
        }
        getGreeting(user) {
            if (user) {
                return <h1>Hello, {this.formatName(user)}!</h1>;
            }
            return <h1>Hello, Stranger.</h1>;
        }
    }
</script>

JSX

<template name="component-name">
    <div tabIndex="0"></div>
</template>

JavaScript

<template name="component-name">
    <div tabIndex="0">
        <img src={this.data.avatarUrl} />
    </div>
</template>
<script>
    export default class {
        install() {
            this.data = {
                avatarUrl: 'https://avatars1.githubusercontent.com/u/17243165?s=460&v=4'
            }
        }
    }
</script>

HTML JSX

HTML JSX
<div class> <div className>
<label for> <label htmlFor>
<div tabindex> <div tabIndex>

JavaScript

JSX JavaScript HTML React DOM camelCase HTML

JSX class className tabindex tabIndex

JSX

/> XML

<img src={this.data.avatarUrl} />
<input onChange={this.getInputValue.bind(this)} />

JSX :

<template name="component-name">
    <div>{this.data.element}</div>
</template>
<script>
    export default class {
        install() {
            this.data = {
                element: (
                    <div>
                        <h1>Hello!</h1>
                        <h2>Good to see you here.</h2>
                    </div>
                )
            }
        }
    }
</script>

JSX

Babel JSX h()

const element = <div>
    <h1 className="greeting">
        Hello, world!
    </h1>
</div>
const element = h(
  "div",
  null,
  h(
    "h1",
    {
      className: "greeting"
    },
    "Hello, world!"
  )
);

h()

// 
const element = {
  children: [{
    attributes: {className: "greeting"},
    children: ["Hello, world!"],
    nodeName: "h1",
  }],
  nodeName: "div"
}

Omi DOM

Props

<component-name myObj={{ name: 'Eno Yao' }} />

props

<template name="component-name">
    <p>{props.myObj.name}</p>
</template>

static defaultPropspropsstatic propTypesprops

<template name="component-name">
    <div>
        <p>{props.name}</p>
        <p>{props.age}</p>
    </div>
</template>
<script>
    export default class {
        static defaultProps = {
            name: 'Omi',
            age: 18
        }

        static propTypes = {
            name: String,
            age: Number
        }
    }
</script>

Omi React DOM :

  • Omi camelCase
  • JSX
<template name="component-name">
    <div>
        <button onClick={this.onClick}>Hello Omi!</button>
        <button onClick={(evt)=> {alert('Hello Omi!')}}>Hello Omi!</button>
        <button onClick={onClick}>Hello Omi!</button>
    </div>
</template>
<script>
    const onClick = (evt) => {
        alert('Hello Omi!')
    }
    export default class {
        onClick(evt) {
            alert('Hello Omi!')
        }
    }
</script>

this

JSX this JavaScript class this this.handleClick onClick this undefined

React JavaScript () onClick={this.handleClick} this

<template name="component-name">
    <div>
        <button onClick={this.onClick.bind(this)}>{this.data.title}</button>
    </div>
</template>
<script>
    export default class {
        install() {
            this.data = { title: 'Hello Omi!' }
        }
        onClick() {
            this.data.title = 'Hi Eno!'
            this.update()
        }
    }
</script>

id ID

<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>

Function.prototype.bind

React e bind

Omi

install DOM
installed DOM
uninstall DOM
beforeUpdate update
updated update
beforeRender render()
receiveProps
<template name="component-name">
    <div>Seconds: {this.data.seconds}</div>
</template>
<script>
    export default class {
        data = {
            seconds: 0
        }
        tick() {
            this.data.seconds++
            this.update()
        }
        install() {
            this.interval = setInterval(() => this.tick(), 1000)
        }
        uninstall() {
            clearInterval(this.interval)
        }
    }
</script>

Update

update :

this.update()

html attributes:

this.update(true)

data this.update()

<template name="component-name">
    <div>
        <button onClick={this.toggle.bind(this)}>Update</button>
        <p style={{display:this.data.bool?'block':'none'}}></p>
    </div>
</template>
<script>
    export default class {
        data = {
            bool: !0
        }
        toggle() {
            this.data.bool = !this.data.bool
            this.update()
        }
    }
</script>

Ref

<template name="component-name">
    <div>
        <h1 ref={e=> { this.h1 = e }} onClick={this.onClick}>Hello, world!</h1>
    </div>
</template>
<script>
    export default class {
        onClick = (evt) => {
            console.log(this.h1)
        }
    }
</script>

ref={e => { this.anyNameYouWant = e }} JS this.anyNameYouWant update

  • createRef

<template name="component-name">
    <div>
        <h1 ref={e=> { this.myRef = e }} onClick={this.onClick}>Hello, world!</h1>
    </div>
</template>
<script>
    export default class {
        myRef = e => { this.h1 = e }
        onClick = (evt) => {
            console.log(this.h1)
        }
    }
</script>

createRef

createRef import { createRef } from "omi":

<template name="component-name">
    <div>
        <h1 ref={this.myRef} onClick={this.onClick}>Hello, world!</h1>
    </div>
</template>
<script>
    import { createRef } from "omi";
    export default class {
        myRef = createRef()
        onClick = (evt) => {
            console.log(this.myRef.current)
        }
    }
</script>

Store

Store Omi

Store

path/elements/app/index.omi

<template name="my-app">
    <div>
        <p>
            Clicked: {this.use.count} times
            {' '}
            <button onClick={this.add}>+</button>
            {' '}
            <button onClick={this.sub}>-</button>
            {' '}
            <button onClick={this.addIfOdd}>
                Add if odd
            </button>
            {' '}
            <button onClick={this.addAsync}>
                Add async
            </button>
        </p>
    </div>
</template>
<script>
    export default class {
        static use = [
            { count: 'count' }
        ]

        add = () => this.store.add()
        sub = () => this.store.sub()

        addIfOdd = () => {
            if (this.use.count % 2 !== 0) {
                this.store.add()
            }
        }

        addAsync = () => {
            setTimeout(() => this.store.add(), 1000)
        }
    }
</script>
<style lang="scss">
    /* CSS */
    p {
        color: #58bc58
    };
</style>

path/src/index.js

import { render } from 'omi'
import './elements/app'

render(<my-app />, '#root', {
    data: {
        count: 0
    },
    sub() {
        this.data.count--
    },
    add() {
        this.data.count++
    },
})
  • static use path
  • store render

Store data:

{
  count: 0,
  arr: ['china', 'tencent'],
  motto: 'I love omi.',
  userInfo: {
    firstName: 'dnt',
    lastName: 'zhang',
    age: 18
  }
}

use

static use = [
  'count', //JSX  this.use[0] 
  'arr[0]', // pathJSX  this.use[1] 
  // json
  {
    //aliasJSX  this.use.reverseMotto 
    reverseMotto: [
      'motto', //path
      target => target.split('').reverse().join('')  //computed
    ]
  },
  { name: 'arr[1]' }, //{ alias: path }JSX  this.use.name 
  {
    //aliasJSX  this.use.fullName 
    fullName: [
      ['userInfo.firstName', 'userInfo.lastName'], //path array
      (firstName, lastName) => firstName + lastName //computed
    ]
  },
]

JSX :

...
...
<template>
    <div>
      <button onClick={this.sub}>-</button>
      <span>{this.use[0]}</span>
      <button onClick={this.add}>+</button>
      <div>
        <span>{this.use[1]}</span>
        <button onClick={this.rename}>rename</button>
      </div>
      <div>{this.use.reverseMotto}</div><button onClick={this.changeMotto}>change motto</button>
      <div>{this.use.name}</div>
      <div>{this.use[3]}</div>
      <div>
        {this.use.fullName}
        <button onClick={this.changeFirstName}>change first name</button>
      </div>
    </div>
</template>
...
...

alias this.store.data.xxx

store.data Path :

Proxy Path() static use path
abc abc
abc[1] abc
abc.a abc
abc abc.a
abc abc[1]
abc abc[1].c
abc.b abc.b

path use use path

CSS

props css static css shadow dom scoped style

<template name="component-name">
    <div>
        <h1>Look at my color!</h1>
    </div>
</template>
<script>
    export default class {
        static css = `h1{
            color: red;
        }`
    }
</script>

my-element h1

<template name="component-name">
    <div onClick={this.onClick}>
        <my-element css={this.myCSS} />
    </div>
</template>
<script>
    export default class {
        myCSS = `
            h1{
                color: green;
            }
        `
        onClick = () => {
            //
            this.myCSS = `
                h1{
                    color: blue;
                }
            `
            this.update()
        }
    }
</script>
color: blue!important;

ReactHOC React HOC React API React

const EnhancedComponent = higherOrderComponent(WrappedComponent);

props UI

HOC React Redux connect

Redux

<template name="Component-name">
    <div><p>{this.state.title}</p></div>
</template>
<script>
    import { connect } from 'react-redux';
    export default connect((state) => {
        return state
    })(class {
        constructor(props) {
            super(props)
            this.state = {
                title: "react"
            }
        }
    })
</script>
<style>
    p {color: #58bc58;}
</style>