1

In my current project we're building native web components according to the v1 specification which we're currently webpacking in a single bundle comp-webcomponents.js.

This is the entry point file for our current bundle:

import 'document-register-element';
import 'nodelist-foreach-polyfill';
import 'babel-polyfill';

import 'components/tabs/comp-tabs';
import 'components/workspace-switcher/workspace-switcher';
import 'components/table/comp-table';
import 'components/date/comp-date';
import 'components/datepicker/comp-datepicker';
import 'components/datetime/comp-datetime';
import 'components/decimal/comp-decimal';
import 'components/number/comp-number';
import 'components/editor/comp-editor';
import 'components/time/comp-time';
import 'components/input/comp-input';
import 'components/button/comp-button';
import 'components/toggle-button/comp-toggle-button';
import 'components/yearmonth/comp-yearmonth';

Some of the components have vendor dependencies like jQuery, datatables.net, jquery-ui, lodash etc.

Question 1: What steps would be required so other projects can selectively import single webcomponents?

Something like

import { compTable, compYearmonth } from "@comp-webcomponents";

Question 2: What would be required to make each web component an npm package which can be installed using a single namespace?

Something like

npm install --save @comp-webcomponents/comp-div

Example component:

class CompDiv extends HTMLDivElement {
  constructor(...args) {
    const self = super(...args);
    self.property = null;
    return self;
  }
  connectedCallback() {
    console.log('connected CompDiv');
  }
}

customElements.define('comp-div', CompDiv, { extends: 'div' });

Even links or other useful resources are highly appreciated!

connexo
  • 53,704
  • 14
  • 91
  • 128

1 Answers1

2

I use Typescript with my web component projects. I have all my individual components in a src folder, and I create an index.ts file in there as well and export each component individually.

export {compDiv, compTable, comeYearmonth} from './compDiv';
export {example} from './example';

You can read about it and follow the directions in this tutorial to try. After I build with tsc and my type declarations are in my dist folder, I publish to NPM. Once published, I can import like so:

import { compTable, compYearmonth } from "@comp-webcomponents";

You can also look into Stencil, a compiler that generates reusable web components.

This is what my web component looks like:

export class ExampleComponent extends HTMLElement {

  constructor() {
    super();

    const shadowRoot = this.attachShadow({ mode: 'open' });
shadowRoot.appendChild(ExampleComponent.template.content.cloneNode(true));        
    }

    connectedCallback() {
      console.log('hello');
    }
}

    ExampleComponent.tag = 'example-component';
    ExampleComponent.template = document.createElement('template');
    ExampleComponent.template.innerHTML = `
    <template>
      <p>hello</p>
    </template>
    `;
    customElements.define(ExampleComponent.tag, ExampleComponent);
Catherine Monroe
  • 153
  • 1
  • 3
  • 9
  • We're not using Typescript, interesting approach nonetheless. Today I tried to change the `comp-webcomponents.js` just like you're suggesting: Instead of `import 'components/tabs/comp-tabs';` I changed that line to `export { compTabs } from 'components/tabs/comp-tabs';`. That kind of worked, but when I had changed all the import statements to export statements, I always received the whole bundle even though in a new file I only did `import { compTabs } from './comp-webcomponents';`. – connexo Aug 27 '18 at 18:46
  • How would I have to adjust the example component to make this approach work? – connexo Aug 27 '18 at 18:48
  • Stencil is not an option for our project since 95% of our web components are customized built-ins, which neither Polymer nor Stencil supports. – connexo Aug 27 '18 at 18:49
  • Hmm are using export default in each individual component? – Catherine Monroe Aug 27 '18 at 19:26
  • The components look like the one I've shown in the question. – connexo Aug 27 '18 at 21:15
  • Can you show where your `customElements.define()` calls take place in your configuration? https://stackoverflow.com/questions/52056674/how-to-make-a-class-based-web-component-side-effect-free – connexo Aug 28 '18 at 16:10
  • I updated my answer to show a sample configuration of my web components. I actually think you need to call Super() – Catherine Monroe Aug 29 '18 at 16:34
  • We're not using Javascript to create the actual elements, and also most of our components are customized built-ins, which for compatibility reasons have `...args` passed to `super()`. If you inspect closely, I am calling super. – connexo Aug 29 '18 at 16:38