ByAdam Platt,
a features writer at New Yorkwho served for many years as the magazine’s critic
Llama-San
Photo: Scott Heins
As always in the dining capital of the USA, this end-of-decade year produced the usual mob of diverse, compelling, generally delicious restaurants from which to cull our annual, highly debatable “Absolute Best Restaurants of the Year” list. As usual, we focus on the very newest restaurants (sorry, Gotham Bar and Grill) and the ones that opened this year (sorry, Benno and Sushi Noz), and, as usual, we have been forced against our will by our click-happy editors to rank our favorites in descending order. Have we missed a few places during the course of our gastronomic rounds? Yes we have! Will we get to them in due course? Yes we will, but in the meantime, here’s Platt’s 2019 list for your merry debating pleasure.
The Absolute Best
1. Llama-San 359 Sixth Ave., nr. Washington Pl.; 646-490-4422
Photo: Scott Heins
There are more stylish new restaurants around town, it’s true, and new restaurants with a little more buzz and higher levels of ambition and gourmet technique. But few of them combine these various elements in such seamless, even artful ways, and none manage to open a window into a new and unexpected realm of cooking as successfully as this Erik Ramirez outpost in Greenwich Village. As you’ve probably heard, the house speciality is Nikkei Japanese-Peruvian cuisine, which in the hands of Ramirez and his chef de cuisine, Sergio Nakayoshi, can mean anything from plump scallop ceviche dappled with Japanese black sesame, to rolls of seaweed-laced rice maki stuffed with a mash of simmered chicken thighs instead of the usual yellowtail or spicy tuna. Most everything on the menu has its charms, but the best dishes (the nori, the Iberico katsu, a luxurious play on surf n’ turf made with lobster and beef heart rolled in Peruvian aji panca paste) contain a multitude of different culinary tastes and cultures in a single bite.
It may not be kosher to put an entire food court with its crowded bars and multiple options on a grandiose best-restaurant list like this one, but then this pleasing, multi-faceted, José Andrés extravaganza isn’t your average food hall. It’s more like a rolling food fair with expertly curated Spanish delicacies designed for every occasion and every part of the day. You can enjoy trencherman breakfasts beginning at 7 a.m. (call for morcilla with eggs and simmered tripe at the excellent Spanish Diner) or pick up a decorous vat of Valencian paella or two to take back for a lunch party at your cubicle. There are crunchy, sugar-crusted churros for an afternoon (or evening) snack, every imaginable kind of tapas to go with your frosty glass of cerveza after work, and if you don’t feel like loitering in the giant shopping mall that is Hudson Yards, do what I do and grab some olive oil, a few ribbons of Iberico ham and a wheel of loose, golden tortilla español or two, and devour them later on, in the comfort of your own home.
Jean-Georges Vongerichten has made a career of taking tired old formulas (French cooking, Asian fusion, farm to table) and standing them artfully on their head, and at this impressive new destination restaurant down on Pier 17 at South Street Seaport, he does the same thing for that most finicky and exacting of restaurant genres — seafood. You can obtain a fish or crustacean dish for every occasion at this excellent waterside establishment, ranging from a first-rate lunchtime crispy fish taco, to bowls of lobster-rich Cantonese-style “Longevity Noodles” for dinner, along with an entire perfectly cooked black sea bass baked to order in a fish-shaped pastry crust. Add in the million-dollar seafood lover’s view, which stretches from the iconic bridges to the north (Brooklyn, Manhattan, etc.), down south to the ferries and sailboats cutting to and fro in the open harbor, and you have, at long last, the kind of new, slightly updated seafood joint this old port town deserves.
All of the tropes of the familiar bromakase experience are on display at this discreet Flatiron kaiseki joint, including the hidden entrance (behind a chipped blue door at the back of a bar called Hall), the 14-seat bar made from polished cedar wood inside, and even the bros themselves (“I love you bro,” I actually heard one of them say). But what sets Chef Hiroki Odo’s operation apart from your run-of-the mill $300 faux-Tokyo extravaganza is the depth and variety of the cooking, which runs the gamut of the Japanese dining experience, from delicate morsels of washugyu beef and carefully sizzled slices of anago tempura, to first-class bites of pearly shrimp and tuna-belly sushi, to stout beautifully constructed bowls of house-made soba, the latter served, on my last visit, in a bowl of clam broth with a fried egg broken on top.
5. Rezdôra 27 E. 20th St., nr. Broadway; 646-692-9090
Photo: Scott Heins
The bounty of that great, Italian bread-basket region, Emilia-Romagna, is the theme of Stefano Secchi’s crowded, much-hyped little Flatiron pasta destination, and although you’ll probably want to join the rest of the clamorous patrons in plunking down $90 for the already fabled ravioli-and-noodle tasting menu, many non-pasta dishes are also worth the price of admission. I’m thinking of servings of wobbly veal cheeks poured with onion sauce, portions of rabbit cooked in various enticing ways (braised and in sausage form with some veal sweetbreads thrown in), and a flowery-sounding steak dish (“Cow Grazing in Emilia Romagna”) that was so good that after my red-meat-loving daughter refused to part with the plate on one visit, we happily ordered it a second time.
6. Kawi 20 Hudson Yards, fifth fl. (entrance at Tenth Ave. and 33rd St.); 646-517-2699
Photo: Melissa Hom
Hardcore East Village Momofuku veterans will probably experience a few twinges of sadness and regret as they make their way up through the network of escalators and deserted boutiques to this new Changian outpost in the Hudson Yards, but Eunjo Park’s punchy, satisfying, homestyle Korean cooking makes the grim, soul-crushing journey more than worthwhile. The dishes we can’t get out of our head arethe rib-sticking stews (oxtail, the excellent stinky soybean with pork belly) and the large format steak and chicken dinners (particularly the chicken, served over a mass of sweet glass noodles), but save room for the desserts like the Korean version of shaved ice kakigori, called bingsoo, which was poured with blueberry syrup the last time we enjoyed it, and dappled with croutons made with sweet cubes of pancake batter.
7. Crown Shy 70 Pine Street, nr. Pearl St.; 212-517-1932
Photo: Scott Heins
Wall Street has been a graveyard for culinary dreams for decades now, but thanks to James Kent and Jeff Katz, both veterans of top-flight restaurants elsewhere in town, the dark days are now officially over, at least for now. The menu of this deceptively sophisticated establishment in the lobby of a famous Art Deco tower down on Pine Street is stocked with elegant, post gourmet treats like fresh-baked bread (the “pull-apart” roll), inspired vegetable creations (romaine salad, the charred carrots), and elevated barnyard dishes (we recommend the chicken and the short ribs). But pay special attention to the elevated, comfort food desserts, like scoops of house-churned ice cream (hazelnut praline, roasted banana, satsuma orange topped with marshmallow) and a pleasingly dense sticky-toffee pudding for two served with great spoonfuls of chantilly cream.
8. Nami Nori 33 Carmine St., nr. Bleecker St.; 646-998-4588
Photo: Melissa Hom
There have been many attempts, over the years, to find a way out of the pricey, stifling, increasingly elitist sushi omakase formula, and at this stylishly pleasing, refreshingly economical West Village homage to the pleasures of the maki hand roll, Lisa Limb and her chef partners, Jihan Lee and Taka Sakeada, may have finally done it. Unlike a lot of effete tasting rooms around town, Masa veterans Lee and Sakeado charge 28 bucks for their omakase “chef’s set,” which might include a seasonal vegan option made with gently sautéed nickels of squash flavored with scallion and ginger, or warm mounds of spicy crab loaded into a square of nori seaweed speckled with toasted rice. There’s also the occasional professional helping of non-hand-roll sashimi, for old times’ sake, and if you wish to go hog wild in the bromakase tradition there are five different grades of market-price uni to choose from, and you can top your maki roll with caviar, or drifts of pricey winter truffles.
9. Luthun 432 E. 13th St., nr. Ave. A; 646-454-9484
Photo: Liz Clayman
This smallish (600 square feet), slightly out of the way East Village tasting room hasn’t received much attention among members of the nattering classes, but don’t let that fool you. The chefs, Nahid Ahmed and Arjuna Bull, are veterans of the city’s high-end pop-up scene, not to mention some of the most storied kitchens in the world (Lespinasse, The Fat Duck, El Bulli) and bite for bite, their modestly priced, ($68) Indian-accented “global” menus (one for carnivores, one for vegetarians) offer a whole variety of polished and unexpected treats. To experience the full rainbow of flavors and technique, we recommend forking over an extra 52 bucks for the “chef’s pass” tasting experience which, on my visit, included frizzled slices of razor clams topped with amaranth leaves, nodules of veal touched with a lingonberry sauce leavened with gochujang, and one of the delicately crunchy octopus tentacles rolled in cornstarch and flash fried with a touch of rice flour.
10. Oxalis 791 Washington Ave., nr. Lincoln Pl., Crown Heights; 347-627-8298
Photo: Erinn Springer
This small Crown Heights establishment features another talented, highly credentialed chef twirling up unexpected treats in out of the way places, and although technically it opened at the end of last year, we’ll sneak it in here as an example of a place which keeps growing in stature as the kitchen continues to experiment and find its way. Nico Russell worked at the world’s number-one restaurant, Mirazur, among many other grand destination venues before opening a place of his own, and although there’s a certain ethereal high-minded lack of practicality to the proceedings (instead of pizza or wings, the bar menu featured pork neck and lardo-covered flat bread the last time we dropped in) the ever-changing $70 “carte blanche” tasting menu in the front of the house (if duck is on the menu, or snails, you’re in for a treat) is one of the better gourmet deals in this increasingly discerning, gourmet-focused part of town.
We’re not usually fans of great Vegas-style restaurants, in general, or great Vegas-style franchises from China, in particular. But this glittering, aircraft-size dining palace — which landed earlier this year in the old Le Cirque space in the courtyard of the Bloomberg Tower off Lexington Avenue — features a surprisingly modest, easy-to-navigate menu, and more than a few of the pan-provincial specialties on it are worth a special trip if you have the necessary funds. We’re thinking, in particular, of the Cantonese-style dim sum, which comes in a variety of festive colors and sizes, and of the Sichuan-accented signature dishes “Hutong Lobster,” or the festive “Red Lantern Soft-Shell Crab,” which is comprised of segments of fried soft shell served in a great lantern-size bowl filled with dried chili peppers.
12. Maison Yaki 626 Vanderbilt Ave., nr. Prospect Pl., Prospect Heights; 718-552-2609
Photo: Liz Clayman
Greg Baxtrom’s follow-up to his hit restaurant Olmsted turns out to be a fast-casual mash-up for the ages — part izakaya-style drinking pub, part haute-French establishment, and part Japanese yakitori joint, all presented in the guise of a posh, slightly raucous neighborhood Brooklyn bar. It’s easy to get lost in the budget-priced cocktails, which are all on tap (order the Vesper Martini for maximum dizzying effect), but we suggest you save your cash for Baxtrom’s bite-size Franco-Japanese fusion creations, like escargot spiked with plenty of shiso along with the usual garlic, delicate brisket-and-beef-tongue “sandos” squeezed between wheels of toasted brioche, and a variety of artfully rendered yakitori skewers (rib eye, lobster) dressed with a veritable rainbow of classically opulent sauces (Bernaise, Dijonaise, Bordelaise, sauce American), which taste like they’ve been airlifted from your grandmother’s favorite midtown French restaurant.
13. Red Hook Tavern 329 Van Brunt St., at Sullivan St., Red Hook; no phone
Photo: Liz Clayman
With its much-praised trophy burger, its sense of raffish, neighborly camaraderie, and its roster of hungry-man foods inventively conjured by a first-class chef, Billy Durney’s latest contribution to the burgeoning Red Hook dining scene is a throwback to the old days of the corner neighborhood tavern, and also to that time in the not-so-distant past when high-end gastro pubs were popping up all over town like barista bars. We’re not big Luger fans, but this Luger-inspired burger is worth a visit, although don’t sleep on chef Allison Plumer other hungry-man specialties, like wedges of romaine salad draped in Neuske’s bacon, crunchy ham croquettes, and a pan-roasted chicken (with mashed Yukon Golds and gravy), which is the best big-city version of this old country classic that we’ve enjoyed this year.
`;
// 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();
// ]]