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.
nuxt-custom-elements
dependency to your projectyarn add nuxt-custom-elements # or npm install nuxt-custom-elements
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'
}
}
}
]
}
]
}]
]
}
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
|
webpackOutput
OptionThe webpack output.filename
is has default two outputs.
With modern
entry files named with:
[name].client.js
[name].modern.js
Or simple client
build:
[name].js
You can override the pattern with own function or pattern (string) e.g. [name].[hash].js
.
{
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'
}
}
}
}
{
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
|
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. |
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.
$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')
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
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>
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 anSPA
mode or useclient-only
tag.
yarn install
or npm install
npm run start:build
http://127.0.0.1:3000/
in Browseror look here
yarn install
or npm install
npm run dev
Author: GrabarzUndPartner
Source Code: https://github.com/GrabarzUndPartner/nuxt-custom-elements
#vuejs #vue #javascript