वेब विकास की दुनिया विशाल है, और हर दिन उभरती नई तकनीकों की निरंतर धारा में खो जाना आसान है। इनमें से अधिकांश नई तकनीकों को जावास्क्रिप्ट या टाइपस्क्रिप्ट का उपयोग करके बनाया गया है। हालाँकि, इस लेख में, मैं आपको सीधे आपके ब्राउज़र के अंदर देशी स्विफ्ट का उपयोग करके वेब विकास से परिचित कराऊँगा, और मुझे विश्वास है कि यह आपको प्रभावित करेगा। ऐसा कैसे हो सकता है? स्विफ्ट के लिए वेब पेज पर मूल रूप से काम करने के लिए इसे पहले WebAssembly बाइट-कोड में संकलित करने की आवश्यकता होती है और फिर जावास्क्रिप्ट उस कोड को पेज पर लोड कर सकता है। संकलन की पूरी प्रक्रिया थोड़ी पेचीदा है क्योंकि हमें विशेष टूलचेन का उपयोग करने और सहायक फ़ाइलों का निर्माण करने की आवश्यकता है, यही कारण है कि सहायक सीएलआई-उपकरण उपलब्ध हैं: कार्टन और वेबर। क्या तृतीय-पक्ष टूलचैन का उपयोग करना ठीक है? समुदाय ने मूल Swift टूलचैन को पैच करके Swift को WebAssembly में संकलित करना संभव बनाने के लिए जबरदस्त काम किया है। वे हर दिन मूल टूलचेन से परिवर्तनों को स्वचालित रूप से खींचकर और परीक्षण विफल होने पर अपने कांटे को ठीक करके टूलचैन को अपडेट करते हैं। उनका लक्ष्य आधिकारिक टूलचेन का हिस्सा बनना है और उन्हें उम्मीद है कि यह निकट भविष्य में होगा। SwiftWasm कार्टन या वेबर? SwiftWasm समुदाय द्वारा बनाया गया है और इसका उपयोग Tokamak परियोजनाओं के लिए किया जा सकता है, जो एक ऐसा ढांचा है जो आपको SwiftUI का उपयोग करके वेबसाइट लिखने की क्षमता देता है। कार्टन को SwifWeb प्रोजेक्ट्स के लिए बनाया गया है। SwifWeb इस मायने में अलग है कि यह संपूर्ण HTML और CSS मानकों के साथ-साथ सभी वेब API को समाहित करता है। वेबर को यद्यपि आप कोड स्थिरता के लिए SwiftUI का उपयोग करके वेब ऐप्स लिखना पसंद कर सकते हैं, मेरा मानना है कि यह गलत तरीका है क्योंकि वेब डेवलपमेंट स्वाभाविक रूप से अलग है और इसे SwiftUI की तरह ही अप्रोच नहीं किया जा सकता है। इसलिए मैंने SwifWeb बनाया है, जो आपको HTML, CSS, और वेब APIs की सभी शक्तियों का सीधे स्विफ्ट से उपयोग करने की क्षमता देता है, इसके सुंदर सिंटैक्स को ऑटो-पूर्णता और प्रलेखन के साथ उपयोग करता है। और मैंने वेबर टूल बनाया क्योंकि कार्टन सही तरीके से SwifWeb ऐप्स को संकलित, डिबग और तैनात करने में सक्षम नहीं है क्योंकि यह इसके लिए नहीं बनाया गया था। मेरा नाम मिखाइल इसेव है, और मैं स्विफवेब का लेखक हूं। इस लेख में, मैं आपको दिखाऊंगा कि कैसे SwifWeb का उपयोग करके वेबसाइट बनाना शुरू करें। आवश्यक उपकरण तीव्र आपको स्विफ्ट स्थापित करने की आवश्यकता है, इसे प्राप्त करने का सबसे आसान तरीका: macOS पर Xcode इंस्टॉल करना है Linux या Windows (WSL2) पर से स्क्रिप्ट का उपयोग करना है Swiftlang.xyz अन्य मामलों में पर एक नज़र डालें आधिकारिक वेबसाइट पर इंस्टॉलेशन निर्देशों वेबर सीएलआई मैंने आपके ऐप्स बनाने, डिबग करने और परिनियोजित करने में आपकी मदद करने के लिए वेबर बनाया है। MacOS पर HomeBrew के साथ इंस्टॉल करना आसान है (इसे उनकी से इंस्टॉल करें) वेबसाइट brew install swifweb/tap/webber बाद में नवीनतम संस्करण में अपडेट करने के लिए बस चलाएं brew upgrade webber उबंटू या विंडोज (WSL2 में उबंटू) पर वेबर को मैन्युअल रूप से क्लोन और संकलित करें sudo apt-get install binaryen curl https://get.wasmer.io -sSfL | sh apt-get install npm cd /opt sudo git clone https://github.com/swifweb/webber cd webber sudo swift build -c release sudo ln -s /opt/webber/.build/release/Webber /usr/local/bin/webber बाद में चलने वाले अंतिम संस्करण में अपडेट करने के लिए cd /opt/webber sudo git pull sudo swift build -c release शाखा में हमेशा स्थिर कोड होता है इसलिए इससे अपडेट प्राप्त करने के लिए स्वतंत्र महसूस करें मुख्य नया प्रोजेक्ट बनाना टर्मिनल खोलें और निष्पादित करें webber new इंटरैक्टिव मेनू में या चुनें और प्रोजेक्ट का नाम डालें। pwa spa निर्देशिका को नव निर्मित प्रोजेक्ट में बदलें और निष्पादित करें। webber serve यह आदेश आपके प्रोजेक्ट को WebAssembly में संकलित करेगा, एक विशेष फ़ोल्डर के अंदर सभी आवश्यक फाइलों को पैकेज करेगा, और डिफ़ॉल्ट रूप से पोर्ट का उपयोग करके सभी इंटरफेस पर आपकी परियोजना की सेवा शुरू करेगा। .webber 8888 के लिए अतिरिक्त तर्क webber serve ऐप प्रकार प्रोग्रेसिव वेब ऐप के लिए -t pwa सिंगल वेब ऐप के लिए -t spa सर्विस वर्कर टारगेट का नाम (आमतौर पर PWA प्रोजेक्ट में नाम दिया जाता है) Service -s Service ऐप लक्ष्य का नाम (डिफ़ॉल्ट रूप से ) App -a App कंसोल में अधिक जानकारी प्रिंट करें -v वेबर सर्वर के लिए पोर्ट (डिफ़ॉल्ट है) 8888 -p 8080 वास्तविक एसएसएल की तरह परीक्षण करने के लिए का उपयोग करें (अनुमत स्व-हस्ताक्षरित एसएसएल सेटिंग के साथ) -p 443 गंतव्य ब्राउज़र नाम स्वचालित रूप से लॉन्च करने के लिए या --browser safari --browser chrome सेवा-कर्मचारियों को डीबग करने के लिए अनुमत स्व-हस्ताक्षरित एसएसएल सेटिंग के साथ ब्राउज़र का अतिरिक्त उदाहरण --browser-self-signed गुप्त मोड में ब्राउज़र का अतिरिक्त उदाहरण --browser-incognito आवेदन ऐप में शुरू होता है Sources/App/App.swift import Web @main class App: WebApp { @AppBuilder override var app: Configuration { Lifecycle.didFinishLaunching { app in app.registerServiceWorker("service") } Routes { Page { IndexPage() } Page("login") { LoginPage() } Page("article/:id") { ArticlePage() } Page("**") { NotFoundPage() } } MainStyle() } } जीवन चक्र यह iOS की तरह काम करता है: जब ऐप अभी शुरू हुआ didFinishLaunching जब ऐप मरने वाला है willTerminate जब विंडो निष्क्रिय होने जा रही है willResignActive जब विंडो सक्रिय हो didBecomeActive जब विंडो पृष्ठभूमि में जा रही हो didEnterBackground जब खिड़की अग्रभूमि में जा रही है willEnterForeground यहां सबसे उपयोगी तरीका है क्योंकि यह ऐप को कॉन्फ़िगर करने के लिए एक शानदार जगह है। आप देखते हैं कि यह वास्तव में एक iOS ऐप जैसा लगता है! 😀 didFinishLaunching यहाँ में उपयोगी सुविधा विधियाँ हैं: app कॉल PWA सेवा कार्यकर्ता पंजीकृत करने के लिए registerServiceWorker(“serviceName“) सापेक्ष या बाहरी स्क्रिप्ट जोड़ने के लिए कॉल करें addScript(“path/to/script.js“) सापेक्ष या बाहरी शैली जोड़ने के लिए कॉल करें addStylesheet(“path/to/style.css“) रिश्तेदार या बाहरी फ़ॉन्ट जोड़ने के लिए कॉल करें, वैकल्पिक रूप से सेट प्रकार addFont(“path/to/font.woff”, type:) आइकन जोड़ने के लिए कॉल करें, वैकल्पिक रूप से प्रकार और रंग सेट करें addIcon(“path/to/icon“, type:color:) इसके अलावा, यह अतिरिक्त पुस्तकालयों जैसे , , , आदि को कॉन्फ़िगर करने का स्थान है। Autolayout Bootstrap Materialize मार्गों वर्तमान यूआरएल के आधार पर उपयुक्त पेज दिखाने के लिए रूटिंग की जरूरत है। रूटिंग का उपयोग कैसे करें यह समझने के लिए आपको यह समझना होगा कि URL क्या है https://website.com/hello/world - यहाँ है /hello/world रास्ता जैसा कि आपने देखा है, शुरुआत में ऐप क्लास में हमें सभी शीर्ष-स्तरीय मार्गों की घोषणा करनी चाहिए। शीर्ष-स्तर का अर्थ है कि इन मार्गों में घोषित पृष्ठ विंडो में संपूर्ण स्थान ले लेंगे। ठीक है, इसलिए उदाहरण के लिए रूट रूट को तीन तरह से सेट किया जा सकता है Page("/") { IndexPage() } Page("") { IndexPage() } Page { IndexPage() } मुझे लगता है कि आखिरी सबसे सुंदर 🙂 है लॉगिन या पंजीकरण मार्ग इस तरह सेट किए जा सकते हैं Page("login") { LoginPage() } Page("registration") { RegistrationPage() } पैरामीटर से संबंधित मार्ग Page("article/:id") { ArticlePage() } उपरोक्त उदाहरण में मार्ग का गतिशील भाग है। हम इस पहचानकर्ता को इससे जुड़े लेख को प्रदर्शित करने के लिए वर्ग में पुनः प्राप्त कर सकते हैं। :id ArticlePage class ArticlePage: PageController { override func didLoad(with req: PageRequest) { if let articleId = req.parameters.get("id") { // Retrieve article here } } } आपके पथ में एक से अधिक पैरामीटर हो सकते हैं। सभी को इसी तरह से निकाल लें। प्रश्नों पथ में अगली दिलचस्प चीज़ है, जिसका उपयोग करना भी बहुत आसान है। उदाहरण के लिए, आइए मार्ग पर विचार करें, जिसमें खोज और क्वेरी पैरामीटर होने की उम्मीद है। क्वेरी /खोज text age https://website.com/search**?text=Alex&age=19** - अंतिम भाग है क्वेरी बस खोज मार्ग घोषित करें Page("search") { SearchPage() } और इस तरह वर्ग में क्वेरी डेटा पुनर्प्राप्त करें SearchPage class SearchPage: PageController { struct Query: Decodable { let text: String? let age: Int? } override func didLoad(with req: PageRequest) { do { let query = try req.query.decode(Query.self) // use optional query.text and query.age // to query search results } catch { print("Can't decode query: \(error)") } } } कुछ भी आप उपयोग मार्ग घोषित करने के लिए भी कर सकते हैं जो इस तरह के विशिष्ट पथ भाग में कुछ भी स्वीकार करते हैं * Page("foo", "*", "bar") { SearchPage() } उपरोक्त मार्ग फू और बार के बीच कुछ भी स्वीकार करेगा, जैसे /foo/aaa/bar, /foo/bbb/bar, आदि। सबको पकड़ो साइन के साथ आप एक विशेष कैच-ऑल रूट सेट कर सकते हैं जो किसी भी ऐसी चीज़ को हैंडल करेगा जो किसी विशिष्ट पथ पर अन्य रूटों से मेल नहीं खाता है। ** इसका उपयोग या तो वैश्विक 404 मार्ग बनाने के लिए करें Page("**") { NotFoundPage() } या विशिष्ट पथ के लिए उदाहरण के लिए जब उपयोगकर्ता नहीं मिला Page("user", "**") { UserNotFoundPage() } आइए ऊपर घोषित मार्गों के साथ स्थितियों को स्पष्ट करें /उपयोगकर्ता/1 - यदि /उपयोगकर्ता/:आईडी के लिए कोई मार्ग है तो यह लौटाएगा। नहीं तो गिर जाएगा... UserPage UserNotFoundPage / उपयोगकर्ता / 1 / हैलो - अगर / उपयोगकर्ता /: आईडी / हैलो के लिए मार्ग हैं तो यह में गिर जाएगा UserNotFoundPage /कुछ - अगर /कुछ के लिए कोई मार्ग नहीं है तो यह में गिर जाएगा NotFoundPage नेस्टेड रूटिंग हो सकता है कि हम अगले मार्ग के लिए पृष्ठ पर संपूर्ण सामग्री को बदलना न चाहें, लेकिन केवल कुछ ब्लॉकों के लिए। यहीं पर काम आता है! FragmentRouter आइए मान लें कि हमारे पास पृष्ठ पर टैब हैं। प्रत्येक टैब एक उपमार्ग है, और हम उपयोग करके उपमार्ग में परिवर्तनों पर प्रतिक्रिया करना चाहते हैं। /उपयोगकर्ता FragmentRouter का क्लास में शीर्ष-स्तरीय मार्ग घोषित करें ऐप Page("user") { UserPage() } और क्लास में घोषित करें UserPage FragmentRouter class UserPage: PageController { @DOM override var body: DOM.Content { // NavBar is from Materialize library :) Navbar() .item("Profile") { self.changePath(to: "/user/profile") } .item("Friends") { self.changePath(to: "/user/friends") } FragmentRouter(self) .routes { Page("profile") { UserProfilePage() } Page("friends") { UserFriendsPage() } } } } ऊपर दिए गए उदाहरण में, और सबरूट्स को संभालता है और इसे के तहत प्रस्तुत करता है, इसलिए पृष्ठ कभी भी पूरी सामग्री को फिर से लोड नहीं करता है बल्कि केवल विशिष्ट अंशों को ही लोड करता है। FragmentRouter /user/profile /user/friends नेवबार एक ही या अलग-अलग उपमार्गों के साथ एक से अधिक खंड भी घोषित किए जा सकते हैं और वे सभी जादू की तरह एक साथ काम करेंगे! बीटीडब्ल्यू एक है और आप इसे कॉल करके कॉन्फ़िगर कर सकते हैं फ्रैगमेंट राउटर डिव FragmentRouter(self) .configure { div in // do anything you want with the div } स्टाइलशीट आप पारंपरिक CSS फाइलों का उपयोग कर सकते हैं, लेकिन आपके पास स्विफ्ट में लिखी गई स्टाइलशीट का उपयोग करने की नई, जादुई क्षमता भी है! मूल बातें स्विफ्ट का उपयोग करके सीएसएस नियम घोषित करने के लिए हमारे पास वस्तु है। नियम इसे इसके तरीकों को कॉल करके घोषणात्मक रूप से बनाया जा सकता है Rule(...selector...) .alignContent(.baseline) .color(.red) // or rgba/hex color .margin(v: 0, h: .auto) या @resultBuilder का उपयोग करते हुए SwiftUI जैसा तरीका Rule(...selector...) { AlignContent(.baseline) Color(.red) Margin(v: 0, h: .auto) } दोनों तरीके समान हैं, हालांकि, मैं टाइप करने के ठीक बाद स्वत: पूर्णता के कारण पहले वाले को पसंद करता हूं 😀 . एमडीएन पर वर्णित सभी सीएसएस विधियां उपलब्ध हैं। इससे भी अधिक यह ब्राउज़र उपसर्गों को स्वचालित रूप से संभालता है! हालाँकि, आप कुछ विशिष्ट मामलों में कस्टम प्रॉपर्टी को इस तरह सेट कर सकते हैं Rule(...selector...) .custom("customKey", "customValue") चयनकर्ता यह निर्धारित करने के लिए कि कौन से तत्व नियम प्रभावित होने चाहिए, हमें एक चयनकर्ता सेट करना होगा। मैं चयनकर्ता को डेटाबेस में क्वेरी के रूप में देखता हूं, लेकिन उस चयनकर्ता क्वेरी के कुछ हिस्सों को मैं पॉइंटर्स कहता हूं। पॉइंटर बनाने का सबसे आसान तरीका यह है कि कच्चे स्ट्रिंग का उपयोग करके इसे इनिशियलाइज़ किया जाए Pointer("a") लेकिन इस तरह के आवश्यक HTML टैग पर कॉल करके इसे बनाने का सही तेज़ तरीका है .pointer H1.pointer // h1 A.pointer // a Pointer.any // * Class("myClass").pointer // .myClass Id("myId").pointer // #myId यह मूल पॉइंटर्स के बारे में है, लेकिन उनके पास संशोधक भी हैं जैसे इत्यादि। :hover :first :first-child H1.pointer.first // h1:first H1.pointer.firstChild // h1:first-child H1.pointer.hover // h1:hover आप किसी मौजूदा संशोधक की घोषणा कर सकते हैं, वे सभी उपलब्ध हैं। अगर कुछ छूट रहा है तो उसे जोड़ने के लिए एक्सटेंशन बनाने में संकोच न करें! और इसे सभी के लिए जोड़ने के लिए जीथब पर पुल अनुरोध भेजना न भूलें। आप पॉइंटर्स को भी जोड़ सकते हैं H1.class(.myClass) // h1.myClass H1.id(.myId) // h1#myId H1.id(.myId).disabled // h1#myId:disabled Div.pointer.inside(P.pointer) // div p Div.pointer.parent(P.pointer) // div > p Div.pointer.immediatedlyAfter(P.pointer) // Div + p P.pointer.precededBy(Ul.pointer) // p ~ ul में चयनकर्ता का उपयोग कैसे करें नियम Rule(Pointer("a")) // or Rule(A.pointer) में एक से अधिक चयनकर्ता का उपयोग कैसे करें नियम Rule(A.pointer, H1.id(.myId), Div.pointer.parent(P.pointer)) यह निम्नलिखित सीएसएस कोड का उत्पादन करता है a, h1#myId, div > p { } जेट आइए अपने ऐप के लिए डार्क और लाइट स्टाइल घोषित करें, और बाद में, हम उनके बीच आसानी से स्विच कर पाएंगे। import Web @main class App: WebApp { enum Theme { case light, dark } @State var theme: Theme = .light @AppBuilder override var app: Configuration { // ... Lifecycle, Routes ... LightStyle().disabled($theme.map { $0 != .happy }) DarkStyle().disabled($theme.map { $0 != .sad }) } } और अलग-अलग फाइलों में या उदाहरण के लिए App.swift में घोषित किया जा सकता है LightStyle DarkStyle को class LightStyle: Stylesheet { @Rules override var rules: Rules.Content { Rule(Body.pointer).backgroundColor(.white) Rule(H1.pointer).color(.black) } } class DarkStyle: Stylesheet { @Rules override var rules: Rules.Content { Rule(Body.pointer).backgroundColor(.black) Rule(H1.pointer).color(.white) } } और फिर कहीं किसी पेज के UI में बस कॉल करें App.current.theme = .light // to switch to light theme // or App.current.theme = .dark // to switch to dark theme और यह संबंधित स्टाइलशीट को सक्रिय या निष्क्रिय कर देगा! क्या यह अच्छा नहीं है? 😎 लेकिन आप कह सकते हैं कि CSS के बजाय स्विफ्ट में शैलियों का वर्णन करना कठिन है, तो क्या बात है? मुख्य बिंदु प्रतिक्रियाशीलता है! हम CSS गुणों के साथ @State का उपयोग कर सकते हैं और फ्लाई पर मूल्यों को बदल सकते हैं! बस एक नज़र डालें, हम कुछ प्रतिक्रियाशील संपत्ति के साथ एक वर्ग बना सकते हैं और इसे रनटाइम में कभी भी बदल सकते हैं, इसलिए स्क्रीन पर कोई भी तत्व जो उस वर्ग का उपयोग करता है, अपडेट हो जाएगा! यह कई तत्वों के लिए कक्षाओं को स्विच करने से कहीं अधिक प्रभावी है! import Web @main class App: WebApp { @State var reactiveColor = Color.cyan @AppBuilder override var app: Configuration { // ... Lifecycle, Routes ... MainStyle() } } extension Class { static var somethingCool: Class { "somethingCool" } } class MainStyle: Stylesheet { @Rules override var rules: Rules.Content { // for all elements with `somethingCool` class Rule(Class.hello.pointer) .color(App.current.$reactiveColor) // for H1 and H2 elements with `somethingCool` class Rule(H1.class(.hello), H2.class(.hello)) .color(App.current.$reactiveColor) } } बाद में कोड में कहीं से भी कॉल करें App.current.reactiveColor = .yellow // or any color you want और यह स्टाइलशीट और इसका उपयोग करने वाले सभी तत्वों में रंग को अपडेट करेगा 😜 साथ ही, कच्चे सीएसएस को स्टाइलशीट में जोड़ना संभव है class MainStyle: Stylesheet { @Rules override var rules: Rules.Content { // for all elements with `somethingCool` class Rule(Class.hello.pointer) .color(App.current.$reactiveColor) // for H1 and H2 elements with `somethingCool` class Rule(H1.class(.hello), H2.class(.hello)) .color(App.current.$reactiveColor) """ /* Raw CSS goes here */ body { margin: 0; padding: 0; } """ } } आप कच्चे सीएसएस स्ट्रिंग्स को जितनी बार जरूरत हो मिक्स-इन कर सकते हैं पृष्ठों राउटर प्रत्येक रूट पर पेज रेंडर कर रहा है। पृष्ठ से प्राप्त कोई भी वर्ग है। पृष्ठ नियंत्रक के पास जीवनचक्र विधियाँ हैं जैसे , UI विधियाँ और , और HTML तत्वों के लिए संपत्ति आवरण चर। पेजकंट्रोलर willLoad didLoad willUnload didUnload buildUI body तकनीकी रूप से सिर्फ एक डिव है और आप इसके किसी भी गुण को विधि में सेट कर सकते हैं। पेजकंट्रोलर buildUI class IndexPage: PageController { // MARK: - Lifecycle override func willLoad(with req: PageRequest) { super.willLoad(with: req) } override func didLoad(with req: PageRequest) { super.didLoad(with: req) // set page title and metaDescription self.title = "My Index Page" self.metaDescription = "..." // also parse query and hash here } override func willUnload() { super.willUnload() } override func didUnload() { super.didUnload() } // MARK: - UI override func buildUI() { super.buildUI() // access any properties of the page's div here // eg self.backgroundcolor(.lightGrey) // optionally call body method here to add child HTML elements body { P("Hello world") } // or alternatively self.appendChild(P("Hello world")) } // the best place to declare any child HTML elements @DOM override var body: DOM.Content { H1("Hello world") P("Text under title") Button("Click me") { self.alert("Click!") print("button clicked") } } } यदि आपका पृष्ठ छोटा है तो आप इसे इस छोटे से तरीके से भी घोषित कर सकते हैं PageController { page in H1("Hello world") P("Text under title") Button("Click me") { page.alert("Click!") print("button clicked") } } .backgroundcolor(.lightGrey) .onWillLoad { page in } .onDidLoad { page in } .onWillUnload { page in } .onDidUnload { page in } क्या यह सुंदर और लैकोनिक नहीं है? 🥲 बोनस सुविधा के तरीके - डायरेक्ट जेएस विधि alert(message: String) alert - यूआरएल पथ स्विच करना changePath(to: String) एचटीएमएल तत्व अंत में, मैं आपको बताऊंगा कि कैसे (!) HTML तत्वों का निर्माण और उपयोग करें! सभी HTML तत्व अपनी विशेषताओं के साथ स्विफ्ट में उपलब्ध हैं, पूरी सूची उदाहरण के लिए पर है। MDN HTML तत्वों की एक उदाहरण छोटी सूची: स्विफवेब कोड HTML कोड Div() <div></div> H1(“text“) <h1>text</h1> A(“Click me“).href(““).target(.blank) <a href=”” target=”_blank”>Click me</a> Button(“Click“).onClick { print(“click“) } <button onclick=”…”>Click</button> InputText($text).placeholder("Title") <input type=”text” placeholder=”title”> InputCheckbox($checked) <input type=”checkbox”> जैसा कि आप देख सकते हैं, स्विफ्ट में किसी भी HTML टैग को एक्सेस करना बहुत आसान है क्योंकि इनपुट को छोड़कर, वे सभी एक ही नाम के तहत दर्शाए जाते हैं। ऐसा इसलिए है क्योंकि विभिन्न इनपुट प्रकारों के अलग-अलग तरीके हैं, और मैं उन्हें मिलाना नहीं चाहता था। साधारण Div Div() हम इसकी सभी विशेषताओं और शैली गुणों को इस तरह एक्सेस कर सकते हैं Div().class(.myDivs) // <div class="myDivs"> .id(.myDiv) // <div id="myDiv"> .backgroundColor(.green) // <div style="background-color: green;"> .onClick { // adds `onClick` listener directly to the DOM element print("Clicked on div") } .attribute("key", "value") // <div key="value"> .attribute("boolKey", true, .trueFalse) // <div boolKey="true"> .attribute("boolKey", true, .yesNo) // <div boolKey="yes"> .attribute("checked", true, .keyAsValue) // <div checked="checked"> .attribute("muted", true, .keyWithoutValue) // <div muted> .custom("border", "2px solid red") // <div style="border: 2px solid red;"> उपवर्गीकरण उपवर्ग HTML तत्व इसके लिए शैली को पूर्वनिर्धारित करने के लिए, या बहुत सारे पूर्वनिर्धारित बाल तत्वों और बाहर उपलब्ध कुछ सुविधाजनक तरीकों के साथ एक समग्र तत्व बनाने के लिए, या जीवनचक्र की घटनाओं जैसे और प्राप्त करने के लिए। didAddToDOM didRemoveFromDOM चलिए एक एलिमेंट बनाते हैं जो सिर्फ एक है लेकिन पूर्वनिर्धारित क्लास के साथ Divider Div .divider public class Divider: Div { // it is very important to override the name // because otherwise it will be <divider> in HTML open class override var name: String { "\(Div.self)".lowercased() } required public init() { super.init() } // this method executes immediately after any init method public override func postInit() { super.postInit() // here we are adding `divider` class self.class(.divider) } } उपवर्गीकरण करते समय सुपर विधियों को कॉल करना बहुत महत्वपूर्ण है। इसके बिना आप अनपेक्षित व्यवहार का अनुभव कर सकते हैं। डीओएम में शामिल हो रहा है तत्व को तुरंत या बाद में या के DOM में जोड़ा जा सकता है। पेजकंट्रोलर HTML तत्व बिल्कुल अभी Div { H1("Title") P("Subtitle") Div { Ul { Li("One") Li("Two") } } } या बाद में उपयोग करना lazy var lazy var myDiv1 = Div() lazy var myDiv2 = Div() Div { myDiv1 myDiv2 } तो आप एक पहले से घोषित कर सकते हैं और इसे बाद में किसी भी समय DOM में जोड़ सकते हैं! HTML तत्व को डोम से निकाला जा रहा है lazy var myDiv = Div() Div { myDiv } // somewhere later myDiv.remove() मूल तत्व तक पहुँचें किसी भी HTML तत्व में एक वैकल्पिक पर्यवेक्षण गुण होता है जो DOM में जोड़े जाने पर उसके माता-पिता तक पहुँच प्रदान करता है Div().superview?.backgroundColor(.red) अगर / और शर्तें हमें अक्सर तत्वों को केवल कुछ स्थितियों में दिखाने की आवश्यकता होती है, तो चलिए उसके लिए उपयोग करते हैं if/else lazy var myDiv1 = Div() lazy var myDiv2 = Div() lazy var myDiv3 = Div() var myDiv4: Div? var showDiv2 = true Div { myDiv1 if showDiv2 { myDiv2 } else { myDiv3 } if let myDiv4 = myDiv4 { myDiv4 } else { P("Div 4 was nil") } } लेकिन यह रिएक्टिव नहीं है। यदि आप पर सेट करने का प्रयास करते हैं तो कुछ नहीं होता है। showDiv2 false प्रतिक्रियाशील उदाहरण lazy var myDiv1 = Div() lazy var myDiv2 = Div() lazy var myDiv3 = Div() @State var showDiv2 = true Div { myDiv1 myDiv2.hidden($showDiv2.map { !$0 }) // shows myDiv2 if showDiv2 == true myDiv3.hidden($showDiv2.map { $0 }) // shows myDiv3 if showDiv2 == false } उपयोग क्यों करना चाहिए हमें $showDiv2.map {…} ? क्रम में: क्योंकि यह SwiftUI नहीं है। बिलकुल। । नीचे @State के बारे में और पढ़ें कच्चा एचटीएमएल आपको पृष्ठ या HTML तत्व में अपरिष्कृत HTML जोड़ने की आवश्यकता हो सकती है और यह आसानी से संभव है Div { """ <a href="https://google.com">Go to Google</a> """ } प्रत्येक के लिए स्थैतिक उदाहरण let names = ["Bob", "John", "Annie"] Div { ForEach(names) { name in Div(name) } // or ForEach(names) { index, name in Div("\(index). \(name)") } // or with range ForEach(1...20) { index in Div() } // and even like this 20.times { Div().class(.shootingStar) } } गतिशील उदाहरण @State var names = ["Bob", "John", "Annie"] Div { ForEach($names) { name in Div(name) } // or with index ForEach($names) { index, name in Div("\(index). \(name)") } } Button("Change 1").onClick { // this will append new Div with name automatically self.names.append("George") } Button("Change 2").onClick { // this will replace and update Divs with names automatically self.names = ["Bob", "Peppa", "George"] } सीएसएस उपरोक्त उदाहरणों के समान, लेकिन भी उपलब्ध है BuilderFunction Stylesheet { ForEach(1...20) { index in CSSRule(Div.pointer.nthChild("\(index)")) // set rule properties depending on index } 20.times { index in CSSRule(Div.pointer.nthChild("\(index)")) // set rule properties depending on index } } आप लूप में उपयोग केवल एक बार कुछ मान की गणना करने के लिए कर सकते हैं, जैसे निम्न उदाहरण में मान ForEach BuilderFunction delay ForEach(1...20) { index in BuilderFunction(9999.asRandomMax()) { delay in CSSRule(Pointer(".shooting_star").nthChild("\(index)")) .custom("top", "calc(50% - (\(400.asRandomMax() - 200)px))") .custom("left", "calc(50% - (\(300.asRandomMax() + 300)px))") .animationDelay(delay.ms) CSSRule(Pointer(".shooting_star").nthChild("\(index)").before) .animationDelay(delay.ms) CSSRule(Pointer(".shooting_star").nthChild("\(index)").after) .animationDelay(delay.ms) } } यह तर्क के रूप में कार्य भी कर सकता है BuilderFunction(calculate) { calculatedValue in // CSS rule or DOM element } func calculate() -> Int { return 1 + 1 } एचटीएमएल तत्वों के लिए भी उपलब्ध है :) बिल्डरफंक्शन @State के साथ प्रतिक्रियाशीलता घोषणात्मक के लिए आजकल सबसे वांछनीय चीज है। प्रोग्रामिंग @State जैसा कि मैंने आपको ऊपर बताया था: यह SwiftUI नहीं है, इसलिए ऐसी कोई ग्लोबल स्टेट मशीन नहीं है जो सब कुछ ट्रैक और रिड्रॉ करती हो। और HTML तत्व अस्थायी संरचनाएं नहीं बल्कि कक्षाएं हैं, इसलिए वे वास्तविक वस्तुएं हैं और आपकी उन तक सीधी पहुंच है। यह बहुत बेहतर और लचीला है, आपके पास सारा नियंत्रण है। यह हुड के नीचे क्या है? यह एक संपत्ति आवरण है जो सभी ग्राहकों को इसके परिवर्तनों के बारे में सूचित करता है। परिवर्तनों की सदस्यता कैसे लें? enum Countries { case usa, australia, mexico } @State var selectedCounty: Countries = .usa $selectedCounty.listen { print("country changed") } $selectedCounty.listen { newValue in print("country changed to \(newValue)") } $selectedCounty.listen { oldValue, newValue in print("country changed from \(oldValue) to \(newValue)") } HTML तत्व परिवर्तनों पर कैसे प्रतिक्रिया कर सकते हैं? सरल पाठ उदाहरण @State var text = "Hello world!" H1($text) // whenever text changes it updates inner-text in H1 InputText($text) // while user is typing text it updates $text which updates H1 सरल संख्या उदाहरण @State var height = 20.px Div().height($height) // whenever height var changes it updates height of the Div सरल बूलियन उदाहरण @State var hidden = false Div().hidden($hidden) // whenever hidden changes it updates visibility of the Div मानचित्रण उदाहरण @State var isItCold = true H1($isItCold.map { $0 ? "It is cold 🥶" : "It is not cold 😌" }) दो राज्यों की मैपिंग @State var one = true @State var two = true Div().display($one.and($two).map { one, two in // returns .block if both one and two are true one && two ? .block : .none }) दो से अधिक राज्यों का मानचित्रण @State var one = true @State var two = true @State var three = 15 Div().display($one.and($two).map { one, two in // returns true if both one and two are true one && two }.and($three).map { oneTwo, three in // here oneTwo is a result of the previous mapping // returns .block if oneTwo is true and three is 15 oneTwo && three == 15 ? .block : .none }) सभी HTML और CSS गुण मानों को संभाल सकते हैं @State एक्सटेंशन HTML तत्वों का विस्तार करें आप Div जैसे ठोस तत्वों में कुछ सुविधाजनक तरीके जोड़ सकते हैं extension Div { func makeItBeautiful() {} } या तत्वों के समूह यदि आप उनके मूल जानते हैं। class कुछ अभिभावक वर्ग हैं। - उन तत्वों के लिए है जिन्हें स्ट्रिंग के साथ प्रारंभ किया जा सकता है, जैसे , , आदि। BaseActiveStringElement a h1 - उन सभी तत्वों के लिए है जिनके अंदर सामग्री हो सकती है, जैसे , , आदि। BaseContentElement div ul - सभी तत्वों के लिए है BaseElement तो सभी तत्वों के लिए एक्सटेंशन इस तरह लिखा जा सकता है extension BaseElement { func doSomething() {} } रंगों की घोषणा करें वर्ग रंगों के लिए ज़िम्मेदार है। इसमें HTML-रंगों को पूर्वनिर्धारित किया गया है, लेकिन आप अपने रंग ले सकते हैं रंग extension Color { var myColor1: Color { .hex(0xf1f1f1) } // which is 0xF1F1F1 var myColor2: Color { .hsl(60, 60, 60) } // which is hsl(60, 60, 60) var myColor3: Color { .hsla(60, 60, 60, 0.8) } // which is hsla(60, 60, 60, 0.8) var myColor4: Color { .rgb(60, 60, 60) } // which is rgb(60, 60, 60) var myColor5: Color { .rgba(60, 60, 60, 0.8) } // which is rgba(60, 60, 60, 0.8) } फिर इसे की तरह इस्तेमाल करें H1(“Text“).color(.myColor1) कक्षाओं की घोषणा करें extension Class { var my: Class { "my" } } फिर इसे की तरह उपयोग करें Div().class(.my) आईडी घोषित करें extension Id { var myId: Id { "my" } } फिर इसे की तरह उपयोग करें Div().id(.my) वेब एपीआई खिड़की ऑब्जेक्ट पूरी तरह से लपेटा हुआ है और चर के माध्यम से पहुँचा जा सकता है। window App.current.window पर पूरा संदर्भ उपलब्ध है। एमडीएन आइए नीचे संक्षिप्त अवलोकन करते हैं अग्रभूमि ध्वज आप इसे में में या सीधे इस तरह से सुन सकते हैं Lifecycle App.swift App.current.window.$isInForeground.listen { isInForeground in // foreground flag changed } या बस इसे कभी भी कहीं भी पढ़ें if App.current.window.isInForeground { // do somethign } या उस पर HTML तत्व के साथ प्रतिक्रिया करें Div().backgroundColor(App.current.window.$isInForeground.map { $0 ? .grey : .white }) सक्रिय ध्वज यह अग्रभूमि ध्वज के समान है, लेकिन के माध्यम से पहुँचा जा सकता है App.current.window.isActive यह पता लगाता है कि क्या उपयोगकर्ता अभी भी विंडो के अंदर इंटरैक्ट कर रहा है। ऑनलाइन स्थिति अग्रभूमि ध्वज के समान, लेकिन के माध्यम से पहुँचा जा सकता है App.current.window.isOnline यह पता लगाता है कि उपयोगकर्ता के पास अभी भी इंटरनेट तक पहुंच है या नहीं। डार्कमोड स्थिति अग्रभूमि ध्वज के समान, लेकिन के माध्यम से पहुँचा जा सकता है App.current.window.isDark यह पता लगाता है कि उपयोगकर्ता का ब्राउज़र या ऑपरेटिंग सिस्टम डार्क मोड में है या नहीं। आंतरिक आकार स्क्रॉलबार सहित विंडो के सामग्री क्षेत्र (व्यूपोर्ट) का आकार अंदर और मूल्यों के भीतर वस्तु है। App.current.window.innerSize width height आकार चर के रूप में भी उपलब्ध है। @State बाहरी आकार टूलबार/स्क्रॉलबार सहित ब्राउज़र विंडो का आकार। अंदर और मूल्यों के भीतर वस्तु है। App.current.window.outerSize width height आकार चर के रूप में भी उपलब्ध है। @State स्क्रीन स्क्रीन के गुणों का निरीक्षण करने के लिए विशेष वस्तु जिस पर वर्तमान विंडो प्रस्तुत की जा रही है। के माध्यम से उपलब्ध है। App.current.window.screen सबसे दिलचस्प गुण आमतौर पर है। pixelRatio इतिहास उपयोगकर्ता द्वारा देखे गए URL शामिल हैं (ब्राउज़र विंडो के भीतर)। या केवल माध्यम से उपलब्ध है। App.current.window.history History.shared यह चर के रूप में सुलभ है, इसलिए यदि आवश्यक हो तो आप इसके परिवर्तनों को सुन सकते हैं। @State App.current.window.$history.listen { history in // read history properties } यह साधारण चर के रूप में भी सुलभ है History.shared.length // size of the history stack History.shared.back() // to go back in history stack History.shared.forward() // to go forward in history stack History.shared.go(offset:) // going to specific index in history stack अधिक विवरण पर उपलब्ध हैं। एमडीएन जगह वर्तमान URL के बारे में जानकारी शामिल है। या केवल माध्यम से उपलब्ध है। App.current.window.location Location.shared यह चर के रूप में सुलभ है, इसलिए यदि आवश्यक हो तो आप इसके परिवर्तनों को सुन सकते हैं। @State उदाहरण के लिए राउटर कैसे काम करता है। App.current.window.$location.listen { location in // read location properties } यह एक साधारण चर के रूप में भी सुलभ है Location.shared.href // also $href Location.shared.host // also $host Location.shared.port // also $port Location.shared.pathname // also $pathname Location.shared.search // also $search Location.shared.hash // also $hash अधिक विवरण पर उपलब्ध हैं। एमडीएन नाविक ब्राउज़र के बारे में जानकारी शामिल है। या सिर्फ के माध्यम से उपलब्ध है App.current.window.navigator Navigator.shared सबसे दिलचस्प विशेषताएँ आमतौर पर । userAgent platform language cookieEnabled स्थानीय भंडारण वेब ब्राउज़र में की/वैल्यू पेयर को सेव करने की अनुमति देता है। डेटा को बिना किसी एक्सपायरी डेट के स्टोर करता है। या केवल के रूप में उपलब्ध है। App.current.window.localStorage LocalStorage.shared // You can save any value that can be represented in JavaScript LocalStorage.shared.set("key", "value") // saves String LocalStorage.shared.set("key", 123) // saves Int LocalStorage.shared.set("key", 0.8) // saves Double LocalStorage.shared.set("key", ["key":"value"]) // saves Dictionary LocalStorage.shared.set("key", ["v1", "v2"]) // saves Array // Getting values back LocalStorage.shared.string(forKey: "key") // returns String? LocalStorage.shared.integer(forKey: "key") // returns Int? LocalStorage.shared.string(forKey: "key") // returns String? LocalStorage.shared.value(forKey: "key") // returns JSValue? // Removing item LocalStorage.shared.removeItem(forKey: "key") // Removing all items LocalStorage.shared.clear() ट्रैकिंग परिवर्तन LocalStorage.onChange { key, oldValue, newValue in print("LocalStorage: key \(key) has been updated") } सभी आइटम हटाने पर नज़र रखना LocalStorage.onClear { print("LocalStorage: all items has been removed") } सेशनस्टोरेज वेब ब्राउज़र में की/वैल्यू पेयर को सेव करने की अनुमति देता है। डेटा को केवल एक सत्र के लिए संग्रहीत करता है। या सिर्फ के रूप में उपलब्ध है। App.current.window.sessionStorage SessionStorage.shared एपीआई बिल्कुल वैसा ही है जैसा ऊपर वर्णित में है। लोकलस्टोरेज दस्तावेज़ ब्राउज़र में लोड किए गए किसी भी वेब पेज का प्रतिनिधित्व करता है और वेब पेज की सामग्री में प्रवेश बिंदु के रूप में कार्य करता है। के माध्यम से उपलब्ध है। App.current.window.document App.current.window.document.title // also $title App.current.window.document.metaDescription // also $metaDescription App.current.window.document.head // <head> element App.current.window.document.body // <body> element App.current.window.documentquerySelector("#my") // returns BaseElement? App.current.window.document.querySelectorAll(".my") // returns [BaseElement] स्थानीयकरण स्थैतिक स्थानीयकरण क्लासिक स्थानीयकरण स्वचालित है और उपयोगकर्ता सिस्टम भाषा पर निर्भर करता है का उपयोग कैसे करें H1(String( .en("Hello"), .fr("Bonjour"), .ru("Привет"), .es("Hola"), .zh_Hans("你好"), .ja("こんにちは"))) गतिशील स्थानीयकरण यदि आप ऑन-द-फ्लाई स्क्रीन पर स्थानीयकृत स्ट्रिंग्स को बदलना चाहते हैं (पृष्ठ पुनः लोड किए बिना) आप कॉल करके वर्तमान भाषा बदल सकते हैं Localization.current = .es अगर आपने यूजर की भाषा को कुकीज या लोकलस्टोरेज में कहीं सेव किया है तो आपको इसे ऐप लॉन्च पर सेट करना होगा Lifecycle.didFinishLaunching { Localization.current = .es } का उपयोग कैसे करें H1(LString( .en("Hello"), .fr("Bonjour"), .ru("Привет"), .es("Hola"), .zh_Hans("你好"), .ja("こんにちは"))) उन्नत उदाहरण H1(Localization.currentState.map { "Curent language: \($0.rawValue)" }) H2(LString(.en("English string"), .es("Hilo Español"))) Button("change lang").onClick { Localization.current = Localization.current.rawValue.contains("en") ? .es : .en } लाना import FetchAPI Fetch("https://jsonplaceholder.typicode.com/todos/1") { switch $0 { case .failure: break case .success(let response): print("response.code: \(response.status)") print("response.statusText: \(response.statusText)") print("response.ok: \(response.ok)") print("response.redirected: \(response.redirected)") print("response.headers: \(response.headers.dictionary)") struct Todo: Decodable { let id, userId: Int let title: String let completed: Bool } response.json(as: Todo.self) { switch $0 { case .failure(let error): break case .success(let todo): print("decoded todo: \(todo)") } } } } XMLHttpRequest import XMLHttpRequest XMLHttpRequest() .open(method: "GET", url: "https://jsonplaceholder.typicode.com/todos/1") .onAbort { print("XHR onAbort") }.onLoad { print("XHR onLoad") }.onError { print("XHR onError") }.onTimeout { print("XHR onTimeout") }.onProgress{ progress in print("XHR onProgress") }.onLoadEnd { print("XHR onLoadEnd") }.onLoadStart { print("XHR onLoadStart") }.onReadyStateChange { readyState in print("XHR onReadyStateChange") } .send() वेबसॉकेट import WebSocket let webSocket = WebSocket("wss://echo.websocket.org").onOpen { print("ws connected") }.onClose { (closeEvent: CloseEvent) in print("ws disconnected code: \(closeEvent.code) reason: \(closeEvent.reason)") }.onError { print("ws error") }.onMessage { message in print("ws message: \(message)") switch message.data { case .arrayBuffer(let arrayBuffer): break case .blob(let blob): break case .text(let text): break case .unknown(let jsValue): break } } Dispatch.asyncAfter(2) { // send as simple string webSocket.send("Hello from SwifWeb") // send as Blob webSocket.send(Blob("Hello from SwifWeb")) } सांत्वना देना सरल जावास्क्रिप्ट में के बराबर है print(“Hello world“) console.log('Hello world') विधियाँ भी प्रेम ❤️ से लिपटी हुई हैं कंसोल Console.dir(...) Console.error(...) Console.warning(...) Console.clear() सजीव पूर्वावलोकन लाइव पूर्वावलोकन कार्य करने के लिए अपनी इच्छित प्रत्येक फ़ाइल में WebPreview क्लास घोषित करें। class IndexPage: PageController {} class Welcome_Preview: WebPreview { @Preview override class var content: Preview.Content { Language.en Title("Initial page") Size(640, 480) // add here as many elements as needed IndexPage() } } एक्सकोड कृपया पर निर्देश पढ़ें। यह मुश्किल है लेकिन पूरी तरह से काम करने वाला समाधान है रिपॉजिटरी पेज वीएससीओडी के अंदर पर जाएं और खोजें। VSCode एक्सटेंशन वेबर एक बार इंस्टॉल हो जाने के बाद (या Linux/Windows पर ) दबाएं Cmd+Shift+P Ctrl+Shift+P ढूंढें और लॉन्च करें। Webber Live Preview दाईं ओर, आपको लाइव पूर्वावलोकन विंडो दिखाई देगी और जब भी आप उस फ़ाइल को सहेजते हैं जिसमें क्लास होती है तो यह ताज़ा हो जाती है। WebPreview जावास्क्रिप्ट तक पहुंच यह के माध्यम से उपलब्ध है जो कि की नींव है। JavaScriptKit SwifWeb में पढ़ें कि आप कैसे हैं। आधिकारिक रिपॉजिटरी संसाधन आप प्रोजेक्ट के अंदर , , , , और अन्य स्थिर संसाधन जोड़ सकते हैं। css js png jpg लेकिन या अंतिम फाइलों में उन्हें उपलब्ध कराने के लिए आपको उन सभी को में इस तरह घोषित करना होगा डिबग के दौरान रिलीज पैकेज.स्विफ्ट .executableTarget(name: "App", dependencies: [ .product(name: "Web", package: "web") ], resources: [ .copy("css/*.css"), .copy("css"), .copy("images/*.jpg"), .copy("images/*.png"), .copy("images/*.svg"), .copy("images"), .copy("fonts/*.woff2"), .copy("fonts") ]), बाद में आप उन्हें इस तरह एक्सेस कर पाएंगे Img().src(“/images/logo.png“) डिबगिंग निम्न तरीके से लॉन्च करें वेबर को इसे जल्दी से लॉन्च करने के लिए webber serve PWA मोड में लॉन्च करने के लिए webber serve -t pwa -s Service अतिरिक्त पैरामीटर या डिबगिंग उद्देश्यों के लिए कंसोल में अधिक जानकारी दिखाने के लिए -v --verbose या डिफ़ॉल्ट 8888 के बजाय 443 पोर्ट पर वेबर सर्वर शुरू करने के लिए -p 443 --port 443 स्वचालित रूप से वांछित ब्राउज़र खोलने के लिए, डिफ़ॉल्ट रूप से यह कोई भी नहीं खोलता है --browser chrome/safari सेवा कर्मियों को स्थानीय रूप से डीबग करने की आवश्यकता है, अन्यथा वे काम नहीं करते हैं --browser-self-signed ब्राउज़र के अतिरिक्त इंस्टेंस को गुप्त मोड में खोलने के लिए, केवल क्रोम के साथ काम करता है --browser-incognito तो अपने ऐप को डिबग मोड में बनाने के लिए, स्वचालित रूप से इसे क्रोम में खोलें और जब भी आप कोई फ़ाइल बदलते हैं तो ब्राउज़र को स्वचालित रूप से रीफ्रेश करें, इसे इस तरह लॉन्च करें एसपीए के लिए webber serve --browser chrome वास्तविक PWA परीक्षण के लिए webber serve -t pwa -s Service -p 443 --browser chrome --browser-self-signed --browser-incognito प्रारंभिक ऐप लोड हो रहा है आप प्रारंभिक लोडिंग प्रक्रिया में सुधार करना चाह सकते हैं। उसके लिए बस प्रोजेक्ट के अंदर फ़ोल्डर खोलें और फ़ाइल को संपादित करें। .webber/entrypoint/dev index.html इसमें बहुत उपयोगी श्रोताओं के साथ प्रारंभिक HTML कोड शामिल है: । WASMLoadingStarted WASMLoadingStartedWithoutProgress WASMLoadingProgress WASMLoadingError आप उस कोड को संपादित करने के लिए स्वतंत्र हैं जो आप अपनी कस्टम शैली 🔥 को लागू करना चाहते हैं जब आप नया कार्यान्वयन समाप्त कर लें तो उसे फ़ोल्डर में सहेजना न भूलें .webber/entrypoint/release भवन विमोचन PWA के लिए बस या निष्पादित करें। webber release webber release -t pwa -s Service फिर फ़ोल्डर से संकलित फ़ाइलें लें और उन्हें अपने सर्वर पर अपलोड करें। .webber/release कैसे तैनात करें आप अपनी फ़ाइलें किसी भी स्थिर होस्टिंग पर अपलोड कर सकते हैं। होस्टिंग को फ़ाइलों के लिए सही सामग्री-प्रकार प्रदान करना चाहिए! wasm हां, सही हेडर होना बहुत जरूरी है files के लिए, अन्यथा दुर्भाग्य से ब्राउज़र आपके WebAssembly एप्लिकेशन को लोड करने में सक्षम नहीं होगा। Content-Type: application/wasm wasm उदाहरण के लिए फ़ाइलों के लिए सही सामग्री-प्रकार प्रदान नहीं करता है, इसलिए दुर्भाग्य से उस पर WebAssembly साइटों को होस्ट करना असंभव है। GithubPages wasm nginx यदि आप nginx के साथ अपने स्वयं के सर्वर का उपयोग करते हैं, तो खोलें और जांचें कि इसमें अभिलेख। यदि हाँ तो आप जाने के लिए अच्छे हैं! /etc/nginx/mime.types application/wasm wasm; निष्कर्ष मुझे आशा है कि आज मैंने आपको चकित कर दिया और आप कम से कम SwifWeb को आजमाएंगे और अधिकतम अपने अगले बड़े वेब प्रोजेक्ट के लिए इसका उपयोग करना शुरू कर देंगे! कृपया किसी भी में बेझिझक योगदान दें और ⭐️उन सभी को तारांकित करें! SwifWeb लाइब्रेरी मेरे पास है जहां आप बहुत बड़ा समर्थन पा सकते हैं, छोटे ट्यूटोरियल पढ़ सकते हैं और किसी भी आगामी अपडेट के बारे में सबसे पहले सूचित किया जा सकता है! आपको हमारे साथ देखकर अच्छा लगेगा! डिस्कॉर्ड में एक शानदार स्विफ्टस्ट्रीम समुदाय यह अभी शुरुआत है, इसलिए SwifWeb के बारे में अधिक लेखों के लिए बने रहें! अपने दोस्तों को कहिए!