@11ty/eleventy-plugin-webc 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.editorconfig CHANGED
@@ -10,3 +10,6 @@ charset = utf-8
10
10
 
11
11
  [*.js]
12
12
  insert_final_newline = true
13
+
14
+ [test/*.js]
15
+ trim_trailing_whitespace = false
package/README.md CHANGED
@@ -4,325 +4,33 @@
4
4
 
5
5
  Adds support for [WebC, the single file web component format](https://github.com/11ty/webc), to Eleventy.
6
6
 
7
- ## Features
8
-
9
- * All of the [framework-independent WebC features](https://github.com/11ty/webc#features) out of the box.
10
- * First-class incremental support (for page templates, components, and Eleventy layouts): use with `--incremental`
11
- * Tired of importing components? Use our new global or per-page no-import components.
12
- * Easily roll up the CSS and JS in-use by WebC components on a page for page-specific bundles. Dirt-simple critical CSS/JS to only load the code you need.
13
- * For more complex templating needs, you _can_ render any existing Eleventy template syntax (Liquid, markdown, Nunjucks, etc.) inside of WebC.
14
- * Works great with out of the box with [is-land](https://www.11ty.dev/docs/plugins/partial-hydration/)
7
+ * [This documentation has moved to 11ty.dev](https://www.11ty.dev/docs/languages/webc/).
8
+ * Watch the [crash course in Eleventy WebC on YouTube](https://www.youtube.com/watch?v=X-Bpjrkz-V8).
9
+ * Watch the [Interactive Components tutorial on YouTube](https://www.youtube.com/watch?v=p0wDUK0Z5Nw)
15
10
 
16
- ## ➡ [Documentation](https://www.11ty.dev/docs/languages/webc/)
11
+ [![npm Version](https://img.shields.io/npm/v/@11ty/eleventy-plugin-webc.svg?style=for-the-badge)](https://www.npmjs.com/package/@11ty/eleventy-plugin-webc)
17
12
 
18
- - Please star [Eleventy on GitHub](https://github.com/11ty/eleventy/)!
13
+ - Star [Eleventy on GitHub](https://github.com/11ty/eleventy/)!
19
14
  - Follow us on Twitter [@eleven_ty](https://twitter.com/eleven_ty)
20
15
  - Support [11ty on Open Collective](https://opencollective.com/11ty)
21
16
  - Subscribe to our [YouTube channel](https://11ty.dev/youtube)
22
- - [11ty on npm](https://www.npmjs.com/org/11ty)
23
- - [11ty on GitHub](https://github.com/11ty)
24
-
25
- [![npm Version](https://img.shields.io/npm/v/@11ty/eleventy-plugin-webc.svg?style=for-the-badge)](https://www.npmjs.com/package/@11ty/eleventy-plugin-webc)
26
-
27
- ## Installation
28
-
29
- It’s on [npm at `@11ty/eleventy-plugin-webc`](https://www.npmjs.com/package/@11ty/eleventy-plugin-webc)!
30
-
31
- ```
32
- npm install @11ty/eleventy-plugin-webc
33
- ```
34
-
35
- To add support for `.webc` files in Eleventy, add the plugin in your Eleventy configuration file:
36
-
37
- ```js
38
- const pluginWebc = require("@11ty/eleventy-plugin-webc");
39
-
40
- module.exports = function(eleventyConfig) {
41
- eleventyConfig.addPlugin(pluginWebc);
42
- };
43
- ```
44
-
45
- <details>
46
- <summary><strong>Full options list</strong></summary>
47
-
48
- ```js
49
- const pluginWebc = require("@11ty/eleventy-plugin-webc");
50
-
51
- module.exports = function(eleventyConfig) {
52
- eleventyConfig.addPlugin(pluginWebc, {
53
- // Glob to find no-import global components
54
- components: false,
55
- // components: "_includes/components/**/*.webc",
56
-
57
- // Adds an Eleventy WebC transform to process all HTML output
58
- useTransform: false,
59
-
60
- // Additional global data used in the Eleventy WebC transform
61
- transformData: {},
62
- });
63
- };
64
- ```
65
-
66
- </details>
67
-
68
- ### How to use it
69
-
70
- There are a few different ways to use WebC in Eleventy:
71
-
72
- 1. Add a new `.webc` file to your Eleventy input directory
73
- 1. Use the [Render plugin](https://www.11ty.dev/docs/plugins/render/) in an existing template
74
- 1. Preprocess all HTML input as WebC
75
- 1. Use the WebC Eleventy transform to process all of the HTML output (disabled by default)
76
-
77
- #### Add New `.webc` files
78
-
79
- Adding the plugin will enable support for `.webc` files in your Eleventy project. Just make a new `.webc` HTML file in your Eleventy input directory and Eleventy will process it for you! If you’re using [global components](#components), don’t forget to point the plugin to your components directory!
80
-
81
- Notably, `.webc` files will operate [WebC in bundler mode](https://github.com/11ty/webc#aggregating-css-and-js), [aggregating the CSS and JS](#css-and-js) in use on each individual page to create a bundle of the assets in use on the page.
82
-
83
- ```js
84
- const pluginWebc = require("@11ty/eleventy-plugin-webc");
85
-
86
- module.exports = function(eleventyConfig) {
87
- eleventyConfig.addPlugin(pluginWebc, {
88
- // Glob to find no-import global components
89
- components: "_includes/components/**/*.webc",
90
- });
91
- };
92
- ```
93
-
94
- #### Use the Render plugin
95
-
96
- Using Eleventy’s built-in [Render plugin](https://www.11ty.dev/docs/plugins/render/) with WebC also works great.
97
-
98
- Consider this example Nunjucks or Liquid template:
99
-
100
- ```
101
- {% renderTemplate "webc" %}
102
- <my-custom-component></my-custom-component>
103
- {% endrenderTemplate %}
104
- ```
105
-
106
- #### Preprocess all HTML input as WebC
107
-
108
- You can use the configuration option to change the default HTML preprocessor (from `liquid`) to `webc`. This might look like `htmlTemplateEngine: "webc"`. Read more on the [Eleventy documentation: Default Template Engine for HTML Files](https://www.11ty.dev/docs/config/#default-template-engine-for-html-files).
109
-
110
- #### Use the global WebC Eleventy transform
111
-
112
- This is a catch-all option to let WebC process _all_ `.html` output files in your project. [Read more about Eleventy transforms.](https://www.11ty.dev/docs/config/#transforms) This method is useful when you want to get up and running with WebC on an existing project quickly (but is also the slowest method for build-performance).
113
-
114
- The WebC Eleventy transform operates WebC in non-bundler mode, which means that it does process WebC but _does not_ aggregate JS or CSS on the page.
115
-
116
- The transform is disabled by default, you will need to add a configuration option to enable it:
117
-
118
- ```js
119
- const pluginWebc = require("@11ty/eleventy-plugin-webc");
120
-
121
- module.exports = function(eleventyConfig) {
122
- eleventyConfig.addPlugin(pluginWebc, {
123
- useTransform: true,
124
- });
125
- };
126
- ```
127
-
128
- ## Examples
129
-
130
- Add a new `.webc` file to your Eleventy input directory and it will render as WebC to your output directory (`_site` by default).
131
-
132
- `my-page.webc`:
133
-
134
- ```html
135
- <!doctype html>
136
- <html lang="en">
137
- <head>
138
- <meta charset="utf-8">
139
- <title>WebC Example</title>
140
- </head>
141
- <body>
142
- WebC *is* HTML.
143
- </body>
144
- </html>
145
- ```
146
-
147
- ### Use Front Matter
148
17
 
149
- WebC in Eleventy works automatically with standard Eleventy conventions for [front matter](https://www.11ty.dev/docs/data-frontmatter/) (though front matter in Eleventy is _optional_).
18
+ ## [Documentation](https://www.11ty.dev/docs/languages/webc/)
150
19
 
151
- Notably you can use `yaml`, `json`, `js`, or [add your own data format](https://www.11ty.dev/docs/data-frontmatter-customize/) for front matter in Eleventy.
20
+ This documentation has [moved to 11ty.dev](https://www.11ty.dev/docs/languages/webc/).
152
21
 
153
- `with-front-matter.webc` (using `_includes/my-layout.webc` as an [Eleventy layout](https://www.11ty.dev/docs/layouts/)):
154
-
155
- ```html
156
- ---
157
- layout: "my-layout.webc"
158
- ---
159
- <my-webc-component>WebC *is* HTML.</my-webc-component>
160
- ```
161
-
162
- `_includes/my-layout.webc`:
163
-
164
- ```html
165
- <!doctype html>
166
- <html lang="en">
167
- <head>
168
- <meta charset="utf-8">
169
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
170
- <meta name="description" content="">
171
- <title></title>
172
- </head>
173
- <body @html="this.content"></body>
174
- </html>
175
- ```
176
-
177
- ### Components
178
-
179
- There are a few ways to use web components here:
180
-
181
- 1. You can use `webc:import` inside of your components to import another component directly.
182
- 2. Use global no-import components specified in your config file.
183
- 3. Specify a glob of no-import components at a directory or template level in the data cascade.
184
-
185
- Notably, WebC components are not restricted to the same naming limitations as custom elements (they do not require a dash in the name). The [WebC documentation has all of the detail on how to use and configure WebC components](https://github.com/11ty/webc#html-imports-kidding-kinda).
186
-
187
- #### Global no-import Components
188
-
189
- Use the `components` property in the Full options list in your Eleventy configuration file to specify project-wide WebC component files available for use in any page.
190
-
191
- ```js
192
- const pluginWebc = require("@11ty/eleventy-plugin-webc");
193
-
194
- module.exports = function(eleventyConfig) {
195
- eleventyConfig.addPlugin(pluginWebc, {
196
- // Glob to find no-import global components
197
- components: "_includes/components/**/*.webc",
198
- });
199
- };
200
- ```
201
-
202
- #### Specify no-import Components in the Data Cascade
203
-
204
- You can also use and configure specific components as part of the data cascade as well (scoped to a folder or a template) by assigning a glob (or array of globs) to `webc.components`, like so:
205
-
206
- `my-directory/my-page.webc`:
207
-
208
- ```html
209
- ---
210
- layout: "my-layout.webc"
211
- webc:
212
- components: "./webc/*.webc"
213
- ---
214
- <my-webc-component>WebC *is* HTML.</my-webc-component>
215
- ```
216
-
217
- * Usage warning: By default these paths are relative to the template file. If you’re setting this in the data cascade to apply multiple child folders deep, it might be better to use the global no-import components option above OR to use `~/` as a prefix (e.g. `~/my-directory/webc/*.webc`) to alias to the project’s root directory.
218
-
219
- ### CSS and JS (Bundler mode)
220
-
221
- [Eleventy Layouts](https://www.11ty.dev/docs/layouts/) can bundle any specific page’s assets (CSS and JS used by components on the page). These are automatically rolled up when a component uses `<script>` or `<style>`. You can use this to easily implement component-driven Critical CSS.
222
-
223
- `_includes/webc/my-webc-component.webc`:
224
-
225
- ```html
226
- <style>/* This is component CSS */</style>
227
- <script>/* This is component JS */</script>
228
- ```
229
-
230
- `_includes/layout.webc`:
231
-
232
- ```html
233
- <!doctype html>
234
- <html lang="en">
235
- <head>
236
- <meta charset="utf-8">
237
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
238
- <meta name="description" content="">
239
- <title></title>
240
- <style @html="this.getCSS(this.page.url)"></style>
241
- <script @html="this.getJS(this.page.url)"></script>
242
- </head>
243
- <body @html="this.content"></body>
244
- </html>
245
- ```
246
-
247
- #### Asset bucketing
248
-
249
- Components can use the `webc:bucket` feature to output to any arbitrary bucket name for compartmentalization at the component level.
250
-
251
- `_includes/webc/my-webc-component.webc`:
252
-
253
- ```html
254
- <style>/* This CSS is put into the default bucket */</style>
255
- <script>/* This JS is put into the default bucket */</script>
256
- <style webc:bucket="defer">/* This CSS is put into the `defer` bucket */</style>
257
- <script webc:bucket="defer">/* This JS is put into the `defer` bucket */</script>
258
- ```
259
-
260
- ```html
261
- <!doctype html>
262
- <html lang="en">
263
- <head>
264
- <meta charset="utf-8">
265
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
266
- <meta name="description" content="">
267
- <title></title>
268
- <!-- Default bucket -->
269
- <style @html="this.getCSS(this.page.url)"></style>
270
- <script @html="this.getJS(this.page.url)"></script>
271
- </head>
272
- <body>
273
- <template webc:nokeep @html="this.content"></template>
274
-
275
- <!-- `defer` bucket -->
276
- <style @html="this.getCSS(this.page.url, 'defer')"></style>
277
- <script @html="this.getJS(this.page.url, 'defer')"></script>
278
- </body>
279
- </html>
280
- ```
281
-
282
- ### Use any Eleventy Template Syntax
283
-
284
- We’ve wired up [WebC’s Custom Transforms feature](https://github.com/11ty/webc#custom-transforms) `webc:type="11ty"` to the [Eleventy Render plugin](https://www.11ty.dev/docs/plugins/render/) to allow you to use existing Eleventy template syntax inside of WebC.
285
-
286
- Use the `11ty:type` attribute to specify a [valid template syntax](https://www.11ty.dev/docs/plugins/render/#rendertemplate).
287
-
288
- `my-page.webc`:
289
-
290
- ```
291
- ---
292
- frontmatterdata: "Hello from Front Matter"
293
- ---
294
- <template webc:type="11ty" 11ty:type="liquid,md">
295
- {% assign t = "Liquid in WebC" %}
296
- ## {{ t }}
297
-
298
- _{{ frontmatterdata }}_
299
- </template>
300
- ```
301
-
302
- You have full access to the data cascade here (see `frontmatterdata` in the example above).
303
-
304
- ### Use with `is-land`
305
-
306
- You can also use this out of the box with Eleventy’s [`is-land` component for web component hydration](https://www.11ty.dev/docs/plugins/partial-hydration/).
307
-
308
- At the component level, components can declare their own is-land loading conditions.
309
-
310
- `_includes/webc/my-webc-component.webc`:
311
-
312
- ```html
313
- <is-land on:visible>
314
- <template data-island>
315
- <!-- CSS -->
316
- <style webc:keep>
317
- /* This is on-visible CSS */
318
- </style>
319
- <link rel="stylesheet" href="some-arbitrary-css.css" webc:keep>
22
+ ## Features
320
23
 
321
- <!-- JS -->
322
- <script type="module" webc:keep>
323
- console.log("This is on-visible JavaScript");
324
- </script>
325
- <script type="module" src="some-arbitrary-js.js" webc:keep></script>
326
- </template>
327
- </is-land>
328
- ```
24
+ * Brings first-class **components** to Eleventy.
25
+ * Expand any HTML element (including custom elements) to HTML with defined conventions from web standards.
26
+ * This means that Web Components created with WebC are compatible with server-side rendering (without duplicating author-written markup)
27
+ * WebC components are [Progressive Enhancement friendly](https://www.youtube.com/watch?v=p0wDUK0Z5Nw).
28
+ * Get first-class **incremental builds** (for page templates, components, and Eleventy layouts) when [used with `--incremental`](https://www.11ty.dev/docs/usage/#incremental-for-partial-incremental-builds)
29
+ * Streaming friendly (stream on the Edge 👀)
30
+ * Easily scope component CSS (or use your own scoping utility).
31
+ * Tired of importing components? Use global or per-page no-import components.
32
+ * Shadow DOM friendly (works with or without Shadow DOM)
33
+ * All configuration extensions/hooks into WebC are async-friendly out of the box.
34
+ * Bundler mode: Easily roll up the CSS and JS in-use by WebC components on a page for page-specific bundles. Dirt-simple critical CSS/JS to only load the code you need.
35
+ * For more complex templating needs, render any existing Eleventy template syntax (Liquid, markdown, Nunjucks, etc.) inside of WebC.
36
+ * Works great with [is-land](https://www.11ty.dev/docs/plugins/partial-hydration/) for web component hydration.
@@ -2,10 +2,6 @@ const pkg = require("./package.json");
2
2
  const templatePlugin = require("./src/eleventyWebcTemplate.js");
3
3
  const transformPlugin = require("./src/eleventyWebcTransform.js");
4
4
 
5
- /* TODO
6
- * Use JavaScript functions or universal shortcodes as built-in components?
7
- */
8
-
9
5
  module.exports = function(eleventyConfig, options = {}) {
10
6
  try {
11
7
  eleventyConfig.versionCheck(pkg["11ty"].compatibility);
@@ -28,6 +24,8 @@ module.exports = function(eleventyConfig, options = {}) {
28
24
 
29
25
  if(options.components) {
30
26
  eleventyConfig.addWatchTarget(options.components);
27
+
28
+ // TODO add to eleventy ignores (if not in _includes folder)
31
29
  }
32
30
 
33
31
  templatePlugin(eleventyConfig, options);
@@ -35,4 +33,4 @@ module.exports = function(eleventyConfig, options = {}) {
35
33
  if(options.useTransform) {
36
34
  transformPlugin(eleventyConfig, options);
37
35
  }
38
- }
36
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@11ty/eleventy-plugin-webc",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "WebC support for Eleventy adds for Single File Web Components",
5
5
  "main": "eleventyWebcPlugin.js",
6
6
  "scripts": {
@@ -39,7 +39,7 @@
39
39
  },
40
40
  "dependencies": {
41
41
  "@11ty/eleventy": "^2.0.0-canary.16",
42
- "@11ty/webc": "^0.4.0"
42
+ "@11ty/webc": "^0.5.2"
43
43
  },
44
44
  "devDependencies": {
45
45
  "ava": "^4.3.3"
@@ -84,15 +84,17 @@ module.exports = function(eleventyConfig, options = {}) {
84
84
  compile: async function(inputContent, inputPath) {
85
85
  let page = incremental.add(inputContent, inputPath);
86
86
 
87
- // TODO add all universal filters/JavaScript functions as helpers here:
87
+ // Add Eleventy JavaScript Functions as WebC helpers (Universal Filters also populate into these)
88
+ for(let helperName in this.config.javascriptFunctions) {
89
+ page.setHelper(helperName, this.config.javascriptFunctions[helperName]);
90
+ }
88
91
 
89
- page.setHelper("getCSS", function(url, bucket) {
90
- return getCss(url, bucket);
91
- });
92
+ // Support both casings (I prefer getCss, but yeah)
93
+ page.setHelper("getCss", (url, bucket) => getCss(url, bucket));
94
+ page.setHelper("getCSS", (url, bucket) => getCss(url, bucket));
92
95
 
93
- page.setHelper("getJS", function(url, bucket) {
94
- return getJs(url, bucket);
95
- });
96
+ page.setHelper("getJs", (url, bucket) => getJs(url, bucket));
97
+ page.setHelper("getJS", (url, bucket) => getJs(url, bucket));
96
98
 
97
99
  page.setTransform("11ty", async function(content) {
98
100
  let syntax = this["11ty:type"];
@@ -135,4 +137,4 @@ module.exports = function(eleventyConfig, options = {}) {
135
137
  };
136
138
  }
137
139
  });
138
- };
140
+ };
@@ -8,7 +8,7 @@ module.exports = function(eleventyConfig, options = {}) {
8
8
  eleventyConfig.addTransform("@11ty/eleventy-plugin-webc", async function(content) {
9
9
  // Skip non-.html output
10
10
  // Skip .webc input
11
- if(this.inputPath.endsWith(".webc") || !this.outputPath?.endsWith(".html")) {
11
+ if(this.inputPath.endsWith(".webc") || !(this.outputPath || "").endsWith(".html")) {
12
12
  return content;
13
13
  }
14
14
 
@@ -37,4 +37,4 @@ module.exports = function(eleventyConfig, options = {}) {
37
37
 
38
38
  return content;
39
39
  });
40
- }
40
+ }
@@ -20,12 +20,12 @@ class WebCIncremental {
20
20
  this.globalComponentsMap = map;
21
21
  }
22
22
  }
23
-
23
+
24
24
  getComponentMap(glob) {
25
25
  if(!this.webc) {
26
26
  return false;
27
27
  }
28
-
28
+
29
29
  let WebC = this.webc;
30
30
  let components = WebC.getComponentsMap(glob);
31
31
  // console.log( glob, Object.keys(components).length );
@@ -46,7 +46,16 @@ class WebCIncremental {
46
46
  add(inputContent, inputPath) {
47
47
  let WebC = this.webc;
48
48
  let page = new WebC();
49
- page.setBundlerMode(true);
49
+
50
+ // Explicitly disable bundler mode for layouts
51
+ if(this.layouts && this.layouts[inputPath]) {
52
+ page.setBundlerMode(false);
53
+ page.setReprocessingMode(false);
54
+ } else {
55
+ page.setBundlerMode(true);
56
+ page.setReprocessingMode(true);
57
+ }
58
+
50
59
  page.setContent(inputContent, inputPath);
51
60
 
52
61
  if(this.globalComponentsMap) {
@@ -79,4 +88,4 @@ class WebCIncremental {
79
88
  }
80
89
  }
81
90
 
82
- module.exports = WebCIncremental;
91
+ module.exports = WebCIncremental;