JSON轉換類型 — quicktype按需編譯

點擊在線體驗        github

一點廢話

quicktype是一個開源的強大的數據轉換工具。支持c#,ts,js,golang,java...多達18種開箱即用的語言支持,若是沒有您想要要的語言,還能夠在原有項目上自行實現。java

quicktype主要是將json,typescript class,postman,mutiple json,json schame數據轉換爲typescript 的interface, golang的struct格式。方便開發人員快速生成代碼。node

因爲quicktype官方提供的開箱工具太過龐大(3.5MB),打算使用源碼自行編譯,去掉不須要的功能。
通過屢次實驗,發現去掉typescript class to typescript interface功能性價比最高。一方面是去掉此功能後文件大小減至1M不到,二是此功能我的感受比較雞肋。webpack

quicktype已經有了vscode插件,自行在vsocde插件庫搜索便可。 git

若是你以爲官方的vscode插件很差用想要本身定製(像我同樣),那麼繼續往下看github

若是你是強迫症。追求極致,能夠經過禁用你不須要的語言選項來進一步縮小代碼。 golang

一般我不建議禁用其餘語言的方案來得到更小的代碼體積,本人只保留了ts,js,golang三種語言,源碼也只是從950K縮小到了709k,雖然少了240K,可是喪失了多達15種語言的支持,有點得不償失。固然具體根據我的需求實現。web

開幹

這裏使用的是webpack 4 。 其實構建庫,最好的構建工具是rollup。無奈本人折騰了兩天,rollup始終沒法獲得滿意結果,(主要是import和require混用致使的)。最後回退到了webpack。不事後來發現,webpack打包後的文件,其實也就比rollup大一丟丟。可是沒有那麼多糟心的錯誤。typescript

獲取源碼安裝依賴npm

git clone https://github.com/quicktype/quicktype.git
//then
npm i
//then 
npm i -D  webpack ts-loader terser-webpack-plugin
touch webpack.config.js
複製代碼

webpack配置json

const path = require('path');
const TerserPlugin = require('terser-webpack-plugin');

module.exports = {
    mode: 'production',
    entry: './src/index.ts',
    // target: "node",
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'qt_lib.js',
        library: "QT",
        libraryTarget: 'umd', //umd是通用模塊,可同時知足 commonjs,AMD,es模塊
        globalObject: "this"  //防止global windows not defined 這類錯誤
    },
    //此處防止編譯出現奇怪的模塊找不到錯誤
    node: { crypto: true, stream: true, fs: 'empty', net: 'empty' },
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                use: {
                    loader: 'ts-loader',
                    options: {
                        transpileOnly: true
                    }
                },
                exclude: /node_modules/,
            },
        ],
    },
    resolve: {
        extensions: ['.tsx', '.ts', '.js'],
    },
    optimization: {
        minimize: true,
        minimizer: [new TerserPlugin()],
    },
};
複製代碼

建立入口文件

cd src/
touch index.ts
複製代碼

index.ts代碼

import * as qt from "./quicktype-core";

class SSS extends qt.JSONSchemaStore {
    fetch(e: any) {
        return Promise.resolve(undefined)
    }
}

export default async function (config: any) {
    let o: any
    switch (config.sourceType) {
        case "JSON Schema":
            o = new qt.JSONSchemaInput(new SSS)
            for (const item of config.sources) {
                await o.addSource({
                    name: item.topLevelName,
                    schema: item.samples[0].source
                });
            }
            break;

        default:
            o = qt.jsonInputForTargetLanguage(config.options.lang);
            for (const item of config.sources) {
                await o.addSource({
                    name: item.topLevelName,
                    samples: item.samples.map((e: any) => e.source),
                    description: item.description
                });
            }
            break;
    }
    config.options.inputData = new qt.InputData
    config.options.inputData.addInput(o)
    return qt.quicktype(config.options)
}

複製代碼

執行

node .\node_modules\webpack\bin\webpack.js
//一次基本不會成功,自行根據TS報錯修復相關的地方,有些是類型不對,直接找到源頭使用 any (anyscript大法好 -_-)
複製代碼

使用方法
commonjs: const qt = require("qt_lib").default
esmodule: import qt from "qt_lib"
browser: script導入後,使用全局變量QT便可。

測試
建立test.js , 代碼以下

const qt = require('../dist/qt_lib.js').default;
const config = {
    "options": {
        "lang": "TypeScript",
        "inferMaps": true,
        "inferEnums": true,
        "inferUuids": true,
        "inferDateTimes": true,
        "inferIntegerStrings": true,
        "inferBooleanStrings": true,
        "combineClasses": true,
        "ignoreJsonRefs": true,
        "allPropertiesOptional": false,
        "rendererOptions": {
            "just-types": true,
            "nice-property-names": false,
            "explicit-unions": false,
            "runtime-typecheck": false,
            "acronym-style": "lowerCase",
            "converters": "all-objects"
        },
        "fixedTopLevels": false
    },
    "sourceType": "JSON",
    "sources": [
        {
            "topLevelName": "Welcome",
            "samples": [
                {
                    "name": "welcome.json",
                    "source": "{\n \"greeting\": \"Welcome to quicktype!\",\n \"instructions\": [\n \"Type or paste JSON here\",\n \"Or choose a sample above\",\n \"quicktype will generate code in your\",\n \"chosen language to parse the sample data\"\n ]\n}"
                }
            ]
        }
    ],
    "receipt": -3942854747
}


qt(config).then(rs => console.log(rs.lines.join("\n")))


複製代碼
node test.js
複製代碼

output:

export interface Welcome {
    greeting:     string;
    instructions: string[];
}
複製代碼

大功告成。 QQ交流羣號:6533416

相關文章
相關標籤/搜索