Publish your components as a vue-custom-element standalone build

nuxt-custom-elements

Publish your Components as a vue-custom-element standalone build.

nuxt-custom-elements is a Nuxt.js module that uses vue-custom-element to publish single components as custom element / web-component.

šŸ“– Release Notes

Setup

  1. Add nuxt-custom-elements dependency to your project
yarn add nuxt-custom-elements # or npm install nuxt-custom-elements
  1. Add nuxt-custom-elements to the modules section of nuxt.config.js
{
  modules: [

    ['nuxt-custom-elements', {
        analyzer: true,
        modern: true,
        polyfill: true,
        entries: [

          // Entry with single tag.
          {
            name: 'CustomElementsOne',
            tags: [
              {
                name: 'ComponentOne',
                path: 'Path to ComponentOne',
                options: {
                  props: ['prop1', 'prop2'],
                }
              }
            ]
          },
          {
            name: 'CustomElementsTwo',
            tags: [
              {
                name: 'ComponentTwo',
                path: 'Path to ComponentTwo',
                options: {
                  props: {
                    'prop1': 'Value 1',
                    'prop2': 'Value 2'
                  }
                }
              }
            ]
          },

          // Entry-Bundle with two tags.
          {
            name: 'CustomElementsBundle',
            tags: [
              {
                async: true,
                name: 'ComponentOne',
                path: 'Path to ComponentOne',
                options: {
                  props: ['prop1', 'prop2']
                }
              },
              {
                async: true,
                name: 'ComponentTwo',
                path: 'Path to ComponentTwo',
                options: {
                  props: {
                    'prop1': 'Value 1',
                    'prop2': 'Value 2'
                  }
                }
              }
            ]
          }
        ]
      }]

  ]
}

Options

Property Type Description Default Value Required
buildDir String Sets destination for custom-element build. undefined
analyzer Boolean, Object Sets true for default module config or object with custom webpack-bundle-analyzer configuration false false
modern Boolean Important: To use modern, modern must be active in nuxt.
Sets false for only client build.
Default using nuxt option nuxt.options.modern === 'client'. undefined false
polyfill Boolean For cross-browser compatibility (IE9+) use Custom Elements polyfill. false false
entries Array Defines the component bundles.

Components can be distributed in separate end points.
Allows the targeted distribution of resources. | null | true |
| webpackOutput | Object | Defines the webpack output options.
filename, publicPath | See webpackOutput Example | false |

Important webpackOutput Option

The webpack output.filename is has default two outputs.

With modern entry files named with:

  • client: [name].client.js
  • modern: [name].modern.js

Or simple client build:

  • client: [name].js

You can override the pattern with own function or pattern (string) e.g. [name].[hash].js.

Override example with function:
{
  webpackOutput: {
    publicPath: '/',
    filename: (chunk, webpackConfig, moduleOptions) => {
      if (moduleOptions.modern) {
        if (webpackConfig.name === 'modern') {
          return '[name].modern.js'
        } else {
          return '[name].client.js'
        }
      } else {
        return '[name].js'
      }
    }
  }
}

Entry

{
  name: 'EndpointName',
  tags: [
    // Simplified props, definition only
    {
      async: false,
      name: 'TagName',
      path: 'component path',
      options: {
        props: ['prop1', 'prop2'],
        shadow: false
      }
    },
    // Extended props, with default values and with native shadow dom
    {
      async: true,
      name: 'AnotherTagName',
      path: 'component path',
      options: {
        props: {
          prop1: false,
          prop2: true
        },
        shadow: true
      }
    }
  ]
}
Property Type Description Default Value Required
name String Name of the endpoint.
Value will be converted to ParamCase later.

Example: EndpointName -> endpoint-name | null | true |
| tags | Array | Tag Definitions. | [] | true |

Tag

Property Type Description
name String Name of the Tag.
Value will be converted to ParamCase later.

Example: TagName -> tag-name |
| async | Boolean | Components are loaded asynchronously.

If there is more than one entry the async will lead to unwanted webpack chunk splitting. |
| path | String | Path to the component to be called by the tag. |
| options | Object | Options from Options. |

Tag Options

Property Type Description Default Value
shadow Boolean Sets true if Native Shadow-Dom is to be used. false
props Array, Object Use array for prop definition and object for default values. []

āš ļø Important: CSS from the SingleFile (.vue) cannot be used, this will be included by the vue-loader by using the style-loader.

For shadow CSS the vue-custom-element property shadowCSS must be used.

Plugins

$registerCustomElementsEntry

Registers the specified name containing custom elements during development.
The name can be specified in Pascal/Param-Case.

Case examples: ComponentAppAbstract or component-app-abstract.

Use in the Vue context.

this.$registerCustomElementsEntry('Name')

Usage

First of all, components that are to be exported as custom elements must be specified in the nuxt.config in the module settings.

{
  modules: [
    [
      'nuxt-custom-elements', {
        polyfill: true,
        entries: [
          {
            name: 'ComponentAppAbstract',
            tags: [
              {
                name: 'CustomElementAppAbstract',
                path: '@/components/apps/AppAbstract',
                options: {
                  props: {
                    basePath: '/'
                  }
                }
              }
            ]
          }
        ]
      }
    ]
  ]  
}

Finally a nuxt generate or nuxt build must be executed. The custom-element build is located in the nuxt-generate directory (generate.dir). e.g. dist/nuxt-custom-elements

Integrations

Vue Router & Vuex Store

To use Vuex Store or Vue Router, the store or router must be referenced on the top component (endpoint).

All child components have access to this.$router and this.$store.

<script>

import Vue from 'vue'
import Vuex from 'vuex'
import VueRouter from 'vue-router'

Vue.use(Vuex)
Vue.use(VueRouter)

// store

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  }
})

// router

const router = new VueRouter({
  routes: [...]
})

export default {

  store,

  router,

  props: {...},

  mounted() {
    console.log(this.$store, this.$router)
  }

}

</script>

Development custom-element on the fly

To develop a custom component in dev mode, the endpoint must be called in the create method of a page.

<script>
export {
  data () {
    return {
      base: '/', // router base
      data: {
        foo: 'bar'
      }
    }
  },
  created () {
    this.$registerCustomElementsEntry('ComponentAppHistory')
  }
}
</script>

The custom elements contained in the page template can now be called.

<template>
  <div>
    <client-only>
      <script type="text/javascript">
        <!-- Used in example/custom-element/utils/router.js:22 -->
        window.CUSTOM_ELEMENT_ROUTER_BASE = '{{ base }}';
      </script>
      <custom-element-app-history
        class="application"
      >
        <script
          type="application/json"
          v-text="data"
        ></script>
      </custom-element-app-history>
    </client-only>
  </div>
</template>

Custom tags must be excluded from the SSR build.
Use an SPA mode or use client-only tag.

Preview

  1. Clone this repository
  2. Install dependencies using yarn install or npm install
  3. Build and start with express npm run start:build
  4. Open endpoints via http://127.0.0.1:3000/ in Browser

or look here

Development

  1. Clone this repository
  2. Install dependencies using yarn install or npm install
  3. Start development server using npm run dev

Download Details:

Author: GrabarzUndPartner

Source Code: https://github.com/GrabarzUndPartner/nuxt-custom-elements

#vuejs #vue #javascript

Publish your components as a vue-custom-element standalone build
9.30 GEEK