README.MD

    SDK开发

    本文讲讲如何进行SDK的开发与编译,以及如何进行ak的验证以及插件的引用。

    涉及技术点

    • express
    • jsdoc
    • rollup

    一、初始化工程

    1. 初始化项目

    新建目录,初始化工程

    # 新建目录
    mkdir sdk-demo && cd ./sdk-demo
    # 初始化工程
    npm init -y

    创建如下目录和文件

    └─config                            // 配置相关
        └─app.js                        // app配置,主要为启动参数
        └─jsdoc.config.js               // jsdoc配置文件
        └─rollup.config.dev.js          // rollup开发配置文件
        └─rollup.config.js              // rollup配置文件
    └─src
        └─utils                         // 工具类
            └─file.js                   // 文件操作工具类
        └─lzugis-map.js                 // SDK主文件 
    └─app.js                            // 服务入口文件

    2. 添加依赖

    修改package.json文件,并执行命令npm i安装依赖。

    {
      ...,
      "dependencies": {
        "express": "~4.16.1"
      },
      "devDependencies": {
        "@babel/core": "^7.14.8",
        "@babel/preset-env": "^7.14.8",
        "@rollup/plugin-commonjs": "^19.0.2",
        "@rollup/plugin-json": "^4.1.0",
        "@rollup/plugin-node-resolve": "^13.0.4",
        "jsdoc": "^3.6.11",
        "rollup": "^2.55.0",
        "rollup-obfuscator": "^3.0.1",
        "rollup-plugin-babel": "^4.4.0",
        "rollup-plugin-livereload": "^2.0.5",
        "rollup-plugin-serve": "^1.1.0",
        "rollup-plugin-uglify": "^6.0.4"
      }
    }

    二、配置文件修改

    1. 修改rollup.config.dev.js

    import babel from 'rollup-plugin-babel'
    import resolve from '@rollup/plugin-node-resolve'
    import commonjs from '@rollup/plugin-commonjs'
    import serve from 'rollup-plugin-serve'
    import livereload from 'rollup-plugin-livereload'
    
    export default {
      input: "./src/lzugis-map.js",
      output: [
        {
          file: './dist/lzugis-map.js',
          name: 'LzugisMap',
          format: 'umd',
          sourcemap: false
        }
      ],
      plugins: [
        serve({
          contentBase: 'dist', // 服务器启动的文件夹,默认是项目根目录
          port: 18080 // 端口号
        }),
        livereload('dist'), // 监听dist目录
        babel({
          exclude: 'node_modules/**'
        }),
        resolve(),
        commonjs()
      ]
    }

    开发时文件,在dist目录下添加index.html文件,引用lzugis-map.js,方便开发时调试。

    2. 修改rollup.config.js

    import babel from 'rollup-plugin-babel'
    import resolve from '@rollup/plugin-node-resolve'
    import commonjs from '@rollup/plugin-commonjs'
    import { obfuscator } from 'rollup-obfuscator';
    import { uglify } from 'rollup-plugin-uglify'
    
    export default {
      input: "./src/lzugis-map.js",
      output: [
        {
          file: './dist/lzugis-map.min.js',
          name: 'LzugisMap',
          format: 'umd',
          sourcemap: false
        }
      ],
      plugins: [
        babel({
          exclude: 'node_modules/**'
        }),
        resolve(),
        commonjs(),
        obfuscator(),
        // js 压缩插件,需要在最后引入
        uglify()
      ]
    }

    打包时配置文件,将sdk进行压缩和混淆处理。

    3. 修改jsdoc.config.js

    'use strict'
    module.exports = {
      'tags': {
        'allowUnknownTags': false
      },
      'source': {
        'include': ['./src'],
        'includePattern': '.+\\lzugis-map.js',
        'excludePattern': '(^|\\/|\\\\)_'
      },
      'plugins': ['plugins/markdown'],
      'recurseDepth': 10,
      "templates": {
        "cleverLinks": true,
        "monospaceLinks": true,
        "default": {
          "outputSourceFiles" : true
        },
        "applicationName": "LZUGIS SDK",
        "openGraph": {},
        "meta": false
      },
      opts: {
        // 文档输出路径
        destination: './public/docs',
        encoding: 'utf8',
        private: true,
        recurse: true,
        template: './doc-template',
        readme: './README-SDK.MD'
      }
    }

    API文档生成配置文件,包括生成路径、使用模板等参数。

    4. 修改package.json文件,添加执行命令

    {
      ...,
      "scripts": {
        "server:dev": "node ./app.js",
        "server": "pm2 start ./app.js",
        "lib:dev": "rollup -wc ./config/rollup.config.dev.js",
        "lib": "rollup -c ./config/rollup.config.js",
        "doc": "./node_modules/.bin/jsdoc -c ./config/jsdoc.config.js"
      }
    }

    三、SDK实现与编译

    1. SDK实现

    为测试功能,修改lzugis-map.js内容如下:

    class LzugisMap {
      /**
       * @class LzugisMap
       * @classdesc lzugis 地图SDK
       * @param {Object} [options] - 地图初始化参数
       * @param {String | Dom} [options.element = 'map'] - 地图容器
       * @param {Number} [options.zoom = 4] - 地图初始化级别
       * @param {Array<Number>} [options.center = [0, 0]] - 地图初始化中心点
       */
      constructor(options) {
        this.options = {
          element: 'map',
          zoom: 4,
          center: [0, 0],
          ...options
        }
      }
    }
    
    module.exports = LzugisMap

    2. 开发

    执行命令npm run lib:dev,修改dist/index.html文件内容如下:

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>LzugisMap Demo</title>
      <style>
          .map {
              height: 100vh;
          }
      </style>
    </head>
    <body>
    <div class="map" id="map"></div>
    <script src="./lzugis-map.js"></script>
    <script>
      const map = new LzugisMap({
        element: 'map',
        zoom: 3,
        center: [0, 0]
      })
    </script>
    </body>
    </html>

    2. SDK和文档编译

    执行命令npm run lib编译生成SDK,指定命令npm run doc,编译生成文档。

    四、AK与插件

    AK控制,一方面是为了控制申请了的用户才能使用我们的SDK,另一方面也是为了监控SDK的使用情况。为了能够实现 AK的监控,一般是由一个对应的“开放平台”或者“AK管控平台”,提供AK的申请和审核等。其实现逻辑是客户端传入AK, 服务端进行校验,如果AK合规,则返回完整的js,如果不合规,则返回错误提示。

    插件的实现是客户端传入需要调用的插件,服务端先进行AK校验,通过之后再将完整的js和插件的js合城一个js返回给客户端使用。

    1. app.js

    本文通过node来实现上述的逻辑,修改app.js文件如下:

    const express = require('express');
    const config = require('./config/app')
    const fileUtil = require('./src/utils/file')
    
    const app = express();
    
    // 自定义跨域中间件
    const allowCors = function (req, res, next) {
      res.header('Access-Control-Allow-Origin', req.headers.origin);
      res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
      res.header('Access-Control-Allow-Headers', 'Content-Type');
      res.header('Access-Control-Allow-Credentials', 'true');
      res.header('Cache-Control', 'public, max-age=604800')
      next();
    };
    app.use(allowCors);
    
    // 设置静态资源访问
    const options = {
      index: "index.html",
      redirect: false,
      setHeaders: function (res, path, stat) {
        res.set('x-timestamp', Date.now())
      }
    }
    app.use(express.static('./public', options))
    
    app.get('/api/map', function (req, res) {
      let {ak, plugins} = req.query
      plugins = plugins || ''
      const errorJs = fileUtil.readFile('./dist/error.js')
      let sdkJs = fileUtil.readFile(`./dist/lzugis-map.min.js`)
      res.type('application/x-javascript;charset=UTF-8');
      // AK验证
      if(ak !== '844e6d3a9cc34cds398e12fae047d6') {
        res.send(errorJs);
      } else {
        plugins = plugins.split(',').filter(v => Boolean(v))
        plugins.forEach(plugin => {
          sdkJs += `\r\n/*${plugin} plugin*/\r\n` + fileUtil.readFile(`./dist/plugins/${plugin}.plugin.min.js`)
        })
        res.send(sdkJs);
      }
    })
    
    // 启动服务
    app.listen(config.port, () => {
      console.log(`服务已启动,访问地址为:http://${config.url}`)
    })

    前端可以通过地址http://localhost:18081/api/map?ak=您申请的ak&plugins=admin进行SDK的调用。 error.js是一个错误提示文件,其内容如下:

    if(window.console&&window.console.error){
      window.console.error("<LzugisMap API> Sorry, valid ak required.");
    }

    通过命令npm run server:dev可进行开发调试,如需要服务端部署,可借助pm2进行服务的启动与监控,可运行命令npm run server

    项目简介

    SDK开发demo

    发行版本

    当前项目没有发行版本

    贡献者 2

    牛老师讲GIS @GISShiXiSheng
    0 01416068 @01416068

    开发语言

    • JavaScript 48.0 %
    • HTML 44.6 %
    • CSS 7.4 %