擁抱ES6——OSSJavaScriptSDK開發手記

rockuw發表於2016-01-29

JavaScript作為當下最火的語言(之一),結合OSS能夠建立出非常豐富的跨前後端的應用。現在,OSS正式推出JavaScript SDK,使用OSS的 前後端 同學 可以方便地使用。

ES6

首先,什麼是ES6?

es6

其實ES6是最新版本的ECMAScript,也就是JavaScript標準。

ECMAScript 6, also known as ECMAScript 2015, is the latest version of the ECMAScript standard. > ES6 is a significant update to the language…

ES6包含了眾多重要的更新,但是今天對我們最重要的就是Generator Function,因為它可以讓我們用同步的方式寫非同步程式碼:

var creds = yield  applySTSToken();
var client = new OSS(creds);
var result = yield client.list();
console.log(result);

上面的程式碼包含了兩個非同步的操作,applySTSTokenlist,如果沒有generator,我們就需要在applySTSToken的callback中做list,然後在list的callback中做log,比如這樣:

applySTSToken(function (creds) {
  var client = new OSS(creds);
  client.list(function (result) {
    console.log(result);
  });
});

如果上面的程式碼看起來也“還可以”的話,那麼當非同步操作多起來之後,再考慮錯誤處理的場景,程式碼將會變得非常複雜。不得不說callback很鍛鍊大腦,但是有高科技為什麼不利用呢?

這看起來不錯,但是如何實現的呢?這篇文章介紹瞭如何實現Promise(這真是個好名字)。最關鍵的地方就是yield讓控制流跳轉到其他程式碼執行,相應的事件(callback)發生時,通過next讓控制流回到上次yield的地方繼續執行,這樣就達到了“非同步非阻塞”的效果。

目前主流的Chrome/Firefox版本都已經支援ES6的大部分功能了。主流的Safari版本和移動端瀏覽器目前還不支援ES6,但是我們後面會講到如何做相容性轉換。

功能

SDK目前支援OSS的絕大部分功能,包括上傳/下載檔案、分片上傳、Bucket管理、檔案管理等,常用的上傳/下載也有多樣的玩法:

  • 上傳本地檔案
  • 上傳Buffer內容
  • 流式上傳
  • 分片上傳
  • 下載到本地檔案
  • 流式下載

安裝

npm install ali-oss co

上傳檔案

使用put介面上傳一個Object:

var OSS = require(`ali-oss`);
var co = require(`co`);
var fs = require(`fs`);

var client = new OSS({
  accessKeyId: `access key id`,
  accessKeySecret: `access key secret`,
  region: `oss-cn-hangzhou`,
  bucket: `my-bucket`,
});

co(function* () {
  // put from local file
  yield client.put(`file`, `/tmp/x`);

  // put from Buffer
  yield client.put(`buffer`, new Buffer(`hello world`));

  // put from Stream
  yield client.put(`stream`, fs.createReadStream(`/tmp/x`));
}).catch(function (err) {
  console.log(err);
});

下載檔案

使用getgetStream方法下載檔案:

co(function* () {
  // get as content
  var result = yield client.get(`object`);
  console.log(result.content);

  // download as file
  yield client.get(`object`, `/tmp/x`);

  // pipe to stream
  yield client.get(`object`, fs.createWriteStream(`/tmp/x`));

  // get as stream
  var result = yield client.getStream(`object`);
  result.stream.pipe(fs.createWriteStream(`/tmp/y`));
}).catch(function (err) {
  console.log(err);
});

管理Bucket

使用putBucketLifecycle等介面來設定Bucket的屬性。注意,目前OSS不支援Bucket相關的跨域請求,所以在瀏覽器中不能使用Bucket的管理介面。

co(function* () {
  var result = yield client.putBucketLifecycle(`bucket`, `region`, [
    {
      id: `delete after one day`,
      prefix: `logs/`,
      status: `Enabled`,
      days: 1
    },
    {
      prefix: `logs2/`,
      status: `Disabled`,
      date: `2022-10-11T00:00:00.000Z`
    }
  ]);
}).catch(function (err) {
  console.log(err);
});

HTTP Headers

SDK的每個方法都可以設定和獲取HTTP Headers:

co(function* () {
  // set headers
  var result = yield client.put(`object`, `/tmp/x`, {
    headers: {
      `content-type`: `application/javascript; charset=utf8`
    }
  });

  // get headers
  console.log(result.res.headers);
}).catch(function (err) {
  console.log(err);
});

前端後端

Browserify, Babel等優秀工具的出現,使得我們能夠在前後端共用一套程式碼。OSS JavaScript SDK基於Node.js開發,通過BrowserifyBabel產生適用於瀏覽器的程式碼,使得OSS JavaScript SDK同時支援在瀏覽器中和Node.js環境中使用。

在瀏覽器中使用

使用者在瀏覽器中使用SDK時,首先在<head>標籤中包含如下<script>標籤:

<script src="http://gosspublic.alicdn.com/aliyun-oss-sdk-4.1.4.min.js"></script>

就可以在程式碼中使用OSS物件:

<script type="text/javascript">
  var client = new OSS({
    region: `<oss region>`,
    accessKeyId: `<Your accessKeyId(STS)>`,
    accessKeySecret: `<Your accessKeySecret(STS)>`,
    stsToken: `<Your securityToken(STS)>`,
    bucket: `<Your bucket name>`
  });

  OSS.co(function* () {
    var result = yield client.list({
      `max-keys`: 10
    });
    console.log(result);
  }).catch(function (err) {
    console.log(err);
  });
</script>

注意:上面的程式碼中用OSS.co代替co,同樣的,如果用到了Buffer,也要使用OSS.Buffer代替。browser.js中顯示了SDK暴露給瀏覽器的全部物件。

我們提供一個demo,使用OSS JavaScript SDK開發了一個瀏覽器應用,提供上傳檔案/上傳文字/列出檔案/下載檔案 四個功能,效果如下:

oss_in_browser_demo

Build SDK

只需要在SDK的程式碼目錄執行npm run build-dist命令,就可以生成用於瀏覽器的SDK lib:

git clone https://github.com/ali-sdk/ali-oss.git
cd ali-oss
npm install
npm run build-dist
# output
# dist/aliyun-oss-sdk.js
# dist/aliyun-oss-sdk.min.js

Build使用者程式碼

上述的例子中使用SDK的程式碼使用了function*yield等ES6的特性,這在支援ES6的瀏覽器(主流版本的Chrome/Firefox)中可以直接執行,若要用於更多的瀏覽器,則需要使用BrowserifyBabel進行相容性轉換:

npm install -g browserify
npm install babelify babel-preset-es2015
echo `{ "presets": ["es2015"] }` > .babelrc
browserify app.js -t babelify > app-babel.js

轉換後只需要在<script>標籤中包含轉換後的程式碼檔案即可:

<script src="app-babel.js"></script>

釋出

在SDK的開發過程中,每釋出一個版本,我需要手動做以下幾件事情:

  • 修改ChangeLog
  • 修改package.json中的版本
  • 生成版本的tag
  • 生成dist/aliyun-oss-sdk.min.js
  • 釋出到npm
  • aliyun-oss-sdk.min.js釋出到cdn

這麼多步驟,不出錯是幾乎不可能的。所以我們使用git-extrasgit-pre-hooks,讓釋出過程變成”All-in-One”,具體參考package.json

首先確保在master分支,然後npm依賴都安裝好了:

git checkout master
npm install

釋出過程:

vi package.json and change "version" to 4.2.0
git changelog -n -t 4.2.0
git release 4.2.0

是不是如絲般順滑?

致謝 @蘇千 大大,@不四 大大


相關文章