In Defense of Prudence Night on Chilling Adventures of Sabrina
ByAngelica Jade Bastién,
a New York and Vulture critic covering film and pop culture
Tati Gabrielle as Prudence in Chilling Adventures of Sabrina.
Photo: Diyah Pera/Netflix/Diyah Pera/Netflix
Witches have long been a vehicle for filmmakers to consider notions of power and womanhood, sexism, and adolescence. Whether a sprightly romance like Bell, Book, and Candle, a horrifying yet immaculate children’s film like The Witches, or a feminist-tinged cult TV masterpiece like Buffy the Vampire Slayer, what unites these disparate works is how they root witchcraft in a fantasy, picking various rituals, ideas, and histories from real-life counterparts like Wicca and hoodoo in order to allow women to experience impossible power. Netflix’s Chilling Adventures of Sabrina, based on showrunner Roberto Aguirre-Sacasa’s darker comic of the same name, is the latest in this pop-cultural phenomenon.
When I first watched Chilling Adventures,I found it to be a darkly spun, delightful confection braiding notions of female rebellion, matriarchal power, and community within its enchanting story. But since its debut last Friday, it has inspired a fascinating conversation I wasn’t expecting about its intersectional feminist bona fides. The most complex of these conversations hones in on Prudence (Tati Gabrielle), an orphaned black witch at the Academy of Unseen Arts who makes Sabrina’s life hellish during the first half of the season. The criticism of her character stems from the discomfort some people felt about Prudence’s characterization being too starkly villainous in relation to Sabrina’s “white fragility,” and a particular scene that some refer to as a lynching. As Taylor Crumpton writes in Teen Vogue, “[T]he show positions Prudence as the angry Black woman who attacks the misunderstood, small, blonde, white girl. It’s a harmful conflict viewers simply did not need to see, especially when the cards are so clearly stacked in Sabrina’s favor. Prudence never stood a chance.”
But discarding Prudence as a mere mean girl used to prop up Sabrina does Gabrielle’s delectable performance and the show itself a disservice. Dissecting the issues within Chilling Adventures with regards to race, feminism, and power deserve a sharpened blade instead of a hammer. Prudence is one of the most fascinating, stylish, and simply fun-to-watch witches pop culture has seen in awhile. Her story carries weight and dimension in ways black witches are rarely granted in pop culture. This isn’t to say the criticisms have no merit. The problems with the show’s approach to race comes down to this: Its definitions of witches as a cultural lineage are murky enough to invite questions about the dynamics of prejudice within its story, and while I find Prudence worthy of praise, the writing is somewhat hampered by a colorblind approach to her character.
The scene that led me to fall in love with Chilling Adventures is nestled within episode two, when Sabrina enlists the help of the Weird Sisters in order to exact vengeance on a cadre of Baxter High jocks tormenting her friend, Susie, for her gender and sexual identity. The prank involves Sabrina and the Weird Sisters luring these boys to the darkened mines to fool around, but the flash of Sabrina’s Polaroid camera reveals the truth: They aren’t making out with these witches, but tricked bytwisted glamour into making out with each other. (For the record, I didn’t see the prank the Weird Sisters and Sabrina as prejudiced, but a cudgel using the jocks’ own homophobia against them.) After sending the boys running into the inky darkness of the evening, Sabrina and Prudence share a potent exchange. Sabrina is hesitant to sign away her soul to the Dark Lord in return for power because it means giving away her freedom, and she doesn’t understand why the Dark Lord wouldn’t want witches like her having both. Prudence, proving her cunning goes far beyond her excellent eye for wardrobe, responds with a knowing purr: “He’s a man, isn’t he?” This scene acts as the show’s own thesis statement and a clever juxtaposition of who each of these young women are, even though each character begins as simplistic archetypes.
If Sabrina is the plucky upstart, Prudence is the resident mean girl all dramas of teen rebellion have. But this ignores both the context of the series and how Prudence is framed. Scenes like the aforementioned team-up add new dimensions to both characters and their relationship, which only deepen as the show continues. Prudence’s animosity toward Sabrina is ultimately rooted in the latter’s immense privilege: While both grew up as orphans, Sabrina is still the child of a powerful warlock who was once the head of the Church of Night. Prudence, by comparison, has to raise herself not knowing she was the abandoned child of Father Blackwood.
But Prudence is never depicted as an outright villain. The writers behind the series clearly want audiences to like her: She has bombastic entrances, great comebacks, and a stylistic fierceness that honors Gabrielle’s inspiration from the iconic Eartha Kitt. For every scene where she is cruel to Sabrina, there are others meant to highlight her depth beyond that mean-girl archetype, like their thoughtful argument about faith in the “Feast of Feasts” episode. Even as they have wildly different perspectives, they learn to respect each other. For Sabrina, she is willing to disregard the rules in order to get freedom and power; for Prudence, power is enough. In many ways, Prudence reminds me of Buffy the Vampire Slayer’s Cordelia Chase (portrayed with vigor and venom by Charisma Carpenter) — a mean girl who becomes a hero with dimension in her own right.
I will admit whenever Prudence referred to Sabrina as “half-breed” to nod to her half-witch, half-mortal lineage, I winced. Those words coming out of the mouth of a black woman — especially a character who is revealed to be the mixed-race daughter of Father Blackwood (Richard Coyle) — is like stepping into a home with fun house mirrors. It’s a jarring occurence repeated at different points in the series, and it seems born from the same well of ignorance that led to the most prickly moment in the series’ fourth episode, “Witch Academy.”
The most controversial scene in Chilling Adventures, at least in regards to Prudence, comes at the end of that episode, which charts Sabrina’s early days in the Academy of the Unseen Arts as she suffers through a cruel hazing experience known as the Harrowing. The Weird Sisters, with Prudence guiding the way, relish torturing Sabrina — imprisoning her in a narrow chamber, forcing her into the cold night where a demon taunts her by imitating her loved ones being grotesquely tortured — and save their cruelest punishment for last. They take Sabrina to a clearing in the dead of night. A noose festoons her neck, rope binds her wrists. But instead of being strung up and perhaps even killed, Sabrina flips the script: With the help of the ghosts of Academy students killed during their own Harrowings, she flings up the Weird Sisters on invisible nooses, strangling them as she declares there will be no more hazing at the school. In a recent io9 piece, Beth Elderkin and Charles Pulliam-Moore critiqued this scene succinctly: “This should not have to be explained, but it is in extremely bad taste to depict black people being hanged on television without an extraordinary amount of context and care that make it clear that (a) the creators of the television show understand the significance of that imagery, and (b) said hanging serves a narrative point.”
Lynching is not a horror transcribed to history, but a present and vicious act. The goal of those that perform these monstrosities throughout the sickening history of this country is more than just pain or violence, it is to consign black people to utter oblivion. As the marvelous journalist Ida B. Wells said to a Chicago crowd in 1900, “Our country’s national crime is lynching. It is not the creature of an hour, the sudden outburst of uncontrolled fury, or the unspeakable brutality of an insane mob. It represents the cool, calculating deliberation of intelligent people who openly avow that there is an ‘unwritten law’ that justifies them in putting human beings to death without complaint under oath, without trial by jury, without opportunity to make defense, and without right of appeal.”
I wasn’t riled by what happens in Chilling Adventures, but I can see how it betrays an ignorance to the optics of the matter, even as the hangings are meant to evoke the history of witch trials leading up to the emergence of the Greendale 13 in the closing episode. Yet to call what happens a lynching is to strip actual lynchings of their tangled complexities and to willfully ignore the context of the scene in the series. Sabrina doesn’t kill Prudence or the other Weird Sisters; she was defending herself in the only way she saw fit to avoid her own demise. (This act also foreshadows the darkness Sabrina is willing to enact by season’s end.) Most importantly, Chilling Adventures from the very beginning treats Prudence as an alluring mean girl, not a villain meant to be punished. If anything, Gabrielle brings her to life with such fierce grace, she becomes more than just a charming supporting character, but an accomplished scene-stealer who at times could be a more engaging anchor for the series than Shipka’s Sabrina.
I think a larger issue with the reception to Chilling Adventures comes down to its humor being ignored in favor of a highly literal reading of the show, even as it flexes its genre muscles in a way that is deeply indebted to Buffy the Vampire Slayer. Buffy excelled at vacillating from interrogating gender politics to finding arch humor in the dark trappings of its fantastical world. Similarly, Chilling Adventures has its tongue firmly planted in its cheek, even in its dark consideration of witchcraft, to interrogate sexism and the way women’s power has been circumscribed. This is a show that takes various Christian iconography and inverts it in hilarious ways, with characters exclaiming, “Hail, Satan!” or drolling about the Unholy Night. There is Thanksgiving-esque celebration in which a woman is crowned the Queen of Feasts to pay homage to an ancestor who laid down her own life to aid her coven. How is she rewarded? By being eaten by her coven, just as that ancestor was. It’s deliriously heightened and utterly ridiculous! The show hasn’t reach the scalpel-sharp grace of Buffy, but this is the lineage in which it tracks.
Meanwhile, the history of black witches in pop culture is a tangled one defined by exoticization and marginalization. Black witches may be granted style and grace, but rarely are the written with any interiority. In The Craft, Rachel True’s Rochelle is mired in the racist attacks of a peer, but she is hastily drawn in comparison to the other, white members of her coven. In American Horror Story: Coven, Angela Bassett brings a fierce grace to Madame Marie Laveau, one of the most important figures of witchcraft in New Orleans and American history, but that series framed race in a way that betrays a queasy ignorance (and her power often paled to that of the white witches, who seemingly cribbed their skills from black women in the first place). Although Tituba is one of the most iconic black witches, thanks to portrayals in a variety of books, films, and series about the Salem witch trials, historical documents prove she wasn’t black at all but a South American Native. The most successful black witches in all of pop culture, to me, remain Mozelle Batiste Delacroix (Debbi Morgan) and the women of Eve’s Bayou, a gorgeous coming-of-age tale that respects and celebrates the rich culture of rural Louisiana.
Where does Prudence fit within this lineage? Does she mark a fascinating step forward in granting black women (and black audiences by proxy) the delight that comes with being a witch, or is she another example of the ways black witches in pop culture garner little respect and even less interiority by the writers that conjure them? Prudence is a tremendous character — beguiling, sharp-witted, fierce. She’s also something I wish I got to see as a kid: a black witch having fun with her powers and reveling in the world she lives in. If anything, she’s dynamic enough thanks to Gabrielle’s slinky performance that she trumps the show’s nagging issues of colorblind perspective. The creators behind Chilling Adventures would be smart to give her even more focus going forward and define the dynamics of race within their world of witchcraft.
The conversation swirling around Chilling Adventures reflects the fascinating, wildly shifting intersections between politics and art that often simplify the former and flatten the latter. Representation need not be a mirror for individual members of the audience, but should encourage writers to address characters of color like Prudence with dimension — including acknowledgements of how race affects the way they move through the world. Chilling Adventures seeks to interrogate the ways women yearn for, experience, and at times, are prohibited from power through its clever, rich story about witches. But to give this story justice, the show must acknowledge that even among women, power takes on a completely different meaning when blackness is a part of their identity.
By submitting your email, you agree to our
Terms and Privacy Notice
and to receive email correspondence from us. This site is protected by reCAPTCHA and the Google
Privacy Policy and
Terms of Service apply.
or
Already a subscriber?
What is your email?
This email will be used to sign into all New York sites. By submitting your email, you agree to our Terms and Privacy Policy and to receive email correspondence from us.
Password must be at least 8 characters and contain:
Lower case letters (a-z)
Upper case letters (A-Z)
Numbers (0-9)
Special Characters (!@#$%^&*)
This password will be used to sign into all New York sites. By submitting your email, you agree to our Terms and Privacy Policy and to receive email correspondence from us.
You’re in!
As part of your account, you’ll receive occasional updates and offers from New York, which you can opt out of anytime.
or
Already a subscriber?
What is your email?
This email will be used to sign into all New York sites. By submitting your email, you agree to our Terms and Privacy Policy and to receive email correspondence from us.
Password must be at least 8 characters and contain:
Lower case letters (a-z)
Upper case letters (A-Z)
Numbers (0-9)
Special Characters (!@#$%^&*)
This password will be used to sign into all New York sites. By submitting your email, you agree to our Terms and Privacy Policy and to receive email correspondence from us.
You’re in!
As part of your account, you’ll receive occasional updates and offers from New York, which you can opt out of anytime.
Already a subscriber?
Already a subscriber?
`;
// integrate Sub(x) scripts and elements
if (hostname !== 'subs.nymag.com') { // do not integrate on this subdomain
document.head.appendChild(trackingScript);
document.body.insertAdjacentHTML('beforeend', subXAnimationElements);
}
There was an error processing the request. Please try again later."}).catch(e=>console.error("Error verifying email: ",e)))(r.querySelector(".content"),o.bannerCTAVerification)})):(l.remove(),s.remove()),o.dismissable||n.remove(),o.useAlertIcon||a.remove(),r.classList.add("show"),n.addEventListener("click",()=>{u(),r.classList.remove("show")})}else r.remove()}});
}, {"1":1,"6":6,"17":17,"35":35,"40":40}];
window.modules["global-nav.client"] = [function(require,module,exports){"use strict";const dom=require(4),auth=require(17),signInButton=dom.find(".user-signin"),signOutButton=dom.find(".user-signout"),globalNav=dom.find('[class^="global-nav"]'),body=dom.find("body"),dropdownItems=dom.findAll(".dropdown-wrap"),gtm=require(1),appendLandingPageParams=require(135),pageUri=require(124).getPageUri(),subscriptionPromoLinks=dom.findAll(".persist-params"),searchString=window.location.search||"";function closeDropdowns(e){let n=globalNav.querySelectorAll(".dropdown.open");dropdownItems.forEach(function(t){let i=t.querySelector(".dropdown");!n||t.contains(e.target)&&27!==e.keyCode||i.classList.remove("open")})}function gtmSendReport(e,n,t){let i={eventCategory:"ecommerce",eventAction:"componentClick",brand:e,dimension23:"global-nav",list:pageUri,pageZone:"header",variant:"nav-link"};"global-nav-link"===t&&(i.eventLabel=n.href),gtm.reportNow(i)}function updateElementTargetUrlsIfQueryStrings(e){if(searchString){const n=new URLSearchParams(searchString);let t=e.href;if(t.includes("?")){const i=t.split("?"),o=new URLSearchParams(i[1]);for(let e of n.entries())o.set(e[0],e[1]);t=`${i[0]}?${o.toString()}`,e.href=t}else e.href=`${t}?${n.toString()}`}}function init(e){const n=e.querySelectorAll(".to-landing-page");window.addEventListener("auth:init",()=>{signInButton.addEventListener("click",function(e){e.preventDefault(),auth.showEmbeddedLoginFlow("top navigation")}),signOutButton.addEventListener("click",function(e){e.preventDefault(),gtmSendReport("Sign Out",e.target,"user-info-link"),auth.logout()}),auth.isAuthenticated()&&e.classList.add("signed-in"),(auth.isSubscriber()||auth.isMobileAppRequest())&&e.classList.add("subscribed"),e.querySelectorAll(".user-link").forEach(e=>{e.classList.add("active")}),subscriptionPromoLinks.forEach(e=>{updateElementTargetUrlsIfQueryStrings(e)}),appendLandingPageParams(n)})}dropdownItems.forEach(function(e){e.addEventListener("click",function(){e.querySelector(".dropdown").classList.toggle("open")})}),body.addEventListener("click",closeDropdowns),document.addEventListener("keydown",closeDropdowns),globalNav.addEventListener("click",function(e){let n=e.target;n.classList.contains("global-nav-track")&>mSendReport(n.text,n,"global-nav-link")}),module.exports=init;
}, {"1":1,"4":4,"17":17,"124":124,"135":135}];
window.modules["aaa-module-mounting.legacy"] = [function(require,module,exports){"use strict";const _pickBy=require(221),_each=require(408),Fingerprint2=require(407),DS=require(406),Eventify=require(246);function registerGlobals(){window.DS=DS,window.Eventify=Eventify,window.Fingerprint2=Fingerprint2,DS.value("Eventify",Eventify),DS.value("Fingerprint2",Fingerprint2),DS.value("$document",window.document),DS.value("$window",window)}function mountDollarSliceComponents(){DS.service("components",["$document","$module",function(e,n){var o=_pickBy(n.definitions,e=>e.providerStrategy===n.providers.controller),r=Object.keys(o);function t(e){return o=>{try{n.get(e,o)}catch(e){logMountError(o,e)}}}_each(r,n=>{var o=e.querySelectorAll('[data-uri*="/_components/'+n+'/"]'),r=e.querySelectorAll('[data-uri$="/_components/'+n+'"]');_each(o,t(n)),_each(r,t(n))}),this.components=r}]),DS.get("components")}function logMountError(e,n){const o=e.outerHTML.slice(0,e.outerHTML.indexOf(e.innerHTML));console.error("Error attaching controller to "+o,n)}registerGlobals(),"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>{mountDollarSliceComponents()}):mountDollarSliceComponents();
}, {"221":221,"246":246,"406":406,"407":407,"408":408}];
window.modules["ads.legacy"] = [function(require,module,exports){"use strict";const _map=require(118),_forEach=require(107),_isString=require(268),_intersectionWith=require(409),_isEqual=require(274),_each=require(408),_debounce=require(182),_sortBy=require(205),page=require(124),visit=require(114);DS.service("adService",["Eventify","$cid","$document","$window",function(e,t,a,i){var o,n,s,r,d,c,u,l,g={},p=this,h=[],f=visit.getQueryParamsObject(["utm_campaign"]),m=document.querySelector('script[data-type="ad-a9"]'),b=[],w=!1,v=[],y=document.querySelector('script[data-name="ad-doubleverify"]');document.querySelector('script[data-name="concert-ads"]')||(i.NYM={},i.NYM.analytics={},i.NYM.analytics.adStartTime=i.performance.now(),i.googletag=i.googletag||{},i.googletag.cmd=i.googletag.cmd||[],u=i.googletag,(m||y)&&(i.googletag.cmd=i.googletag.cmd||[],i.googletag.cmd.push(function(){i.googletag.pubads().disableInitialLoad()})),m&&(l=i.setInterval(function(){void 0!==window.apstag&&void 0!==window.apstag.timeout&&(i.clearInterval(l),window.apstag.cleared=!0,l=null)},10),setTimeout(function(){l&&(i.clearInterval(l),i.googletag.pubads().refresh(),window.apstag||console.log("MESSAGE: Timeout for A9 load exceeded, aborting"))},500)),y&&(b.push(new Promise(function(e){w?e():v.push(e)})),c=i.setTimeout(T,2500)),o=function(e){var t,a,o=e.data,n=[];return o.loaded?e:(o.loaded=!0,t=null,(t=o.sizes?u.defineSlot(o.name,o.sizes,o.id).addService(u.pubads()):u.defineOutOfPageSlot(o.name,o.id).addService(u.pubads())).setTargeting("adid",o.id),f.hasOwnProperty("utm_campaign")&&t.setTargeting("utmcamp",f.utm_campaign),a=p.getAdCount(o.label),t.setTargeting("label",o.label+"_"+o.site+"-"+a),u.display(o.id),u.pubads().addEventListener("slotOnload",function(){i.NYM.analytics.firstAdLoadTime||(i.NYM.analytics.firstAdLoadTime=i.performance.now(),i.NYM.analytics.firstAdLoadLabel=e.data.label)}),n=_(o),Promise.all(b).then(function(){n?window.apstag&&window.apstag.cleared?window.apstag.fetchBids({slots:[n],timeout:window.apstag.timeout},function(){u.cmd.push(function(){window.apstag.setDisplayBids(),u.pubads().refresh([t],{changeCorrelator:!1})})}):y&&u.pubads().refresh([t],{changeCorrelator:!1}):u.pubads().refresh([t],{changeCorrelator:!1})}),e.slot=t,e)},n=function(e){var a,i,o,n=t(),s=e.getAttribute("data-name"),r=e.getAttribute("data-sizes"),d=e.getAttribute("data-label"),c=e.getAttribute("data-site");n=e.id,r&&r.length?(r=r.split(","),a=[],_map(r,function(e){e=e.split("x"),i=parseInt(e[0]),o=parseInt(e[1]),a.push([i,o])})):(e.classList.add("oop"),a=!1),this.data={id:n,name:s,sizes:a,loaded:!1,label:d,site:c},g[n]=this},r=function(e){u.cmd.push(function(){var t=o(e);g[e.data.id]=t})},s=function(e){var t=[];e.slot?(t=_(e))&&window.apstag&&window.apstag.cleared&&window.apstag.fetchBids({slots:[t],timeout:window.apstag.timeout},function(){u.cmd.push(function(){window.apstag.setDisplayBids(),u.pubads().refresh([e.slot],{changeCorrelator:!1})})}):e&&r(e)},u.cmd.push(function(){var e,t,o,n=page.getMeta("article:tag"),s=page.getMeta("author"),r=i.location.href,d=(e=a.head.querySelector(".head-gtm"),t=a.body.querySelector(".gtm"),e&&"top"===e.getAttribute("data-gtm")?"gtmtop":t&&"bottom"===t.getAttribute("data-gtm")?"gtmbottom":"");o=[],_forEach([n,s,d],function(e){_forEach(e.split(","),function(e){(e=e.trim().toLowerCase().replace(/\s/g,"-").replace(/\'|\’/g,"")).length&&o.push(e)})}),u.pubads().setTargeting("kw",o),u.pubads().setTargeting("entry_group",o),r=r.slice(r.lastIndexOf("/")+1),u.pubads().setTargeting("pn",r),u.companionAds().setRefreshUnfilledSlots(!0),u.pubads().enableAsyncRendering(),u.enableServices()}),this.load=r,this.create=function(e){return new n(e)},this.refresh=function(e){var t;_isString(e)?(t=this.getById(e),s(t)):s(e)},this.remove=function(e){var t=e.data.id;a.getElementById(t).innerHTML=""},this.getAdCount=function(e){var t,a=0,i=Object.keys(g);return _each(i,function(i){(t=g[i]).data.loaded&&t.data.label===e&&a++}),a},this.getById=function(e){return g[e]},d=_debounce(function(){var e={TopLeaderboard:1,RightColTopMPU:2,outOfPage:99,"homepageTakeover/TopLeaderboard":1},t=_sortBy(h,function(t){return e[t.data.label]||10});_forEach(t,function(e){return e.data.sizes?r(e):i.setTimeout(function(){r(e)},2e3)}),y&&window.PQ.cmd.push(()=>{try{window.PQ.loadSignals(["ids","bsc","vlp"],T)}catch(e){T(),console.error(`There has been an error loading Double Verify signals: ${e}`)}}),h=[]},10),this.addToPageLoadQueue=function(e){h.push(e),d()});function _(e){var t,a=e.sizes;return a=_intersectionWith(a,[[970,250],[970,90],[728,90],[300,600],[300,250],[320,100],[320,50]],_isEqual),e.sizes&&e.sizes.length&&(t={slotID:e.id,sizes:a,slotName:e.label}),t}function T(){i.clearTimeout(c),w=!0,_forEach(v,function(e){e()})}}]);
}, {"107":107,"114":114,"118":118,"124":124,"182":182,"205":205,"268":268,"274":274,"408":408,"409":409}];
window.modules["cid.legacy"] = [function(require,module,exports){"use strict";DS.service("$cid",function(){var r=Math.floor(100*Math.random());return function(){return"cid-"+ ++r}});
}, {}];
window.modules["client.legacy"] = [function(require,module,exports){"use strict";require("cid.legacy"),require("ads.legacy"),require("facebook.legacy"),require("aaa-module-mounting.legacy");
}, {"cid.legacy":"cid.legacy","ads.legacy":"ads.legacy","facebook.legacy":"facebook.legacy","aaa-module-mounting.legacy":"aaa-module-mounting.legacy"}];
window.modules["facebook.legacy"] = [function(require,module,exports){"use strict";DS.service("facebook",[function(){this.fb=function(i){window.FB&&window.FB[i].apply(this,Array.prototype.slice.call(arguments,1))}}]);
}, {}];
require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o typeof key === 'string' && key.match(/\.legacy$/)).forEach(key => window.require(key));
}
function tryToMount(fn, el, name) {
try {
fn(el); // init the controller
} catch (e) {
const elementTag = el.outerHTML.slice(0, el.outerHTML.indexOf(el.innerHTML));
console.error(`Error initializing controller for "${name}" on "${elementTag}"`, e);
}
}
/**
* mount client.js component controllers
*/
function mountComponentModules() {
Object.keys(window.modules).filter(key => typeof key === 'string' && key.match(/\.client$/)).forEach(key => {
let controllerFn = window.require(key);
if (typeof controllerFn === 'function') {
const name = key.replace('.client', ''),
instancesSelector = `[data-uri*="_components/${name}/"]`,
defaultSelector = `[data-uri$="_components${name}"]`,
instances = document.querySelectorAll(instancesSelector),
defaults = document.querySelectorAll(defaultSelector);
for (let el of instances) {
tryToMount(controllerFn, el, name);
}
for (let el of defaults) {
tryToMount(controllerFn, el, name);
}
}
});
}
// Make sure that a `window.process.env.NODE_ENV` is available in the client for any dependencies,
// services, or components that could require it
// note: the `` value is swapped for the actual environment variable in /lib/cmd/compile/scripts.js
window.process = window.process || {};
window.process.env = window.process.env || {};
if (!window.process.env.NODE_ENV) {
window.process.env.NODE_ENV = '';
}
// note: legacy controllers that require legacy services (e.g. dollar-slice) must
// wait for DOMContentLoaded to initialize themselves, as the files themselves must be mounted first
mountLegacyServices();
mountComponentModules();
// ]]