-
-
Notifications
You must be signed in to change notification settings - Fork 11
/
.eleventy.js
206 lines (169 loc) · 6.63 KB
/
.eleventy.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
const lodashMerge = require("lodash.merge");
const debug = require("debug")("EleventyVue");
const { InlineCodeManager } = require("@11ty/eleventy-assets");
const EleventyVue = require("./EleventyVue");
const pkg = require("./package.json");
const globalOptions = {
input: [], // point to a specific list of Vue files (defaults to **/*.vue)
readOnly: false,
cacheDirectory: ".cache/vue/",
// See https://www.rollupjs.org/guide/en/#big-list-of-options
rollupOptions: {},
// See https://rollup-plugin-vue.vuejs.org/options.html
rollupPluginVueOptions: {},
assets: {
css: null
} // optional `eleventy-assets` instances
};
module.exports = function(eleventyConfig, configGlobalOptions = {}) {
try {
eleventyConfig.versionCheck(pkg["11ty"].compatibility);
} catch(e) {
console.log( `WARN: Eleventy Plugin (${pkg.name}) Compatibility: ${e.message}` );
}
let options = lodashMerge({}, globalOptions, configGlobalOptions);
let eleventyVue = new EleventyVue();
eleventyVue.setCacheDir(options.cacheDirectory);
eleventyVue.setReadOnly(options.readOnly);
let cssManager = options.assets.css || new InlineCodeManager();
eleventyVue.setCssManager(cssManager);
let changedVueFilesOnWatch = [];
let skipVueBuild = false;
// Only add this filter if you’re not re-using your own asset manager.
// TODO Add warnings to readme
// * This will probably only work in a layout template.
// * Probably complications with components that are only used in a layout template.
eleventyConfig.addFilter("getVueComponentCssForPage", (url) => {
let components = cssManager.getComponentListForUrl(url);
let css = cssManager.getCodeForUrl(url);
debug("Component CSS for %o component count: %o, CSS size: %o: %O", url, components.length, css.length, components);
return css;
});
let eleventyIgnores;
eleventyConfig.on("eleventy.ignores", ignores => {
eleventyIgnores = ignores;
});
// Default output
let isVerboseMode = true;
eleventyConfig.on("eleventy.config", config => {
// Available in 1.0.0-beta.6+
if(config.verbose !== undefined) {
isVerboseMode = config.verbose;
}
});
eleventyConfig.on("afterBuild", () => {
let count = eleventyVue.componentsWriteCount;
if(isVerboseMode && count > 0) {
console.log( `Built ${count} component${count !== 1 ? "s" : ""} (eleventy-plugin-vue v${pkg.version}${version ? ` with Vue ${version}` : ""})` );
}
});
// `beforeWatch` is available on Eleventy 0.11.0 and newer
eleventyConfig.on("beforeWatch", (changedFiles) => {
let hasChangedFiles = changedFiles && changedFiles.length > 0;
// `changedFiles` array argument is available on Eleventy 0.11.1+
changedVueFilesOnWatch = (changedFiles || []).filter(file => file.endsWith(".vue"));
// Only reset what changed! (Partial builds for Vue rollup files)
if(changedVueFilesOnWatch.length > 0) {
skipVueBuild = false;
} else {
if(hasChangedFiles) {
skipVueBuild = true;
}
}
eleventyVue.clearRequireCache();
});
eleventyConfig.addTemplateFormats("vue");
eleventyConfig.addExtension("vue", {
read: false, // We use rollup to read the files
getData: [ // get data from both the data function and serverPrefetch
"data",
// including this by default is bad because a lot of async data fetching happens here!
// "serverPrefetch"
],
getInstanceFromInputPath: function(inputPath) {
return eleventyVue.getComponent(inputPath);
},
init: async function() {
eleventyVue.setInputDir(this.config.inputDir);
eleventyVue.setIncludesDir(this.config.dir.includes);
eleventyVue.setLayoutsDir(this.config.dir.layouts);
eleventyVue.resetIgnores(eleventyIgnores);
eleventyVue.setRollupOptions(options.rollupOptions);
eleventyVue.setRollupPluginVueOptions(options.rollupPluginVueOptions);
if(skipVueBuild) {
// we only call this to set the write count for the build
eleventyVue.createVueComponents([]);
} else if(options.readOnly && eleventyVue.hasRollupOutputCache()) {
await eleventyVue.loadRollupOutputCache();
} else {
let files = changedVueFilesOnWatch;
let isSubset = false;
if(files && files.length) {
isSubset = true;
} else {
// input passed in via config
if(options.input && options.input.length) {
files = options.input;
isSubset = true;
} else {
files = await eleventyVue.findFiles();
}
}
// quit early
if(!files || !files.length) {
return;
}
try {
let bundle = await eleventyVue.getBundle(files, isSubset);
let output = await eleventyVue.write(bundle);
eleventyVue.createVueComponents(output);
} catch(e) {
if(e.loc) {
e.message = `Error in Vue file ${e.loc.file} on Line ${e.loc.line} Column ${e.loc.column}: ${e.message}`
}
throw e;
}
if(!options.readOnly && !isSubset) { // implied eleventyVue.hasRollupOutputCache() was false
await eleventyVue.writeRollupOutputCache();
}
}
},
// Caching
compileOptions: {
cache: true,
permalink: false,
getCacheKey: function(str, inputPath) {
return inputPath;
},
},
compile: function(str, inputPath) {
return async (data) => {
// since `read: false` is set 11ty doesn't read file contents
// so if str has a value, it's a permalink (which can be a string or a function)
// currently Vue template syntax in permalink string is not supported.
let vueMixin = {
methods: this.config.javascriptFunctions,
};
if (str) {
if(typeof str === "function") {
return str(data);
}
if(typeof str === "string" && str.trim().charAt("0") === "<") {
return eleventyVue.renderString(str, data, vueMixin);
}
return str;
}
let vueComponent = eleventyVue.getComponent(inputPath);
let componentName = eleventyVue.getJavaScriptComponentFile(inputPath);
// if user attempts to render a Vue template in `serverPrefetch` or `data` to add to the data cascade
// this will fail because data.page does not exist yet!
if(data.page) {
debug("Vue CSS: Adding component %o to %o", componentName, data.page.url);
cssManager.addComponentForUrl(componentName, data.page.url);
}
return eleventyVue.renderComponent(vueComponent, data, vueMixin);
};
}
});
};
module.exports.EleventyVue = EleventyVue;