摘要:轉(zhuǎn)譯利用構(gòu)建應(yīng)用英文原文地址引入了來創(chuàng)建這使得可以訪問類庫我已經(jīng)深入研究這塊并且編寫了一些今天這篇文章會(huì)講解一些基礎(chǔ)東西并且一步步的來創(chuàng)建一個(gè)小的上面有一個(gè)主題專門解釋用來代替創(chuàng)建自動(dòng)化應(yīng)用程序這是個(gè)非常激動(dòng)的事情使用來構(gòu)建自動(dòng)化任務(wù)已經(jīng)存
轉(zhuǎn):[譯]利用js構(gòu)建osx應(yīng)用
英文原文地址
OSX Yosemite引入了js來創(chuàng)建Automation,這使得javascript可以訪問nativeOSX類庫,我已經(jīng)深入研究這塊并且編寫了一些examples,今天這篇文章會(huì)講解一些基礎(chǔ)東西并且一步步的來創(chuàng)建一個(gè)小的example app.
WWDC 2014上面有一個(gè)JavaScript for Automation主題,專門解釋用javascript來代替applescript創(chuàng)建自動(dòng)化應(yīng)用程序,這是個(gè)非常激動(dòng)的事情,使用applescript來構(gòu)建自動(dòng)化任務(wù)已經(jīng)存在很長(zhǎng)時(shí)間了,它的一些語法一直都不是很受歡迎.
在這個(gè)主題上,主持人講解了object-c bridge,這個(gè)是非??岬臇|西,可以往javascript中導(dǎo)入任何底層的方法,例如,如用你想用標(biāo)準(zhǔn)的OS X控件來創(chuàng)建gui應(yīng)用的話,你將要引入cocoa:
ObjC.import("Cocoa");
Foundation框架就跟它名字一樣,提供一些基礎(chǔ)模塊給osx app,它包含很多類以及接口,比如NSArray,NSURL,NSUserNotification等等,也許你對(duì)這些類不熟悉,但是根據(jù)字面意思大概就能知道它們的功能,這些類比較常用,所以可以直接在app中使用而不需要多帶帶導(dǎo)入它.它是默認(rèn)就會(huì)加載的
我可以這么跟你說,只要是用objective-c或者swift創(chuàng)建的app,用javascript都可以做出來.
build and example app注意:你的操作系統(tǒng)要在yosemite開發(fā)版7+,下面的例子才可以正常運(yùn)行
了解它的最好方法就是實(shí)踐,下面我們將要實(shí)現(xiàn)一個(gè)簡(jiǎn)單的app(從你電腦上選取一個(gè)圖片并顯示它),效果如圖
制定一個(gè)app.js,包括一個(gè)窗口,一個(gè)文本標(biāo)簽,一個(gè)輸入框和一個(gè)按鈕,對(duì)應(yīng)的class名稱就是NSWindow,NSTextField,NSTextField和NSButton.
單擊選擇圖片文件按鈕,將會(huì)顯示一個(gè)NSOpenPanel,它將會(huì)顯示一個(gè)文件選擇窗口,我們還需要配置這個(gè)窗口的文件過濾屬性,只能選擇.jpg,.png或者.gif
當(dāng)選擇一個(gè)圖片之后,將會(huì)在窗口中顯示出來,并且自適應(yīng)圖片大小,窗口設(shè)置了一個(gè)最小的寬高以免圖片被裁剪
創(chuàng)建一個(gè)project打開Apple Script Editor應(yīng)用程序,定位到Applications > Utilities,Script Editor并不是最好用的編輯器,但是現(xiàn)在有必要用它,它提供了很多的特性用來創(chuàng)建JS OSX APP,并且可以用來編譯和運(yùn)行你的js osx app,它也可以添加些擴(kuò)展文件像我們app需要的info.plist文件.我猜也許還有別的編輯器可以做同樣的事情,不過目前我還沒有找到.
創(chuàng)建一個(gè)新的文檔,定位到File->New或者使用命令cmd + n,首先要做的就是保存它為Application,定位到File->Save或者使用命令cmd + s,確認(rèn)保存之前,有兩個(gè)選項(xiàng)需要注意下,看下圖:
文件格式選擇Application,選中Stay open after run handler
如果沒有選中Stay open after run handler,打開應(yīng)用之后會(huì)一閃而過,然后自動(dòng)關(guān)閉,這些網(wǎng)上都沒有什么教程,只是自己幾個(gè)小時(shí)摸索出來的.
現(xiàn)在應(yīng)該是做些有意義的時(shí)候了
添加下面兩行代碼到你的編輯器中,然后運(yùn)行它,定位到Script->Run Application或者opt + cmd + r.
Objc.import("Cocoa"); $.NSLog("hello feenan!");
這時(shí)候運(yùn)行應(yīng)用什么都沒有發(fā)生,唯一看到改變的就是全局菜單欄以及dock,因?yàn)閼?yīng)用名稱以及file,edit并排在菜單欄上,應(yīng)用圖片顯示在dock上,這些都代表著應(yīng)用已經(jīng)在運(yùn)行.
那么hello feenan!跑哪去了呢?$符號(hào)是什么,是jquery?,我們先把應(yīng)用程序退出了,定位到File->Quit或者cmd + q,然后我們來找找NSLog輸出的內(nèi)容.
打開Console app,定位到Applications > Utilities > Console,任何一個(gè)應(yīng)用程序都可以記錄日志到console app中,它跟chrome,firefox,safari中的控制臺(tái)沒多大區(qū)別,主要的區(qū)別在于你可以使用它來調(diào)試應(yīng)用程序代替website
在console app中有很多日志信息,你可以在右上角的輸入框中輸入applet來過濾日志,輸入applet到過濾框中之后,回到Script Editor中,再次運(yùn)行應(yīng)用程序,使用opt + cmd + r命令,控制臺(tái)信息如下圖
你是不是看到在控制臺(tái)中顯示hello feenan!了,如果沒有的話,退出應(yīng)用程序再次運(yùn)行看看,有時(shí)候我們忘記退出應(yīng)用程序,代碼并沒有再次運(yùn)行.
$符號(hào)是什么呢?$讓你能夠訪問Objective-C bridge.任何時(shí)候你需要訪問Objective-C其中某個(gè)類或者常量,你都可能使用$.foo或者ObjC.foo,后面還有講到關(guān)于使用$的其它一些方法.
Console app和NSLog是必不可少的工具,你將會(huì)不停的使用它們來調(diào)試你的應(yīng)用程序,想要了解更多的信息,可以點(diǎn)擊NSLog example
創(chuàng)建一個(gè)窗口讓我們創(chuàng)建一個(gè)可以顯示并且有交互的窗口,代碼看起來像下面這樣
ObjC.import("Cocoa"); var styleMask = $.NSTitledWindowMask | $.NSClosableWindowMask | $.NSMiniaturizableWindowMask; var windowHeight = 85; var windowWidth = 600; var ctrlsHeight = 80; var minWidth = 400; var minHeight = 340; var window = $.NSWindow.alloc.initWithContentRectStyleMaskBackingDefer( $.NSMakeRect(0, 0, windowWidth, windowHeight), styleMask, $.NSBackingStoreBuffered, false ); window.center; window.title = "Choose and Display Image"; window.makeKeyAndOrderFront(window);
當(dāng)這些都在合適的位置之后,我們運(yùn)行它通過opt + cmd + r,然后我們可以說,只需要這么點(diǎn)代碼就可以啟動(dòng)一個(gè)app并且打開一個(gè)窗口,而且我們可以移動(dòng),最小化和關(guān)閉它.
如果你跟我一樣沒有用Objective-C或者Cocoa來創(chuàng)建一個(gè)app的話,這些可以看起來有點(diǎn)難以理解,對(duì)我來說,這些方法名稱的長(zhǎng)度有點(diǎn)難以接受,雖然我喜歡描述性的方法名稱,但是像Cocoa這樣的還是太極端了.
看上面的代碼其實(shí)就是javascript,就跟你編寫網(wǎng)站代碼一樣.
第一行中的styleMask是干么的呢?它提供了一些對(duì)窗口屬性設(shè)置的功能,有標(biāo)題,關(guān)閉按鈕,最小化按鈕,這些選項(xiàng)都是常量,通過|符號(hào)來添加多個(gè),|符號(hào)是C里的or操作符,不用去理解它的原理,只要知道它是用來并列多個(gè)選項(xiàng)的就足夠了.
這里有很多種樣式信息,想了解詳情的可以點(diǎn)擊the docs,NSResizableWindowMask將是接下來要使用的一個(gè)樣式,可以添加到上面的代碼中看看效果
這里還有一些有趣的語法需要你記住,$.NSWindow.alloc調(diào)用NSWindow里的alloc方法,但是并沒有在后面插入(),這種調(diào)用方式就跟js里獲取屬性一樣,但是js里調(diào)用方法不是這樣的,原來,在OSX JS中,假如方法沒有參數(shù)的時(shí)候,是不能在后面加入()的,否則它會(huì)出現(xiàn)運(yùn)行時(shí)錯(cuò)誤.所以以后當(dāng)你發(fā)現(xiàn)有些事件并沒有像你期望中發(fā)生時(shí)就要檢查下console里的輸出內(nèi)容了.
下一個(gè)要關(guān)注的事情是這個(gè)超長(zhǎng)的方法:
initWithContentRectStyleMaskBackingDefer
讓我們來看看NSWindow的doc上講解這個(gè)方法的,你會(huì)發(fā)現(xiàn)有一點(diǎn)不同:
initWithContentRect:styleMask:backing:defer:
上面的描述相當(dāng)于在Objective-c中創(chuàng)建下面的代碼
NSWindow* window [[NSWindow alloc] initWithContentRect: NSMakeRect(0, 0, windowWidth, windowHeight) styleMask: styleMask, backing: NSBackingStoreBuffered defer: NO];
注意下上面方法簽名中的:,當(dāng)你想把一個(gè)Objective-c中的方法轉(zhuǎn)換成js的方法時(shí),首先需要把:除掉然后把跟在后面的第一個(gè)字母大寫.當(dāng)看到方括號(hào)[]里有兩項(xiàng)是,代表調(diào)用一個(gè)類或者對(duì)象的方法,NSWindow alloc表示調(diào)用NSWindow的alloc方法,換成js的話,需要在兩者之前添加一個(gè).,像NSWindow.alloc這樣
我認(rèn)為剩下的代碼足夠用來描述創(chuàng)建一個(gè)窗口并顯示它,我跳過了很多關(guān)于這方面的細(xì)節(jié)說明,這個(gè)需要很多時(shí)間用來閱讀相關(guān)文檔,不過你可以這些.當(dāng)你做到顯示出一個(gè)窗口來已經(jīng)不錯(cuò)了,讓我們做更多的事情吧
添加控件窗口里還需要一個(gè)標(biāo)簽,一個(gè)輸入框,一個(gè)按鈕,我使用NSTextField和NSButton來創(chuàng)建它,輸入下面的代碼然后運(yùn)行你的app
ObjC.import("Cocoa"); var styleMask = $.NSTitledWindowMask | $.NSClosableWindowMask | $.NSMiniaturizableWindowMask; var windowHeight = 85; var windowWidth = 600; var ctrlsHeight = 80; var minWidth = 400; var minHeight = 340; var window = $.NSWindow.alloc.initWithContentRectStyleMaskBackingDefer( $.NSMakeRect(0, 0, windowWidth, windowHeight), styleMask, $.NSBackingStoreBuffered, false ); var textFieldLabel = $.NSTextField.alloc.initWithFrame($.NSMakeRect(25, (windowHeight - 40), 200, 24)); textFieldLabel.stringValue = "Image: (jpg, png, or gif)"; textFieldLabel.drawsBackground = false; textFieldLabel.editable = false; textFieldLabel.bezeled = false; textFieldLabel.selectable = true; var textField = $.NSTextField.alloc.initWithFrame($.NSMakeRect(25, (windowHeight - 60), 205, 24)); textField.editable = false; var btn = $.NSButton.alloc.initWithFrame($.NSMakeRect(230, (windowHeight - 62), 150, 25)); btn.title = "Choose an Image..."; btn.bezelStyle = $.NSRoundedBezelStyle; btn.buttonType = $.NSMomentaryLightButton; window.contentView.addSubview(textFieldLabel); window.contentView.addSubview(textField); window.contentView.addSubview(btn); window.center; window.title = "Choose and Display Image"; window.makeKeyAndOrderFront(window);
如果應(yīng)用跑起來沒問題的話,將會(huì)看到下面的效果,你可以在輸入框中輸入內(nèi)容,按鈕點(diǎn)擊沒有任何效果,不過我們后面會(huì)加些東西上去
看到上面的代碼是不是對(duì)添加有些疑惑,到底怎么實(shí)現(xiàn)的呢?textFieldLabel和textField非常相似,它們都是NSTextField的實(shí)例,在這里都是通過相似的方法實(shí)現(xiàn)的,當(dāng)你看到initWithFrame和NSMakeRect時(shí),它們是創(chuàng)建ui元素的好方法,NSMakeRect就跟它的名字一樣,用來創(chuàng)建有一定大小的方形用給定的位置信息(x, y, width, height).這就相當(dāng)于創(chuàng)建了Objective-c中的結(jié)構(gòu)體信息,在js中我們引用它為一個(gè)對(duì)象或者hash,或者一個(gè)dict,擁有自己的鍵值對(duì).
創(chuàng)建完輸入框這后,給它賦一些屬性,Cocoa并沒有多帶帶創(chuàng)建標(biāo)簽的方法,所以這里我們利用NSTextField,禁用它的編輯屬性并且設(shè)置的背景樣式來模擬標(biāo)簽效果.
假如是正常的輸入框的話,其實(shí)只需要設(shè)置一行代碼就可以了
對(duì)于按鈕我們使用NSButton類,跟輸入框一樣,創(chuàng)建它也需要先畫一個(gè)矩形,不過這里有兩個(gè)屬性需要強(qiáng)調(diào)下:bezelStyle和buttonType.它們的值就是常量,主要用來控制按鈕的渲染以及有什么樣式信息,想了解更多的信息,可以點(diǎn)擊docs,我也有一些關(guān)于不同樣式的按鈕例子,example app
最后的事情就是通過addSubview把這些控件添加到我們的window中去,剛開始我調(diào)用window.addSubview(theView),但是并沒添加起來,最后發(fā)現(xiàn)只能添加其它用NSView創(chuàng)建的實(shí)例,我不知道為什么會(huì)這樣,但是想要添加NSWindow創(chuàng)建的實(shí)例的話,只能調(diào)用window.contentView.addSubview(theView).官方文檔上是這樣描述的,NSView對(duì)象是窗口里最高的訪問層次.
給按鈕添加代碼當(dāng)點(diǎn)擊按鈕的時(shí)候,我想顯示一個(gè)面板出來,上面列出本地的文件信息,做這些之前,讓我們先添加一個(gè)日志信息熱熱身.
在javascript中添加事件一般是給對(duì)象添加監(jiān)聽,但是在Objective-C中沒有這樣的概念,在它這里叫消息通訊,你得發(fā)送一個(gè)包含方法名的消息給目標(biāo)對(duì)象,目標(biāo)對(duì)象收到這個(gè)包含方法名的消息之后才能決定做什么,也許我說的不是很準(zhǔn)確,但是大概就是這個(gè)意思
首先我們要做的就是添加一個(gè)target和一個(gè)action,target是發(fā)送給action的一個(gè)對(duì)象,也許現(xiàn)在還沒什么意義,但是后面我會(huì)增加更多的代碼,先增加下面的一部分代碼,用來更新按鈕屬性的:
... btn.target = appDelegate; btn.action = "btnClickHandler"; ...
appDelegate和btnClickHandler還沒存在,所以要先創(chuàng)建它們,在下面的代碼有提供,然后代碼中還增加了注釋用來告訴你把這些新的代碼添加到何處
ObjC.import("Cocoa"); // New stuff ObjC.registerSubclass({ name: "AppDelegate", methods: { "btnClickHandler": { types: ["void", ["id"]], implementation: function (sender) { $.NSLog("Clicked!"); } } } }); var appDelegate = $.AppDelegate.alloc.init; // end of new stuff // Below here is in place already var textFieldLabel = $.NSTextField.alloc.initWithFrame($.NSMakeRect(25, (windowHeight - 40), 200, 24)); textFieldLabel.stringValue = "Image: (jpg, png, or gif)"; ...
運(yùn)行app,然后在console中查看是否有顯示Clicked!,如果顯示了,說明代碼沒問題,否則檢查下代碼跟文中是否有區(qū)別,然后仔細(xì)看下console中的錯(cuò)誤信息.
Subclassing(子類)ObjC.registerSubclass是干什么的呢?Subclassing是創(chuàng)建一個(gè)子類的方法,它可以繼承一個(gè)父類.也許這個(gè)名稱叫的不專業(yè),還請(qǐng)多多包含.registerSubclass需要一個(gè)參數(shù),它是一個(gè)對(duì)象,成員可以包含name,superclass,protocols,properties,methods,我不敢保證這里列出了所有的成員,不過你可以看release notes.
一切看起來挺不錯(cuò)的,但是上面的代碼做了什么呢?因?yàn)椴]有寫superclass屬性,所以默認(rèn)繼承NSObject,它是所有Objective-c里的基類, 設(shè)置name屬性方便后面我們用$或者Objc來引用它.
$.AppDelegate.alloc.init會(huì)創(chuàng)建一個(gè)AppDelegate類實(shí)例,需要再次注意的是,alloc和init后面并沒有插入(),因?yàn)槲覀儾]有傳任何參數(shù).
Subclass methods(子類方法)可以通過一個(gè)字符串內(nèi)容來創(chuàng)建一個(gè)方法,比如上面的btnClickHandler,然后給它提供一個(gè)對(duì)象參數(shù),成員包括types和implementation,官方文檔上并沒有說明types數(shù)組應(yīng)該包括什么,但是經(jīng)過我不斷嘗試感覺它的參數(shù)說明應(yīng)該是這樣的:
["return type", ["arg 1 type", "arg 2 type",...]]
btnClickHandler沒返回任務(wù)東西所以設(shè)置return type為void,它需要一個(gè)參數(shù),就是發(fā)送的對(duì)象,所以這里設(shè)置參數(shù)名為id,它可以表示任何對(duì)象.
想查看整個(gè)類型的列表信息,可以點(diǎn)擊release notes
implementation是一個(gè)普通的函數(shù),在這里面可以寫javascript,同時(shí)可以訪問$符號(hào)以及外面定義的變量.
使用protocols的問題在子類中可以實(shí)現(xiàn)Cocoa protocols,但是我發(fā)現(xiàn)在你腳本中使用protocols數(shù)組,應(yīng)用程序會(huì)停止而且沒有任何錯(cuò)誤,我寫了一些example and explanation來說明這些問題,有興趣的可以看一看.
Choosing and displaying images(選擇并顯示圖片)我們準(zhǔn)備打開一個(gè)面板,選擇一個(gè)圖片,然后顯示它,更新btnClickHandler的implementation函數(shù),代碼如下
... implementation: function (sender) { var panel = $.NSOpenPanel.openPanel; panel.title = "Choose an Image"; var allowedTypes = ["jpg", "png", "gif"]; // NOTE: We bridge the JS array to an NSArray here. panel.allowedFileTypes = $(allowedTypes); if (panel.runModal == $.NSOKButton) { // NOTE: panel.URLs is an NSArray not a JS array var imagePath = panel.URLs.objectAtIndex(0).path; textField.stringValue = imagePath; var img = $.NSImage.alloc.initByReferencingFile(imagePath); var imgView = $.NSImageView.alloc.initWithFrame( $.NSMakeRect(0, windowHeight, img.size.width, img.size.height)); window.setFrameDisplay( $.NSMakeRect( 0, 0, (img.size.width > minWidth) ? img.size.width : minWidth, ((img.size.height > minHeight) ? img.size.height : minHeight) + ctrlsHeight ), true ); imgView.setImage(img); window.contentView.addSubview(imgView); window.center; } }
首先我們創(chuàng)建NSOpenPanel一個(gè)實(shí)例,如果你從來沒有打開過文件或者保存操作,那么默認(rèn)顯示的面板是活動(dòng)文件列表.
我只想打開圖片文件,所以需要過濾文件列表,設(shè)置allowedFileTypes屬性,它是一個(gè)NSArray類型,我們創(chuàng)建一個(gè)js數(shù)組allowedTypes來給它賦值,但是我們需要轉(zhuǎn)換成NSArray類型,通過$(allowedTypes),這是bridge橋的另外一種用法,可以通過這個(gè)方法在js和Objective-c之間進(jìn)行類型轉(zhuǎn)換,想轉(zhuǎn)換Objective-c類型為js中對(duì)應(yīng)的類型的話,使用$(ObjCThing).js方法.
打開面板通過panel.runModal方法,這個(gè)代碼會(huì)馬上執(zhí)行,你可以點(diǎn)擊取消和確定,然后我們可以通過返回值來判斷你點(diǎn)擊是哪個(gè),當(dāng)點(diǎn)擊確定返回的是$.NSOKButton.
另一個(gè)需要注意的是panel.URLs,通常我們?cè)L問js中的數(shù)組元素是通過[],因?yàn)?b>URLS是NSArray類型,所以不能通過[]來訪問,這里提供了objectAtIndex方法來訪問,它跟[]的效果是一樣的.
只要我們獲取到圖片的URL,那么我們就可以創(chuàng)建一個(gè)NSImage實(shí)例,這里有一個(gè)專門的方法
initByReferencingFile
跟創(chuàng)建其它ui元素一樣, 這里我們創(chuàng)建一個(gè)NSImageView實(shí)例來顯示圖片
我們想窗口的大小能夠自適應(yīng)圖片的大小,但是不能低于最小寬高,為了設(shè)置窗口的大小,這里調(diào)用setFrameDisplay方法
我們通過圖像視圖來包裝圖片,然后把它添加到window視圖中,因?yàn)榇翱诖笮「淖兞?所以需要重新計(jì)算居中顯示.
Tidbits(花絮)迄今為止,我們已經(jīng)在Script Editor中創(chuàng)建了一個(gè)app并用命令opt + cmd + d運(yùn)行它,也可以像其它app一樣,雙擊它的應(yīng)用圖標(biāo)來運(yùn)行.
你也可以修改app圖標(biāo)的路徑,替換/Contents/Resources/applet.icns就行,想訪問應(yīng)用的資源文件,可以右鍵app選擇Show Package Contents就行.
WHY I’M EXCITED(為什么我這么激動(dòng)?)我對(duì)它的潛能感到非常激動(dòng),下面是我已經(jīng)想到的一點(diǎn)觀點(diǎn).當(dāng)Yosemite正式發(fā)布之后,很多人可以坐下來開發(fā)原生app了,使用最普通的編程語言,而且不用下載或者安裝別的東西,假如你想的話連xcode也可以不用安裝,完全降低了進(jìn)入app開發(fā)的門檻,這簡(jiǎn)直太瘋狂了.
我知道有很多大型應(yīng)用程序通過腳本是辦不到的,我也沒有說腳本是創(chuàng)建app的唯一方式,但是我們可以讓一些人創(chuàng)建一些小的app為他自己或者別人.當(dāng)一個(gè)團(tuán)隊(duì)整天在命令行下工作的不舒服時(shí),我們可以為它們創(chuàng)建一個(gè)gui程序;當(dāng)需要快速,可視化的創(chuàng)建或者修改配置文件時(shí),也可以為它創(chuàng)建一個(gè)小的app.
當(dāng)然也有其它編程語言可以辦到,像python和ruby也可以訪問到低層api,然后創(chuàng)建app.只是利用javascript來創(chuàng)建app顯的更與眾不同,這簡(jiǎn)直有點(diǎn)顛覆我們的思想.這感覺就像一些網(wǎng)站敲響了桌面上的門,apple讓這個(gè)門解鎖了,我完全被它吸引了.
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/85490.html
摘要:巔峰人生年老兵思路上的轉(zhuǎn)變,遠(yuǎn)比單純提升技術(shù)更有價(jià)值本文節(jié)選自趙成教授在極客時(shí)間開設(shè)的趙成的運(yùn)維體系管理課,是其對(duì)自己十年技術(shù)生涯的回顧與總結(jié)。趙成教授來自美麗聯(lián)合集團(tuán),集團(tuán)旗下兩大主力產(chǎn)品是蘑菇街和美麗說,目前負(fù)責(zé)管理集團(tuán)的技術(shù)服務(wù)團(tuán)隊(duì)。 showImg(https://segmentfault.com/img/remote/1460000012476504?w=1240&h=826...
摘要:同時(shí)也是對(duì)無法完整支持的一種補(bǔ)充。不過我們只能通過的返回結(jié)果判斷執(zhí)行成功還是失敗。另外,雖然有垃圾回收機(jī)制,但開發(fā)者還是應(yīng)當(dāng)在使用完數(shù)據(jù)后手動(dòng)刪除相應(yīng)的。最新版版本已經(jīng)修復(fù)上述問題。 原文地址:https://github.com/Microsoft/... 本文介紹 Napa.js 的核心概念,帶領(lǐng)大家探索 Napa.js 是如何運(yùn)轉(zhuǎn)起來的。關(guān)于它的由來和開發(fā)初衷,可以閱讀 這篇文章...
摘要:簡(jiǎn)介是一個(gè)開源的應(yīng)用容器引擎,讓開發(fā)者可以打包他們的應(yīng)用以及依賴包到一個(gè)可移植的容器中,然后發(fā)布到任何流行的機(jī)器上,也可以實(shí)現(xiàn)虛擬化。該虛擬機(jī)需要安裝操作系統(tǒng)以便在您機(jī)上運(yùn)行。 Docker簡(jiǎn)介 Docker 是一個(gè)開源的應(yīng)用容器引擎,讓開發(fā)者可以打包他們的應(yīng)用以及依賴包到一個(gè)可移植的容器中,然后發(fā)布到任何流行的 Linux 機(jī)器上,也可以實(shí)現(xiàn)虛擬化。 docker的英文本意是碼頭工人...
閱讀 864·2021-10-09 09:44
閱讀 754·2019-08-30 13:55
閱讀 3219·2019-08-29 15:07
閱讀 3278·2019-08-29 13:09
閱讀 2466·2019-08-29 11:10
閱讀 1356·2019-08-26 14:05
閱讀 3680·2019-08-26 13:57
閱讀 2256·2019-08-23 16:42