Skip to content

Commit

Permalink
Merge pull request #1793 from 11ty/zl/serverless
Browse files Browse the repository at this point in the history
Eleventy Serverless: Adds the Serverless utility and Serverless Bundler plugin
  • Loading branch information
zachleat authored Jun 9, 2021
2 parents 6be2a09 + 51917a4 commit 782f18b
Show file tree
Hide file tree
Showing 21 changed files with 1,036 additions and 213 deletions.
5 changes: 3 additions & 2 deletions cmd.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ try {
// --quiet and --quiet=true both resolve to true
quietMode: argv.quiet,
configPath: argv.config,
source: "cli",
});

// reuse ErrorHandler instance in Eleventy
Expand Down Expand Up @@ -104,7 +105,7 @@ try {
.catch((e) => {
// Build failed but error message already displayed.
startBrowsersync = false;
console.log("Watch catch");
// A build error occurred and we aren’t going to --serve
})
.then(function () {
if (startBrowsersync) {
Expand All @@ -113,7 +114,7 @@ try {
});
} else if (argv.watch) {
elev.watch().catch((e) => {
console.log("watch catch 2");
// A build error occurred and we aren’t going to --watch
});
} else {
if (argv.to === "json") {
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@
},
"dependencies": {
"@11ty/dependency-tree": "^2.0.0",
"@iarna/toml": "^2.2.5",
"browser-sync": "^2.26.14",
"chalk": "^4.1.0",
"chokidar": "^3.5.1",
Expand Down Expand Up @@ -124,6 +125,7 @@
"slugify": "^1.4.7",
"split": "^1.0.1",
"time-require": "^0.1.2",
"url-pattern": "^1.0.3",
"valid-url": "^1.0.9"
}
}
44 changes: 34 additions & 10 deletions src/Eleventy.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ class Eleventy {
*/
this.configPath = options.configPath;

/**
* @member {String} - Called via CLI (`cli`) or Programmatically (`script`)
* @default "script"
*/
this.source = options.source || "script";

/**
* @member {Object} - Initialize Eleventy environment variables
* @default null
Expand Down Expand Up @@ -338,18 +344,29 @@ class Eleventy {
this.writer.extensionMap = this.extensionMap;
this.writer.setEleventyFiles(this.eleventyFiles);

let dirs = {
input: this.inputDir,
data: this.templateData.getDataDir(),
includes: this.eleventyFiles.getIncludesDir(),
layouts: this.eleventyFiles.getLayoutsDir(),
output: this.outputDir,
};

debug(`Directories:
Input: ${this.inputDir}
Data: ${this.templateData.getDataDir()}
Includes: ${this.eleventyFiles.getIncludesDir()}
Layouts: ${this.eleventyFiles.getLayoutsDir()}
Output: ${this.outputDir}
Input: ${dirs.input}
Data: ${dirs.data}
Includes: ${dirs.includes}
Layouts: ${dirs.layouts}
Output: ${dirs.output}
Template Formats: ${formats.join(",")}
Verbose Output: ${this.verboseMode}`);

this.writer.setVerboseOutput(this.verboseMode);
this.writer.setDryRun(this.isDryRun);

this.config.events.emit("eleventy.directories", dirs);

// …why does this return this
return this.templateData.cacheData();
}

Expand All @@ -362,6 +379,7 @@ Verbose Output: ${this.verboseMode}`);
return {
config: absolutePathToConfig,
root,
source: this.source,
};
}

Expand All @@ -374,6 +392,8 @@ Verbose Output: ${this.verboseMode}`);
process.env.ELEVENTY_ROOT = env.root;
debug("Setting process.env.ELEVENTY_ROOT: %o", env.root);

process.env.ELEVENTY_SOURCE = this.source;

// careful here, setting to false will cast to string "false" which is truthy
if (process.env.AWS_LAMBDA_FUNCTION_NAME) {
process.env.ELEVENTY_SERVERLESS = true;
Expand Down Expand Up @@ -529,7 +549,7 @@ Arguments:
* @param {String} changedFilePath - File that triggered a re-run (added or modified)
*/
async _addFileToWatchQueue(changedFilePath) {
eventBus.emit("resourceModified", changedFilePath);
eventBus.emit("eleventy.resourceModified", changedFilePath);
this.watchManager.addToPendingQueue(changedFilePath);
}

Expand All @@ -546,10 +566,9 @@ Arguments:

this.watchManager.setBuildRunning();

await this.config.events.emit(
"beforeWatch",
this.watchManager.getActiveQueue()
);
let queue = this.watchManager.getActiveQueue();
await this.config.events.emit("beforeWatch", queue);
await this.config.events.emit("eleventy.beforeWatch", queue);

// reset and reload global configuration :O
if (
Expand Down Expand Up @@ -875,6 +894,8 @@ Arguments:

try {
await this.config.events.emit("beforeBuild");
await this.config.events.emit("eleventy.before");

let promise;
if (to === "fs") {
promise = this.writer.write();
Expand All @@ -897,6 +918,7 @@ Arguments:
}

await this.config.events.emit("afterBuild");
await this.config.events.emit("eleventy.after");
} catch (e) {
hasError = true;
ret = {
Expand Down Expand Up @@ -926,3 +948,5 @@ Arguments:
}

module.exports = Eleventy;
module.exports.EleventyServerless = require("./Serverless");
module.exports.EleventyServerlessBundlerPlugin = require("./Plugins/ServerlessBundlerPlugin");
4 changes: 2 additions & 2 deletions src/Engines/Nunjucks.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const eventBus = require("../EventBus");
// }
// }
// };
// eventBus.on("resourceModified", evictByPath);
// eventBus.on("eleventy.resourceModified", evictByPath);

// let _compile = NunjucksLib.Template.prototype._compile;
// NunjucksLib.Template.prototype._compile = function _wrap_compile(...args) {
Expand Down Expand Up @@ -128,7 +128,7 @@ class Nunjucks extends TemplateEngine {
this.njkEnv = env || new NunjucksLib.Environment(fsLoader);
// Correct, but overbroad. Better would be to evict more granularly, but
// resolution from paths isn't straightforward.
eventBus.on("resourceModified", (path) => {
eventBus.on("eleventy.resourceModified", (path) => {
this.njkEnv.invalidateCache();
});

Expand Down
73 changes: 42 additions & 31 deletions src/Plugins/Pagination.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,36 @@ class Pagination {

this.size = data.pagination.size;
this.alias = data.pagination.alias;
// TODO do we need the full data set for serverless?
this.fullDataSet = this._get(this.data, this._getDataKey());

this.target = this._resolveItems();
this.chunkedItems = this.pagedItems;
// truncate pagination data to one entry for serverless render
if (
data.pagination.serverless &&
this._has(data, data.pagination.serverless)
) {
// Warn: this doesn’t run filter/before/pagination transformations
// Warn: `pagination.pages`, pageNumber, links, hrefs, etc
let serverlessPaginationKey = this._get(data, data.pagination.serverless);
this.chunkedItems = [
[this._get(this.fullDataSet, serverlessPaginationKey)],
];
} else {
// this returns an array
this.target = this._resolveItems();

// Serverless Shortcut when key is not found in data set (probably running local build and expected a :path param in data)
// Only collections are relevant for templates that don’t have a permalink.build, they don’t have a templateContent and aren’t written to disk
if (
data.pagination.serverless &&
!data.pagination.addAllPagesToCollections
) {
// use the first page only
this.chunkedItems = [this.pagedItems[0]];
} else {
this.chunkedItems = this.pagedItems;
}
}
}

setTemplate(tmpl) {
Expand Down Expand Up @@ -100,6 +127,12 @@ class Pagination {
return false;
}

_has(target, key) {
let notFoundValue = "__NOT_FOUND_ERROR__";
let data = lodashGet(target, key, notFoundValue);
return data !== notFoundValue;
}

_get(target, key) {
let notFoundValue = "__NOT_FOUND_ERROR__";
let data = lodashGet(target, key, notFoundValue);
Expand All @@ -112,17 +145,13 @@ class Pagination {
}

_resolveItems() {
let fullDataSet = this._get(this.data, this._getDataKey());

// TODO maybe don’t operate on the full data set for a serverless render

let keys;
if (Array.isArray(fullDataSet)) {
keys = fullDataSet;
if (Array.isArray(this.fullDataSet)) {
keys = this.fullDataSet;
} else if (this.resolveDataToObjectValues()) {
keys = Object.values(fullDataSet);
keys = Object.values(this.fullDataSet);
} else {
keys = Object.keys(fullDataSet);
keys = Object.keys(this.fullDataSet);
}

// keys must be an array
Expand Down Expand Up @@ -269,11 +298,7 @@ class Pagination {
return [];
}

if (this.pagesCache) {
return this.pagesCache;
}

let pagesCache = [];
let pages = [];
let items = this.chunkedItems;
let tmpl = this.template;
let templates = [];
Expand Down Expand Up @@ -318,24 +343,10 @@ class Pagination {
let cloned = templates[pageNumber];
cloned.setPaginationData(overrides[pageNumber]);

pagesCache.push(cloned);
}

this.pagesCache = pagesCache;

return pagesCache;
}

getTruncatedServerlessData(data) {
if (!("serverless" in data.pagination)) {
throw new Error(
"Missing `serverless` key in `pagination` object to point to pagination data."
);
pages.push(cloned);
}

let resolvedKey = this._get(data, data.pagination.serverless);
let fullDataSet = this._get(data, this._getDataKey());
return [this._get(fullDataSet, resolvedKey)];
return pages;
}
}

Expand Down
Loading

0 comments on commit 782f18b

Please sign in to comment.