@11ty/eleventy-plugin-webc 0.8.0 → 0.9.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.
@@ -1,3 +1,4 @@
1
+ const eleventyBundlePlugin = require("@11ty/eleventy-plugin-bundle");
1
2
  const pkg = require("./package.json");
2
3
  const templatePlugin = require("./src/eleventyWebcTemplate.js");
3
4
  const transformPlugin = require("./src/eleventyWebcTransform.js");
@@ -9,6 +10,7 @@ module.exports = function(eleventyConfig, options = {}) {
9
10
  console.log( `WARN: Eleventy Plugin (${pkg.name}) Compatibility: ${e.message}` );
10
11
  }
11
12
 
13
+ // Deprecated: this lives in @11ty/eleventy-plugin-bundle now
12
14
  let filters = Object.assign({
13
15
  css: "webcGetCss",
14
16
  js: "webcGetJs",
@@ -20,6 +22,7 @@ module.exports = function(eleventyConfig, options = {}) {
20
22
  transformData: {}, // extra global data for transforms specifically
21
23
  }, options);
22
24
 
25
+ // Deprecated: this lives in @11ty/eleventy-plugin-bundle now
23
26
  options.filters = filters;
24
27
 
25
28
  if(options.components) {
@@ -33,6 +36,13 @@ module.exports = function(eleventyConfig, options = {}) {
33
36
  eleventyConfig.ignores.add(options.components);
34
37
  }
35
38
 
39
+ // TODO Remove this when @11ty/eleventy-plugin-bundle is moved to core.
40
+ // If the bundle plugin has not been added, we add it here:
41
+ let bundlePlugin = eleventyConfig.plugins.find(entry => entry.plugin.eleventyPackage === "@11ty/eleventy-plugin-bundle");
42
+ if(!bundlePlugin) {
43
+ eleventyConfig.addPlugin(eleventyBundlePlugin);
44
+ }
45
+
36
46
  templatePlugin(eleventyConfig, options);
37
47
 
38
48
  if(options.useTransform) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@11ty/eleventy-plugin-webc",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "WebC support for Eleventy adds for Single File Web Components",
5
5
  "main": "eleventyWebcPlugin.js",
6
6
  "scripts": {
@@ -14,7 +14,7 @@
14
14
  "node": ">=14.18"
15
15
  },
16
16
  "11ty": {
17
- "compatibility": ">=2.0.0-canary.17"
17
+ "compatibility": ">=2.0.0-canary.19"
18
18
  },
19
19
  "funding": {
20
20
  "type": "opencollective",
@@ -34,14 +34,20 @@
34
34
  "ava": {
35
35
  "failFast": true,
36
36
  "files": [
37
- "./test/*.js"
37
+ "./test/test*.js"
38
+ ],
39
+ "ignoredByWatcher": [
40
+ "**/_site/**",
41
+ ".cache"
38
42
  ]
39
43
  },
40
44
  "dependencies": {
41
- "@11ty/eleventy": "^2.0.0-canary.18",
42
- "@11ty/webc": "^0.8.0"
45
+ "@11ty/eleventy": "^2.0.0",
46
+ "@11ty/eleventy-plugin-bundle": "^1.0.1",
47
+ "@11ty/webc": "^0.9.0"
43
48
  },
44
49
  "devDependencies": {
45
- "ava": "^5.0.1"
50
+ "ava": "^5.1.0",
51
+ "node-retrieve-globals": "^2.0.4"
46
52
  }
47
53
  }
@@ -1,12 +1,10 @@
1
1
  const path = require("path");
2
+ const debug = require("debug")("Eleventy:WebC");
3
+
2
4
 
3
5
  const { EleventyRenderPlugin } = require("@11ty/eleventy");
4
6
  const CompileString = EleventyRenderPlugin.String;
5
7
 
6
- const CodeManager = require("./codeManager.js");
7
- const WebCIncremental = require("./incremental.js");
8
- const BundleAssetsToContent = require("./bundleAssets.js");
9
-
10
8
  function relativePath(inputPath, newGlob) {
11
9
  // project root
12
10
  if(newGlob.startsWith("~/")) {
@@ -21,107 +19,85 @@ function relativePath(inputPath, newGlob) {
21
19
  }
22
20
 
23
21
  module.exports = function(eleventyConfig, options = {}) {
22
+ // TODO remove this when WebC is moved out of plugin-land into core.
24
23
  eleventyConfig.addTemplateFormats("webc");
25
24
 
26
- let cssManager = new CodeManager();
27
- let jsManager = new CodeManager();
28
- let incremental = new WebCIncremental();
25
+ let _WebC;
29
26
  let componentsMap = false; // cache the glob search
30
- let componentsMapKey;
31
27
  let moduleScript;
32
28
 
33
29
  eleventyConfig.on("eleventy.before", async () => {
34
- cssManager.reset();
35
- jsManager.reset();
36
-
37
30
  // For ESM in CJS
38
31
  let { WebC, ModuleScript } = await import("@11ty/webc");
39
32
  moduleScript = ModuleScript;
40
- incremental.setWebC(WebC);
33
+ _WebC = WebC;
41
34
 
42
35
  if(options.components) {
43
36
  componentsMap = WebC.getComponentsMap(options.components);
44
- componentsMapKey = JSON.stringify(componentsMap);
45
37
  }
46
38
  });
47
39
 
48
- // Expose bundled CSS code to other template languages
40
+ // Deprecated (backwards compat only): this lives in @11ty/eleventy-plugin-bundle now
49
41
  if(options.filters.css) {
50
- function getCss(pageUrl, bucket = "default") {
51
- return cssManager.getForPage(pageUrl, bucket);
52
- }
53
-
54
- eleventyConfig.addFilter(options.filters.css, (url, bucket) => getCss(url, bucket));
42
+ eleventyConfig.addFilter(options.filters.css, (url, bucket) => {
43
+ return eleventyConfig.javascriptFunctions.getBundle("css", bucket);
44
+ });
55
45
  }
56
46
 
57
- // Expose bundled JS code to other template languages
47
+ // Deprecated (backwards compat only): this lives in @11ty/eleventy-plugin-bundle now
58
48
  if(options.filters.js) {
59
- function getJs(pageUrl, bucket = "default") {
60
- return jsManager.getForPage(pageUrl, bucket);
61
- }
62
-
63
- eleventyConfig.addFilter(options.filters.js, (url, bucket) => getJs(url, bucket));
49
+ eleventyConfig.addFilter(options.filters.js, (url, bucket) => {
50
+ return eleventyConfig.javascriptFunctions.getBundle("js", bucket)
51
+ });
64
52
  }
65
53
 
66
- eleventyConfig.on("eleventy.layouts", layouts => {
67
- incremental.setLayouts(layouts);
68
- });
69
-
70
54
  eleventyConfig.addExtension("webc", {
71
55
  outputFileExtension: "html",
72
56
 
73
- isIncrementalMatch: function (incrementalFilePath) {
74
- // Eleventy layouts don’t appear directly in the WebC component graph, so we use the `eleventy.layouts` map here
75
- if(incremental.isFileUsingLayout(this.inputPath, incrementalFilePath)) {
76
- return true;
77
- }
78
-
79
- let {page, setup} = incremental.get(this.inputPath);
80
-
81
- if(page && setup) {
82
- let components = page.getComponents(setup);
83
- if(components.includes(incrementalFilePath)) {
84
- return true;
85
- }
86
- }
87
-
88
- return false;
89
- },
90
-
91
57
  compileOptions: {
92
- cache: true,
93
- getCacheKey: function(contents, inputPath) {
94
- // if global components change, recompile!
95
- return contents + inputPath + componentsMapKey;
96
- },
97
58
  permalink: function(contents, inputPath) {
98
- return (data) => {
99
- return moduleScript.evaluateScript("permalink", contents, {
100
- ...this,
101
- ...data,
102
- });
59
+ if(contents && typeof contents === "string") {
60
+ return async (data) => {
61
+ try {
62
+ // Hard to know if this is JavaScript code or just a raw string value.
63
+ let evaluatedString = await moduleScript.evaluateScript(contents, {
64
+ ...this,
65
+ ...data,
66
+ }, `Check the permalink for ${inputPath}`);
67
+ return evaluatedString;
68
+ } catch(e) {
69
+ debug("Error evaluating dynamic permalink, returning raw string contents instead: %o\n%O", contents, e);
70
+ return contents;
71
+ }
72
+ }
103
73
  }
74
+
75
+ return contents;
104
76
  }
105
77
  },
106
78
 
107
79
  compile: async function(inputContent, inputPath) {
108
- let page = incremental.add(inputContent, inputPath);
80
+ let page = new _WebC();
81
+
82
+ page.setBundlerMode(true);
83
+ page.setContent(inputContent, inputPath);
109
84
 
110
85
  if(componentsMap) {
111
86
  page.defineComponents(componentsMap);
112
87
  }
113
88
 
114
- // Add Eleventy JavaScript Functions as WebC helpers (Universal Filters also populate into these)
89
+ // Add Eleventy JavaScript Functions as WebC helpers
90
+ // Note that Universal Filters and Shortcodes populate into javascriptFunctions and will be present here
115
91
  for(let helperName in this.config.javascriptFunctions) {
116
92
  page.setHelper(helperName, this.config.javascriptFunctions[helperName]);
117
93
  }
118
94
 
119
95
  // Support both casings (I prefer getCss, but yeah)
120
- page.setHelper("getCss", (url, bucket) => BundleAssetsToContent.getAssetKey("css", bucket));
121
- page.setHelper("getCSS", (url, bucket) => BundleAssetsToContent.getAssetKey("css", bucket));
96
+ page.setHelper("getCss", (url, bucket) => this.config.javascriptFunctions.getBundle("css", bucket));
97
+ page.setHelper("getCSS", (url, bucket) => this.config.javascriptFunctions.getBundle("css", bucket));
122
98
 
123
- page.setHelper("getJs", (url, bucket) => BundleAssetsToContent.getAssetKey("js", bucket));
124
- page.setHelper("getJS", (url, bucket) => BundleAssetsToContent.getAssetKey("js", bucket));
99
+ page.setHelper("getJs", (url, bucket) => this.config.javascriptFunctions.getBundle("js", bucket));
100
+ page.setHelper("getJS", (url, bucket) => this.config.javascriptFunctions.getBundle("js", bucket));
125
101
 
126
102
  page.setTransform("11ty", async function(content) {
127
103
  let syntax = this["11ty:type"];
@@ -138,45 +114,39 @@ module.exports = function(eleventyConfig, options = {}) {
138
114
  let setupObject = {
139
115
  data,
140
116
  };
117
+
141
118
  if(data.webc?.components) {
142
- let WebC = incremental.webc;
143
- setupObject.components = WebC.getComponentsMap(relativePath(data.page.inputPath, data.webc.components));
119
+ setupObject.components = _WebC.getComponentsMap(relativePath(data.page.inputPath, data.webc.components));
144
120
  }
145
121
 
146
122
  if(options.before && typeof options.before === "function") {
147
123
  await options.before(page);
148
124
  }
149
125
 
150
- let setup = await page.setup(setupObject);
151
- incremental.addSetup(inputPath, setup);
126
+ let { html, css, js, buckets, components } = await page.compile(setupObject);
152
127
 
153
- let { ast, serializer } = setup;
154
- let { html, css, js, buckets } = await serializer.compile(ast);
128
+ // 2.0.0-canary.19+
129
+ this.addDependencies(inputPath, components);
155
130
 
156
- cssManager.addToPage(data.page.url, css, "default");
131
+ // Add CSS to bundle
132
+ this.config.javascriptFunctions.css(css, "default", data.page.url);
157
133
 
158
134
  if(buckets.css) {
159
135
  for(let bucket in buckets.css) {
160
- cssManager.addToPage(data.page.url, buckets.css[bucket], bucket);
136
+ this.config.javascriptFunctions.css(css, buckets.css[bucket], data.page.url);
161
137
  }
162
138
  }
163
139
 
164
- jsManager.addToPage(data.page.url, js, "default");
140
+ // Add JS to bundle
141
+ this.config.javascriptFunctions.js(js, "default", data.page.url);
165
142
 
166
143
  if(buckets.js) {
167
144
  for(let bucket in buckets.js) {
168
- jsManager.addToPage(data.page.url, buckets.js[bucket], bucket);
145
+ this.config.javascriptFunctions.js(js, buckets.js[bucket], data.page.url);
169
146
  }
170
147
  }
171
148
 
172
- // Always do a two pass render for assets to catch any CSS/JS that were compiled *in* the same template.
173
- // https://github.com/11ty/eleventy-plugin-webc/issues/33
174
- // This unlocks use of bundled asset code anywhere in the WebC component tree (not just Eleventy Layouts)
175
- let bundler = new BundleAssetsToContent(html);
176
- bundler.setAssetManager("css", cssManager);
177
- bundler.setAssetManager("js", jsManager);
178
-
179
- return bundler.replaceAll(data.page.url);
149
+ return html;
180
150
  };
181
151
  }
182
152
  });
@@ -22,6 +22,7 @@ module.exports = function(eleventyConfig, options = {}) {
22
22
  componentsMap = WebC.getComponentsMap(options.components); // "./_includes/webc/*.webc"
23
23
  }
24
24
 
25
+ page.setBundlerMode(false);
25
26
  page.defineComponents(componentsMap);
26
27
  page.setContent(content, this.outputPath);
27
28
 
@@ -1,50 +0,0 @@
1
- class BundleAssetsToContent {
2
- static SPLIT_REGEX = /(\/\*__WebC:[^:]*:[^:]*:WebC__\*\/)/;
3
- static SEPARATOR = ":";
4
-
5
- constructor(content) {
6
- this.content = content;
7
- this.managers = {};
8
- }
9
-
10
- static getAssetKey(name, bucket) {
11
- return `/*__WebC:${name}:${bucket || "default"}:WebC__*/`
12
- }
13
-
14
- setAssetManager(name, assetManager) {
15
- this.managers[name] = assetManager;
16
- }
17
-
18
- normalizeMatch(match) {
19
- if(match.startsWith("/*__WebC:")) {
20
- let [prefix, name, bucket, suffix] = match.split(BundleAssetsToContent.SEPARATOR);
21
- return { name, bucket };
22
- }
23
- return match;
24
- }
25
-
26
- findAll() {
27
- let matches = this.content.split(BundleAssetsToContent.SPLIT_REGEX);
28
- let ret = [];
29
- for(let match of matches) {
30
- ret.push(this.normalizeMatch(match));
31
- }
32
- return ret;
33
- }
34
-
35
- replaceAll(url) {
36
- let matches = this.findAll();
37
- return matches.map(match => {
38
- if(typeof match === "string") {
39
- return match;
40
- }
41
- let {name, bucket} = match;
42
- if(!this.managers[name]) {
43
- throw new Error(`No asset manager found for ${name}. Known keys: ${Object.keys(this.managers)}`);
44
- }
45
- return this.managers[name].getForPage(url, bucket);
46
- }).join("");
47
- }
48
- }
49
-
50
- module.exports = BundleAssetsToContent;
@@ -1,33 +0,0 @@
1
- class Manager {
2
- constructor() {
3
- this.reset();
4
- }
5
-
6
- reset() {
7
- this.pages = {};
8
- }
9
-
10
- addToPage(pageUrl, code = [], bucket = "default") {
11
- if(code.length === 0) {
12
- return;
13
- }
14
-
15
- if(!this.pages[pageUrl]) {
16
- this.pages[pageUrl] = {};
17
- }
18
- if(!this.pages[pageUrl][bucket]) {
19
- this.pages[pageUrl][bucket] = new Set();
20
- }
21
-
22
- this.pages[pageUrl][bucket].add(code.join("\n"));
23
- }
24
-
25
- getForPage(pageUrl, bucket = "default") {
26
- if(this.pages[pageUrl]) {
27
- return Array.from(this.pages[pageUrl][bucket] || []).join("\n");
28
- }
29
- return "";
30
- }
31
- }
32
-
33
- module.exports = Manager;
@@ -1,54 +0,0 @@
1
- class WebCIncremental {
2
- constructor() {
3
- this.pages = {};
4
- this.setups = {};
5
- }
6
-
7
- setWebC(cls) {
8
- this.webc = cls;
9
- }
10
-
11
- setLayouts(layouts) {
12
- this.layouts = layouts;
13
- }
14
-
15
- isFileUsingLayout(templateFilePath, layoutFilePath) {
16
- if(this.layouts && this.layouts[layoutFilePath] && this.layouts[layoutFilePath].includes(templateFilePath)) {
17
- return true;
18
- }
19
- return false;
20
- }
21
-
22
- add(inputContent, inputPath) {
23
- let WebC = this.webc;
24
- let page = new WebC();
25
-
26
- page.setBundlerMode(true);
27
- page.setContent(inputContent, inputPath);
28
-
29
- this.pages[inputPath] = page;
30
-
31
- return page;
32
- }
33
-
34
- addSetup(inputPath, setup) {
35
- this.setups[inputPath] = setup;
36
- }
37
-
38
- get(inputPath) {
39
- let setup = this.setups[inputPath];
40
- let components = setup.serializer.components;
41
-
42
- if(setup && components) {
43
- setup.serializer.restorePreparsedComponents(components);
44
- }
45
-
46
- return {
47
- page: this.pages[inputPath],
48
- setup,
49
- components,
50
- }
51
- }
52
- }
53
-
54
- module.exports = WebCIncremental;