What does the SDK really stand for in terms of the front end? My understanding is that SDK is the integration of development tools specific to a platform, a system, or a software, which can include multiple apis or just a programming tool

1. The type of the SDK

The JS-SDK of an application can be divided into the following three categories

  • Web API collection (similar to the official jS-SDK tool of wechat)
  • Analysis and statistics tools (similar to Baidu statistics JS-SDK tool)
  • Embedded types are widgets

2. How to design

By developing a KSDK (JS-SDK), according to the current browser environment or manual matching, to identify the called third party SDK (Dingding, enterprise wechat, Cloud home)

2.1 Develop the document catalog

  • Enterprise WeChat: work.weixin.qq.com/api/doc/900…
  • Nailing: ding-doc.dingtalk.com/doc#/dev/we…
  • The home of cloud: open.yunzhijia.com/openplatfor…

2.2 Design Mode

There are several common JS design patterns

  • Singleton: a class returns only one instance, once created and called again (e.g. JQuery, Lodash, Moment, etc.)
  • Constructor pattern
  • Hybrid mode: prototype mode + constructor mode
  • The factory pattern
  • Publish and subscribe model

Since the abstract factory design pattern is suitable for multiple product class clusters in the system and only one of them is used at a time, it is suitable to use the abstract factory design pattern to encapsulate KSDK

Abstract factory design patterns do not generate instances directly, but are used to create clusters of product classes. SDK uses different third party JS-SDK to register, such as: Dingding, enterprise wechat, Cloud home and so on. Then these three tools are the corresponding class clusters. In the abstract factory, it actually consists of several subtypes, and when creating an SDK class instance, it determines which subclass to use, and then creates an instance of that subclass and returns it to you

// Factory design patternfunction SDKFactory(type) {
    if(this instanceof SDKFactory) {
      return new this[type] (); }else {
      return new SDKFactory(type);
    }
  }
  SDKFactory.prototype = {
    YUNZHIJIA: function() {
      this.jsApi = 'https://static.yunzhijia.com/public/js/qing/latest/qing.js'
      this.init = function () {
        qing.config({});
      };
      //
      this.getInfo = function (fn) {
        qing.call('getPersonInfo', {
          success: function(res) { fn(); }}); }; this.getVersion =function () {
        return qing.version;
      };
    },
     DINGDING: function() {
      this.jsApi = 'https://g.alicdn.com/dingding/dingtalk-jsapi/2.7.13/dingtalk.open.js'
      this.init = function (fn) {
        dd.ready(function () {
          fn();
        });
      };
      this.getInfo = function (fn) {
  
      };
      this.getVersion = function () {
        return dd.version;
      };
    },
     WEIXINWORKSDK: function() {
    this.jsApi = 'http://res.wx.qq.com/open/js/jweixin-1.2.0.js'
    this.init = function (fn) {
      wx.config({beta: true, debug: true});
      wx.ready(function () {
        fn();
      });
    };
    this.getVersion = function() {}; }}Copy the code

Before using the KSDK method, the corresponding third-party JS resources need to be loaded successfully, and the loading mode is asynchronous loading

Consider that when you use asynchronous loading, the function in the page will not be able to call the SDK method properly. That is, when the call occurs before the script is loaded, how to wrap the SDK to execute properly? Let’s talk about script synchronization versus asynchrony.

  • Synchronous mode: Script tags do not defer or async properties, script fetch and execution are synchronous, the page is blocked and the browser parses and loads

  • Asynchronous mode: The

  • The difference between defer and async: defer means “execute after rendering” while async means “execute after downloading”. The difference between async and defer is that the script will be executed automatically after the async loading is complete, while the code will be executed only after the page has been loaded

 function initScript(src, params = {}, fn) {
    const script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = src;
    if (script.addEventListener) {
      script.addEventListener('load'.function () {
        fn();
      }, false);
    }
    document.head.appendChild(script);
  }
Copy the code

The KSDK constructor supports the identification of which subclass should be used after the type is passed in, and then asynchronously loads the JS file of the third party SDK, and finally completes the initialization through the prototype chain inheritance.

 (function () {
 
  'use strict'; / / for manual configuration type const scriptDOM = document. The getElementsByTagName ("script"), [scriptDetail] = scriptDOM, URL = scriptDetail.src,
  type = URL.match(new RegExp("(? : \ \? | &)" + 'type' + "= (. *?) (? = & | $)"))[1], domain = document.domain; // Integrate tool objectsfunction KSDK() {
  this.domain = domain;
  this.ready = function(fn) {// dynamically load const that = this;let sdkFac;
    try {
      sdkFac = SDKFactory(type || this.domain);
    } catch (e) {
      console.log('This type of SDK is not supported')}if (sdkFac) {
      initScript(sdkFac.jsApi, {
        async: true,
        defer: true,},function () {
        that.__proto__ = sdkFac;
        that.init(function() { fn(); }); }); }}; } window.ksdk = new KSDK(); })(window);Copy the code

2.3 How to Use it

The introduction of the SDK

<script src="kdsk.min.js? type=DINGDING"></script>
<script type="text/javascript">
  window.ksdk.ready(function () {
    window.ksdk.getVersion(function () {

    })
  })
</script>
Copy the code

2.4 Version Management

In general, we have different ways to declare SDK versions, depending on the business and design for which we are addressing them. There are three common types of version management:

  • Use the query string path: http://xxx.com/sdk.js?v=1.0.0

  • Use folder named: http://xxx.com/v1.0.0/sdk.js

  • Use the host name or subdomain http://v1.xxx.com/sdk.js

This project uses the folder naming method, combined with aliyun object storage service OSS (with CDN acceleration)

3. How to pack

Package is an essential process for the launch of SDK. Rollup is used as a package tool for the project. Rollup puts all resources in the same place and loads them at one time. Rollup always produces smaller, faster packages. Official link: www.rollupjs.com

3.1 a Rollup

Rollup is more suitable for packaging JS SDK or packaged framework. Compared with the familiar Webpack, rollup is more suitable for packaging some applications, such as SPA or isomorphic projects

3.2 a Rollup configuration

  • Write a rollup. Config. Js
import resolve from 'rollup-plugin-node-resolve';
import json from 'rollup-plugin-json';
import commonjs from "rollup-plugin-commonjs";
import babel from 'rollup-plugin-babel';

export default {
  input: 'src/index.js',
  format: 'iife',
  output: {
    file: 'dist/kdsk.min.js',
    format: 'iife'}, plugins: [resolve(), //rollup-plugin-node-resolve tells rollup how to find external json() modules. Commonjs () // converts CommonJS to ES2015 modules.  babel({ exclude:'node_modules/**',}), // need to create.babelrc file writing rules]}Copy the code

🚀 Runtime environment supported by packaged files (format)

  • Amd – Asynchronous module definition for module loaders like RequireJS
  • CJS — CommonJS, for Node and Browserify/Webpack
  • Iife – an auto-executing feature, suitable as<script>The label
  • Umd – Common module definition, amd, CJS and IIFE all in one

Only script is currently supported, and packaging is in iIFE (execute function expression mode now) format, which adds closures to function scope to avoid variable contamination

(function () {
  
}());
Copy the code

3.3 run

rollup -c
Copy the code

Please point to 👏 if you have any questions