From 1cda471818c6d3ae7cfbc76a4f1e93d2d87559f2 Mon Sep 17 00:00:00 2001 From: Thomas Allmer Date: Thu, 24 Oct 2019 00:59:49 +0200 Subject: [PATCH] chore: apply prettier to all *.md files --- CONTRIBUTING.md | 2 +- README.md | 45 +- docs/README.md | 13 +- docs/about/README.md | 5 +- docs/about/blog.md | 8 +- docs/about/rationales.md | 8 +- docs/automating/README.md | 8 +- docs/building/README.md | 7 + docs/codelabs/README.md | 2 +- docs/developing/README.md | 8 + docs/developing/best-practices.md | 2 +- docs/developing/code-examples.md | 117 +++--- docs/developing/lit-html.md | 5 +- docs/developing/routing.md | 2 +- docs/developing/types.md | 33 +- docs/faq/README.md | 11 +- docs/faq/component-libraries.md | 16 + docs/faq/rerender.md | 38 +- docs/faq/unit-testing-custom-events.md | 25 +- docs/faq/unit-testing-init-error.md | 8 +- docs/guide/README.md | 3 + docs/linting/README.md | 4 + docs/linting/linting-types.md | 3 + docs/publishing/README.md | 4 + docs/testing/README.md | 2 +- packages/building-rollup/README.md | 7 +- packages/building-utils/README.md | 2 +- packages/building-webpack/README.md | 118 +++--- packages/chai-a11y-axe/README.md | 53 ++- packages/codelabs/README.md | 3 +- packages/codelabs/src/example-codelabs/a.md | 11 +- packages/codelabs/src/example-codelabs/b.md | 11 +- packages/create/README.md | 16 +- packages/demoing-storybook/README.md | 48 ++- packages/demoing-storybook/demo/README.md | 2 + packages/es-dev-server/README.md | 383 ++++++++++-------- packages/eslint-config/README.md | 6 +- packages/import-maps-generate/README.md | 31 +- packages/import-maps-resolve/README.md | 5 +- packages/karma-esm/README.md | 56 ++- packages/prettier-config/README.md | 9 +- packages/rollup-plugin-index-html/README.md | 56 ++- packages/semantic-dom-diff/README.md | 2 +- packages/testing-helpers/README.md | 76 +++- packages/testing-karma-bs/README.md | 9 +- packages/testing-karma/README.md | 34 +- packages/testing-wallaby/README.md | 7 +- packages/testing/README.md | 2 +- packages/webpack-import-meta-loader/README.md | 8 +- packages/webpack-index-html-plugin/README.md | 55 ++- 50 files changed, 837 insertions(+), 552 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5481f471..ac82a216 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -31,7 +31,7 @@ Make your changes to the project. Commits are linted using precommit hooks, mean # Committing Your Changes Open WC uses [commitlint](https://github.com/marionebl/commitlint) to standardize commit messages in the project. Commit messages must follow the [conventional commit format](https://www.conventionalcommits.org/en/v1.0.0-beta.2/) -Open WC uses package name as scope. So for example if you fix a *terrible bug* in the package `@open-wc/testing`, the commit message should look like this: +Open WC uses package name as scope. So for example if you fix a _terrible bug_ in the package `@open-wc/testing`, the commit message should look like this: ``` fix(testing): fix terrible bug diff --git a/README.md b/README.md index 8b242e0e..7e34c653 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@

Open-wc Logo

# Open Web Component Recommendations + Open Web Components provides a set of defaults, recommendations and tools to help facilitate your web component project. Our recommendations include: developing, linting, testing, building, tooling, demoing, publishing and automating. [![CircleCI](https://circleci.com/gh/open-wc/open-wc.svg?style=shield)](https://circleci.com/gh/open-wc/open-wc) @@ -8,6 +9,7 @@ Open Web Components provides a set of defaults, recommendations and tools to hel [![Renovate enabled](https://img.shields.io/badge/renovate-enabled-brightgreen.svg)](https://renovatebot.com/) ## Usage + ```bash # in a new or existing folder: npm init @open-wc @@ -15,6 +17,7 @@ npm init @open-wc ``` This will kickstart a menu guiding you through all available actions. + ``` $ npm init @open-wc npx: installed 14 in 4.074s @@ -25,44 +28,46 @@ What would you like to do today? ``` ## Homepage + For more details please visit us at [open-wc.org](https://open-wc.org). ## Packages -| Package | Version | Description | -|------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [building-rollup](./packages/building-rollup) | [![building-rollup](https://img.shields.io/npm/v/@open-wc/building-rollup.svg)](https://www.npmjs.com/package/@open-wc/building-rollup) | Default configuration for working with rollup. | -| [building-webpack](./packages/building-webpack) | [![building-webpack](https://img.shields.io/npm/v/@open-wc/building-webpack.svg)](https://www.npmjs.com/package/@open-wc/building-webpack) | Default configuration for working with webpack. | -| [chai-dom-equals](./packages/chai-dom-equals) | [![chai-dom-equals](https://img.shields.io/npm/v/@open-wc/chai-dom-equals.svg)](https://www.npmjs.com/package/@open-wc/chai-dom-equals) | Chai Plugin to compare dom and shadow dom trees. Part of open-wc recommendations. | -| [create](./packages/create) | [![create](https://img.shields.io/npm/v/@open-wc/create.svg)](https://www.npmjs.com/package/@open-wc/create) | Scaffold web components following open-wc recommendations. | -| [demoing-storybook](./packages/demoing-storybook) | [![demoing-storybook](https://img.shields.io/npm/v/@open-wc/demoing-storybook.svg)](https://www.npmjs.com/package/@open-wc/demoing-storybook) | Storybook configuration following open-wc recommendations. | -| [eslint-config](./packages/eslint-config) | [![eslint-config](https://img.shields.io/npm/v/@open-wc/eslint-config.svg)](https://www.npmjs.com/package/@open-wc/eslint-config) | Eslint configuration following open-wc recommendations. | -| [es-dev-server](./packages/es-dev-server) | [![es-dev-server](https://img.shields.io/npm/v/es-dev-server.svg)](https://www.npmjs.com/package/es-dev-server) | Development server for modern web apps. | -| [polyfills-loader](./packages/polyfills-loader) | [![polyfills-loader](https://img.shields.io/npm/v/@open-wc/polyfills-loader.svg)](https://www.npmjs.com/package/@open-wc/polyfills-loader) | Load web component polyfills using dynamic imports. | -| [prettier-config](./packages/prettier-config) | [![prettier-config](https://img.shields.io/npm/v/@open-wc/prettier-config.svg)](https://www.npmjs.com/package/@open-wc/prettier-config) | Prettier configuration following open-wc recommendations. | -| [semantic-dom-diff](./packages/semantic-dom-diff) | [![semantic-dom-diff](https://img.shields.io/npm/v/@open-wc/semantic-dom-diff.svg)](https://www.npmjs.com/package/@open-wc/semantic-dom-diff) | To compare dom and shadow dom trees. Part of open-wc recommendations. | -| [testing](./packages/testing) | [![testing](https://img.shields.io/npm/v/@open-wc/testing.svg)](https://www.npmjs.com/package/@open-wc/testing) | Testing following open-wc recommendations. | -| [testing-helpers](./packages/testing-helpers) | [![testing-helpers](https://img.shields.io/npm/v/@open-wc/testing-helpers.svg)](https://www.npmjs.com/package/@open-wc/testing-helpers) | Testing Helpers following open-wc recommendations. | -| [testing-karma](./packages/testing-karma) | [![testing-karma](https://img.shields.io/npm/v/@open-wc/testing-karma.svg)](https://www.npmjs.com/package/@open-wc/testing-karma) | Testing with Karma following open-wc recommendations. | -| [testing-karma-bs](./packages/testing-karma-bs) | [![testing-karma-bs](https://img.shields.io/npm/v/@open-wc/testing-karma-bs.svg)](https://www.npmjs.com/package/@open-wc/testing-karma-bs) | Testing with Karma using Browserstack following open-wc recommendations. | -| [testing-wallaby](./packages/testing-wallaby) | [![testing-wallaby](https://img.shields.io/npm/v/@open-wc/testing-wallaby.svg)](https://www.npmjs.com/package/@open-wc/testing-wallaby) | Testing with wallaby following open-wc recommendations. | -| [webpack-import-meta-loader](./packages/webpack-import-meta-loader) | [![webpack-import-meta-loader](https://img.shields.io/npm/v/@open-wc/webpack-import-meta-loader.svg)](https://www.npmjs.com/package/@open-wc/webpack-import-meta-loader) | Webpack loader plugin to support import.meta. | +| Package | Version | Description | +| ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------- | +| [building-rollup](./packages/building-rollup) | [![building-rollup](https://img.shields.io/npm/v/@open-wc/building-rollup.svg)](https://www.npmjs.com/package/@open-wc/building-rollup) | Default configuration for working with rollup. | +| [building-webpack](./packages/building-webpack) | [![building-webpack](https://img.shields.io/npm/v/@open-wc/building-webpack.svg)](https://www.npmjs.com/package/@open-wc/building-webpack) | Default configuration for working with webpack. | +| [chai-dom-equals](./packages/chai-dom-equals) | [![chai-dom-equals](https://img.shields.io/npm/v/@open-wc/chai-dom-equals.svg)](https://www.npmjs.com/package/@open-wc/chai-dom-equals) | Chai Plugin to compare dom and shadow dom trees. Part of open-wc recommendations. | +| [create](./packages/create) | [![create](https://img.shields.io/npm/v/@open-wc/create.svg)](https://www.npmjs.com/package/@open-wc/create) | Scaffold web components following open-wc recommendations. | +| [demoing-storybook](./packages/demoing-storybook) | [![demoing-storybook](https://img.shields.io/npm/v/@open-wc/demoing-storybook.svg)](https://www.npmjs.com/package/@open-wc/demoing-storybook) | Storybook configuration following open-wc recommendations. | +| [eslint-config](./packages/eslint-config) | [![eslint-config](https://img.shields.io/npm/v/@open-wc/eslint-config.svg)](https://www.npmjs.com/package/@open-wc/eslint-config) | Eslint configuration following open-wc recommendations. | +| [es-dev-server](./packages/es-dev-server) | [![es-dev-server](https://img.shields.io/npm/v/es-dev-server.svg)](https://www.npmjs.com/package/es-dev-server) | Development server for modern web apps. | +| [polyfills-loader](./packages/polyfills-loader) | [![polyfills-loader](https://img.shields.io/npm/v/@open-wc/polyfills-loader.svg)](https://www.npmjs.com/package/@open-wc/polyfills-loader) | Load web component polyfills using dynamic imports. | +| [prettier-config](./packages/prettier-config) | [![prettier-config](https://img.shields.io/npm/v/@open-wc/prettier-config.svg)](https://www.npmjs.com/package/@open-wc/prettier-config) | Prettier configuration following open-wc recommendations. | +| [semantic-dom-diff](./packages/semantic-dom-diff) | [![semantic-dom-diff](https://img.shields.io/npm/v/@open-wc/semantic-dom-diff.svg)](https://www.npmjs.com/package/@open-wc/semantic-dom-diff) | To compare dom and shadow dom trees. Part of open-wc recommendations. | +| [testing](./packages/testing) | [![testing](https://img.shields.io/npm/v/@open-wc/testing.svg)](https://www.npmjs.com/package/@open-wc/testing) | Testing following open-wc recommendations. | +| [testing-helpers](./packages/testing-helpers) | [![testing-helpers](https://img.shields.io/npm/v/@open-wc/testing-helpers.svg)](https://www.npmjs.com/package/@open-wc/testing-helpers) | Testing Helpers following open-wc recommendations. | +| [testing-karma](./packages/testing-karma) | [![testing-karma](https://img.shields.io/npm/v/@open-wc/testing-karma.svg)](https://www.npmjs.com/package/@open-wc/testing-karma) | Testing with Karma following open-wc recommendations. | +| [testing-karma-bs](./packages/testing-karma-bs) | [![testing-karma-bs](https://img.shields.io/npm/v/@open-wc/testing-karma-bs.svg)](https://www.npmjs.com/package/@open-wc/testing-karma-bs) | Testing with Karma using Browserstack following open-wc recommendations. | +| [testing-wallaby](./packages/testing-wallaby) | [![testing-wallaby](https://img.shields.io/npm/v/@open-wc/testing-wallaby.svg)](https://www.npmjs.com/package/@open-wc/testing-wallaby) | Testing with wallaby following open-wc recommendations. | +| [webpack-import-meta-loader](./packages/webpack-import-meta-loader) | [![webpack-import-meta-loader](https://img.shields.io/npm/v/@open-wc/webpack-import-meta-loader.svg)](https://www.npmjs.com/package/@open-wc/webpack-import-meta-loader) | Webpack loader plugin to support import.meta. | ## Contact + Feel free to reach out to us on [twitter](https://twitter.com/OpenWc) or create [a github issue](https://github.com/open-wc/open-wc/issues/new) for any feedback or questions you might have. You can also find us on the Polymer slack in the [#open-wc](https://polymer.slack.com/messages/CE6D9DN05) channel. You can join the Polymer slack by visiting [https://www.polymer-project.org/slack-invite](https://www.polymer-project.org/slack-invite). - ## We Proudly Use + Browserstack Logo netlify logo - ## Guide + ```bash # bootstrap/setup yarn install diff --git a/docs/README.md b/docs/README.md index 2fca5390..6e21058b 100644 --- a/docs/README.md +++ b/docs/README.md @@ -4,14 +4,15 @@ heroImage: /hero.png actionText: Get Started → actionLink: /guide/ features: -- title: Smart Defaults - details: Enjoy the peace of mind that comes from having a well-known default solution for almost everything. From linting to testing to demos to publishing - have the full experience. -- title: Awesome Generators - details: Get up and running quickly with opinionated generators, or add recommended tools to existing projects. Our comprehensive fleet of generators have got you covered. -- title: Open Source Love - details: Open Web Components is a community-effort, independent of any framework or company. We use mostly open-source tools and services. + - title: Smart Defaults + details: Enjoy the peace of mind that comes from having a well-known default solution for almost everything. From linting to testing to demos to publishing - have the full experience. + - title: Awesome Generators + details: Get up and running quickly with opinionated generators, or add recommended tools to existing projects. Our comprehensive fleet of generators have got you covered. + - title: Open Source Love + details: Open Web Components is a community-effort, independent of any framework or company. We use mostly open-source tools and services. footer: MIT Licensed | Copyright © 2018-2019 open-wc --- +

I used open-wc to get testing working, it was so helpful, works like a charm! diff --git a/docs/about/README.md b/docs/about/README.md index 9113de76..8f0512b8 100644 --- a/docs/about/README.md +++ b/docs/about/README.md @@ -23,7 +23,7 @@ Many web developers have experienced the dreaded "Javascript Fatigue". With our We want web component development to be accessible and approachable for everyone, regardless of their background. Therefore, our recommendations aim to be easy to use, be ready to use, and provide that "it just works" developer experience we all crave for the various aspects of web component development. -Best practices/recommendations and examples may change and evolve over time. +Best practices/recommendations and examples may change and evolve over time. ### Why Web Components @@ -46,12 +46,15 @@ What if you could remove code, gain performance, and streamline implementation a - Write using a streamlined component API that combines the best bits of popular libraries and frameworks! ##### Performance + Just like `querySelector` reduces developers' dependence on jQuery, the web components standards reduces the size and complexity of component libraries and frameworks. This ultimately benefits users by decreasing page load times and increasing app performance. ##### Future Proofing + Using the browser's standards-based component model will increase the longevity of your application. The web has an extremely strong tradition of backwards-compatibility. Standards bodies have consistently gone out of their way to maintain legacy APIs. ##### Flexibility + The web components standards are fairly low-level, letting library authors build upon them with innovative APIs. By using such libraries you can build your app in the style you want while still leveraging built-in browser features. ## Contribute diff --git a/docs/about/blog.md b/docs/about/blog.md index ddb75ffb..0dd0c13c 100644 --- a/docs/about/blog.md +++ b/docs/about/blog.md @@ -1,10 +1,10 @@ # Blog -## [Announcing Open Web Components](https://dev.to/thepassle/announcing-open-web-components-5h7) +## [Announcing Open Web Components](https://dev.to/thepassle/announcing-open-web-components-5h7) by [open-wc](https://github.com/open-wc) -## [Cross Browser Testing your Stencil Web Component like a boss](https://medium.com/vincent-ogloblinsky/cross-browser-testing-your-stencil-web-component-like-a-boss-93c1b154bfd9) +## [Cross Browser Testing your Stencil Web Component like a boss](https://medium.com/vincent-ogloblinsky/cross-browser-testing-your-stencil-web-component-like-a-boss-93c1b154bfd9) by [Vincent Ogloblinsky](https://github.com/vogloblinsky) @@ -12,10 +12,10 @@ by [Vincent Ogloblinsky](https://github.com/vogloblinsky) by [npm](npmjs.com) -## [Not Another To Do App](https://medium.com/@westbrook/not-another-to-do-app-169c14bb7ef9) +## [Not Another To Do App](https://medium.com/@westbrook/not-another-to-do-app-169c14bb7ef9) by [Westbrook Johnson](https://github.com/westbrook) -## [Web Components: spoils of the browser wars](https://www.andrewzigler.com/blog/2019/02/28/web-components-spoils-of-the-browser-wars/) +## [Web Components: spoils of the browser wars](https://www.andrewzigler.com/blog/2019/02/28/web-components-spoils-of-the-browser-wars/) by [Andrew Zigler](https://github.com/azigler) diff --git a/docs/about/rationales.md b/docs/about/rationales.md index 87389ba3..cc766f4d 100644 --- a/docs/about/rationales.md +++ b/docs/about/rationales.md @@ -10,7 +10,6 @@ This is such a powerful and widely-used pattern in the current JavaScript ecosys We want to help you build your apps as easily and efficiently as possible, so for now we've adopted this practice as our only exception to the above rules. The [import maps](https://github.com/WICG/import-maps) proposal aims to bring bare modules to the web browser. You can follow that repository to stay up to date. - ## Workflows We recommend implementing the following three workflows for specific tasks while developing your component or application. @@ -26,9 +25,11 @@ We recommend our [ES Dev Server](../developing/es-dev-server.html) as it does no ::: When would you choose this workflow: + - When developing new features Why would you choose this: + - Simple to setup - As fast as it gets @@ -38,16 +39,17 @@ Chances are that the web components you're building will need to run in more tha In these cases it's time to open your toolbox and make sure everything works in all supported browsers. When would you choose this workflow: + - To verify everything works in all supported browsers - To debug legacy browsers We recommend our [Open Web Components Building Setup](../building). Why would you choose it: + - As good as it gets when you need to work with legacy browsers - Auto-bundling/reloading - ### Production Workflow Once you're happy with your web components, it's time to put them somewhere more useful. @@ -55,11 +57,13 @@ Most likely a publicly available web server. Before you do that let's apply all the optimizations magic we can cook up. When would you use this: + - Optimize your build - Publishing to production We recommend our [Open Web Components Building Setup](../building). Why would you choose it: + - Multiple bundles for differential serving - Conditional auto-loader for those bundles (without a special server) diff --git a/docs/automating/README.md b/docs/automating/README.md index 63343ff1..9aba51ed 100644 --- a/docs/automating/README.md +++ b/docs/automating/README.md @@ -3,6 +3,7 @@ Having continuous integration in your project can provide valuable insights, and we consider it an essential in your projects. ## Circle ci + If you use the default generator you will already have CircleCi setup with a .circleci folder. It also contains a config that takes care of linting and testing. @@ -11,13 +12,14 @@ This is part of the default [open-wc](https://open-wc.org/) recommendation. ::: ## Setup + ```bash npm init @open-wc automating ``` ### Manual Setup -- copy [.circleci/config.yml](https://github.com/open-wc/open-wc/blob/master/packages/create/src/generators/tools-circleci/templates/static/.circleci/config.yml) to `.circleci/config.yml` +- copy [.circleci/config.yml](https://github.com/open-wc/open-wc/blob/master/packages/create/src/generators/tools-circleci/templates/static/.circleci/config.yml) to `.circleci/config.yml` ## Usage @@ -36,5 +38,5 @@ npm init @open-wc automating - Look for "Automate", and write down the "Access Key" and "Username" - Open your [circleci App](https://circleci.com/dashboard) or direclty via https://circleci.com/gh/{groupname}/{reponame}/edit - Go to the project settings -> Environment Variables -- Add Variable: BROWSER_STACK_USERNAME + ${username from url above} -- Add Variable: BROWSER_STACK_ACCESS_KEY + ${key from url above} +- Add Variable: BROWSER_STACK_USERNAME + \${username from url above} +- Add Variable: BROWSER_STACK_ACCESS_KEY + \${key from url above} diff --git a/docs/building/README.md b/docs/building/README.md index 0aeda1d5..e80bbed8 100644 --- a/docs/building/README.md +++ b/docs/building/README.md @@ -1,10 +1,13 @@ # Building ## Browser standards + We strongly believe that staying close to browser standards will be the best long term investment for your code. It is the basis for all our recommendations, and it means that sometimes we will not recommend a popular feature or functionality. It also means we can be faster to adopt and recommend new browser standards. ## Building web apps + Building is a necessary optimization when shipping apps to production. Generally speaking, build tools accomplish some or all of the following: + 1. Reduce app size (tree shaking, inlining, minification etc.) 2. Bundling and code splitting (combining many into few files) 3. Transforming/polyfilling standard code for older browsers @@ -14,8 +17,10 @@ Building is a necessary optimization when shipping apps to production. Generally Our recommended setups address the first four points but refrain from introducing non-standard features. We think it's best to avoid those, as they might lock your source code to a specific build setup which can be hard to get away from at a later time. Javascript is evolving fast, your code can quickly become out of sync with new developments. ## Using `index.html` as an entry point + Our configs for `rollup` & `webpack` are unique in that sense that they take a single html file as an entry point. Doing so allows you to work with the same entry point no matter if you use + - webpack - rollup - es-dev-server @@ -27,6 +32,7 @@ This allows you to easily switch between build configurations; if you want to sw It also means you can use `es-dev-server` for your regular development, and then use either `rollup` or `webpack` to prepare your application for your production environment. ## Rollup + We recommend [Rollup](https://rollupjs.org/) for building front-end projects. Rollup is convenient to use and gets out of your way. It is easy to understand what's going on. Quite a relief in a world of complex javascript tooling. Rollup is focused on statically analyzing es module based projects, significantly reducing the size of your app through tree shaking, minification and code splitting. Rollup can output es modules, making use of the native module loader available in modern browsers. @@ -34,6 +40,7 @@ Rollup is focused on statically analyzing es module based projects, significantl Our [default configuration](/building/building-rollup.html) gets your started with a setup for modern browsers, and optionally for supporting legacy browsers. ## Webpack + [Webpack](https://webpack.js.org/) is a popular and flexible build tool, with a large ecosystem of plugins. Out of the box, webpack handles different module formats, such as esm, commonjs, amd and umd. It is not able to output native es modules, relying instead on it's own module loader. Compared to rollup it is a more complex tool, with more options for composing and managing complex projects. It also comes with a dev server with features such as auto-reload and hot module reloading. diff --git a/docs/codelabs/README.md b/docs/codelabs/README.md index 6c8d1138..bff06f59 100644 --- a/docs/codelabs/README.md +++ b/docs/codelabs/README.md @@ -1,3 +1,3 @@ # Codelabs -TODO \ No newline at end of file +TODO diff --git a/docs/developing/README.md b/docs/developing/README.md index 1bd11c86..6acd2a8e 100644 --- a/docs/developing/README.md +++ b/docs/developing/README.md @@ -1,6 +1,7 @@ # Developing ## Going buildless + Browsers have improved a lot over the past years. It's now possible to do web development without requiring any build tools, using the native module loader of the browser. We think this is a great fit for web components, and we recommend this as a general starting point. Build tools can quickly add a lot of complexity to your code, and make your code reliant on a specific build setup. We think it's best to avoid them during development, or only add them for light transformations if you know what you're doing. @@ -8,9 +9,11 @@ Build tools can quickly add a lot of complexity to your code, and make your code Read [this article](https://dev.to/open-wc/developing-without-a-build-1-introduction-26ao) to learn more about this approach. ## Development server + We created [es-dev-server](https://open-wc.org/developing/es-dev-server.html) to help developing without build tools. ## Web component libraries + You can write web components using just the basic web component APIs. This can be a great choice when you're looking to keep dependencies low. But generally, we recommend using lightweight libraries to help improve the developer experience and reduce boilerplate. We recommend [lit-html](https://www.npmjs.com/package/lit-html) with the [lit-element](https://www.npmjs.com/package/lit-element) base class as a general-purpose library for building web components. `lit-html` is feature complete, extremely lightweight and offers a great development experience. Check out the [lit-html page](/developing/lit-html/) for code examples and more information. @@ -18,6 +21,7 @@ We recommend [lit-html](https://www.npmjs.com/package/lit-html) with the [lit-el In the code snippets throughout our documentation we use `lit-html` and `lit-element`, but our recommendations and tools are not specific to them. You should be able to use them with any web component library that follows browser standards. If you do run into issues, or have any questions, let us know about it! ### Alternative libraries + Besides `lit-html`, there are other great options available: - [haunted](https://www.npmjs.com/package/haunted) functional-style web components, with react-like hooks @@ -27,13 +31,17 @@ Besides `lit-html`, there are other great options available: - [stencil](https://stenciljs.com/) web component with typescript and JSX (requires a build step) ## Code examples + Check out the [code examples](/developing/code-examples/) page for a collection of best practices and design patterns. ## Testing + Check out our [testing documentation](/testing/) for help with setting up testing. ## Building + When you are ready to ship your app to production, or when you need to test your app on older browsers, take a look at our [building documentation](/building/) to get you started. ## Further reading + See: [awesome lit-html](https://github.com/web-padawan/awesome-lit-html) for a great collection of resources. diff --git a/docs/developing/best-practices.md b/docs/developing/best-practices.md index 0b0a02a2..dfd76062 100644 --- a/docs/developing/best-practices.md +++ b/docs/developing/best-practices.md @@ -16,4 +16,4 @@ We're actively looking to extend this page with common best practices. If you ha Every developer at some point will run into the problem of moving some data upwards to a parent element. While there are many ways to manage state in your application like Redux, or passing down a bound function to a child element to mutate state in the parent, our default recommendation for moving data upwards is simply using events. The benefits of using events are that it's close to the platform, and will always have the same expected behavior across frameworks. You can find a demo of using `CustomEvents` [here](https://stackblitz.com/edit/open-wc-lit-demos?file=01-basic%2F12-firing-events.js). -If you find yourself moving a lot of data around, it may be time to look into some state management libraries like [Redux](https://redux.js.org/) or consider some more advanced composition techniques with [slotting](https://stackblitz.com/edit/open-wc-lit-demos?file=02-intermediate%2F09-slotting.js). \ No newline at end of file +If you find yourself moving a lot of data around, it may be time to look into some state management libraries like [Redux](https://redux.js.org/) or consider some more advanced composition techniques with [slotting](https://stackblitz.com/edit/open-wc-lit-demos?file=02-intermediate%2F09-slotting.js). diff --git a/docs/developing/code-examples.md b/docs/developing/code-examples.md index 739e36fc..544fb698 100644 --- a/docs/developing/code-examples.md +++ b/docs/developing/code-examples.md @@ -2,45 +2,49 @@ ## lit-html and lit-element -A simple base class for creating fast, lightweight web components. +A simple base class for creating fast, lightweight web components. [LitElement documentation](https://lit-element.polymer-project.org) [lit-html documentation](https://lit-html.polymer-project.org) Click on the links below to view live code samples: -* [Basic](https://open-wc-lit-demos.stackblitz.io/basic) - - [01 Basic setup](https://stackblitz.com/edit/open-wc-lit-demos?file=01-basic%2F01-basic-setup.js) - - [02 Manage properties](https://stackblitz.com/edit/open-wc-lit-demos?file=01-basic%2F02-manage-properties.js) - - [03 Property changes](https://stackblitz.com/edit/open-wc-lit-demos?file=01-basic%2F03-property-changes.js) - - [04 Properties and attributes](https://stackblitz.com/edit/open-wc-lit-demos?file=01-basic%2F04-properties-and-attributes.js) - - [05 Passing properties](https://stackblitz.com/edit/open-wc-lit-demos?file=01-basic%2F05-passing-properties.js) - - [06 Handle events](https://stackblitz.com/edit/open-wc-lit-demos?file=01-basic%2F06-handle-events.js) - - [07 Conditional rendering](https://stackblitz.com/edit/open-wc-lit-demos?file=01-basic%2F07-conditional-rendering.js) - - [08 Repeated templates](https://stackblitz.com/edit/open-wc-lit-demos?file=01-basic%2F08-repeated-templates.js) - - [09 Update arrays and objects](https://stackblitz.com/edit/open-wc-lit-demos?file=01-basic%2F09-update-arrays-and-objects.js) - - [10 Render styles](https://stackblitz.com/edit/open-wc-lit-demos?file=01-basic%2F10-render-styles.js) - - [11 Fetching data](https://stackblitz.com/edit/open-wc-lit-demos?file=01-basic%2F11-fetching-data.js) - - [12 Firing events](https://stackblitz.com/edit/open-wc-lit-demos?file=01-basic%2F12-firing-events.js) -* [Intermediate](https://open-wc-lit-demos.stackblitz.io/intermediate) - - [01 First updated](https://stackblitz.com/edit/open-wc-lit-demos?file=01-intermediate%2F01-first-updated.js) - - [02 Updated](https://stackblitz.com/edit/open-wc-lit-demos?file=02-intermediate%2F02-updated.js) - - [03 Lifecycle](https://stackblitz.com/edit/open-wc-lit-demos?file=02-intermediate%2F03-lifecycle.js) - - [04 Computed properties](https://stackblitz.com/edit/open-wc-lit-demos?file=02-intermediate%2F04-computed-properties.js) - - [05 Querying dom](https://stackblitz.com/edit/open-wc-lit-demos?file=02-intermediate%2F05-querying-dom.js) - - [06 Light dom](https://stackblitz.com/edit/open-wc-lit-demos?file=02-intermediate%2F06-light-dom.js) - - [07 Reflecting attributes](https://stackblitz.com/edit/open-wc-lit-demos?file=02-intermediate%2F07-reflecting-attributes.js) - - [08 Dynamic repeated templates](https://stackblitz.com/edit/open-wc-lit-demos?file=02-intermediate%2F08-dynamic-repeated-templates.js) - - [09 Slotting](https://stackblitz.com/edit/open-wc-lit-demos?file=02-intermediate%2F09-slotting.js) -* [Advanced](https://open-wc-lit-demos.stackblitz.io/advanced) - - [01 Property setter observer](https://stackblitz.com/edit/open-wc-lit-demos?file=03-advanced%2F01-property-setter-observer.js) - - [02 Until directive](https://stackblitz.com/edit/open-wc-lit-demos?file=03-advanced%2F02-until-directive.js) - - [03 Template wrapping](https://stackblitz.com/edit/open-wc-lit-demos?file=03-advanced%2F03-template-wrapping.js) - - [04 Shared templates](https://stackblitz.com/edit/open-wc-lit-demos?file=03-advanced%2F04-shared-templates.js) - - [05 Shared styles](https://stackblitz.com/edit/open-wc-lit-demos?file=03-advanced%2F05-shared-styles.js) - - [06 External template](https://stackblitz.com/edit/open-wc-lit-demos?file=03-advanced%2F06-external-template.js) - - [07 Template factories](https://stackblitz.com/edit/open-wc-lit-demos?file=03-advanced%2F07-template-factories.js) - - [08 Should update](https://stackblitz.com/edit/open-wc-lit-demos?file=03-advanced%2F08-should-update.js) +- [Basic](https://open-wc-lit-demos.stackblitz.io/basic) + - [01 Basic setup](https://stackblitz.com/edit/open-wc-lit-demos?file=01-basic%2F01-basic-setup.js) + - [02 Manage properties](https://stackblitz.com/edit/open-wc-lit-demos?file=01-basic%2F02-manage-properties.js) + - [03 Property changes](https://stackblitz.com/edit/open-wc-lit-demos?file=01-basic%2F03-property-changes.js) + - [04 Properties and attributes](https://stackblitz.com/edit/open-wc-lit-demos?file=01-basic%2F04-properties-and-attributes.js) + - [05 Passing properties](https://stackblitz.com/edit/open-wc-lit-demos?file=01-basic%2F05-passing-properties.js) + - [06 Handle events](https://stackblitz.com/edit/open-wc-lit-demos?file=01-basic%2F06-handle-events.js) + - [07 Conditional rendering](https://stackblitz.com/edit/open-wc-lit-demos?file=01-basic%2F07-conditional-rendering.js) + - [08 Repeated templates](https://stackblitz.com/edit/open-wc-lit-demos?file=01-basic%2F08-repeated-templates.js) + - [09 Update arrays and objects](https://stackblitz.com/edit/open-wc-lit-demos?file=01-basic%2F09-update-arrays-and-objects.js) + - [10 Render styles](https://stackblitz.com/edit/open-wc-lit-demos?file=01-basic%2F10-render-styles.js) + - [11 Fetching data](https://stackblitz.com/edit/open-wc-lit-demos?file=01-basic%2F11-fetching-data.js) + - [12 Firing events](https://stackblitz.com/edit/open-wc-lit-demos?file=01-basic%2F12-firing-events.js) + +- [Intermediate](https://open-wc-lit-demos.stackblitz.io/intermediate) + + - [01 First updated](https://stackblitz.com/edit/open-wc-lit-demos?file=01-intermediate%2F01-first-updated.js) + - [02 Updated](https://stackblitz.com/edit/open-wc-lit-demos?file=02-intermediate%2F02-updated.js) + - [03 Lifecycle](https://stackblitz.com/edit/open-wc-lit-demos?file=02-intermediate%2F03-lifecycle.js) + - [04 Computed properties](https://stackblitz.com/edit/open-wc-lit-demos?file=02-intermediate%2F04-computed-properties.js) + - [05 Querying dom](https://stackblitz.com/edit/open-wc-lit-demos?file=02-intermediate%2F05-querying-dom.js) + - [06 Light dom](https://stackblitz.com/edit/open-wc-lit-demos?file=02-intermediate%2F06-light-dom.js) + - [07 Reflecting attributes](https://stackblitz.com/edit/open-wc-lit-demos?file=02-intermediate%2F07-reflecting-attributes.js) + - [08 Dynamic repeated templates](https://stackblitz.com/edit/open-wc-lit-demos?file=02-intermediate%2F08-dynamic-repeated-templates.js) + - [09 Slotting](https://stackblitz.com/edit/open-wc-lit-demos?file=02-intermediate%2F09-slotting.js) + +- [Advanced](https://open-wc-lit-demos.stackblitz.io/advanced) + + - [01 Property setter observer](https://stackblitz.com/edit/open-wc-lit-demos?file=03-advanced%2F01-property-setter-observer.js) + - [02 Until directive](https://stackblitz.com/edit/open-wc-lit-demos?file=03-advanced%2F02-until-directive.js) + - [03 Template wrapping](https://stackblitz.com/edit/open-wc-lit-demos?file=03-advanced%2F03-template-wrapping.js) + - [04 Shared templates](https://stackblitz.com/edit/open-wc-lit-demos?file=03-advanced%2F04-shared-templates.js) + - [05 Shared styles](https://stackblitz.com/edit/open-wc-lit-demos?file=03-advanced%2F05-shared-styles.js) + - [06 External template](https://stackblitz.com/edit/open-wc-lit-demos?file=03-advanced%2F06-external-template.js) + - [07 Template factories](https://stackblitz.com/edit/open-wc-lit-demos?file=03-advanced%2F07-template-factories.js) + - [08 Should update](https://stackblitz.com/edit/open-wc-lit-demos?file=03-advanced%2F08-should-update.js) ## Haunted @@ -49,25 +53,28 @@ React's Hooks API implemented for web components 👻 Click on the links below to view live code samples: -* [Basic](https://open-wc-haunted-demos.stackblitz.io/basic) - - [01 Basic setup](https://stackblitz.com/edit/open-wc-haunted-demos?file=01-basic%2F01-basic-setup.js) - - [02 Manage properties](https://stackblitz.com/edit/open-wc-haunted-demos?file=01-basic%2F02-manage-properties.js) - - [03 Property changes](https://stackblitz.com/edit/open-wc-haunted-demos?file=01-basic%2F03-property-changes.js) - - [04 Handling attributes](https://stackblitz.com/edit/open-wc-haunted-demos?file=01-basic%2F04-handling-attributes.js) - - [05 Passing properties](https://stackblitz.com/edit/open-wc-haunted-demos?file=01-basic%2F05-passing-properties.js) - - [06 Handle events](https://stackblitz.com/edit/open-wc-haunted-demos?file=01-basic%2F06-handle-events.js) - - [07 Conditional rendering](https://stackblitz.com/edit/open-wc-haunted-demos?file=01-basic%2F07-conditional-rendering.js) - - [08 Repeated templates](https://stackblitz.com/edit/open-wc-haunted-demos?file=01-basic%2F08-repeated-templates.js) - - [09 Firing events](https://stackblitz.com/edit/open-wc-haunted-demos?file=01-basic%2F09-firing-events.js) - - [10 Virtual Components](https://stackblitz.com/edit/open-wc-haunted-demos?file=01-basic%2F10-virtual-components.js) - - [11 Using styles](https://stackblitz.com/edit/open-wc-haunted-demos?file=01-basic%2F11-using-styles.js) -* [Intermediate](https://open-wc-haunted-demos.stackblitz.io/intermediate) - - [01 Using state](https://stackblitz.com/edit/open-wc-haunted-demos?file=02-intermediate%2F01-using-state.js) - - [02 Using effects](https://stackblitz.com/edit/open-wc-haunted-demos?file=02-intermediate%2F02-using-effects.js) - - [03 Fetch data](https://stackblitz.com/edit/open-wc-haunted-demos?file=02-intermediate%2F03-fetch-data.js) - - [04 Using reducer](https://stackblitz.com/edit/open-wc-haunted-demos?file=02-intermediate%2F04-using-reducer.js) - - [05 Using ref](https://stackblitz.com/edit/open-wc-haunted-demos?file=02-intermediate%2F04-using-ref.js) - - [06 Using memo](https://stackblitz.com/edit/open-wc-haunted-demos?file=02-intermediate%2F06-using-memo.js) -* [Advanced](https://open-wc-haunted-demos.stackblitz.io/advanced) - - [01 Using context](https://stackblitz.com/edit/open-wc-haunted-demos?file=03-advanced%2F01-using-context.js) - \ No newline at end of file +- [Basic](https://open-wc-haunted-demos.stackblitz.io/basic) + + - [01 Basic setup](https://stackblitz.com/edit/open-wc-haunted-demos?file=01-basic%2F01-basic-setup.js) + - [02 Manage properties](https://stackblitz.com/edit/open-wc-haunted-demos?file=01-basic%2F02-manage-properties.js) + - [03 Property changes](https://stackblitz.com/edit/open-wc-haunted-demos?file=01-basic%2F03-property-changes.js) + - [04 Handling attributes](https://stackblitz.com/edit/open-wc-haunted-demos?file=01-basic%2F04-handling-attributes.js) + - [05 Passing properties](https://stackblitz.com/edit/open-wc-haunted-demos?file=01-basic%2F05-passing-properties.js) + - [06 Handle events](https://stackblitz.com/edit/open-wc-haunted-demos?file=01-basic%2F06-handle-events.js) + - [07 Conditional rendering](https://stackblitz.com/edit/open-wc-haunted-demos?file=01-basic%2F07-conditional-rendering.js) + - [08 Repeated templates](https://stackblitz.com/edit/open-wc-haunted-demos?file=01-basic%2F08-repeated-templates.js) + - [09 Firing events](https://stackblitz.com/edit/open-wc-haunted-demos?file=01-basic%2F09-firing-events.js) + - [10 Virtual Components](https://stackblitz.com/edit/open-wc-haunted-demos?file=01-basic%2F10-virtual-components.js) + - [11 Using styles](https://stackblitz.com/edit/open-wc-haunted-demos?file=01-basic%2F11-using-styles.js) + +- [Intermediate](https://open-wc-haunted-demos.stackblitz.io/intermediate) + + - [01 Using state](https://stackblitz.com/edit/open-wc-haunted-demos?file=02-intermediate%2F01-using-state.js) + - [02 Using effects](https://stackblitz.com/edit/open-wc-haunted-demos?file=02-intermediate%2F02-using-effects.js) + - [03 Fetch data](https://stackblitz.com/edit/open-wc-haunted-demos?file=02-intermediate%2F03-fetch-data.js) + - [04 Using reducer](https://stackblitz.com/edit/open-wc-haunted-demos?file=02-intermediate%2F04-using-reducer.js) + - [05 Using ref](https://stackblitz.com/edit/open-wc-haunted-demos?file=02-intermediate%2F04-using-ref.js) + - [06 Using memo](https://stackblitz.com/edit/open-wc-haunted-demos?file=02-intermediate%2F06-using-memo.js) + +- [Advanced](https://open-wc-haunted-demos.stackblitz.io/advanced) + - [01 Using context](https://stackblitz.com/edit/open-wc-haunted-demos?file=03-advanced%2F01-using-context.js) diff --git a/docs/developing/lit-html.md b/docs/developing/lit-html.md index 074ad5d9..e385d40d 100644 --- a/docs/developing/lit-html.md +++ b/docs/developing/lit-html.md @@ -5,10 +5,13 @@ We recommend [lit-html](https://www.npmjs.com/package/lit-html) with the [lit-el Under the hood new Web Component APIs such as [Constructable Stylesheets](https://developers.google.com/web/updates/2019/02/constructable-stylesheets) are used when they are available. As browser support improves, you get performance improvements for free. ## Getting started + To get started, we recommend using our project scaffolding: + ```bash npm init @open-wc ``` ## Examples -Check out the [code examples](/developing/code-examples/) page for a collection of best practices and design patterns. \ No newline at end of file + +Check out the [code examples](/developing/code-examples/) page for a collection of best practices and design patterns. diff --git a/docs/developing/routing.md b/docs/developing/routing.md index f6c33e13..95717f04 100644 --- a/docs/developing/routing.md +++ b/docs/developing/routing.md @@ -10,5 +10,5 @@ In alphabetical order: - [lit-router](https://github.com/danevans/lit-router) - [pwa-helpers router](https://github.com/Polymer/pwa-helpers#routerjs) - [redux first routing](https://github.com/mksarge/redux-first-routing) -- [simplr-router](https://github.com/Matsuuu/simplr-router) +- [simplr-router](https://github.com/Matsuuu/simplr-router) - [vaadin-router](https://github.com/vaadin/vaadin-router) diff --git a/docs/developing/types.md b/docs/developing/types.md index b189c422..f89b3149 100644 --- a/docs/developing/types.md +++ b/docs/developing/types.md @@ -7,6 +7,7 @@ Types provide valuable information about the nature of code, and help identify typos, enable refactoring, etc. Most editors these days provide some kind of IntelliSense based on type information gleaned from the code. My favorite is Visual Studio Code. With proper type information it can give you symbol defintions on hover, code completion, symbol renaming across files, etc. ### Benefits of Types + 1. Early detection of type errors 2. Better code analysis 3. Improved IDE support @@ -50,13 +51,8 @@ In order to get type linting in a JavaScript project using VS Code all you need "alwaysStrict": true, "esModuleInterop": true }, - "include": [ - "**/*.js", - "node_modules/@open-wc/**/*.js" - ], - "exclude": [ - "node_modules/!(@open-wc)" - ] + "include": ["**/*.js", "node_modules/@open-wc/**/*.js"], + "exclude": ["node_modules/!(@open-wc)"] } ``` @@ -65,17 +61,14 @@ In order to get type linting in a JavaScript project using VS Code all you need If you wish to use our typings in TypeScript you will to do a little more. You will need to add to this to your `tsconfig.json`. + ```json { "compilerOptions": { "allowJs": true }, - "include": [ - "node_modules/@open-wc/**/*.js" - ], - "exclude": [ - "node_modules/!(@open-wc)" - ] + "include": ["node_modules/@open-wc/**/*.js"], + "exclude": ["node_modules/!(@open-wc)"] } ``` @@ -83,7 +76,6 @@ e.g. we need to include the js files from @open-wc and you can not have it in an However as `allowJs` prevents you from generating definition files for your own typescript files ([issue 7546](https://github.com/Microsoft/TypeScript/issues/7546)) you probably want to have an alternative config `tsconfig.build.json` for that. - ```json { "extends": "./tsconfig.json", @@ -95,6 +87,7 @@ However as `allowJs` prevents you from generating definition files for your own ``` You can then use it like so in you `package.json` + ```json { "scripts": { @@ -105,11 +98,12 @@ You can then use it like so in you `package.json` ``` That way + - `tsconfig.json` will be used by the language server (in VS code) - `tsconfig.build.json` will be used to build your typescript project (including definition files) - Example how a full config might look like + ```json { "compilerOptions": { @@ -125,12 +119,7 @@ Example how a full config might look like "alwaysStrict": true, "esModuleInterop": true }, - "include": [ - "**/*.js", - "node_modules/@open-wc/**/*.js" - ], - "exclude": [ - "node_modules/!(@open-wc)" - ] + "include": ["**/*.js", "node_modules/@open-wc/**/*.js"], + "exclude": ["node_modules/!(@open-wc)"] } ``` diff --git a/docs/faq/README.md b/docs/faq/README.md index e2723bd3..4cf327fd 100644 --- a/docs/faq/README.md +++ b/docs/faq/README.md @@ -6,20 +6,20 @@ In this section you can find answers to frequently asked questions regarding jav [[toc]] **Deep dives:** + - [Component Libraries](./component-libraries.html) - [Rerender not triggered](./rerender.html) - [Unit testing custom events](./unit-testing-custom-events.html) - [Unit testing initialization error](./unit-testing-init-error.html) - ## Custom elements render life cycle - ## How can I set `:host` width via a property? The following example features 3 variations: + - `disabled` style differently if a property is set - `type` style if type has a certain value - `width` map a property to a css variable @@ -71,15 +71,15 @@ Many elements reflect their properties as attributes, and vice versa, like for e ``` ```js -console.log(myButton.disabled) // true -console.log(myButton.hasAttribute('disabled')) // true +console.log(myButton.disabled); // true +console.log(myButton.hasAttribute('disabled')); // true ``` If we set the property to false, it'll _reflect_ it to an attribute. (In this case, because it's a boolean attribute, it'll be omitted) ```js myButton.disabled = false; -console.log(myButton.hasAttribute('disabled')) // false +console.log(myButton.hasAttribute('disabled')); // false ``` This concept is called attribute reflection. @@ -91,6 +91,7 @@ However, this is not true for the `checked` attribute on an input element of typ ``` It will only set the property the first time: + ```js console.log(mycheck.checked); // true ``` diff --git a/docs/faq/component-libraries.md b/docs/faq/component-libraries.md index 65a35bb9..023522db 100644 --- a/docs/faq/component-libraries.md +++ b/docs/faq/component-libraries.md @@ -5,51 +5,67 @@ The hardest part of any project is often getting content onto that first blank p - [Aybolit](https://web-padawan.github.io/aybolit/) A growing family of elements with default styling for Bootstrap, Bulma, and Material, as well as a solid white-label basis for extending the underlying functionality with your own custom designs. + - [Bolt](https://boltdesignsystem.com/) A family of web components built with first-class participation in the Twig templating system for PHP in mind. This set is backed by an expansive catalog of usage variants. + - [Clever Components](https://github.com/CleverCloud/clever-components) A collection of low-level (atoms) and high-level (domain specific) Web Components made by Clever Cloud for its different Web UIs (public and internal). + - [Elix](https://component.kitchen/elix) The Elix project aims to create a universal library of all general-purpose user interface patterns commonly found in desktop and mobile UIs, where each pattern is implemented as a well-designed, attractive, high-quality, performant, accessible, localizable, and extensively customizable web component. + - [HelixUI](https://rackerlabs.github.io/helix-ui/) The HelixUI library provides front-end developers a set of reusable CSS classes and HTML Custom Elements that adhere to Helix design standards, as outlined by Rackspace. + - [Ink Components](https://components.ink/) Web components for interactive scientific writing, reactive documents and explorable explanations. The Ink Components library can bring your math and science documents to the next level by breathing life into charts, equations, and variables that can be used throughout your application or content. + - [Io GUI](https://io-gui.dev/#page=elements) Io is a UI framework for web applications and custom elements. It supports virtual DOM, reactive rendering and data binding. It includes a design system composed of UI elements ranging from simple input fields, to menu systems and responsive layouts. Its unique feature is the ability to create visually complex, yet fast and GPU-optimized elements using WebGL shaders. + - [Ionic UI Components](https://ionicframework.com/docs/components) Take advantage of the component system that powers Ionic applications with a large ecosystem to choose from and in-depth usage instructions, no matter the framework you use. + - [Lightning Web Components by SalesForce](https://developer.salesforce.com/docs/component-library/overview/components) Lightning Web Components are now the go-to standard for developing applications in the SalesForce ecosystem, and with the power of web components, they can be the basis of applications outside of their ecosystem, too! + - [Lion Web Components by ING Bank](https://github.com/ing-bank/lion) Lion web components is a set of highly performant, accessible and flexible Web Components. They provide an unopinionated, white label layer that can be extended to your own layer of components. + - [Material Web Components](https://material-components.github.io/material-components-web-components/demos/index.html) Material Design Components from Material Design team themselves. Stay as close as possible to the changing specification with these components from Google's own Material Design team. + - [Morningstar](http://designsystem.morningstar.com/components/component-status.html) The Morningstar Design System combines vanilla HTML/CSS with web components in just the right proportions to empower the design and development of wide reaching content and functionality. + - [UI5 Web Components](https://sap.github.io/ui5-webcomponents/) Get the power and flexibility of SAP's UI5 rendering stack with the ergonomics and ease of use of web components, and bring enterprise-grade features, Fiori UX and themeability home to your application. + - [Smart HTML Elements](https://www.htmlelements.com) With the goal of helping to deliver modern responsive websites and applications that work on any device and are pleasure to use, the Smart HTML Elements collection is one the most feature rich and comprehensive javascript user interface frameworks. + - [Vaadin](https://vaadin.com/components) Vaadin has a comprehensive set of beautifully crafted, performant, and adaptable UI components for modern mobile-first Web apps. They are the ideal building blocks for Progressive Web Applications. + - [Weightless](https://weightless.dev/) A lightweight component library featuring a wide array of design concepts. It surfaces a good amount of customizability via comprehensive component and CSS Custom Property APIs with a small footprint, [just short of 30KB](https://bundlephobia.com/result?p=weightless@0.0.34). + - [Wired Elements](https://wiredjs.com/) A set of common UI elements with a hand-drawn, sketchy look. These can be used for wireframes, mockups, or just the fun hand-drawn look. diff --git a/docs/faq/rerender.md b/docs/faq/rerender.md index 7296d93c..9c5651cd 100644 --- a/docs/faq/rerender.md +++ b/docs/faq/rerender.md @@ -3,18 +3,22 @@ # Modifying an array or objects members does not trigger rerender Imagine the following scenario: you've created a custom element that observes an `items` property: + ```js class MyEl extends LitElement { - render() {/*...*/} + render() { + /*...*/ + } static get properties() { return { - items: { type: Array } - } + items: { type: Array }, + }; } } ``` -You might think that changing *one of* the items should trigger a rerender: +You might think that changing _one of_ the items should trigger a rerender: + ```js const myEl = document.querySelector('my-el'); myEl.items; // [{ name: 'foo' }, { name: 'bar' }] @@ -24,16 +28,19 @@ myEl.items[0].name = 'baz'; But this won't cause the element to update. Why not? ### Reference Values + Javascript has two kinds of types: direct values and reference values. Direct values are things like `'a string'` or `1` or `true`. Their value flows directly from what they are, and there's no ambiguity - the number 1 is always and simply the number 1. Reference values like `Object` and `Array` are like containers for multiple direct (or reference) values. An array for instance can contain multiple values at any numeric index. -In the case of direct values, equality is determined by directly comparing the value: +In the case of direct values, equality is determined by directly comparing the value: + ```js -1 === 1 // true -'three' === 'three' // true +1 === 1; // true +'three' === 'three'; // true ``` -But in the case of reference types, the thing that is compared is the *reference* to the object, not its contents. +But in the case of reference types, the thing that is compared is the _reference_ to the object, not its contents. + ```js const o = { foo: 'bar' } const p === { foo: 'bar' } @@ -41,19 +48,17 @@ o === p // false ``` ### LitElement's Property System + LitElement's property system only observes changes to the reference. Recursively listening for changes to child properties would be prohibitively expensive, especially for large nested objects. -Therefore, setting a child or grandchild property of `myEl.items` will *not* trigger a render. +Therefore, setting a child or grandchild property of `myEl.items` will _not_ trigger a render. So what can we do if we need to update a nested child? Immutable data patterns can help us. ```js const [oldItem, ...rest] = myEl.items; const newItem = { name: 'baz' }; -myEl.items = [ - newItem, - ...rest, -]; +myEl.items = [newItem, ...rest]; ``` For objects, the syntax is even simpler: @@ -62,15 +67,16 @@ For objects, the syntax is even simpler: // example of updating the `changed` property on `myEl.objectProperty` myEl.objectProperty = { ...myEl.objectProperty, - changed: newVal + changed: newVal, }; ``` ### Summary + Polymer slack user Dracco adds: > Actually it's not about JS, every objective language can have a collection structure, but modifying the collection does not modify the object. -> Comparing in JS means comparing references (it would be impossible to make a universal and fast content comparison), so pushing things to an array keeps the reference the same (as it is still the same instance of an Array class) - just the contents change. -> Similarly in `class Person { constructor() { this.isBanned = false; } }`, if you create a new instance (`const p = new Person();`) and then modify the property (`p.isBanned = true;`), it is still the same instance it was before, just the property differs. +> Comparing in JS means comparing references (it would be impossible to make a universal and fast content comparison), so pushing things to an array keeps the reference the same (as it is still the same instance of an Array class) - just the contents change. +> Similarly in `class Person { constructor() { this.isBanned = false; } }`, if you create a new instance (`const p = new Person();`) and then modify the property (`p.isBanned = true;`), it is still the same instance it was before, just the property differs. -- Dracco diff --git a/docs/faq/unit-testing-custom-events.md b/docs/faq/unit-testing-custom-events.md index 81ee2355..334acf8c 100644 --- a/docs/faq/unit-testing-custom-events.md +++ b/docs/faq/unit-testing-custom-events.md @@ -1,18 +1,20 @@ # Testing Event Listeners in lifecycle events Let's say you have a mixin that dispatches an event on `firstUpdated` and `connectedCallback`: -```js -const mixin = superclass => class extends superclass { - firstUpdated() { - super.firstUpdated(); - this.dispatchEvent(new CustomEvent('first-updated')); - } - connectedCallback() { - super.connectedCallback(); - this.dispatchEvent(new CustomEvent('connected-callback')); - } -}; +```js +const mixin = superclass => + class extends superclass { + firstUpdated() { + super.firstUpdated(); + this.dispatchEvent(new CustomEvent('first-updated')); + } + + connectedCallback() { + super.connectedCallback(); + this.dispatchEvent(new CustomEvent('connected-callback')); + } + }; ``` These are the suggested ways of testing these events: @@ -32,7 +34,6 @@ it('dispatches a custom event on firstUpdated', async () => { }); ``` - #### connectedCallback For `connectedCallback`, since this callback is fired immediately after calling `fixture`, you can't catch it anymore. What you can do is define a new component and test its callback function in a `setTimeout`. diff --git a/docs/faq/unit-testing-init-error.md b/docs/faq/unit-testing-init-error.md index 2df5427a..39cacea2 100644 --- a/docs/faq/unit-testing-init-error.md +++ b/docs/faq/unit-testing-init-error.md @@ -27,11 +27,9 @@ This method should be called before the first render when the element gets attac ## The test case ```js -it("should throw when missing definition property", async () => { +it('should throw when missing definition property', async () => { const el = new StringField(); - expect(() => el.checkProperties()).to.throw( - 'property "definition" required' - ); + expect(() => el.checkProperties()).to.throw('property "definition" required'); }); ``` @@ -45,7 +43,7 @@ it('checkProperties gets called', async () => { checkProperties() { checkCalled = true; } - } + }, ); await fixture(`<${tag}>`); expect(checkCalled).to.be.true; diff --git a/docs/guide/README.md b/docs/guide/README.md index cee8fac0..897e5f37 100644 --- a/docs/guide/README.md +++ b/docs/guide/README.md @@ -13,6 +13,7 @@ npm init @open-wc ``` ## Available Recommendations + - [Developing](/developing/) - [Linting](/linting/) - [Testing](/testing/) @@ -26,8 +27,10 @@ npm init @open-wc You can read all about our motivation and our philosophy [here](/about/). ## FAQ + - [FAQ](/faq/) ## Example + The [Set-Game Example](https://github.com/open-wc/example-vanilla-set-game/) uses all the above recommendations. You can find a published storybook here: [https://example-set-game-open-wc.netlify.com/](https://example-set-game-open-wc.netlify.com/). diff --git a/docs/linting/README.md b/docs/linting/README.md index eaf0fc97..6f9f89cc 100644 --- a/docs/linting/README.md +++ b/docs/linting/README.md @@ -3,12 +3,14 @@ Linting can help you write consistent code, and easily prevent mistakes. Open-wc recommends the following tools: We recommend + - [ESLint](https://eslint.org/) to lint your es6 code - [Prettier](https://prettier.io/) to auto format your code - [lint-staged](https://www.npmjs.com/package/lint-staged) to apply linting fixed only to changed files - [commitlint](https://www.npmjs.com/package/@commitlint/cli) so commit messages follow a certain flow ## Setup + ```bash npm init @open-wc # Upgrade > Linting @@ -19,6 +21,7 @@ This is part of the default [open-wc](https://open-wc.org/) recommendation ::: ### Manual + - `yarn add --dev @open-wc/eslint-config @open-wc/prettier-config lint-staged husky @commitlint/cli @commitlint/config-conventional` - Copy [.eslintignore](https://github.com/open-wc/open-wc/blob/master/packages/create/src/generators/linting-eslint/templates/static/.eslintignore) to `.eslintignore` - Copy [.eslintrc.js](https://github.com/open-wc/open-wc/blob/master/packages/create/src/generators/linting-prettier/templates/static/.eslintrc.js) to `.eslintrc.js` @@ -54,6 +57,7 @@ This is part of the default [open-wc](https://open-wc.org/) recommendation ## Usage Run: + - `npm run lint` to check if any file is correctly formatted - `npm run format` to auto format your files diff --git a/docs/linting/linting-types.md b/docs/linting/linting-types.md index 3d0b0671..2ddce438 100644 --- a/docs/linting/linting-types.md +++ b/docs/linting/linting-types.md @@ -3,6 +3,7 @@ Use [TypeScript](https://www.typescriptlang.org/) to type lint your es6 JSDoc annotated code. ## Setup + ```bash npm init @open-wc linting-types-js ``` @@ -12,6 +13,7 @@ This is an OPTIONAL recommendation. You will need to opt-in by running the gener ::: ## Manual + - `yarn add --dev typescript` - Copy [tsconfig.json](https://github.com/open-wc/open-wc/blob/master/packages/create/src/generators/linting-types-js/templates/static/tsconfig.json) to `tsconfig.json` - Add these scripts to your package.json @@ -32,6 +34,7 @@ For general information about types please see [developing/types](../developing/ ## Usage Run: + - `npm run lint:types` to check if you have type errors ## Type linting error example diff --git a/docs/publishing/README.md b/docs/publishing/README.md index 7e97bac9..41580064 100644 --- a/docs/publishing/README.md +++ b/docs/publishing/README.md @@ -12,12 +12,14 @@ To publish your Web Component we recommend [netlify](https://www.netlify.com/). Head over to [netlify](https://www.netlify.com/) and register. Select your github account and repository. If you follow these recommendations all you need to do is + - Build command: `npm run site:build` - Publish directory: `_site` And you're all set up. ## Example + The [Set-Game Example](https://github.com/open-wc/example-vanilla-set-game/) has the default publishing via storybook on netlify. You can see the finished page here: [https://example-set-game-open-wc.netlify.com/](https://example-set-game-open-wc.netlify.com/). @@ -28,6 +30,7 @@ If you're using our [build configuration](http://open-wc.org/building), the `dis - Build command: `npm run build` - Copy the `dist` directory to your desired location: `sudo cp -R dist /Library/WebServer/Documents/myapp` - Add a `` directive to `httpd.conf`, either directly or by an `Include` directive: + ``` DocumentRoot "/Library/WebServer/Documents/myapp" @@ -40,6 +43,7 @@ If you're using our [build configuration](http://open-wc.org/building), the `dis ``` + - Restart Apache: `sudo /usr/sbin/apachectl restart` - Open the page in your browser using the URL `http://mypwa.localhost/` diff --git a/docs/testing/README.md b/docs/testing/README.md index 0017317c..e7728d10 100644 --- a/docs/testing/README.md +++ b/docs/testing/README.md @@ -1,6 +1,6 @@ # Testing -[//]: # (AUTO INSERT HEADER PREPUBLISH) +[//]: # 'AUTO INSERT HEADER PREPUBLISH' Testing is an important part of any software project. We have collected a set of libraries, tools and best practices to get you started with testing. diff --git a/packages/building-rollup/README.md b/packages/building-rollup/README.md index e728a4e9..5ba568eb 100644 --- a/packages/building-rollup/README.md +++ b/packages/building-rollup/README.md @@ -439,8 +439,7 @@ Alternatively, you can create a `workbox-config.js` in the root of your project, ```js const { createDefaultConfig } = require('@open-wc/building-rollup'); const deepmerge = require('deepmerge'); -const { injectManifest, /* generateSW */ } = require('rollup-plugin-workbox'); - +const { injectManifest /* generateSW */ } = require('rollup-plugin-workbox'); const basicConfig = createDefaultConfig({ input: './index.html', @@ -452,9 +451,7 @@ const basicConfig = createDefaultConfig({ const workboxConfig = require('./workbox-config.js'); export default merge(basicConfig, { - plugins: [ - injectManifest(workboxConfig), - ], + plugins: [injectManifest(workboxConfig)], }); ``` diff --git a/packages/building-utils/README.md b/packages/building-utils/README.md index 7111ef41..74a2876f 100644 --- a/packages/building-utils/README.md +++ b/packages/building-utils/README.md @@ -1,6 +1,6 @@ # Building utils -[//]: # (AUTO INSERT HEADER PREPUBLISH) +[//]: # 'AUTO INSERT HEADER PREPUBLISH' Utils for `@open-wc` building packages. diff --git a/packages/building-webpack/README.md b/packages/building-webpack/README.md index 70bc7212..9afdd59e 100644 --- a/packages/building-webpack/README.md +++ b/packages/building-webpack/README.md @@ -1,8 +1,9 @@ # Webpack -[//]: # (AUTO INSERT HEADER PREPUBLISH) +[//]: # 'AUTO INSERT HEADER PREPUBLISH' ## Configuration + Webpack configuration to help you get started building modern web applications. You write modern javascript using the latest browser features, webpack will optimize your code for production ensure it runs on all supported browsers. The input for webpack is the same `index.html` you use for development. Any module scripts in your index are run through webpack and your index is updated with the output from rollup. @@ -12,11 +13,13 @@ See 'config features' for all details. See the extending section for customizati ## Setup ### New project + ```bash npm init @open-wc ``` ### Existing project + ```bash npm init @open-wc # Upgrade > Building > Webpack @@ -25,6 +28,7 @@ npm init @open-wc ### Manual setup 1. Install the required dependencies: + ```bash npm i -D @open-wc/building-webpack webpack webpack-cli es-dev-server ``` @@ -47,8 +51,9 @@ module.exports = createDefaultConfig({ ``` 3. Create an `index.html`: + ```html - + @@ -62,35 +67,42 @@ module.exports = createDefaultConfig({ We use [webpack-index-html-plugin](https://open-wc.org/building/webpack-index-html-plugin.html). Contrary to other webpack plugins, you **do** need to include your app's module entrypoint in your `index.html`. This allows you to use the same index during development and when building. 4. Add the following commands to your `package.json`: + ```json { "scripts": { "build": "webpack --mode production", - "start:build": "es-dev-server --app-index dist/index.html --open", + "start:build": "es-dev-server --app-index dist/index.html --open" } } ``` + - `start` runs your app for development, reloading on file changes - `start:build` runs your app after it has been built using the build command - `build` builds your app and outputs it in your `dist` directory ## Browser support + `createDefaultConfig` creates a single build of your app for modern browsers (by default last 2 of major browsers). This is recommended if you only need to support modern browsers, otherwise you will need to ship compatibility code for browsers which don't need it. `createCompatibilityConfig` creates two builds of your app. A modern build like the above, and a legacy build for IE11. Additional code is injected to load polyfills and the correct version of your app. This is recommended if you need to support IE11. ## Config features + All configs: + - resolve bare imports (`import { html } from 'lit-html'`) - preserve `import.meta.url` value from before bundling - minify + treeshake js - minify html and css in template literals `createDefaultConfig`: + - single build output - compatible with any browser which supports Web Components `createCompatibilityConfig`: + - Two build outputs: - Modern: - compatible with modern browsers (default: last 2 chrome, firefox safari and edge) @@ -106,19 +118,19 @@ All configs: See below for more configuration options. ## Customizing the babel config + You can define your own babel plugins by adding a `.babelrc` or `babel.config.js` to your project. See [babeljs config](https://babeljs.io/docs/en/configuration) for more information. For example to add support for class properties: ```json { - "plugins": [ - "@babel/plugin-proposal-class-properties" - ] + "plugins": ["@babel/plugin-proposal-class-properties"] } ``` ## Adjusting browser support for the modern build + The legacy build targets IE11, which is the earliest browser supported by the webcomponents polyfill. For the modern build we target the lates 2 versions of the major browsers (chrome, firefox, safari and edge). You can adjust this by adding a [browserslist](https://github.com/browserslist/browserslist) configuration. For example by adding a `.browserslistrc` file to your project, or adding an entry to your package.json. See the [browserslist documentation](https://github.com/browserslist/browserslist) for more information. @@ -126,7 +138,9 @@ You can adjust this by adding a [browserslist](https://github.com/browserslist/b > Note: you should not add IE11 or other very early browsers as a target in your browserslist, as it would result in a broken modern build because it makes some assumptions around browser support. Use the `--legacy` flag for legacy builds. ## Extending the webpack config + A webpack config is an object. To extend it, we recommend using `webpack-merge` to ensure plugins are merged correctly. For example to adjust the output folder: + ```javascript const merge = require('webpack-merge'); const { createDefaultConfig } = require('@open-wc/building-webpack'); @@ -137,7 +151,7 @@ const config = createDefaultConfig({ module.exports = merge(config, { output: { - path: 'build' + path: 'build', }, }); ``` @@ -152,19 +166,23 @@ const configs = createCompatibilityConfig({ input: path.resolve(__dirname, './index.html'), }); -module.exports = configs.map(config => merge(config, { - output: { - path: 'build' - }, -})); +module.exports = configs.map(config => + merge(config, { + output: { + path: 'build', + }, + }), +); ``` ### Common extensions + ::: warning Some extensions or plugins add non-native or experimental features to your code. This can be bad for the maintenance of your code in the long term, we therefore don't recommend it unless you know what you're doing. ::: #### Customizing index.html output + If you need to customize the output of your `index.html` you can pass extra options to [webpack-index-html-plugin](https://open-wc.org/building/webpack-index-html-plugin.html): ```javascript @@ -185,6 +203,7 @@ module.exports = createDefaultConfig({ See the documentation for all options. #### non index.html entrypoint + By default we look for an `index.html` as entrypoint. If want to use regular entrypoints you will need to provide your `index.html` for output manually: ```javascript @@ -205,6 +224,7 @@ module.exports = createDefaultConfig({ ``` #### Adding or removing polyfills + By default we polyfill `core-js`, `webcomponentsjs` and `fetch`. It is possile to add or remove polyfills by passing `webpack-index-html` configuration like above: ```javascript @@ -232,6 +252,7 @@ module.exports = createDefaultConfig({ [See the documentation](https://open-wc.org/building/webpack-index-html-plugin.html) for more information. #### Copy assets + Web apps often include assets such as css files and images. These are not part of your regular dependency graph, so they need to be copied into the build directory. [copy-webpack-plugin](https://github.com/webpack-contrib/copy-webpack-plugin) is a popular plugin fo this. @@ -252,11 +273,7 @@ const configs = createCompatibilityConfig({ module.exports = [ // add plugin to the first config merge(configs[0], { - plugins: [ - new CopyWebpackPlugin([ - 'images/**/*.png', - ]), - ], + plugins: [new CopyWebpackPlugin(['images/**/*.png'])], }), // the second config left untouched @@ -265,13 +282,14 @@ module.exports = [ ``` #### Support typescript + Make sure to prevent any compilation done by the typescript compiler `tsconfig.json`, as babel and webpack do this for you: ```json { "compilerOptions": { "target": "ESNEXT", - "module": "ESNext", + "module": "ESNext" } } ``` @@ -279,45 +297,44 @@ Make sure to prevent any compilation done by the typescript compiler `tsconfig.j Within webpack there are two options to add typescript support. ##### 1. Babel + We recommend using the babel typescript plugin. Add this to your `.babelrc`: + ```json { - "presets": [ - "@babel/preset-typescript" - ], + "presets": ["@babel/preset-typescript"] } ``` This the fastest method, as it strips away types during babel transformormation of your code. It will not perform any type checking though. We recommend setting up the type checking as part of your linting setup, so that you don't need to run the typechecker during development for faster builds. -

Supporting decorators - ::: warning - Please note that decorators will add [non standard syntax](https://open-wc.org/building/building-webpack.html#common-extensions) to your code. - ::: +::: warning +Please note that decorators will add [non standard syntax](https://open-wc.org/building/building-webpack.html#common-extensions) to your code. +::: + +```json +{ + "presets": ["@babel/preset-typescript"], + // for libraries that support babel decorators (lit-element) use: + "plugins": [ + ["@babel/plugin-proposal-decorators", { "decoratorsBeforeExport": true }], + "@babel/plugin-proposal-class-properties" + ] + // for libraries that only support typescript: + // "plugins": [ + // ["@babel/plugin-proposal-decorators", { "legacy": true }], + // ["@babel/plugin-proposal-class-properties", { "loose": true }] + // ], +} +``` - ```json - { - "presets": [ - "@babel/preset-typescript" - ], - // for libraries that support babel decorators (lit-element) use: - "plugins": [ - ["@babel/plugin-proposal-decorators", { "decoratorsBeforeExport": true }], - "@babel/plugin-proposal-class-properties" - ] - // for libraries that only support typescript: - // "plugins": [ - // ["@babel/plugin-proposal-decorators", { "legacy": true }], - // ["@babel/plugin-proposal-class-properties", { "loose": true }] - // ], - } - ```
##### 2. Plugin + It is also possible to add the webpack typescript plugin, which does typechecking and compiling for you: ```javascript @@ -342,8 +359,7 @@ module.exports = configs.map(config => ### Making your app installable -Make sure your PWA meets the installable criteria, which you can find [here](https://developers.google.com/web/fundamentals/app-install-banners/). You can find a tool to generate your `manifest.json` [here](https://www.pwabuilder.com/generate). When your app has a service worker with a `fetch` handler (generated by this configuration), a `manifest.json`, and is served over HTTPS, your app is ready to be installed. - +Make sure your PWA meets the installable criteria, which you can find [here](https://developers.google.com/web/fundamentals/app-install-banners/). You can find a tool to generate your `manifest.json` [here](https://www.pwabuilder.com/generate). When your app has a service worker with a `fetch` handler (generated by this configuration), a `manifest.json`, and is served over HTTPS, your app is ready to be installed. ### Enabling the service worker @@ -358,9 +374,10 @@ This configuration will by default generate a service worker for you, using [wor } ``` + ### Overriding the workbox config -If you want to override the default config with your own workbox configuration, you can disable the default workbox configuration by setting `options.plugins.workbox` to false in the `options` object that you pass to `createBasicConfig`, and then you can override the plugins +If you want to override the default config with your own workbox configuration, you can disable the default workbox configuration by setting `options.plugins.workbox` to false in the `options` object that you pass to `createBasicConfig`, and then you can override the plugins ```js const merge = require('deepmerge'); @@ -370,13 +387,12 @@ const createDefaultConfig = require('@open-wc/building-webpack'); const defaultConfig = createDefaultConfig({ plugins: { workbox: false, - } + }, }); module.exports = merge(defaultConfig, { plugins: [new InjectManifest(/* */)], }); - ``` You can find the options for configuring Workbox [here](https://developers.google.com/web/tools/workbox/modules/workbox-build). @@ -387,9 +403,9 @@ To opt out of using workbox to generate a service worker, you can disabled it by ```js module.exports = createBasicConfig({ - plugins: { - workbox: false - } + plugins: { + workbox: false, + }, }); ``` @@ -397,7 +413,7 @@ module.exports = createBasicConfig({ By default, the service worker generated will _not_ call `skipWaiting`. The reason for this is that it becomes very painful very quickly if you're lazyloading code in your application. -If you want to add a user-friendly 'Add To Home Screen' experience, you can use the [pwa-update-available](https://github.com/thepassle/pwa-helpers) web component. +If you want to add a user-friendly 'Add To Home Screen' experience, you can use the [pwa-update-available](https://github.com/thepassle/pwa-helpers) web component. - - - ``` +```json +{ + "presets": ["@babel/preset-typescript"] +} +``` - 4. Run `es-dev-server` with these flags: - ```bash - es-dev-server --file-extensions .ts --node-resolve --babel --open - ``` +3. Import a typescript file from your `index.html` - To add support for experimental features that are normally handled by the typescript compiler, you can add extra babel plugins: +```html + + - 1. Install the plugins: - ```bash - npm i --save-dev @babel/plugin-proposal-decorators @babel/plugin-proposal-class-properties - ``` + + + + +``` - 2. Update your babel configuration: - ```json - { - "presets": [ - "@babel/preset-typescript" - ], - // for libraries that support babel decorators (lit-element) use: - "plugins": [ - ["@babel/plugin-proposal-decorators", { "decoratorsBeforeExport": true }], - "@babel/plugin-proposal-class-properties" - ] - // for libraries that only support typescript: - // "plugins": [ - // ["@babel/plugin-proposal-decorators", { "legacy": true }], - // ["@babel/plugin-proposal-class-properties", { "loose": true }] - // ], - } - ``` +4. Run `es-dev-server` with these flags: + +```bash +es-dev-server --file-extensions .ts --node-resolve --babel --open +``` + +To add support for experimental features that are normally handled by the typescript compiler, you can add extra babel plugins: + +1. Install the plugins: + +```bash +npm i --save-dev @babel/plugin-proposal-decorators @babel/plugin-proposal-class-properties +``` + +2. Update your babel configuration: + +```json +{ + "presets": ["@babel/preset-typescript"], + // for libraries that support babel decorators (lit-element) use: + "plugins": [ + ["@babel/plugin-proposal-decorators", { "decoratorsBeforeExport": true }], + "@babel/plugin-proposal-class-properties" + ] + // for libraries that only support typescript: + // "plugins": [ + // ["@babel/plugin-proposal-decorators", { "legacy": true }], + // ["@babel/plugin-proposal-class-properties", { "loose": true }] + // ], +} +``` @@ -314,37 +338,42 @@ Compatibility mode enables bundle-free development with features such as es modu Read more - If you want to make use of import maps, you can provide an import map in your `index.html`. To generate an import map, you can check out our package [import-maps-generate](https://github.com/open-wc/open-wc/tree/master/packages/import-maps-generate), or you can add one manually. +If you want to make use of import maps, you can provide an import map in your `index.html`. To generate an import map, you can check out our package [import-maps-generate](https://github.com/open-wc/open-wc/tree/master/packages/import-maps-generate), or you can add one manually. - Three modes can be enabled: - ### esm - `esm` mode adds [es-module-shims](https://github.com/guybedford/es-module-shims) to enable new module features such as dynamic imports and import maps. +Three modes can be enabled: - This mode has a negligible performance impact and is great when working on modern browsers. +### esm - ### modern - `modern` mode expands `esm` mode, adding a babel transform and a polyfill loader. +`esm` mode adds [es-module-shims](https://github.com/guybedford/es-module-shims) to enable new module features such as dynamic imports and import maps. - The babel transform uses the [present-env](https://babeljs.io/docs/en/babel-preset-env) plugin. This transforms standard syntax which isn't yet supported by all browsers. By default, it targets the latest two versions of Chrome, Safari, Firefox, and Edge. This can be configured with a [browserslist configuration](https://www.npmjs.com/package/browserslist). +This mode has a negligible performance impact and is great when working on modern browsers. - The polyfill loader does lightweight feature detection to determine which polyfills to load. By default it loads polyfills for web components, these can be turned off or custom polyfills can be added in the configuration. +### modern - This mode has a moderate performance impact. Use this when using new javascript syntax that is not yet supported on all browsers. +`modern` mode expands `esm` mode, adding a babel transform and a polyfill loader. - ### all - `all` mode expands `modern` mode by making your code compatible with browsers that don't yet support modules. +The babel transform uses the [present-env](https://babeljs.io/docs/en/babel-preset-env) plugin. This transforms standard syntax which isn't yet supported by all browsers. By default, it targets the latest two versions of Chrome, Safari, Firefox, and Edge. This can be configured with a [browserslist configuration](https://www.npmjs.com/package/browserslist). - In addition to the web component polyfills, it loads the general [core-js polyfills](https://www.npmjs.com/package/core-js) and a polyfill for [fetch](https://www.npmjs.com/package/whatwg-fetch) +The polyfill loader does lightweight feature detection to determine which polyfills to load. By default it loads polyfills for web components, these can be turned off or custom polyfills can be added in the configuration. - When loading your application it detects module support. If it is not supported, your app is loaded through [system-js](https://github.com/systemjs/systemjs) and your code is transformed to `es5`. +This mode has a moderate performance impact. Use this when using new javascript syntax that is not yet supported on all browsers. - The `es5` transformation is only done for browsers which don't support modules, so you can safely use this mode on modern browsers where it acts the same way as `modern` mode. +### all - `all` mode has the same moderate impact as `modern` mode on browsers that support modules. On browsers that don't support modules, it has a heavier impact. Use this mode if you want to verify if your code runs correctly on older browsers without having to run a build. +`all` mode expands `modern` mode by making your code compatible with browsers that don't yet support modules. + +In addition to the web component polyfills, it loads the general [core-js polyfills](https://www.npmjs.com/package/core-js) and a polyfill for [fetch](https://www.npmjs.com/package/whatwg-fetch) + +When loading your application it detects module support. If it is not supported, your app is loaded through [system-js](https://github.com/systemjs/systemjs) and your code is transformed to `es5`. + +The `es5` transformation is only done for browsers which don't support modules, so you can safely use this mode on modern browsers where it acts the same way as `modern` mode. + +`all` mode has the same moderate impact as `modern` mode on browsers that support modules. On browsers that don't support modules, it has a heavier impact. Use this mode if you want to verify if your code runs correctly on older browsers without having to run a build. ## Using es-dev-server programmatically + You can use different components from `es-dev-server` as a library and integrate it with other tools:
@@ -379,7 +408,7 @@ Returns an array of koa middleware functions. import Koa from 'koa'; import { createConfig, createMiddlewares } from 'es-dev-server'; -const config = createConfig({ }); +const config = createConfig({}); const middlewares = createMiddlewares(config); const app = new Koa(); diff --git a/packages/eslint-config/README.md b/packages/eslint-config/README.md index b7f5949f..96786599 100644 --- a/packages/eslint-config/README.md +++ b/packages/eslint-config/README.md @@ -1,10 +1,11 @@ # Linting ESLint -[//]: # (AUTO INSERT HEADER PREPUBLISH) +[//]: # 'AUTO INSERT HEADER PREPUBLISH' Use [ESLint](https://eslint.org/) to lint your es6 code. ## Setup + ```bash npm init @open-wc # Upgrade > Linting @@ -15,6 +16,7 @@ This is part of the default [open-wc](https://open-wc.org/) recommendation ::: ## Manual + - `yarn add --dev @open-wc/eslint-config` - Copy [.eslintignore](https://github.com/open-wc/open-wc/blob/master/packages/create/src/generators/linting-eslint/templates/static/.eslintignore) to `.eslintignore` - Copy [.eslintrc.js](https://github.com/open-wc/open-wc/blob/master/packages/create/src/generators/linting-eslint/templates/static/.eslintrc.js) to `.eslintrc.js` @@ -29,6 +31,7 @@ This is part of the default [open-wc](https://open-wc.org/) recommendation ## What you get This will install [`@open-wc/eslint-config`](https://github.com/open-wc/open-wc/blob/master/packages/eslint-config/index.js), a config based on airbnb but allows for some specialities needed for Web Components. + - Apply linting to js and html files - Apply linting for best practices - Allow dynamic module imports @@ -40,6 +43,7 @@ This will install [`@open-wc/eslint-config`](https://github.com/open-wc/open-wc/ ## Usage Run: + - `npm run lint:eslint` to check if any file is not correctly formatted - `npm run format:eslint` to auto format your files diff --git a/packages/import-maps-generate/README.md b/packages/import-maps-generate/README.md index 6a4ef742..9e06922e 100644 --- a/packages/import-maps-generate/README.md +++ b/packages/import-maps-generate/README.md @@ -1,6 +1,6 @@ # Generate Import Map -[//]: # (AUTO INSERT HEADER PREPUBLISH) +[//]: # 'AUTO INSERT HEADER PREPUBLISH' This will allow you to generate a flat [import-map](https://github.com/WICG/import-maps). It allows you to fix the "nested" npm problem for front end development. @@ -14,6 +14,7 @@ This is still in early beta (Windows paths are not supported yet) ::: ## Features + - Generates a flat import-map - Prompts the user when there are version conflicts that are not automatically resolvable - Supports resolutions, overrides, and deletions via the `importMap` property in package.json @@ -46,6 +47,7 @@ npx @import-map/generate You can add a `importMap` key in your `package.json` file to specify overrides, deletions or resolutions. `package.json`: + ``` { "name": "my-package", @@ -64,7 +66,7 @@ You can add a `importMap` key in your `package.json` file to specify overrides, ### Overrides -There may be times where you'll want to override certain imports. For example, if you're using the built-in `std:kv-storage` module along with `kv-storage-polyfill` for nonsupporting browsers, then `kv-storage-polyfill` will be in your lockfile. The generated import map will look like this: +There may be times where you'll want to override certain imports. For example, if you're using the built-in `std:kv-storage` module along with `kv-storage-polyfill` for nonsupporting browsers, then `kv-storage-polyfill` will be in your lockfile. The generated import map will look like this: ```json { @@ -87,10 +89,7 @@ You can achieve that via an override in your `package.json`'s `importMap` config "importMap": { "overrides": { "imports": { - "kv-storage-polyfill": [ - "std:kv-storage", - "/node_modules/kv-storage-polyfill/index.js" - ] + "kv-storage-polyfill": ["std:kv-storage", "/node_modules/kv-storage-polyfill/index.js"] } }, "deletions": ["kv-storage-polyfill/"] @@ -103,18 +102,17 @@ Note that if you apply overrides, you may also need to specify deletions for the ::: Which will result in the following import map: + ```json { "imports": { - "std:kv-storage": [ - "std:kv-storage", - "/node_modules/kv-storage-polyfill/index.js" - ] + "std:kv-storage": ["std:kv-storage", "/node_modules/kv-storage-polyfill/index.js"] } } ``` Overrides may be useful for: + - Polyfilling - Fixing a dependency with a local fork - Getting a dependency from a CDN instead @@ -135,12 +133,12 @@ You can also override entire scopes: } ``` - ### Deletions You can apply deletions to the generated import map by adding a `deletions` property to your package.json: `package.json`: + ```json { "importMap": { @@ -159,6 +157,7 @@ There may be times where you have conflicting versions of the same package in yo Alternatively, you can specify your own resolutions in your package.json. `package.json`: + ```json { "importMap": { @@ -170,11 +169,13 @@ Alternatively, you can specify your own resolutions in your package.json. ``` ## Command line flags overview + ### Development help -| name | type | description | -| --------------- | -------------- | ------------------------------------------------------------------------ | -| inject-to | string | Injects the import map to the specified html file | - + +| name | type | description | +| --------- | ------ | ------------------------------------------------- | +| inject-to | string | Injects the import map to the specified html file | + + + + My app + + + +

Hello world!

+ + + ``` 4. Optionally adds a loader script for conditionally loading polyfills and/or a separate build for older browsers. @@ -48,6 +66,7 @@ Rollup plugin to make rollup understand your index.html. Note that only module scripts with a `src` attribute are used as entrypoints, regular scripts and inline modules are minified but not parsed by rollup. ## Usage + To use this plugin, add it to your rollup configuration and set your index.html as entrypoint: ```js @@ -56,15 +75,14 @@ const indexHTML = require('rollup-plugin-index-html'); module.exports = { input: path.resolve(__dirname, './index.html'), - plugins: [ - indexHTML(config), - ], + plugins: [indexHTML(config)], }; ``` ## Configuration ### Polyfills + > Note when using `@open-wc/building-rollup` many polyfills are already configured for you. Depending on which browser you need to support you may need to polyfill certain browser features. To keep your bundles small, we don't serve any polyfills by default. You can enable polyfills in the configuration. @@ -72,6 +90,7 @@ Depending on which browser you need to support you may need to polyfill certain When enabling polyfills a small loader script is injected to your index.html. Polyfills are loaded based on feature detection. This causes a small delay in loading your app. We mediate this by adding a preload link during the build. To enable polyfills: + ```js indexHTML({ polyfills: { @@ -80,13 +99,14 @@ indexHTML({ webcomponents: true, fetch: true, intersectionObserver: true, - } -}) + }, +}); ``` `core-js` polyfills many language features such as `Promise`, `Symbol` and `String.prototype.includes`. `regeneratorRuntime` is necessary when you compile `async await` code which is transpiled to javascript ES5. These two polyfills are mainly for supporting legacy browsers. They are only loaded on browsers which don't support modules, such as IE11. The rest of the polyfills target specific browser features, see their documentation for more info: + - [core-js](https://github.com/zloirock/core-js) - [regenerator-runtime](https://github.com/facebook/regenerator/tree/master/packages/regenerator-runtime) - [webcomponents](https://github.com/webcomponents/webcomponentsjs) @@ -94,6 +114,7 @@ The rest of the polyfills target specific browser features, see their documentat - [intersection-observer](https://github.com/w3c/IntersectionObserver) If you need a polyfill which is not on this list, consider creating an issue so that we can add it. You can also specify custom polyfills: + ```js indexHTML({ polyfills: { @@ -111,10 +132,11 @@ indexHTML({ }, ], }, -}) +}); ``` ### Multi (legacy and modern) build + > Note when using `@open-wc/building-rollup/modern-and-legacy-config` the multi build is already configured for you If you need to support non-modern browsers, such IE11 or older versions of chrome, safari and firefox, it's better to create multiple builds of your app. @@ -137,7 +159,7 @@ module.exports = [ coreJs: true, regeneratorRuntime: true, webcomponents: true, - } + }, }), ], }, @@ -166,25 +188,29 @@ For the legacy build you do not need to configure any polyfills, as these are al You will probably need to use babel as well to transpile your code to ES5. Remember to change the browser targets for the modern and legacy build accordingly. For example latest 2 of the major browsers for modern and IE11 for the legac build. ### Minification + We use [html-minifier](https://github.com/kangax/html-minifier) for minifcation with a default configuration. You can adjust this configuration by passing a minify object: + ```js indexHTML({ minify: { // minify options - } -}) + }, +}); ``` The options object is passed as is to `html-minifier`. See the documentation of [html-minifier](https://github.com/kangax/html-minifier) for all possible minification options. It is also possible to turn off minification completely by passing minify: + ```js indexHTML({ - minify: false -}) + minify: false, +}); ``` ### Non index.html entrypoints + You can use this plugin without an index.html plugin if you still want to make use of the polyfilling features. You can do this by adding a custom template function: ```js @@ -213,6 +239,7 @@ module.exports = { ``` ### CSP + When loading polyfills we inject a small script in your index.html. If you need CSP you can separate the script in a separate file: ```js @@ -237,4 +264,5 @@ module.exports = { ], }; ``` + The template function receives the project's `assets` and `entries`. If applicable it also receives the `legacyEntries` and `variation`. diff --git a/packages/semantic-dom-diff/README.md b/packages/semantic-dom-diff/README.md index d2926434..ccb28f27 100644 --- a/packages/semantic-dom-diff/README.md +++ b/packages/semantic-dom-diff/README.md @@ -1,6 +1,6 @@ # Semantic Dom Diff -[//]: # (AUTO INSERT HEADER PREPUBLISH) +[//]: # 'AUTO INSERT HEADER PREPUBLISH' ## Manual Setup diff --git a/packages/testing-helpers/README.md b/packages/testing-helpers/README.md index 37151475..bca76138 100644 --- a/packages/testing-helpers/README.md +++ b/packages/testing-helpers/README.md @@ -1,6 +1,6 @@ # Testing Helpers -[//]: # (AUTO INSERT HEADER PREPUBLISH) +[//]: # 'AUTO INSERT HEADER PREPUBLISH' A library with helpers functions for testing in the browser. @@ -9,6 +9,7 @@ A library with helpers functions for testing in the browser. Testing helpers uses [lit-html](https://lit-html.polymer-project.org/), but it's set up as a peer dependency to avoid version conflicts. You don't need to write your components with lit-html to use this library, but you will need to install it: + ```bash npm i -D lit-html ``` @@ -16,6 +17,7 @@ npm i -D lit-html ::: # Usage + We recommend using this library through [@open-wc/testing](https://open-wc.org/testing/testing.html) which preconfigures and combines this library with other testing libraries. The examples that are shown here assume this setup, and import from `@open-wc/testing`. If you want to use this library standalone, you will need to import from `@open-wc/testing-helpers` directly instead: @@ -29,14 +31,17 @@ import { fixture } from '@open-wc/testing-helpers'; ``` ## Test fixtures + A test fixture renders a piece of HTML and injects into the DOM so that you can test the behavior of your component. It returns the first dom element from the template so that you can interact with it if needed. For example you can call functions, look up dom nodes or inspect the rendered HTML. Test fixtures are async to ensure rendering is properly completed. ### Templates + Test fixtures can be set up by using a string or a [lit-html](https://github.com/Polymer/lit-html) template. You don't need to use `lit-html` in your project to use the test fixtures, it just renders standard HTML. ### Test a custom element + ```js import { fixture } from '@open-wc/testing'; @@ -47,50 +52,64 @@ it('can instantiate an element', async () => { ``` ### Test a custom element with properties + ```js import { html, fixture } from '@open-wc/testing'; it('can instantiate an element with properties', async () => { - const el = await fixture(html``); + const el = await fixture( + html` + + `, + ); expect(el.foo).to.equal('bar'); -}) +}); ``` ### Test a custom class + If you're testing a mixin, or have multiple base classes that offer a various set of options you might find yourself in the situation of needing multiple custom element names in your tests. This can be dangerous as custom elements are global, so you don't want to have overlapping names in your tests. We recommend using the `defineCE` function to avoid that: + ```js import { fixture, defineCE } from '@open-wc/testing'; -const tag = defineCE(class extends MyMixin(HTMLElement) { - constructor() { - super(); - this.foo = true; - } -}); +const tag = defineCE( + class extends MyMixin(HTMLElement) { + constructor() { + super(); + this.foo = true; + } + }, +); const el = await fixture(`<${tag}>`); expect(el.foo).to.be.true; ``` ## Test a custom class with properties + For lit-html it's a little tougher as it does not support dynamic tag names by default. This uses a workaround that's not performant for rerenders, which is fine for testing, but do NOT use this in production code. ```js import { html, fixture, defineCE, unsafeStatic } from '@open-wc/testing'; -const tagName = defineCE(class extends MyMixin(HTMLElement) { - constructor() { - super(); - this.foo = true; - } -}); +const tagName = defineCE( + class extends MyMixin(HTMLElement) { + constructor() { + super(); + this.foo = true; + } + }, +); const tag = unsafeStatic(tagName); const el = await fixture(html`<${tag} .bar=${'baz'}>`); expect(el.bar).to.equal('baz'); ``` ## Timings + By default fixture awaits the elements "update complete" Promise. + - for [lit-element](https://github.com/polymer/lit-element) that is `el.updateComplete`; - for [stencil](https://github.com/ionic-team/stencil/) that is `el.componentOnReady()`; @@ -100,25 +119,38 @@ If none of those specfic Promise hooks are found, it will wait for one frame via Essentially, `fixture` creates a synchronous fixture, then waits for the element to finish updating, checking `updateComplete` first, then falling back to `componentReady()`, and `nextFrame()` as a last resort. This way, you can write your tests more succinctly, without having to explicitly `await` those hooks yourself. + ```js -const el = await fixture(html``); +const el = await fixture( + html` + + `, +); expect(el.foo).to.equal('bar'); // vs -const el = fixtureSync(html``); +const el = fixtureSync( + html` + + `, +); await elementUpdated(el); expect(el.foo).to.equal('bar'); ``` ### nextFrame + Uses `requestAnimationFrame` to wait for the next frame. + ```js await nextFrame(); ``` ### aTimeout + Waits for `x` ms via `setTimeout`; + ```js await aTimeout(10); // would wait 10ms ``` @@ -138,16 +170,17 @@ describe('Attributes', () => { const el = await fixture(''); expect(el.title).to.eq('test'); - el.title = "test 2" - await elementUpdated(el) + el.title = 'test 2'; + await elementUpdated(el); expect(el).dom.to.equal(``); }); //... - }) + }); }); ``` ## Testing Events + If you want to interact with web components you will sometimes need to await a specific event before you can continue testing. Ordinarily, you might pass the `done` callback to a test, and call it in the body of an event handler. This does not work with async test functions, though, which must return a promise instead of calling the `done` callback. @@ -179,6 +212,7 @@ it('can await an event', async () => { ``` ## Testing Focus & Blur on IE11 + Focus and blur events are synchronous events in all browsers except IE11. If you need to support that browser in your tests, you can await `triggerFocusFor` and `triggerBlurFor` helper functions. @@ -197,8 +231,10 @@ it('can be focused and blured', async () => { ``` ## Fixture Cleanup + By default, if you import anything via `import { ... } from '@open-wc/testing';`, it will automatically register a side-effect that cleans up your fixtures. If you want to be in full control you can do so by using + ```js import { fixture, fixtureCleanup } from '@open-wc/testing-helpers/index-no-side-effects.js'; diff --git a/packages/testing-karma-bs/README.md b/packages/testing-karma-bs/README.md index 43c5fa08..cfb3d8cf 100644 --- a/packages/testing-karma-bs/README.md +++ b/packages/testing-karma-bs/README.md @@ -1,6 +1,6 @@ # Testing via Browserstack -[//]: # (AUTO INSERT HEADER PREPUBLISH) +[//]: # 'AUTO INSERT HEADER PREPUBLISH' To make sure your project is production-ready, we recommend running tests in all the browsers you want to support. @@ -10,13 +10,17 @@ Browserstack offers free accounts for [open source projects](https://www.browser The `testing-karma-bs` configuration helps setting up karma with Browserstack. To set it up you need to use the configuration in your project, and follow the instructions below to set up a user account ## Setup + With our project scaffolding you can set up a pre-configured project, or you can upgrade an existing project by choosing `Upgrade -> Testing`: + ```bash npm init @open-wc ``` ### Manual + Install: + ```bash npm i -D @open-wc/testing-karma-bs deepmerge ``` @@ -42,6 +46,7 @@ module.exports = config => { ``` Add a script to your `package.json`: + ```json { "scripts": { @@ -51,6 +56,7 @@ Add a script to your `package.json`: ``` ### Setup user + key + - Go to [https://www.browserstack.com/accounts/settings](https://www.browserstack.com/accounts/settings) - Look for "Automate" and write down your "Access Key" and "Username" @@ -69,6 +75,7 @@ echo "Key: $BROWSER_STACK_ACCESS_KEY" ``` ### Usage + ```bash npm run test:bs ``` diff --git a/packages/testing-karma/README.md b/packages/testing-karma/README.md index c32fedd5..83e3b8c4 100644 --- a/packages/testing-karma/README.md +++ b/packages/testing-karma/README.md @@ -1,6 +1,6 @@ # Testing with Karma -[//]: # (AUTO INSERT HEADER PREPUBLISH) +[//]: # 'AUTO INSERT HEADER PREPUBLISH' We recommend karma as a general-purpose tool for testing code which runs in the browser. Karma can run a large range of browsers, including IE11. This way you are confident that your code runs correctly in all supported environments. @@ -9,11 +9,13 @@ During development you can run Chrome Headless, giving fast feedback in the term Karma can be used both for running unit tests, as well as for running more complex e2e/integration tests in the DOM. ## Getting started + Our configuration sets up karma to run tests based on es modules with the necessary polyfills and fallbacks for older browsers and convenient test reporting. This page explains how to set up `karma`, see the [testing overview](https://open-wc.org/testing/) for guides and libraries to get started with testing in general. ### Features + - Runs tests with es modules - Serves static files - Runs tests through mocha @@ -22,18 +24,23 @@ This page explains how to set up `karma`, see the [testing overview](https://ope - Supports older browsers (down to IE11) when passing the `compatibility` flag ## Setup + With our project scaffolding you can set up a pre-configured project, or you can upgrade an existing project by choosing `Upgrade -> Testing`: + ```bash npm init @open-wc ``` ### Manual + Install: + ```bash npm i -D @open-wc/testing-karma deepmerge karma ``` Create a `karma.conf.js`: + ```js const { createDefaultConfig } = require('@open-wc/testing-karma'); const merge = require('deepmerge'); @@ -47,21 +54,22 @@ module.exports = config => { // // npm run test -- --grep test/foo/bar.test.js // npm run test -- --grep test/bar/* - { pattern: config.grep ? config.grep : 'test/**/*.test.js', type: 'module' } + { pattern: config.grep ? config.grep : 'test/**/*.test.js', type: 'module' }, ], // see the karma-esm docs for all options esm: { // if you are using 'bare module imports' you will need this option - nodeResolve: true - } - }) + nodeResolve: true, + }, + }), ); return config; }; ``` Add scripts to your package.json: + ```json { "scripts": { @@ -75,7 +83,9 @@ Add scripts to your package.json: ``` ## Workflow + Commands explained: + - `test`: does a single test run on the configured browsers (default headless chrome) and prints tests and coverage results. - `test:watch`: does a single test run, and then re-runs on file changes. coverage is not analyzed for performance. in watch mode you can also visit http://localhost:9876/debug.html to debug in the browser - `test:update-snapshots`: updates any snapshots files from `@open-wc/semantic-dom-diff`. Use this when your component's rendered HTML changed. @@ -83,11 +93,13 @@ Commands explained: - `test:compatibility`: like `test:watch`, except that it makes your tests compatible with older browsers (including IE11). ## Testing single files or folders + By default, karma runs all your test files. To test a single file or folder, use the `--grep` flag. (If you did a manual setup, makes sure your config handles this flag). Pass which files to test to the grep flag: `npm run test -- --grep test/foo/bar.test.js`. ## Debugging in the browser + While testing, it can be useful to debug your tests in a real browser so that you can use the browser's dev tools. Use `npm run test:watch` to keep karma running. Then open the URL printed by karma when it boots up. By default, this is `http://localhost:9876/`. Click the debug button in the top right corner, or go directly to `http://localhost:9876/debug.html`. @@ -97,12 +109,13 @@ You can bookmark this page for easy access. Adding `debugger` statements will allow you to debug using the browser's dev tools. ## Testing on older browsers + By default, our configuration does not do any modifications to your code. It just runs it as is in the browser. Depending on which features you use, this should be fine for most major browsers. By passing the `compatibility` flag, we enable compatibility mode which makes your code run on older browsers as well. It loads polyfills and transforms modern syntax where needed. There are a few possible modes, but generally 'all' is sufficient for testing. This mode is powered by `karma-esm`. [Check out the documentaton](https://open-wc.org/testing/karma-esm.html) for more information. - ## Why don't you recommend testing tool X? + Sometimes people ask why we recommend Karma and not other popular testing tools. We're always on the lookout for improving our recommendations, so if you think we can do better please let us know. What's important for us is that the testing tool is robust, simple to use, does not require any building and runs in a real browser. Testing tools that don't use a real browser but something like jsdom constantly need to keep up with the latest browser standards, so you need to wait for your testing tool to update before you can use a new feature. It doesn't give the same confidence as testing in a real browser, and with Headless Chrome and Puppeteer it hardly seems necessary anymore. @@ -124,7 +137,7 @@ module.exports = config => { // // npm run test -- --grep test/foo/bar.test.js // npm run test -- --grep test/bar/* - { pattern: config.grep ? config.grep : 'test/**/*.test.js', type: 'module' } + { pattern: config.grep ? config.grep : 'test/**/*.test.js', type: 'module' }, ], coverageIstanbulReporter: { @@ -144,14 +157,17 @@ module.exports = config => { ``` ### Custom babel plugins or typescript support + `karma-esm` supports custom babel configurations and typescript. [Check out the documentaton](https://open-wc.org/testing/karma-esm.html) for more information. ### Testing in a monorepository + When testing without a bundler you will be serving every imported module straight from the file system. Karma cannot serve files outside the path of the webserver, which by default starts from the directory of your karma config. In a monorepo dependencies are often two levels higher in the root of the repository. To run tests in a monorepository you either have to put your config in the root of the repository, or adjust the basePath in your karma config: ### Other configuration + `karma-esm` is the plugin powering our configuration, and it supports a few more for advanced use cases. [Check out the documentaton](https://open-wc.org/testing/karma-esm.html) for more information. ```js @@ -161,9 +177,7 @@ const merge = require('deepmerge'); module.exports = config => { config.set( merge(createDefaultConfig(config), { - files: [ - { pattern: config.grep ? config.grep : 'test/**/*.test.js', type: 'module' } - ], + files: [{ pattern: config.grep ? config.grep : 'test/**/*.test.js', type: 'module' }], basePath: '../../', }), diff --git a/packages/testing-wallaby/README.md b/packages/testing-wallaby/README.md index 7ee6e5c2..04add27e 100644 --- a/packages/testing-wallaby/README.md +++ b/packages/testing-wallaby/README.md @@ -1,25 +1,30 @@ # Testing in IDE via Wallaby -[//]: # (AUTO INSERT HEADER PREPUBLISH) +[//]: # 'AUTO INSERT HEADER PREPUBLISH' Wallaby.js is a Plugin for your IDE and runs tests in real time while you are typing. Using: + - In IDE Testing via [wallaby.js](https://wallabyjs.com/) ## Setup + ```bash npm init @open-wc ``` ### Manual + 1. Copy the [config](https://github.com/open-wc/open-wc/blob/master/packages/create/src/generators/testing-wallaby/templates/static/wallaby.js) and save it as `wallaby.js` into your project root 2. `npm i -D @open-wc/testing-wallaby` ## Usage + Open your wallaby.js supported IDE and start with the provided config. ## Example + The [Set-Game Example](https://github.com/open-wc/example-vanilla-set-game/) has Wallaby Setup. + + + My app + + + +

Hello world!

+ + + ``` 4. Optionally adds a loader script for conditionally loading polyfills and/or a separate build for older browsers. @@ -48,6 +66,7 @@ Webpack plugin to make webpack understand your index.html. Note that only module scripts with a `src` attribute are used as entrypoints, regular scripts and inline modules are minified but not parsed by webpack. ## Usage + To use this plugin, add it to your webpack configuration and set your index.html as entrypoint: ```js @@ -62,16 +81,14 @@ module.exports = { chunkFilename: '[name].[chunkhash].js', }, - plugins: [ - new WebpackIndexHTMLPlugin(), - ], + plugins: [new WebpackIndexHTMLPlugin()], }; ``` ## Configuration - ### Polyfills + > Note when using `@open-wc/building-webpack` polyfills are already configured for you. Depending on which browser you need to support you may need to polyfill certain browser features. To keep your bundles small, we don't serve any polyfills by default. You can enable polyfills in the configuration. @@ -79,6 +96,7 @@ Depending on which browser you need to support you may need to polyfill certain When enabling polyfills a small loader script is injected to your index.html. Polyfills are loaded based on feature detection. This causes a small delay in loading your app. We mediate this by adding a preload link during the build. To enable polyfills: + ```js new WebpackIndexHTMLPlugin({ polyfills: { @@ -88,13 +106,14 @@ new WebpackIndexHTMLPlugin({ webcomponents: true, fetch: true, intersectionObserver: true, - } -}) + }, +}); ``` `core-js` polyfills many language features such as `Promise`, `Symbol` and `String.prototype.includes`. `regeneratorRuntime` is necessary when you compile `async await` code which is transpiled to javascript ES5. These two polyfills are mainly for supporting legacy browsers. They are only loaded on browsers which don't support modules, such as IE11. The rest of the polyfills target specific browser features, see their documentation for more info: + - [core-js](https://github.com/zloirock/core-js) - [regenerator-runtime](https://github.com/facebook/regenerator/tree/master/packages/regenerator-runtime) - [webcomponents](https://github.com/webcomponents/webcomponentsjs) @@ -102,6 +121,7 @@ The rest of the polyfills target specific browser features, see their documentat - [intersection-observer](https://github.com/w3c/IntersectionObserver) If you need a polyfill which is not on this list, consider creating an issue so that we can add it. You can also specify custom polyfills: + ```js new WebpackIndexHTMLPlugin({ polyfills: { @@ -125,6 +145,7 @@ You can disable the content hash in the distributed polyfill filenames by settin ``` ### Multi (legacy and modern) build + > Note when using `@open-wc/building-webpack/modern-and-legacy-config` the multi build is already configured for you If you need to support non-modern browsers, such IE11 or older versions of chrome, safari and firefox, it's better to create multiple builds of your app. @@ -147,7 +168,7 @@ module.exports = [ coreJs: true, regeneratorRuntime: true, webcomponents: true, - } + }, }), ], }, @@ -176,25 +197,29 @@ For the legacy build you do not need to configure any polyfills, as these are al You will probably need to use babel as well to transpile your code to ES5. Remember to change the browser targets for the modern and legacy build accordingly. For example latest 2 of the major browsers for modern and IE11 for the legac build. ### Minification + We use [html-minifier](https://github.com/kangax/html-minifier) for minifcation with a default configuration. You can adjust this configuration by passing a minify object: + ```js new WebpackIndexHTMLPlugin({ minify: { // minify options - } -}) + }, +}); ``` The options object is passed as is to `html-minifier`. See the documentation of [html-minifier](https://github.com/kangax/html-minifier) for all possible minification options. It is also possible to turn off minification completely by passing minify: + ```js new WebpackIndexHTMLPlugin({ - minify: false -}) + minify: false, +}); ``` ### Non index.html entrypoints + You can use this plugin without an index.html plugin if you still want to make use of the polyfilling features. You can do this by adding a custom template function: ```js @@ -223,6 +248,7 @@ module.exports = { ``` ### CSP + When loading polyfills we inject a small script in your index.html. If you need CSP you can separate the script in a separate file: ```js @@ -247,4 +273,5 @@ module.exports = { ], }; ``` + The template function receives the project's `assets` and `entries`. If applicable it also receives the `legacyEntries` and `variation`.