JSPM

  • Created
  • Published
  • Downloads 26
  • Score
    100M100P100Q62335F
  • License MIT

Webpack loader for Omi.js components

Package Exports

  • omil
  • omil/libs/scripts/extension/transform
  • omil/libs/styles/extension

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (omil) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

Install

Webpack loader for Omi Single-File Components

You can use npm install or git clone it.

npm install omil --save-dev
# or
npm install eno-loader --save-dev

Configuration webpack file like this:

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']
    }]
}

Loader Demo

Why Omil Or Eno Loader?

omil is a loader for webpack that allows you to author Omi components in a format called Single-File Components.

Usage In Omi

A *.omi file is a custom file format that uses HTML-like syntax to describe a Omi component. Each *.omi file consists of three types of top-level language blocks: <template>, <script>, and <style>, and optionally additional custom blocks:

<template lang="html" name="component-name">
  <!-- replace render function -->
  <header onClick="${this.test}">${this.data.title}</header>
</template>
<script>
import style from './_oHeader.css'
export default class {
  static css = style + `p{color:red}` // it will combine scoped css,only support static css = xxx
  test(){
    console.log('Hello Eno!')
  }
  install() {
    this.data = {
      title: 'Omi'
    }
  }
}
</script>
<style>
/* scoped css */
header {
  height: 50px;
  background-color: #07c160;
  color: white;
  text-align: center;
  line-height: 50px;
  width: 100%;
}
</style>

Single-File Components Demo

It also supports JSX, if you want to do that, you only write <template> without lang="html" attribute in your component like this:

<template>
  <header onClick={this.test}>{this.data.title}</header>
</template>

JSX Demo

omil supports using non-default languages, such as CSS pre-processors and compile-to-HTML template languages, by specifying the lang attribute for a language block. For example, you install node-sass after you can use Sass for the style of your component like this:

<style lang="scss">
$height: 50px;
$color: #07c160;
header {
  height: $height;
  background-color: $color;
}
</style>

Sass Demo

Support React

You can also use an ES6 class to define a class component by omil.

<template name="ComponentName">
    <p>{this.state.title}</p>
</template>
<script>
    export default class {
        constructor(props) {
            super(props)
            this.state.title = "Eno Yao"
        }
    }
</script>
<style lang="scss">
    p {color: #58bc58;}
</style>

A higher-order component (HOC) is an advanced technique in React for reusing component logic. HOCs are not part of the React API. Here's a concrete example.

<template name="ComponentName">
    <div>
        <p>{this.state.title}</p>
    </div>
</template>
<script>
    const HOC = (props) => {
        return (WraooedComponent) => {
            return class HOC extends WeElement {
                state = {
                    name: 'Eno Yao',
                    ...props
                }
                render() {
                    return (
                        <div>
                            Hello World
                            <WraooedComponent name={{ ...this.state }} />
                        </div>
                    )
                }
            }
        }
    }
    export default HOC({
        age: 18
    })(class {
        constructor(props) {
            super(props)
            this.state = {
                title: 'Lemon'
            }
        }
        componentDidMount() {
            console.log(this)
        }
        handleChange() {}
    })
</script>
<style lang="scss">
    /* CSS */
    p {
        color: #58bc58;
    }
</style>

There are many cool features provided by omil:

  • Allows using other webpack loaders for each part of a Omi component, for example Sass for <style lang="scss"> and JSX/HTML for <template lang="html"> and ES5+ for <script type="text/babel">;
  • Allows custom blocks in a .omi or .eno file that can have custom loader chains applied to them Here Online Demo;
  • Treat static assets referenced in <style> and <template> as module dependencies and handle them with webpack loaders (Such as htm, to-string-loader);
  • Simulate scoped CSS for each component (Use Shadow DOM);
  • State-preserving hot-reloading during development.

In a nutshell, the combination of webpack and omil gives you a modern, flexible and extremely powerful front-end workflow for authoring Omi.js applications.

Thanks

Contributors


Eno Yao

License

MIT