Skip to content

Commit

Permalink
Saving/resetting config file should apply new config values everywher…
Browse files Browse the repository at this point in the history
…e (including layouts) (#2867)
  • Loading branch information
zachleat committed Mar 17, 2023
2 parents 0db66a2 + d45d880 commit 373d4b5
Show file tree
Hide file tree
Showing 17 changed files with 217 additions and 274 deletions.
54 changes: 38 additions & 16 deletions src/Eleventy.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const ConsoleLogger = require("./Util/ConsoleLogger");
const PathPrefixer = require("./Util/PathPrefixer");
const TemplateConfig = require("./TemplateConfig");
const FileSystemSearch = require("./FileSystemSearch");

const PathNormalizer = require("./Util/PathNormalizer.js");
const simplePlural = require("./Util/Pluralize");
const checkPassthroughCopyBehavior = require("./Util/PassthroughCopyBehaviorCheck");
const debug = require("debug")("Eleventy");
Expand Down Expand Up @@ -55,6 +55,12 @@ class Eleventy {
this.eleventyConfig.setPathPrefix(this.pathPrefix);
}

/**
* @member {Object} - Options object passed to the Eleventy constructor
* @default {}
*/
this.options = options;

/* Programmatic API config */
if (options.config && typeof options.config === "function") {
// TODO use return object here?
Expand Down Expand Up @@ -728,7 +734,7 @@ Arguments:
* @method
* @param {String} changedFilePath - File that triggered a re-run (added or modified)
*/
async _addFileToWatchQueue(changedFilePath) {
async _addFileToWatchQueue(changedFilePath, isResetConfig) {
// Currently this is only for 11ty.js deps but should be extended with usesGraph
let usedByDependants = [];
if (this.watchTargets) {
Expand All @@ -738,24 +744,27 @@ Arguments:
}

// Note: this is a sync event!
eventBus.emit("eleventy.resourceModified", changedFilePath, usedByDependants);
eventBus.emit("eleventy.resourceModified", changedFilePath, usedByDependants, {
viaConfigReset: isResetConfig,
});

this.watchManager.addToPendingQueue(changedFilePath);
}

_shouldResetConfig() {
let configFilePaths = this.eleventyConfig.getLocalProjectConfigFiles();
let configFilesChanged = this.watchManager.hasQueuedFiles(configFilePaths);

if (configFilesChanged) {
return true;
shouldTriggerConfigReset(changedFiles) {
let configFilePaths = new Set(this.eleventyConfig.getLocalProjectConfigFiles());
for (let filePath of changedFiles) {
if (configFilePaths.has(filePath)) {
return true;
}
}

for (const configFilePath of configFilePaths) {
// Any dependencies of the config file changed
let configFileDependencies = this.watchTargets.getDependenciesOf(configFilePath);
let configFileDependencies = new Set(this.watchTargets.getDependenciesOf(configFilePath));

for (let dep of configFileDependencies) {
if (this.watchManager.hasQueuedFile(dep)) {
for (let filePath of changedFiles) {
if (configFileDependencies.has(filePath)) {
return true;
}
}
Expand All @@ -764,13 +773,26 @@ Arguments:
return false;
}

// Checks the build queue to see if any configuration related files have changed
_shouldResetConfig(activeQueue = []) {
if (!activeQueue.length) {
return false;
}

return this.shouldTriggerConfigReset(
activeQueue.map((path) => {
return PathNormalizer.normalizeSeperator(TemplatePath.addLeadingDotSlash(path));
})
);
}

/**
* tbd.
*
* @private
* @method
*/
async _watch() {
async _watch(isResetConfig = false) {
if (this.watchManager.isBuildRunning()) {
return;
}
Expand All @@ -785,7 +807,6 @@ Arguments:
this.watchTargets.clearRequireCacheFor(queue);

// reset and reload global configuration
let isResetConfig = this._shouldResetConfig();
if (isResetConfig) {
this.resetConfig();
}
Expand Down Expand Up @@ -1019,12 +1040,13 @@ Arguments:
let watchRun = async (path) => {
path = TemplatePath.normalize(path);
try {
this._addFileToWatchQueue(path);
let isResetConfig = this._shouldResetConfig([path]);
this._addFileToWatchQueue(path, isResetConfig);
clearTimeout(watchDelay);

await new Promise((resolve, reject) => {
watchDelay = setTimeout(async () => {
this._watch().then(resolve, reject);
this._watch(isResetConfig).then(resolve, reject);
}, this.config.watchThrottleWaitTime);
});
} catch (e) {
Expand Down
2 changes: 1 addition & 1 deletion src/EleventyExtensionMap.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class EleventyExtensionMap {

get engineManager() {
if (!this._engineManager) {
this._engineManager = new TemplateEngineManager(this.config);
this._engineManager = new TemplateEngineManager(this.eleventyConfig);
}

return this._engineManager;
Expand Down
20 changes: 8 additions & 12 deletions src/Engines/TemplateEngine.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const debug = require("debug")("Eleventy:TemplateEngine");
class TemplateEngineConfigError extends EleventyBaseError {}

class TemplateEngine {
constructor(name, dirs, config) {
constructor(name, dirs, eleventyConfig) {
this.name = name;

if (!dirs) {
Expand All @@ -25,21 +25,17 @@ class TemplateEngine {
this.engineLib = null;
this.cacheable = false;

if (!config) {
throw new TemplateEngineConfigError("Missing `config` argument.");
if (!eleventyConfig) {
throw new TemplateEngineConfigError("Missing `eleventyConfig` argument.");
}
this._config = config;
}

set config(cfg) {
this._config = cfg;
this.eleventyConfig = eleventyConfig;
}

get config() {
if (this._config instanceof TemplateConfig) {
return this._config.getConfig();
if (this.eleventyConfig instanceof TemplateConfig) {
return this.eleventyConfig.getConfig();
}
return this._config;
throw new Error("Expecting a TemplateConfig instance.");
}

get benchmarks() {
Expand All @@ -61,7 +57,7 @@ class TemplateEngine {

get extensionMap() {
if (!this._extensionMap) {
this._extensionMap = new EleventyExtensionMap([], this.config);
this._extensionMap = new EleventyExtensionMap([], this.eleventyConfig);
}
return this._extensionMap;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Template.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ class Template extends TemplateContent {
return TemplateLayout.getTemplate(
layoutKey,
this.getInputDir(),
this.config,
this.eleventyConfig,
this.extensionMap
);
}
Expand Down
26 changes: 18 additions & 8 deletions src/TemplateCache.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ class TemplateCache {
this.cacheByInputPath = {};
}

// alias
removeAll() {
this.clear();
}

size() {
return Object.keys(this.cacheByInputPath).length;
}
Expand Down Expand Up @@ -60,29 +65,34 @@ class TemplateCache {
return this.cache[key];
}

remove(filePath) {
filePath = TemplatePath.stripLeadingDotSlash(filePath);

if (!this.cacheByInputPath[filePath]) {
remove(layoutFilePath) {
layoutFilePath = TemplatePath.stripLeadingDotSlash(layoutFilePath);
if (!this.cacheByInputPath[layoutFilePath]) {
// not a layout file
return;
}

let layoutTemplate = this.cacheByInputPath[filePath];
let layoutTemplate = this.cacheByInputPath[layoutFilePath];
layoutTemplate.resetCaches();

let keys = layoutTemplate.getCacheKeys();
for (let key of keys) {
delete this.cache[key];
}

delete this.cacheByInputPath[filePath];
delete this.cacheByInputPath[layoutFilePath];
}
}

let layoutCache = new TemplateCache();

eventBus.on("eleventy.resourceModified", (path) => {
layoutCache.remove(path);
eventBus.on("eleventy.resourceModified", (path, usedBy, metadata = {}) => {
// https://github.com/11ty/eleventy-plugin-bundle/issues/10
if (metadata.viaConfigReset) {
layoutCache.removeAll();
} else {
layoutCache.remove(path);
}
});

// singleton
Expand Down
33 changes: 20 additions & 13 deletions src/TemplateContent.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class TemplateContent {
if (!config) {
throw new TemplateContentConfigError("Missing `config` argument to TemplateContent");
}
this.config = config;
this.eleventyConfig = config;

this.inputPath = inputPath;

Expand Down Expand Up @@ -72,7 +72,7 @@ class TemplateContent {
/* Used by tests */
get extensionMap() {
if (!this._extensionMap) {
this._extensionMap = new EleventyExtensionMap([], this.config);
this._extensionMap = new EleventyExtensionMap([], this.eleventyConfig);
}
return this._extensionMap;
}
Expand All @@ -81,26 +81,33 @@ class TemplateContent {
this._extensionMap = map;
}

set config(config) {
set eleventyConfig(config) {
this._config = config;
}

get config() {
if (this._config instanceof TemplateConfig) {
return this._config.getConfig();
this._configOptions = this._config.getConfig();
} else {
throw new TemplateContentConfigError("Tried to get an TemplateConfig but none was found.");
}
return this._config;
}

get bench() {
return this.config.benchmarkManager.get("Aggregate");
}

get eleventyConfig() {
if (this._config instanceof TemplateConfig) {
return this._config;
}
throw new TemplateContentConfigError("Tried to get an eleventyConfig but none was found.");
throw new TemplateContentConfigError("Tried to get an TemplateConfig but none was found.");
}

get config() {
if (this._config instanceof TemplateConfig && !this._configOptions) {
this._configOptions = this._config.getConfig();
}

return this._configOptions;
}

get bench() {
return this.config.benchmarkManager.get("Aggregate");
}

get engine() {
Expand All @@ -109,7 +116,7 @@ class TemplateContent {

get templateRender() {
if (!this._templateRender) {
this._templateRender = new TemplateRender(this.inputPath, this.inputDir, this.config);
this._templateRender = new TemplateRender(this.inputPath, this.inputDir, this.eleventyConfig);
this._templateRender.extensionMap = this.extensionMap;
}

Expand Down
2 changes: 1 addition & 1 deletion src/TemplateData.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ class TemplateData {

get extensionMap() {
if (!this._extensionMap) {
this._extensionMap = new EleventyExtensionMap([], this.config);
this._extensionMap = new EleventyExtensionMap([], this.eleventyConfig);
}
return this._extensionMap;
}
Expand Down
20 changes: 11 additions & 9 deletions src/TemplateEngineManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,19 @@ const EleventyBaseError = require("./EleventyBaseError");
class TemplateEngineManagerConfigError extends EleventyBaseError {}

class TemplateEngineManager {
constructor(config) {
if (!config) {
constructor(eleventyConfig) {
if (!eleventyConfig) {
throw new TemplateEngineManagerConfigError("Missing `config` argument.");
}
this.config = config;
this.eleventyConfig = eleventyConfig;

this.engineCache = {};
}

get config() {
return this.eleventyConfig.getConfig();
}

static isCustomEngineSimpleAlias(entry) {
let keys = Object.keys(entry);
if (keys.length > 2) {
Expand Down Expand Up @@ -74,7 +78,7 @@ class TemplateEngineManager {
}

getEngineClassByExtension(extension) {
// We include these as raw strings (and not more readable variables) so they’re parsed by the bundler.
// We include these as raw strings (and not more readable variables) so they’re parsed by the serverless bundler.
if (extension === "ejs") {
return require("./Engines/Ejs");
} else if (extension === "md") {
Expand Down Expand Up @@ -102,9 +106,7 @@ class TemplateEngineManager {

getEngine(name, dirs, extensionMap) {
if (!this.hasEngine(name)) {
throw new Error(
`Template Engine ${name} does not exist in getEngine (dirs: ${dirs})`
);
throw new Error(`Template Engine ${name} does not exist in getEngine (dirs: ${dirs})`);
}

// TODO these cached engines should be based on extensions not name, then we can remove the error in
Expand All @@ -115,7 +117,7 @@ class TemplateEngineManager {

let cls = this.getEngineClassByExtension(name);

let instance = new cls(name, dirs, this.config);
let instance = new cls(name, dirs, this.eleventyConfig);
instance.extensionMap = extensionMap;
instance.engineManager = this;

Expand All @@ -128,7 +130,7 @@ class TemplateEngineManager {
instance.constructor.name !== "CustomEngine"
) {
const CustomEngine = this.getEngineClassByExtension();
const overrideCustomEngine = new CustomEngine(name, dirs, this.config);
const overrideCustomEngine = new CustomEngine(name, dirs, this.eleventyConfig);
// Keep track of the "default" engine 11ty would normally use
// This allows the user to access the default engine in their override
overrideCustomEngine.setDefaultEngine(instance);
Expand Down

0 comments on commit 373d4b5

Please sign in to comment.