A Webpack loader that makes it incredibly easy to import HTML-centric Web Components into your project.
Importing a Web Component that consists of a single JavaScript file isn't particularly difficult, but what about Web Components that require HTML imports which themselves import various other JavaScript, CSS, and other HTML files? This is more more complicated, and, before web-components-loader, involved a lot of manual intervention.
Simply import
or require
the HTML file for the web component you'd like to pull into your project. The loader does the following for you:
- Copies the HTML file and all of its dependencies to a namespaced location in your public/output directory. It determines the Web Component's dependencies by parsing the tree of files, starting with the root HTML file.
- Optionally minifies all related HTML, CSS, and JavaScript files.
- Makes it simple to transpile the JavaScript files associated with your Web Component, or augment them in any other way you choose, using an intutive callback mechanism.
- Watches all files associated with your Web Component and triggers a rebuild whenever any of them change (assuming the Webpack watcher is running).
- Returns the location of the public path to the root HTML file. You can then add this to an HTML import element in your project.
This will install the loader and update your package.json
file with the appropriate entry/version:
npm install web-components-loader --save-dev
All configuration lives inside of your Webpack configuration file.
All query parameters are sub-properties of the loader's query
property:
-
minify
-true
to minify all HTML, JS, and CSS files for imported Web Components -
outputPath
- This takes presedence over theouput.path
property specified elsewhere in your Webpack config. Specify this param to override the output path used by the loader when writing out your Web Component files. -
outputPublicPath
- This takes presedence over theouput.publicPath
property specified elsewhere in your Webpack config. Specify this param to override the output public path used by the loader when generating the public path returned by the loader.
If you'd like to augment/transpile the JavaScript files associated with an imported Web Compoenent, you can do so by defining a "callback" function as a sub-property of a root webComponentsLoader
object in your Webpack configuration:
webComponentsLoader: {
transformJs: jsFileContents => {
//...do something to the JS file contents string
const newContents = transpile(jsFileContents)
return newContents
}
}
This will key on any imported/required HTML files inside a web-components
directory:
// webpack.config.js
module.exports = {
entry: {
main: '/src/main.js'
},
output: {
path: '/public',
publicPath: '/public',
filename: '[name].bundle.js'
},
module: {
loaders: [
{
test: /web-components\//,
loader: 'web-components-loader'
}
]
}
}
For example:
// main.js
var htmlHrefPath = require('/src/web-components/my-component.html')
var importEl = document.createElement('link')
importEl.rel = 'import'
importEl.href = htmlHrefPath
document.body.appendChild(importEl)
{
test: /web-components\//,
loader: 'web-components-loader',
query: {
minify: true
}
}
// webpack.config.js
var babel = require('babel-core')
module.exports = {
entry: {
main: '/src/main.js'
},
output: {
path: '/public',
publicPath: '/public',
filename: '[name].bundle.js'
},
webComponentsLoader: {
transformJs: rawCode => {
return babel.transform(rawCode, {
presets: ['es2015']
}).code;
},
},
module: {
loaders: [
{
test: /web-components\//,
loader: 'web-components-loader'
}
]
}
}
This loader works very well with the React Web Component Wrapper component, which allows you to use Web Components using familiar React conventions. See the wrapper project for details, but integration may look something like this (provided you have already configured Webpack as described above):
import React, { Component } from 'react'
import webComponentHref from 'file-input-web-component/file-input.html'
import FileInput from 'web-component-wrapper'
const extensions = [
'jpg',
'jpeg'
]
class FileInputDemo extends Component {
render() {
return (
<FileInput extensions={ extensions }
onChange={ event => console.log(event.detail) }
webComponentHtmlHref={ webComponentHref }
webComponentName='file-input'
>
Select Files
</FileInput>
)
}
}
export default FileInputDemo