Giter Site home page Giter Site logo

abraham / nutmeg Goto Github PK

View Code? Open in Web Editor NEW
115.0 8.0 8.0 4.76 MB

Build, test, and publish vanilla Web Components with a little spice

Home Page: https://nutmeg.dev

License: MIT License

JavaScript 3.85% HTML 2.18% TypeScript 93.97%
webcomponents cli typescript javascript lit-html shadow-dom web-components custom-elements webpack karma

nutmeg's Introduction

Nutmeg icon

Nutmeg logo

Build, test, and publish vanilla Web Components with a little spice

Version Status macOS Build Status Linux Build Status Windows Build Status Dependency Status

🚧 Nutmeg is in active development and it's APIs are still in flux.

👌 Overview

Nutmeg is here to help you build, test, and publish Web Components in minutes.

By default you get the following:

  • Custom Elements v1
  • Shadow DOM v1
  • TypeScript
  • lit-html
  • Karma test runner with headless browser launchers
  • Git
  • MIT license
  • Web Component best practices

🌱 Build

Generating a Nutmeg Web Component skeleton with npm init has the API <element-name> [property:type...].

npm init @nutmeg hello-world name:string

This will create a hello-world directory, stub out a base Web Component class HelloWorld that extends the Nutmeg Seed base class, and install the default dependencies. You can use either fullName or full-name for multi-word properties and full-name will be used for HTML attributes and fullName will be used in JavaScript.

Note: Yarn is not supported but may work.

🏡 Properties

Properties must be valid TypeScript types. For example string, boolean, number, string[], Element.

npm init @nutmeg grilled-cheese quantity:number pickles:boolean cheese:string[]

Properties are the public API of your Web Component and external code can set/get them.

export class GrilledCheese extends Seed {
  @property() public bread: string;
  @property() public cheese: string[];
  @property() public pickles: boolean;
  @property() public quantity: number;
  ...
}

The @property() decorator provides some nice features out of the box. There are two kinds of properties.

  • Primitive: boolean, string, and number.
  • Complex: any types that are not primitive.

✍️ Automatic rendering

Any properties decorated with @property will automatically render when set.

📟 Primitive properties are reflected to the DOM

  • boolean: grilledCheese.pickle = true; => <grilled-cheese pickle></grilled-cheese>
  • number: grilledCheese.quantity = 5; => <grilled-cheese quantity="5"></grilled-cheese>
  • string: grilledCheese.bread = 'sourdough'; => <grilled-cheese bread="sourdough"></grilled-cheese>

📱 One-time complex property loading from attributes

On instantiation of a Web Component a one-time loading and JSON parsing happens of complex properties. In the following example cheese has the type of string[]. When connected the component will have the attribute removed and the value set as a property after JSON.parse.

The following example:

<grilled-cheese cheese="[\"sharp cheddar\"]"></grilled-cheese>

Yields:

grilledCheese.cheese.includes('sharp cheddar') === true;
<grilled-cheese></grilled-cheese>

$ and $$

$ and $$ are shortcuts provided for quickly selecting elements within the shadowRoot.

  • $ is a shortcut for this.shadowRoot.querySelector.
  • $$ is a shortcut for this.shadowRoot.querySelectorAll.

🍽️ Serve

You can now serve the component for development on http://localhost:8080 by running:

npm start

With start running you can make edits to the component and see the changes take effect automatically without manually refreshing.

🧪 Test

Running the tests from within hello-world.

npm test

🔭 Continuous Integration

Components are generated with AppVeyor, CircleCI, and TravisCI pre-configured to run tests on Windows, macOS, and Linux respectively.

🗞️ Publish

Publishing to NPM is easy but make sure you are logged in first with npm login. Be sure to fill out package.json values like author and update the name in readme.md if you change it.

npm publish

📇 Dependencies

Once published, it's recommended that you set up Renovate to keep your dependencies current. Nutmeg has already setup a default renovate config for you, you just have to install the free GitHub app.

😎 Best practices

Out of the box many of the Google Web Fundamentals Custom Element Best Practices are handled automatically.

🔍 Examples

👔 License

Nutmeg is released under an MIT license.

nutmeg's People

Contributors

abraham avatar dependabot[bot] avatar pearlbea avatar rarkins avatar renovate-bot avatar renovate[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nutmeg's Issues

CircleCI Firefox needs to be updated

https://circleci.com/gh/abraham/nutmeg-cli/259

10 01 2018 05:53:00.028:INFO [Firefox 47.0.0 (Linux 0.0.0)]: Connected on socket hzCZIQO9hf5qv7xGAAAB with id 80594156
WARN: 'Custom Elements: `Element#insertAdjacentElement` was not patched.'
Firefox 47.0.0 (Linux 0.0.0) ERROR
  {
    "message": "SyntaxError: missing = in const declaration\nat dist/ci-test.bundled.js:1579:19\n\n",
    "str": "SyntaxError: missing = in const declaration\nat dist/ci-test.bundled.js:1579:19\n\n"
  }

Action Required: Fix Renovate Configuration

There is an error with this repository's Renovate configuration that needs to be fixed. As a precaution, Renovate will stop PRs until it is resolved.

Error type: undefined. Note: this is a nested preset so please contact the preset author if you are unable to fix it yourself.

CI should fail when Karma has issues running tests

Even with #157 having tests fail to run the CI passes. If the tests fail to run CI needs to fail.

https://circleci.com/gh/abraham/nutmeg-cli/259

10 01 2018 05:53:00.028:INFO [Firefox 47.0.0 (Linux 0.0.0)]: Connected on socket hzCZIQO9hf5qv7xGAAAB with id 80594156
WARN: 'Custom Elements: `Element#insertAdjacentElement` was not patched.'
Firefox 47.0.0 (Linux 0.0.0) ERROR
  {
    "message": "SyntaxError: missing = in const declaration\nat dist/ci-test.bundled.js:1579:19\n\n",
    "str": "SyntaxError: missing = in const declaration\nat dist/ci-test.bundled.js:1579:19\n\n"
  }

https://travis-ci.org/abraham/nutmeg-cli/jobs/327924488

12 01 2018 00:10:01.108:ERROR [launcher]: Cannot start ChromeHeadless
	[0112/001000.972590:FATAL:setuid_sandbox_host.cc(157)] The SUID sandbox helper binary was found, but is not configured correctly. Rather than run without sandboxing I'm aborting now. You need to make sure that /opt/google/chrome/chrome-sandbox is owned by root and has mode 4755.
Failed to generate minidump.
12 01 2018 00:10:01.108:ERROR [launcher]: ChromeHeadless stdout: 
12 01 2018 00:10:01.108:ERROR [launcher]: ChromeHeadless stderr: [0112/001000.972590:FATAL:setuid_sandbox_host.cc(157)] The SUID sandbox helper binary was found, but is not configured correctly. Rather than run without sandboxing I'm aborting now. You need to make sure that /opt/google/chrome/chrome-sandbox is owned by root and has mode 4755.
Failed to generate minidump.
12 01 2018 00:10:01.109:ERROR [launcher]: ChromeHeadless failed 2 times (cannot start). Giving up.

Explore using webcomponentjs loader

<script src="./node_modules/@webcomponents/webcomponentsjs/webcomponents-loader.js"></script>
if (window.WebComponents !== undefined || !window.WebComponents.ready) {
  window.addEventListener('WebComponentsReady', () => {
    window.customElements.define('poly-async', PolyAsync);
  });
} else {
  window.customElements.define('poly-async', PolyAsync);
}

Open Requirements

Hi - I would love to contribute, but I'm shy of doing so without more details as to the requirements. Let me know if you want to chat about it.

Regards
Rodrigo

fix webcomponents-sd-ce.js reference

I'm having a 404 error in the demo sandbox that is produced by the script url import of webcomponents in the index.html.
Now is:
<script src="./node_modules/@webcomponents/webcomponentsjs/webcomponents-sd-ce.js"></script>
and it should be:
<script src="./node_modules/@webcomponents/webcomponentsjs/bundles/webcomponents-sd-ce.js"></script>

Fail to compile and serve when importing helper classes in the component

I migrated a web component library built using [email protected] to [email protected], and started experiencing problems serving the web component, which were not observed when using [email protected].

I created a very simple version of this library to illustrate the problem, you can find it at nutmeg-web-component-library, with three essential elements:

  • hello-world-simple: a vanilla [email protected] web component, with one minor change; the get template method calls a local method, renderWebComponent. It works fine.
  • hello-world-complex: a vanilla [email protected] web component, with one minor change; the get template method calls a renderWebComponent method in another class, UtilClass1, located in a separate folder, util-lib/src. This fails to serve, see below for the logs.
  • util-lib: a vanilla [email protected] web component, designed to hold the helper classes. Added util-class-1.ts, with the exported UtilClass1 helper class.

The challenge is that the recent nutmeg versions have abstracted so much from the developer, without proving enough documentation for me to hunt for the problem. I’m sure that if I read the source I’ll find the source, but I suspect that you will find the problem in two point four nanoseconds!

PS.: Two notes:

  • I read the source, and did not find a simple way to address it, other than writing my own scripts and webpack.config.js, as it was done before. Perhaps you might have a more elegant suggestion.
  • Until now I was using another application to visualize the component. I decided I like the simplicity of using the components' own index.html to valdate them before declaring them into an application.

[~/work/nutmeg-web-component-library/hello-world-complex]$ npm run start
11:15:44 - Starting compilation in watch mode...
11:15:45 - Found 0 errors. Watching for file changes.
ℹ 「wds」: Project is running at http://localhost:8080/
ℹ 「wds」: webpack output is served from /
ℹ 「wds」: Content not from webpack is served from /Users/rodrigomattososilveira/work/nutmeg-web-component-library/hello-world-complex
ℹ 「wdm」: wait until bundle finished: /
webpack v4.20.2
b4f2f30da6f232089fbd
size name module status
7.96 kB localhost:8080 (webpack)-dev-server/client?http://localhost:8080 built
3.67 kB overlay.js (webpack)-dev-server/client/overlay.js built
1.08 kB socket.js (webpack)-dev-server/client/socket.js built
509 B global.js (webpack)/buildin/global.js built
519 B module.js (webpack)/buildin/module.js built
170 B log$ (webpack)/hot sync nonrecursive ^./log$ built
52 B 0 multi (webpack)-dev-server/client?http://localhost:8080 (webpack)/hot/dev-server.js ./dist/hello-world-complex.js built ✖
1.64 kB dev-server.js (webpack)/hot/dev-server.js built
77 B emitter.js (webpack)/hot/emitter.js built
1.3 kB log-apply-result.js (webpack)/hot/log-apply-result.js built
1.13 kB log.js (webpack)/hot/log.js built
size name asset status
376 kB hello-world-complex.bundled hello-world-complex.bundled.js emitted
1.15 kB html index.html emitted
11:17:06 - Starting compilation in watch mode...
11:17:07 - Found 0 errors. Watching for file changes.
ℹ 「wds」: Project is running at http://localhost:8080/
ℹ 「wds」: webpack output is served from /
ℹ 「wds」: Content not from webpack is served from /Users/rodrigomattososilveira/work/nutmeg-web-component-library/hello-world-complex
ℹ 「wdm」: wait until bundle finished: /
webpack v4.20.2
b4f2f30da6f232089fbd
size name module status
7.96 kB localhost:8080 (webpack)-dev-server/client?http://localhost:8080 built
3.67 kB overlay.js (webpack)-dev-server/client/overlay.js built
1.08 kB socket.js (webpack)-dev-server/client/socket.js built
509 B global.js (webpack)/buildin/global.js built
519 B module.js (webpack)/buildin/module.js built
170 B log$ (webpack)/hot sync nonrecursive ^./log$ built
52 B 0 multi (webpack)-dev-server/client?http://localhost:8080 (webpack)/hot/dev-server.js ./dist/hello-world-complex.js built ✖
1.64 kB dev-server.js (webpack)/hot/dev-server.js built
77 B emitter.js (webpack)/hot/emitter.js built
1.3 kB log-apply-result.js (webpack)/hot/log-apply-result.js built
1.13 kB log.js (webpack)/hot/log.js built
size name asset status
376 kB hello-world-complex.bundled hello-world-complex.bundled.js emitted
1.15 kB html index.html emitted
Δt 621ms (16 modules hidden)
multi (webpack)-dev-server/client?http://localhost:8080 (webpack)/hot/dev-server.js ./dist/hello-world-complex.js
0:0 error Module not found: Error: Can't resolve
'/Users/rodrigomattososilveira/work/nutmeg-web-component-library/hello-world-complex/dist/hello-world-complex.js'
in
'/Users/rodrigomattososilveira/work/nutmeg-web-component-library/hello-world-complex'
✖ 1 problem (1 error, 0 warnings)
✖ 「wdm」: Hash: b4f2f30da6f232089fbd
Version: webpack 4.20.2
Time: 621ms
Built at: 2018-11-17 11:17:08
Asset Size Chunks Chunk Names
hello-world-complex.bundled.js 367 KiB hello-world-complex.bundled [emitted] hello-world-complex.bundled
index.html 1.13 KiB [emitted]
Entrypoint hello-world-complex.bundled = hello-world-complex.bundled.js
[./node_modules/ansi-html/index.js] 4.16 KiB {hello-world-complex.bundled} [built]
[./node_modules/loglevel/lib/loglevel.js] 7.68 KiB {hello-world-complex.bundled} [built]
[./node_modules/querystring-es3/index.js] 127 bytes {hello-world-complex.bundled} [built]
[./node_modules/webpack-dev-server/client/overlay.js] (webpack)-dev-server/client/overlay.js 3.58 KiB {hello-world-complex.bundled} [built]
[0] multi (webpack)-dev-server/client?http://localhost:8080 (webpack)/hot/dev-server.js ./dist/hello-world-complex.js 52 bytes {hello-world-complex.bundled} [built]
[./node_modules/sockjs-client/dist/sockjs.js] 177 KiB {hello-world-complex.bundled} [built]
[./node_modules/strip-ansi/index.js] 161 bytes {hello-world-complex.bundled} [built]
[./node_modules/url/url.js] 22.8 KiB {hello-world-complex.bundled} [built]
[./node_modules/webpack-dev-server/client/index.js?http://localhost:8080] (webpack)-dev-server/client?http://localhost:8080 7.78 KiB {hello-world-complex.bundled} [built]
[./node_modules/webpack-dev-server/client/socket.js] (webpack)-dev-server/client/socket.js 1.05 KiB {hello-world-complex.bundled} [built]
[./node_modules/webpack/hot sync ^./log$] (webpack)/hot sync nonrecursive ^./log$ 170 bytes {hello-world-complex.bundled} [built]
[./node_modules/webpack/hot/dev-server.js] (webpack)/hot/dev-server.js 1.61 KiB {hello-world-complex.bundled} [built]
[./node_modules/webpack/hot/emitter.js] (webpack)/hot/emitter.js 77 bytes {hello-world-complex.bundled} [built]
[./node_modules/webpack/hot/log-apply-result.js] (webpack)/hot/log-apply-result.js 1.27 KiB {hello-world-complex.bundled} [built]
[./node_modules/webpack/hot/log.js] (webpack)/hot/log.js 1.11 KiB {hello-world-complex.bundled} [built]
+ 12 hidden modules
ERROR in multi (webpack)-dev-server/client?http://localhost:8080 (webpack)/hot/dev-server.js ./dist/hello-world-complex.js
Module not found: Error: Can't resolve '/Users/rodrigomattososilveira/work/nutmeg-web-component-library/hello-world-complex/dist/hello-world-complex.js' in '/Users/rodrigomattososilveira/work/nutmeg-web-component-library/hello-world-complex'
@ multi (webpack)-dev-server/client?http://localhost:8080 (webpack)/hot/dev-server.js ./dist/hello-world-complex.js hello-world-complex.bundled[2]
Child HtmlWebpackCompiler:
1 asset
Entrypoint HtmlWebpackPlugin_0 = __child-HtmlWebpackPlugin_0
[./node_modules/html-webpack-plugin/lib/loader.js!./index.html] 1.31 KiB {HtmlWebpackPlugin_0} [built]
[./node_modules/lodash/lodash.js] 527 KiB {HtmlWebpackPlugin_0} [built]
[./node_modules/webpack/buildin/global.js] (webpack)/buildin/global.js 509 bytes {HtmlWebpackPlugin_0} [built]
[./node_modules/webpack/buildin/module.js] (webpack)/buildin/module.js 519 bytes {HtmlWebpackPlugin_0} [built]
ℹ 「wdm」: Failed to compile.

Provide more examples

  • External dependencies
  • Event API
  • Style API
  • Integrate with CI
  • Testing
  • Add/remove event listeners

Rework compiled formats

I'm thinking four modes would probably be good.

  • module - ES Module
  • main - UMD
  • browser - UMD bundled/minified

Maybe also:

  • ??? - ES Module bundled/minified

Loading an module version in a browser loads 1+ implementation file, 1 Nutmeg files, 14 lit-html files, and 1 reflection file.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.