国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

2020年如何寫一個(gè)現(xiàn)代的JavaScript庫

joyqi / 2405人閱讀

摘要:我寫過一些開源項(xiàng)目,在開源方面有一些經(jīng)驗(yàn),最近開到了阮老師的微博,深有感觸,現(xiàn)在一個(gè)開源項(xiàng)目涉及的東西確實(shí)挺多的,特別是對(duì)于新手來說非常不友好最近我寫了一個(gè),旨在從多方面快速幫大家搭建一個(gè)標(biāo)準(zhǔn)的庫,本文將已為例,介紹寫一個(gè)開源庫的知識(shí)

我寫過一些開源項(xiàng)目,在開源方面有一些經(jīng)驗(yàn),最近開到了阮老師的微博,深有感觸,現(xiàn)在一個(gè)開源項(xiàng)目涉及的東西確實(shí)挺多的,特別是對(duì)于新手來說非常不友好

最近我寫了一個(gè)jslib-base,旨在從多方面快速幫大家搭建一個(gè)標(biāo)準(zhǔn)的js庫,本文將已jslib-base為例,介紹寫一個(gè)開源庫的知識(shí)

jslib-base 最好用的js第三方庫腳手架,賦能js第三方庫開源,讓開發(fā)一個(gè)js庫更簡(jiǎn)單,更專業(yè)
文檔

所謂代碼未動(dòng),文檔先行,文檔對(duì)于一個(gè)項(xiàng)目非常重要,一個(gè)項(xiàng)目的文檔包括

README.md

TODO.md

CHANGELOG.md

LICENSE

doc

README.md

README是一個(gè)項(xiàng)目的門面,應(yīng)該簡(jiǎn)單明了的呈現(xiàn)用戶最關(guān)心的問題,一個(gè)開源庫的用戶包括使用者和貢獻(xiàn)者,所以一個(gè)文檔應(yīng)該包括項(xiàng)目簡(jiǎn)介,使用者指南,貢獻(xiàn)者指南三部分

項(xiàng)目簡(jiǎn)介用該簡(jiǎn)單介紹項(xiàng)目功能,使用場(chǎng)景,兼容性的相關(guān)知識(shí),這里重點(diǎn)介紹下徽章,相信大家都見過別人項(xiàng)目中的徽章,如下所示

徽章通過更直觀的方式,將更多的信息呈現(xiàn)出來,還能夠提高顏值,有一個(gè)網(wǎng)站專門制作各種徽章,可以看這里

這里有一個(gè)README的完整的例子

TODO.md

TODO應(yīng)該記錄項(xiàng)目的未來計(jì)劃,這對(duì)于貢獻(xiàn)者和使用者都有很重要的意義,下面是TODO的例子

- [X] 已完成
- [ ] 未完成
CHANGELOG.md

CHANGELOG記錄項(xiàng)目的變更日志,對(duì)項(xiàng)目使用者非常重要,特別是在升級(jí)使用版本時(shí),CHANGELOG需要記錄項(xiàng)目的版本,發(fā)版時(shí)間和版本變更記錄

## 0.1.0 / 2018-10-6

- 新增xxx功能
- 刪除xxx功能
- 更改xxx功能
LICENSE

開源項(xiàng)目必須要選擇一個(gè)協(xié)議,因?yàn)闆]有協(xié)議的項(xiàng)目是沒有人敢使用的,關(guān)于不同協(xié)議的區(qū)別可以看下面這張圖(出自阮老師博客),我的建議是選擇MIT或者BSD協(xié)議

doc

開源項(xiàng)目還應(yīng)該提供詳細(xì)的使用文檔,一份詳細(xì)文檔的每個(gè)函數(shù)介紹都應(yīng)該包括如下信息:

函數(shù)簡(jiǎn)單介紹

函數(shù)詳細(xì)介紹

函數(shù)參數(shù)和返回值(要遵守下面的例子的規(guī)則)

- param {string} name1 name1描述
- return {string} 返回值描述

舉個(gè)例子(要包含代碼用例)

// 代碼

特殊說明,比如特殊情況下會(huì)報(bào)錯(cuò)等
構(gòu)建

理想的情況如下:

庫開發(fā)者美滋滋的寫ES6+的代碼;

庫使用者能夠運(yùn)行在瀏覽器(ie6-11)和node(0.12-10)中

庫使用者能夠使用AMD或CMD模塊方案

庫使用者能夠使用webpack、rollup或fis等預(yù)編譯工具

理想很豐滿,現(xiàn)實(shí)很。。。,如何才能夠讓開發(fā)者和使用者都能夠開心呢,jslib-base通過babel+rollup提供了解決方案

編譯

通過babel可以把ES6+的代碼編譯成ES5的代碼,babel經(jīng)理了5到6的進(jìn)化,下面一張圖總結(jié)了babel使用方式的變遷

本文不討論babel的進(jìn)化史(后面會(huì)多帶帶開一片博文介紹),而是選擇最現(xiàn)代化的babel-preset-env方案,babel-preset-env可以通過提供提供兼容環(huán)境,而決定要編譯那些ES特性

其原理大概如下,首先通過ES的特性和[特性的兼容列表](http://kangax.github.io/compa...
)計(jì)算出每個(gè)特性的兼容性信息,再通過給定兼容性要求,計(jì)算出要使用的babel插件

首先需要安裝babel-preset-env

$ npm i --save-dev babel-preset-env

然后新增一個(gè).babelrc文件,添加下面的內(nèi)容

{
  "presets": [
    ["env",
    {
      "targets": {
        "browsers": "last 2 versions, > 1%, ie >= 6, Android >= 4, iOS >= 6, and_uc > 9",
        "node": "0.10"
      },
      "modules": false,
      "loose": false
    }]
  ]
}

targets中配置需要兼容的環(huán)境,關(guān)于瀏覽器配置對(duì)應(yīng)的瀏覽器列表,可以從browserl.ist上查看

modules表示編出輸出的模塊類型,支持"amd","umd","systemjs","commonjs",false這些選項(xiàng),false表示不輸出任何模塊類型

loose代表松散模式,將loose設(shè)置為true,能夠更好地兼容ie8以下環(huán)境,下面是一個(gè)例子(ie8不支持Object.defineProperty

// 源代碼
const aaa = 1;
export default aaa;


// loose false
Object.defineProperty(exports, "__esModule", {
    value: true
});
var aaa = 1;
exports.default = 1;


// loose true
exports.__esModule = true;
var aaa = 1;
exports.default = 1;

babel-preset-env解決了語法新特性的兼容問題,如果想使用api新特性,在babel中一般通過babel-polyfill來解決,babel-polyfill通過引入一個(gè)polyfill文件來解決問題,這對(duì)于普通項(xiàng)目很實(shí)用,但對(duì)于庫來說就不太友好了

babel給庫開發(fā)者提供的方案是babel-transform-runtime,runtime提供類似程序運(yùn)行時(shí),可以將全局的polyfill沙盒化

首先需要安裝babel-transform-runtime

$ npm i --save-dev babel-plugin-transform-runtime

在.babelrc增加下面的配置

"plugins": [
  ["transform-runtime", {
    "helpers": false,
    "polyfill": false,
    "regenerator": false,
    "moduleName": "babel-runtime"
  }]
]

transform-runtime,支持三種運(yùn)行時(shí),下面是polyfill的例子

// 源代碼
var a = Promise.resolve(1);

// 編譯后的代碼
var _promise = require("babel-runtime/core-js/promise");

var a = _promise.resolve(1); // Promise被替換為_promise

雖然雖然可以優(yōu)雅的解決問題,但是引入的文件非常之大,比如只用了ES6中數(shù)組的find功能,可能就會(huì)引入一個(gè)幾千行的代碼,我的建議對(duì)于庫來說能不用最好不用

打包

編譯解決了ES6到ES5的問題,打包可以把多個(gè)文件合并成一個(gè)文件,對(duì)外提供統(tǒng)一的文件入口,打包解決的是依賴引入的問題

rollup vs webpack

我選擇的rollup作為打包工具,rollup號(hào)稱下一代打包方案,其有如下功能

依賴解析,打包構(gòu)建

僅支持ES6模塊

Tree shaking

webpack作為最流行的打包方案,rollup作為下一代打包方案,其實(shí)一句話就可以總結(jié)二者的區(qū)別:庫使用rollup,其他場(chǎng)景使用webpack

為什么我會(huì)這么說呢?下面通過例子對(duì)比下webpack和rollup的區(qū)別

假設(shè)我們有兩個(gè)文件,index.js和bar.js,其代碼如下

bar.js對(duì)外暴漏一個(gè)函數(shù)bar

export default function bar() {
  console.log("bar")
}

index.js引用bar.js

import bar from "./bar";

bar()

下面是webpack的配置文件webpack.config.js

const path = require("path");

module.exports = {
    entry: "./src/index.js",
    output: {
        path: path.resolve(__dirname, "dist"),
        filename: "bundle.js"
    }
};

下面來看一下webpack打包輸出的內(nèi)容,o(╯□╰)o,別著急,我們的代碼在最下面的幾行,上面這一大片代碼其實(shí)是webpack生成的簡(jiǎn)易模塊系統(tǒng),webpack的方案問題在于會(huì)生成很多冗余代碼,這對(duì)于業(yè)務(wù)代碼來說沒什么問題,但對(duì)于庫來說就不太友好了

注意:下面的代碼基于webpack3,webpack4增加了scope hoisting,已經(jīng)把多個(gè)模塊合并到一個(gè)匿名函數(shù)中

/******/
(function(modules) { // webpackBootstrap
    /******/ // The module cache
    /******/
    var installedModules = {};
    /******/
    /******/ // The require function
    /******/
    function __webpack_require__(moduleId) {
        /******/
        /******/ // Check if module is in cache
        /******/
        if (installedModules[moduleId]) {
            /******/
            return installedModules[moduleId].exports;
            /******/
        }
        /******/ // Create a new module (and put it into the cache)
        /******/
        var module = installedModules[moduleId] = {
            /******/
            i: moduleId,
            /******/
            l: false,
            /******/
            exports: {}
            /******/
        };
        /******/
        /******/ // Execute the module function
        /******/
        modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
        /******/
        /******/ // Flag the module as loaded
        /******/
        module.l = true;
        /******/
        /******/ // Return the exports of the module
        /******/
        return module.exports;
        /******/
    }
    /******/
    /******/
    /******/ // expose the modules object (__webpack_modules__)
    /******/
    __webpack_require__.m = modules;
    /******/
    /******/ // expose the module cache
    /******/
    __webpack_require__.c = installedModules;
    /******/
    /******/ // define getter function for harmony exports
    /******/
    __webpack_require__.d = function(exports, name, getter) {
        /******/
        if (!__webpack_require__.o(exports, name)) {
            /******/
            Object.defineProperty(exports, name, {
                /******/
                configurable: false,
                /******/
                enumerable: true,
                /******/
                get: getter
                /******/
            });
            /******/
        }
        /******/
    };
    /******/
    /******/ // getDefaultExport function for compatibility with non-harmony modules
    /******/
    __webpack_require__.n = function(module) {
        /******/
        var getter = module && module.__esModule ?
            /******/
            function getDefault() { return module["default"]; } :
            /******/
            function getModuleExports() { return module; };
        /******/
        __webpack_require__.d(getter, "a", getter);
        /******/
        return getter;
        /******/
    };
    /******/
    /******/ // Object.prototype.hasOwnProperty.call
    /******/
    __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
    /******/
    /******/ // __webpack_public_path__
    /******/
    __webpack_require__.p = "";
    /******/
    /******/ // Load entry module and return exports
    /******/
    return __webpack_require__(__webpack_require__.s = 0);
    /******/
})
/************************************************************************/
/******/
([
    /* 0 */
    /***/
    (function(module, __webpack_exports__, __webpack_require__) {

        "use strict";
        Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
        /* harmony import */
        var __WEBPACK_IMPORTED_MODULE_0__bar__ = __webpack_require__(1);


        Object(__WEBPACK_IMPORTED_MODULE_0__bar__["a" /* default */ ])()


        /***/
    }),
    /* 1 */
    /***/
    (function(module, __webpack_exports__, __webpack_require__) {

        "use strict";
        /* harmony export (immutable) */
        __webpack_exports__["a"] = bar;

        function bar() {
            //
            console.log("bar")
        }


        /***/
    })
    /******/
]);

下面來看看rollup的結(jié)果,rollup的配置和webpack類似

export default {
    input: "src/index.js",
    output: {
        file: "dist/bundle2.js",
        format: "cjs"
    }
};

下面看看rollup的產(chǎn)出,簡(jiǎn)直完美有沒有,模塊完全消失了,rollup通過順序引入到同一個(gè)文件來解決模塊依賴問題,rollup的方案如果要做拆包的話就會(huì)有問題,因?yàn)槟K完全透明了,但這對(duì)于庫開發(fā)者來說簡(jiǎn)直就是最完美的方案

"use strict";

function bar() {
  //
  console.log("bar");
}

bar();
模塊化方案

在ES6模塊化之前,JS社區(qū)探索出了一些模塊系統(tǒng),比如node中的commonjs,瀏覽器中的AMD,還有可以同時(shí)兼容不同模塊系統(tǒng)的UMD,如果對(duì)這部分內(nèi)容感興趣,可以看我之前的一篇文章《JavaScript模塊的前世今生》

對(duì)于瀏覽器原生,預(yù)編譯工具和node,不同環(huán)境中的模塊化方案也不同;由于瀏覽器環(huán)境不能夠解析第三方依賴,所以瀏覽器環(huán)境需要把依賴也進(jìn)行打包處理;不同環(huán)境下引用的文件也不相同,下面通過一個(gè)表格對(duì)比下

瀏覽器(script,AMD,CMD) 預(yù)編譯工具(webpack,rollup,fis) Node
引用文件 index.aio.js index.esm.js index.js
模塊化方案 UMD ES Module commonjs
自身依賴 打包 打包 打包
第三方依賴 打包 不打包 不打包

*注意: legacy模式下的模塊系統(tǒng)可以兼容ie6-8,但由于rollup的一個(gè)[bug](https://github.com/rollup/rol...
)(這個(gè)bug是我發(fā)現(xiàn)的,但rollup并不打算修復(fù),╮(╯▽╰)╭哎),legacy模式下,不可同時(shí)使用 export 與 export default*

tree shaking

rollup是天然支持tree shaking,tree shaking可以提出依賴模塊中沒有被使用的部分,這對(duì)于第三方依賴非常有幫助,可以極大的降低包的體積

舉個(gè)例子,假設(shè)index.js只是用了第三方包is.js中的一個(gè)函數(shù)isString,沒有treeshaking會(huì)將is.js全部引用進(jìn)來

而使用了treeshaking的話則可以將is.js中的其他函數(shù)剔除,僅保留isString函數(shù)

規(guī)范

無規(guī)矩不成方圓,特別是對(duì)于開源項(xiàng)目,由于會(huì)有多人參與,所以大家遵守一份規(guī)范會(huì)事半功倍

編輯器規(guī)范

首先可以通過.editorconfig來保證縮進(jìn)、換行的一致性,目前絕大部分瀏覽器都已經(jīng)支持,可以看這里

下面的配置設(shè)置在js,css和html中都用空格代替tab,tab為4個(gè)空格,使用unix換行符,使用utf8字符集,每個(gè)文件結(jié)尾添加一個(gè)空行

root = true

[{*.js,*.css,*.html}]
indent_style = space
indent_size = 4
end_of_line = lf
charset = utf-8
insert_final_newline = true

[{package.json,.*rc,*.yml}]
indent_style = space
indent_size = 2
代碼風(fēng)格

其次可以通過eslint來保證代碼風(fēng)格一致,關(guān)于eslint的安裝和配置這里不再展開解釋了,在jslib-base中只需要運(yùn)行下面的命令就可以進(jìn)行代碼校驗(yàn)了,eslint的配置文件位于config/.eslintrc.js

$ npm run lint
設(shè)計(jì)規(guī)范

eslint只能夠保證代碼規(guī)范,卻不能保證提供優(yōu)秀的接口設(shè)計(jì),關(guān)于函數(shù)接口設(shè)計(jì)有一些指導(dǎo)規(guī)則

參數(shù)數(shù)量

函數(shù)的參數(shù)個(gè)數(shù)最多不要超過5個(gè)

可選參數(shù)

可選參數(shù)應(yīng)該放到后面

可選參數(shù)數(shù)量超過三個(gè)時(shí),可以使用對(duì)象傳入

可選參數(shù),應(yīng)該提供默認(rèn)值

參數(shù)校驗(yàn)與類型轉(zhuǎn)換

必傳參數(shù),如果不傳要報(bào)錯(cuò)

對(duì)下列類型要做強(qiáng)制檢驗(yàn),類型不對(duì)要報(bào)錯(cuò)(object, array, function)

對(duì)下列類型要做自動(dòng)轉(zhuǎn)換(number, string, boolean)

對(duì)于復(fù)合類型的內(nèi)部數(shù)據(jù),也要做上面的兩個(gè)步驟

對(duì)于number轉(zhuǎn)換后如果為NaN,要做特殊處理(有默認(rèn)值的賦值為默認(rèn)值,無默認(rèn)值的要報(bào)錯(cuò))

參數(shù)類型

參數(shù)盡量使用值類型(簡(jiǎn)單類型)

參數(shù)盡量不要使用復(fù)雜類型(避免副作用)

使用復(fù)雜類型時(shí),層級(jí)不要過深

使用復(fù)雜數(shù)據(jù)類型時(shí),應(yīng)該進(jìn)行深拷貝(避免副作用)

函數(shù)返回值

返回值可返回操作結(jié)果(獲取接口),操作是否成功(保存接口)

返回值的類型要保持一致

返回值盡量使用值類型(簡(jiǎn)單類型)

返回值盡量不要使用復(fù)雜類型(避免副作用)

版本規(guī)范

版本應(yīng)該遵守開源社區(qū)通用的[語義化版本](https://semver.org/lang/zh-CN/
)

版本號(hào)格式:x.y.z

x 主版本號(hào),不兼容的改動(dòng)

y 次版本號(hào),兼容的改動(dòng)

z 修訂版本號(hào),bug修復(fù)

Git commit規(guī)范

代碼的提交應(yīng)該遵守規(guī)范,這里推薦一個(gè)我的規(guī)范

測(cè)試

沒有單元測(cè)試的庫都是耍流氓,單元測(cè)試能夠保證每次交付都是有質(zhì)量保證的,業(yè)務(wù)代碼由于一次性和時(shí)間成本可以不做單元測(cè)試,但開源庫由于需要反復(fù)迭代,對(duì)質(zhì)量要求又極高,所以單元測(cè)試是必不可少的

關(guān)于單元測(cè)試有很多技術(shù)方案,其中一種選擇是[mocha](https://mochajs.org/
)+[chai](http://www.chaijs.com/
),mocha是一個(gè)單元測(cè)試框架,用來組織、運(yùn)行單元測(cè)試,并輸出測(cè)試報(bào)告;chai是一個(gè)斷言庫,用來做單元測(cè)試的斷言功能

由于chai不能夠兼容ie6-8,所以選擇了另一個(gè)斷言庫——expect.js,expect是一個(gè)BDD斷言庫,兼容性非常好,所以我選擇的是mocha+expect.js

關(guān)于BDD與TDD的區(qū)別這里不再贅述,感興趣的同學(xué)可以自行查閱相關(guān)資料

有了測(cè)試的框架,還需要寫單元測(cè)試的代碼,下面是一個(gè)例子

var expect = require("expect.js");

var base = require("../dist/index.js");

describe("單元測(cè)試", function() {
    describe("功能1", function() {
        it("相等", function() {
            expect(1).to.equal(1);
        });
    });
});

然后只需運(yùn)行下面的命令,mocha會(huì)自動(dòng)運(yùn)行test目錄下面的js文件

$ mocha

mocha支持在node和瀏覽器中測(cè)試,但上面的框架在瀏覽器下有一個(gè)問題,瀏覽器沒法支持require("expect.js"),我用了一個(gè)比較hack的方法解決問題,早瀏覽器中重新定義了require的含義



下面是用mocha生成測(cè)試報(bào)告的例子,左邊是在node中,右邊是在瀏覽器中

可持續(xù)集成

沒有可持續(xù)集成的庫都是原始人,如果每次push都能夠自動(dòng)運(yùn)行單元測(cè)試就好了,這樣就省去了手動(dòng)運(yùn)行的繁瑣,好在[travis-ci](https://www.travis-ci.org/
)已經(jīng)為我們提供了這個(gè)功能

用GitHub登錄travis-ci,就可以看到自己在GitHub上的項(xiàng)目了,然后需要打開下項(xiàng)目的開關(guān),才能夠打開自動(dòng)集成功能

第二步,還需要在項(xiàng)目中添加一個(gè)文件.travis.yml,內(nèi)容如下,這樣就可以在每次push時(shí)自動(dòng)在node 4 6 8版本下運(yùn)行npm test命令,從而實(shí)現(xiàn)自動(dòng)測(cè)試的目的

language: node_js
node_js:
  - "8"
  - "6"
  - "4"
其他內(nèi)容

開源庫希望得到用戶的反饋,如果對(duì)用戶提的issue有要求,可以設(shè)置一個(gè)模版,用來規(guī)范github上用戶反饋的issue需要制定一些信息

通過提供.github/ISSUE_TEMPLATE文件可以給issue提供模版,下面是一個(gè)例子,用戶提issue時(shí)會(huì)自動(dòng)帶上如下的提示信息

### 問題是什么
問題的具體描述,盡量詳細(xì)

### 環(huán)境
- 手機(jī): 小米6
- 系統(tǒng):安卓7.1.1
- 瀏覽器:chrome 61
- jslib-base版本:0.2.0
- 其他版本信息

### 在線例子
如果有請(qǐng)?zhí)峁┰诰€例子

### 其他
其他信息
jsmini

jsmini是基于jslib-base的一系列庫,jsmini的理念是小而美,并且無第三方依賴,開源了很多能力,能夠
助力庫開發(fā)者

總結(jié)

五年彈指一揮間,本文總結(jié)了自己做開源項(xiàng)目的一些經(jīng)驗(yàn),希望能夠幫助大家,所有介紹的內(nèi)容都可以在jslib-base里面找到

jslib-base是一個(gè)拿來即用腳手架,賦能js第三方庫開源,快速開源一個(gè)標(biāo)準(zhǔn)的js庫

最后再送給大家一句話,開源一個(gè)項(xiàng)目,重在開始,貴在堅(jiān)持

最后推薦下我的新書《React狀態(tài)管理與同構(gòu)實(shí)戰(zhàn)》,深入解讀前沿同構(gòu)技術(shù),感謝大家支持

京東:https://item.jd.com/12403508.html

當(dāng)當(dāng):http://product.dangdang.com/25308679.html

最后最后招聘前端,后端,客戶端啦!地點(diǎn):北京+上海+成都,感興趣的同學(xué),可以把簡(jiǎn)歷發(fā)到我的郵箱: yanhaijing@yeah.net

原文網(wǎng)址:http://yanhaijing.com/javascr...

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/98176.html

相關(guān)文章

  • CloudBest:度復(fù)盤丨盤點(diǎn)2020無處不在「云原生」

    摘要:華為云華為云在云原生這場(chǎng)游戲中,最具競(jìng)爭(zhēng)力的玩家之一。年,金山云在云原生領(lǐng)域推出了三款重磅產(chǎn)品星曜裸金屬服務(wù)器云服務(wù)器和云盤。在線上智博會(huì)上,浪潮云發(fā)布了經(jīng)過全新迭代升級(jí)的浪潮云,進(jìn)一步提升平臺(tái)云原生服務(wù)能力。面對(duì)數(shù)字時(shí)代復(fù)雜系統(tǒng)的不確定性,傳統(tǒng)的 IT 應(yīng)用架構(gòu)研發(fā)交付周期長、維護(hù)成本高、創(chuàng)新升級(jí)難,煙囪式架構(gòu),開放性差、組件復(fù)用度低,這些都成為了企業(yè)業(yè)務(wù)快速增長的瓶頸。而云原生以其敏捷、...

    Tecode 評(píng)論0 收藏0
  • 關(guān)于JavaScript, NPM官方發(fā)布了2018回顧以及2019預(yù)測(cè)

    摘要:不過,根據(jù)伯克利大學(xué)的這篇文章來看,擁有豐富的開源庫,是開發(fā)者在選擇一門開發(fā)語言時(shí),最重要的因素。擁有超過個(gè)可用的開源庫,是目前世界上最大的開源庫集合。月份,我們發(fā)布了。這和年的情況是相反的。在的調(diào)查中,超過的受訪者表示他們正在使用。 showImg(https://segmentfault.com/img/bVblvke?w=693&h=300); 原文標(biāo)題:This year in...

    dadong 評(píng)論0 收藏0
  • 前端每周清單半盤點(diǎn)之 JavaScript

    摘要:前端每周清單專注前端領(lǐng)域內(nèi)容,以對(duì)外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點(diǎn)分為新聞熱點(diǎn)開發(fā)教程工程實(shí)踐深度閱讀開源項(xiàng)目巔峰人生等欄目。背后的故事本文是對(duì)于年之間世界發(fā)生的大事件的詳細(xì)介紹,闡述了從提出到角力到流產(chǎn)的前世今生。 前端每周清單專注前端領(lǐng)域內(nèi)容,以對(duì)外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點(diǎn);分為新聞熱點(diǎn)、開發(fā)教程、工程實(shí)踐、深度閱讀、開源項(xiàng)目、巔峰人生等欄目。歡迎...

    Vixb 評(píng)論0 收藏0
  • 持續(xù)擁抱云原生,現(xiàn)代化應(yīng)用將把云計(jì)算帶進(jìn)怎樣“新世界”?_云資訊

    摘要:全球云計(jì)算廠商躬身入局,開啟現(xiàn)代化應(yīng)用之旅事實(shí)上,包括亞馬遜云科技華為云在內(nèi)的全球云計(jì)算廠商已在這一領(lǐng)域進(jìn)行了多年實(shí)踐。過去年,亞馬遜云科技一直在持續(xù)不斷地突破很多現(xiàn)代化應(yīng)用技術(shù)。年,亞馬遜云科技發(fā)布第一個(gè)消息隊(duì)列的服務(wù),至今已有年歷史。 2006年,是云計(jì)算滾滾浪潮的開端,這場(chǎng)IT技術(shù)變革始于亞馬遜AWS的成立,它讓公有云成為整個(gè)云行業(yè)的標(biāo)桿,也形成了...

    RyanQ 評(píng)論0 收藏0
  • 前端每周清單:Node.js 微服務(wù)實(shí)踐,Vue.js 與 GraphQL,Angular 組件技巧

    摘要:前端每周清單第期微服務(wù)實(shí)踐,與,組件技巧,攻防作者王下邀月熊編輯徐川前端每周清單專注前端領(lǐng)域內(nèi)容,以對(duì)外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點(diǎn)分為新聞熱點(diǎn)開發(fā)教程工程實(shí)踐深度閱讀開源項(xiàng)目巔峰人生等欄目。 前端每周清單第 26 期:Node.js 微服務(wù)實(shí)踐,Vue.js 與 GraphQL,Angular 組件技巧,HeadlessChrome 攻防 作者:王下邀月熊 編輯:徐川...

    wall2flower 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<