“A Dream of a Dream” is now streaming on Hulu. It will air on FX tonight at 10 p.m.
As befits a series filled with characters whose dual identities require them to see the world from different perspectives, there are two ways to think about Shōgun’s decision to title its penultimate episode “Crimson Sky.” Crimson Sky is, of course, the name of Toranaga’s battle plan, presumed by all around him to be a relentless assault on Osaka and Ishido. Those paying attention to episode titles had every reason to expect the series’ ninth episode would depict the battle to end all battles. From that perspective, it was a bit of a fake-out. But from another, the one expressed by Toranaga in the series-ending “A Dream of a Dream,” we did see Crimson Sky last week, just not in the form we might have expected. Mariko’s mission effectively ended Ishido’s claim to power. Challenged and undermined, he’s become a dead warlord walking. He just doesn’t recognize it right away.
Similarly, there are two ways of looking at “A Dream of a Dream.” It can be seen as an anticlimax, one that offers only a fleeting glimpse of the battle that will bring Toranaga to power. (It is called Shōgun. It would have to end with that outcome, even if the James Clavell novel that serves as the source material wasn’t based on historical fact.) From another, and I suspect this will be the way most viewers who’ve stuck with the show will see it, it’s the finale the series needs, one more concerned with its characters and the overarching story of how nations get made than sword-clanging action (not that Shōgun has lacked that either).
Yet as the finale opens, it appears at first as if we’ve skipped past all that, landing years into the future. Blackthorne has become old and frail but also, based on his surroundings, quite wealthy. He lives in a fine English house surrounded by mementos of his time in Japan. Grandchildren run about and talk about his deeds, but they also talk about him as if he’s not there, apart from asking about his time with the savages. And, indeed, he seems barely present. But he’s with it enough to hold a precious reminder of the past: Mariko’s cross. Coupled with his grandson’s question, this appears to send Blackthorne’s mind back to the past.
It’s not a happy memory. Blackthorne is recalling — if what we’re watching is really him flashing back — the night of Mariko’s explosive death. (The previous episode didn’t leave a lot of ambiguity about her fate but, yes, she is really dead.) Blackthorne is despondent and Yabushige asks forgiveness, forgetting for the moment that no one should know he would have anything to ask forgiveness for.
From there, the story returns to Toranaga, who remained a distant figure in the previous episode. Enough time has passed for the news of Mariko’s death to have reached him, if not yet news of the discord it has sown among the Regents. This is, however, what he wanted. And though we can assume that he didn’t necessarily consider Mariko’s death a core part of his plan, he knew it was a possible, even likely, outcome. Yet as sad as the method of achieving it might make him, Toranaga has gotten what he wanted. Ishido’s grip on the council loosens as they consider what else could have been done and what happens next, particularly if Toranaga attacks. No one buys Ishido’s claim that Toranaga was behind the attack, but in some ways their discussion doesn’t matter, nor does their agreement to go to war. It’s clear even before she speaks that Ochiba is no longer onboard. And without her, it will all fall apart. (The bad-omen earthquake doesn’t help Ishido’s case, but it’s already superfluous.)
Ishido also has a Yabushige problem: Although his hearing seems to be recovering from the explosion, he’s apparently lost his mind. Haunted by Mariko’s death, he works himself into a frenzy looking for imaginary catfish as Ishido talks to him, ordering him back to Izu and to Toranaga. But if Ishido is hoping to have a man inside his enemy’s camp, Yabushige’s no longer that man. This is his Lady Macbeth moment, and the guilt that haunts him will follow wherever he goes.
Blackthorne too has to make his way to Izu, though he doesn’t expect he’ll make it there alive. Told he can return to Yabushige’s ship, he’s escorted through the woods by Father Martin, anticipating he’ll be ambushed and killed along the way. He’s not right, but he’s not exactly wrong, either. After Blackthorne tells Martin that Toranaga got exactly what he wanted without going to war, even if this isn’t immediately apparent, Martin confesses that the plan was to lead Blackthorne into an ambush, but “an arrangement was made.” As he boards, Martin tells him he promised Mariko he’d spare Blackthorne’s life. Only later will Blackthorne understand the full scope of the deal that’s kept him safe.
As they near their destination Blackthorne learns two things: (1) Yabushige has lost his mind, and (2) the Erasmus, the ship he’s so desperately wanted to reclaim since he first washed up on Japanese shores, has been sunk. Their arrival sheds some light on both developments when Omi asks for his uncle’s swords and Muraji — the Ajiro fisherman and Toranaga spy we haven’t seen in a while but who will come to play a sizable role in this episode — tells him he suspects Christians are behind the sinking of his ship. The severed heads that greet Blackthorne as he enters the village confirm just how seriously this possibility is being taken.
Toranaga wastes no time once Yabushige is brought before him. He knows it was Yabushige who admitted the shinobi thanks to Omi, who received word of the betrayal from one of Mariko’s ladies in waiting. Yabushige confesses and receives a sentence of death. He desperately pleads for a “good” death (like being torn apart by dogs), but the madness seems to leave him as he does so. He’s accepted his fate and, though he would prefer Blackthorne, agrees to have Toranaga serve as second to his seppuku.
It’s Fuji who next seeks out Blackthorne. The relationship between the barbarian and his consort has quietly been one of the most compelling of the series. Blackthorne’s connections to Toranaga, Mariko, and Yabushige have all been intense in different ways. Fuji, once she settled into her role in Blackthorne’s house, has offered calmness and acceptance and has taught him as much about Japanese culture by example as others did through actions. Now, talking to him without a translator — specifically Mariko, whose absence they acknowledge in silence — she attempts to say good-bye. She is not, as planned, going to take her life. Instead, she’s going to start a new life as a nun. Blackthorne does not want this, but he also really has no say in the matter. Her service to Toranaga, and thus Blackthorne, is complete. She can now do what she wants with her life. But that doesn’t mean she has let go of all her attachments. She’s unsure what to do with the remains of her husband and child, and she wishes Ajiro’s villagers were not being persecuted for the sinking of Blackthorne’s ship. Hearing this, Blackthorne asks for a meeting with Toranaga.
The next day, Toranaga grants Blackthorne’s request with Muraji acting as translator. If this seems odd, it is, or at least until Muraji lets Blackthorne know that he speaks fluent Portuguese, that he’s a samurai, and that he has been acting as Toranaga’s spy among the Catholics for years (in the process becoming a true believer of his adopted faith). Blackthorne apologizes, in the best Japanese he can muster, for his recent behavior and asks that Ajiro be spared. He also reveals he knows that Mariko is responsible for burning the Erasmus, a concession that allowed Blackthorne’s life to be spared. When Toranaga asks about Blackthorne’s war against his Catholic enemies, he replies, “I don’t need it anymore.” He is, in many respects, a changed man.
Nevertheless, Toranaga refuses Blackthorne’s request and, in response, Blackthorne offers to take his own life. No, he demands to take his own life as the one who’s truly been disloyal to Toranaga. When he arrived, he planned to “use” Toranaga and take advantage of the Japanese. And if that’s not clear enough, he declares himself an “enemy” before preparing to perform seppuku in earnest. And he almost does until Toranaga stays his hand (and not gently). Each has attempted to use the other, but that time is over. They’ve come to understand each other, without the need for translation by Mariko or Muraji, and now Toranaga wants Blackthorne to build him a fleet of his own.
Later, in what’s proving to be an eventful day for Toranaga, he meets with Yabushige (after Yabushige leaves Omi a colorful, perfectly in character death poem with the request his body be fed to “some hungry dog”). Toranaga and Yabushige, too, have come to an understanding. And in Yabushige’s final moments on earth, he learns of Toranaga’s plans for the future and the strategy that put him in the position to make such plans. He too played a role in burning Blackthorne’s ship, in part to spare the Anjin’s life, in part to test him.
All that’s well and good, but what is Toranaga’s plan? Yabushige has to know, even if he’s about to die. This is where Toranaga tells his treacherous soon-to-die ally that Crimson Sky has already taken place thanks to Mariko’s actions, saying, “I sent a woman to do what an army never could.” The rest, as the letter he received from Ochiba has already confirmed, is just a matter of playing out the actions already set in motion. There will be a battle, but not much of one. And, at the end, he’ll be Shōgun of a united Japan, ruling a “nation without wars” from Edo.
Of this, Yabushige says, “It’s what you always wanted, isn’t it? You’re no better than us in your secret heart.” But he’s not entirely sure, and he asks Toranaga to tell him as a dying wish. Although he’s been generous and understanding of the traitor, this, it seems, is further than Toranaga can go.
And with that, we’ve reached the end of this tale, or quite near it. But what of the scenes that opened the episode showing the aged Blackthorne in England? Look to the title, “A Dream of a Dream,” for a possible answer. These seem to have been the fantasies of the unconscious Blackthorne as he recovers from injuries sustained by the explosion. A final scene with Fuji puts the matter to rest. He encourages her to put the remains of her family to rest in the sea. She, in turn, does the same of Mariko’s cross, saying, “Let your hands be the last to hold her.”
As with Toranaga last week, Mariko’s shadow looms over this episode in spite of her absence. Blackthorne does little to hide his heartbreak, even though he doesn’t talk about her extensively. This exchange with Fuji is an exception in part because they’ve both now experienced the unthinkable. Barbarian and consort no longer, they’re something like equals here, friends even. Blackthorne’s not the only one to feel it, though. It’s hard to tell the degree to which Toranaga feels guilt for the actions that serve his master plan; he let Hiromatsu sacrifice himself for the plan’s sake and likely knew he’d lose Mariko, just as Mariko knew the slim odds of returning from her mission. But he too can feel loss, as is clear when he quotes her poem and considers “what a bonfire” she made.
Blackthorne’s hurt cuts even deeper, though he ends the series learning to move on. After he lets Mariko go, we last see him attempting to retrieve what’s left of his ship from the sea, joined by Buntaro, a man he never thought he’d regard as a friend. But then he never expected any of this. “How does it feel to shape the wind to your will?” Yabushige asks Toranaga. “I don’t control the wind,” he replies. “I only study it.” But some can only ride it, and as Blackthorne exchanges a look with Toranaga in the show’s final scene, both seem to understand who they are and where they belong.
Feudal Gestures
• Remember in the last episode how Mariko bristled at the suggestion that Toranaga could afford to lose Nagakado because he had other sons? Note the matter-of-fact way Toranaga says, “Thankfully, I have more sons” as he cradles his his newest progeny. Maybe that insult was closer to the truth than Mariko knew.
• Although it’s not heavily referenced in the series, Blackthorne and the Erasmus’s previous stop was in what we now call South America. This comes up a few times in Clavell’s novel, which makes clear that Blackthorne and his crew indulged in all the ugly behavior about which explorers apparently didn’t think twice. His time in Japan has not been what he’s used to.
• Let’s give a final tip of the hat to Tadanobu Asano, whose performance as Yabushige made a sadistic, deceitful character charismatic and even likable in spite of all he does. It shouldn’t work, but Asano keeps Yabushige charismatic in spite of himself. It makes sense for Toranaga to show the traitor such respect in his final moments, even if he never learns the full truth before his death.
• About that: The series’ great unanswered question is whether Toranaga wanted to be Shōgun or not. Was all of this part of his plan? Did he study the wind that well? Beyond that, did he lust for power, or did he really do all this for the good of Japan? Do motives even matter? Yabushige will never know, and neither will we.
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,"12":12,"35":35,"40":40}];
window.modules["global-nav.client"] = [function(require,module,exports){"use strict";const dom=require(3),auth=require(12),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(136),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 o=t.querySelector(".dropdown");!n||t.contains(e.target)&&27!==e.keyCode||o.classList.remove("open")})}function gtmSendReport(e,n,t){let o={eventCategory:"ecommerce",eventAction:"componentClick",brand:e,dimension23:"global-nav",list:pageUri,pageZone:"header",variant:"nav-link"};"global-nav-link"===t&&(o.eventLabel=n.href),gtm.reportNow(o)}function updateElementTargetUrlsIfQueryStrings(e){if(searchString){const n=new URLSearchParams(searchString);let t=e.href;if(t.includes("?")){const o=t.split("?"),i=new URLSearchParams(o[1]);for(let e of n.entries())i.set(e[0],e[1]);t=`${o[0]}?${i.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()&&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,"3":3,"12":12,"124":124,"136":136}];
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","aaa-module-mounting.legacy":"aaa-module-mounting.legacy","ads.legacy":"ads.legacy","facebook.legacy":"facebook.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();
// ]]