.6-淺析webpack源碼之validateSchema模塊

来源:http://www.cnblogs.com/QH-Jimmy/archive/2017/12/13/8034301.html
-Advertisement-
Play Games

validateSchema模塊 首先來看錯誤檢測: 可以註意到,這裡傳了兩個參數,其實第一個參數來源於一個JSON文件: 這個JSON文件非常大,可以觀察一下部分內容: 從描述可以猜測,這裡的key對應options中的key,value就是檢測方式。 比如說entry放到required代表是必 ...


validateSchema模塊

 

  首先來看錯誤檢測:

    const webpackOptionsValidationErrors = validateSchema(webpackOptionsSchema, options);
    if(webpackOptionsValidationErrors.length) {
        throw new WebpackOptionsValidationError(webpackOptionsValidationErrors);
    }

  可以註意到,這裡傳了兩個參數,其實第一個參數來源於一個JSON文件:

    const webpackOptionsSchema = require("../schemas/webpackOptionsSchema.json");

  這個JSON文件非常大,可以觀察一下部分內容:

{
    "plugins": {
    "description": "Add additional plugins to the compiler.",
    "type": "array"
    },
    "resolve": {
    "description": "Options for the resolver",
    "anyOf": [
        {
        "$ref": "#/definitions/resolve"
        }
    ]
    },
    "required": [
      "entry"
    ],
    "type": "object"
}

  從描述可以猜測,這裡的key對應options中的key,value就是檢測方式。

  比如說entry放到required代表是必須的,plugins的type為array代表這個鍵必須是一個數組,而$ref代表一個路徑映射,即#/definnitions/resolve。

  在JSON文件的開頭有一個definitions,其中resolve對應的內容如下:

{
    "definitions": {
        "resolve": {
            "additionalProperties": false,
            "properties": {
                "alias": {
                    // ...
                }
                // ...
            },
            "type": "object"
        }
    }
}

  簡單明瞭,就不多解釋了。

 

  下麵進入validateSchema模塊,流程如圖:

  

  內部代碼簡化如下:

const Ajv = require("ajv");
const ajv = new Ajv({
    errorDataPath: "configuration",
    allErrors: true,
    verbose: true
});
require("ajv-keywords")(ajv, ["instanceof"]);
require("../schemas/ajv.absolutePath")(ajv);

function validateSchema(schema, options) {
    // 仍然是多配置與單配置
    if(Array.isArray(options)) { /*...*/ } 
    else {
        return validateObject(schema, options);
    }
}

function validateObject(schema, options) {
    // 轉換JSON文件
    const validate = ajv.compile(schema);
    // 檢測配置對象
    const valid = validate(options);
    // 返回錯誤對象
    return valid ? [] : filterErrors(validate.errors);
}

function filterErrors(errors) { /*...*/ }
module.exports = validateSchema;

  這裡引入的ajv模塊是一個工具,就像之前的JSON5一樣,作用是將一個JSON配置文件轉換成一個對象,用於檢測對象的合法性。

  在github上,該工具的Getting started如圖所示:

  

  簡直跟源碼中的使用過程一模一樣,所以有興趣的可以自己去看看教程學一下。

  

  由於JSON十分巨大,所以編譯後的對象也十分巨大,這裡根據vue腳手架中的配置,只看常規的參數是如何進行檢測的,比如說devServer、devtool、entry、module、output、plugins、resolve,測試代碼如下:

var Ajv = require('ajv');
const ajv = new Ajv({
    errorDataPath: "configuration",
    allErrors: true,
    verbose: true
});
// 簡化後的JSON文件
const json = require('./tmp.json');
const validate = ajv.compile(json);

  打包後嘗試獲取生成的validate函數,整理後源碼如下:

(function(self, RULES, formats, root, refVal, defaults, customRules, co, equal, ucs2length, ValidationError) {
    var refVal0 = refVal[0];
    // ...
    var refVal13 = refVal[13];
    var validate = (function(data, dataPath, parentData, parentDataProperty, rootData) {
        'use strict';
        // 負責收集錯誤信息
        var vErrors = null;
        // 負責對錯誤進行計數
        var errors = 0;
        if (rootData === undefined) rootData = data;
        // 這是根級對象
        if ((data && typeof data === "object" && !Array.isArray(data))) {
            var errs__0 = errors;
            var valid1 = true;
            for (var key0 in data) { /*...*/ }
            // 在這裡進行檢測
            // 每出現一個錯誤errors+1並記錄vErrors中
            var data1 = data.devServer;
            if (data1 !== undefined) { /*...*/ }
            var data1 = data.devtool;
            if (data1 !== undefined) { /*...*/ }
            var data1 = data.entry;
            if (data1 === undefined) { /*...*/ } 
            else { /*...*/ }
            var data1 = data.module;
            if (data1 !== undefined) { /*...*/ }
            var data1 = data.output;
            if (data1 !== undefined) { /*...*/ }
            var data1 = data.plugins;
            if (data1 !== undefined) { /*...*/ }
            var data1 = data.resolve;
            if (data1 !== undefined) { /*...*/ }
        } else { /*...*/ }
        validate.errors = vErrors;
        // 判斷是否產生錯誤
        return errors === 0;
    });
    return validate;
})

  調用validate(options),options在函數中就相當於那個data,validate會依次從data中取出需要校驗的key,按照JSON文件中的規則進行判斷。

  這裡有一個比較麻煩的點,就是頂部的refVal,由於這是一個內部的IIFE,所以從這裡看不出refVal數組如何定義的。憑藉我的聰明才智,還是從源碼中獲取到了對應的定義:

  

  打開後,其實是一堆validate函數,所以就不展開看了。

  其實validate並不只有這麼多,其中還可以分為特殊校驗器和公共校驗器,其中公共校驗器不會針對特殊的鍵來進行校驗,在這裡可以先列出來。(友情警告:千萬不要點開!!!)

 

refVal1

        if ((data && typeof data === "object" && !Array.isArray(data))) {
            if (Object.keys(data).length < 1) {
                var err = { keyword: 'minProperties', dataPath: (dataPath || '') + "", schemaPath: '#/oneOf/0/minProperties', params: { limit: 1 }, message: 'should NOT have less than 1 properties', schema: 1, parentSchema: validate.schema.oneOf[0], data: data };
                if (vErrors === null) vErrors = [err];
                else vErrors.push(err);
                errors++;
            }
            var errs__1 = errors;
            var valid2 = true;
            for (var key1 in data) {
                var data1 = data[key1];
                var errs_2 = errors;
                var errs__2 = errors;
                var prevValid2 = false;
                var valid2 = false;
                var errs_3 = errors;
                if (typeof data1 === "string") {
                    if (ucs2length(data1) < 1) {
                        var err = { keyword: 'minLength', dataPath: (dataPath || '') + '[\'' + key1 + '\']', schemaPath: '#/oneOf/0/additionalProperties/oneOf/0/minLength', params: { limit: 1 }, message: 'should NOT be shorter than 1 characters', schema: 1, parentSchema: validate.schema.oneOf[0].additionalProperties.oneOf[0], data: data1 };
                        if (vErrors === null) vErrors = [err];
                        else vErrors.push(err);
                        errors++;
                    }
                } else {
                    var err = { keyword: 'type', dataPath: (dataPath || '') + '[\'' + key1 + '\']', schemaPath: '#/oneOf/0/additionalProperties/oneOf/0/type', params: { type: 'string' }, message: 'should be string', schema: validate.schema.oneOf[0].additionalProperties.oneOf[0].type, parentSchema: validate.schema.oneOf[0].additionalProperties.oneOf[0], data: data1 };
                    if (vErrors === null) vErrors = [err];
                    else vErrors.push(err);
                    errors++;
                }
                var valid3 = errors === errs_3;
                if (valid3) valid2 = prevValid2 = true;
                var errs_3 = errors;
                var errs__3 = errors;
                var valid3 = false;
                var errs_4 = errors;
                var errs_5 = errors;
                if (Array.isArray(data1)) {
                    if (data1.length < 1) {
                        var err = { keyword: 'minItems', dataPath: (dataPath || '') + '[\'' + key1 + '\']', schemaPath: '#/definitions/common.nonEmptyArrayOfUniqueStringValues/minItems', params: { limit: 1 }, message: 'should NOT have less than 1 items', schema: 1, parentSchema: refVal2, data: data1 };
                        if (vErrors === null) vErrors = [err];
                        else vErrors.push(err);
                        errors++;
                    }
                    var valid5 = true;
                    if (data1.length > 1) {
                        var i = data1.length,
                            j;
                        outer: for (; i--;) { for (j = i; j--;) { if (equal(data1[i], data1[j])) { valid5 = false; break outer; } } }
                    }
                    if (!valid5) {
                        var err = { keyword: 'uniqueItems', dataPath: (dataPath || '') + '[\'' + key1 + '\']', schemaPath: '#/definitions/common.nonEmptyArrayOfUniqueStringValues/uniqueItems', params: { i: i, j: j }, message: 'should NOT have duplicate items (items ## ' + j + ' and ' + i + ' are identical)', schema: true, parentSchema: refVal2, data: data1 };
                        if (vErrors === null) vErrors = [err];
                        else vErrors.push(err);
                        errors++;
                    }
                    var errs__5 = errors;
                    var valid5;
                    for (var i5 = 0; i5 < data1.length; i5++) {
                        var data2 = data1[i5];
                        var errs_6 = errors;
                        if (typeof data2 === "string") {
                            if (ucs2length(data2) < 1) {
                                var err = { keyword: 'minLength', dataPath: (dataPath || '') + '[\'' + key1 + '\'][' + i5 + ']', schemaPath: '#/definitions/common.nonEmptyArrayOfUniqueStringValues/items/minLength', params: { limit: 1 }, message: 'should NOT be shorter than 1 characters', schema: 1, parentSchema: refVal2.items, data: data2 };
                                if (vErrors === null) vErrors = [err];
                                else vErrors.push(err);
                                errors++;
                            }
                        } else {
                            var err = { keyword: 'type', dataPath: (dataPath || '') + '[\'' + key1 + '\'][' + i5 + ']', schemaPath: '#/definitions/common.nonEmptyArrayOfUniqueStringValues/items/type', params: { type: 'string' }, message: 'should be string', schema: refVal2.items.type, parentSchema: refVal2.items, data: data2 };
                            if (vErrors === null) vErrors = [err];
                            else vErrors.push(err);
                            errors++;
                        }
                        var valid6 = errors === errs_6;
                    }
                } else {
                    var err = { keyword: 'type', dataPath: (dataPath || '') + '[\'' + key1 + '\']', schemaPath: '#/definitions/common.nonEmptyArrayOfUniqueStringValues/type', params: { type: 'array' }, message: 'should be array', schema: refVal2.type, parentSchema: refVal2, data: data1 };
                    if (vErrors === null) vErrors = [err];
                    else vErrors.push(err);
                    errors++;
                }
                var valid5 = errors === errs_5;
                var valid4 = errors === errs_4;
                valid3 = valid3 || valid4;
                if (!valid3) {
                    var err = { keyword: 'anyOf', dataPath: (dataPath || '') + '[\'' + key1 + '\']', schemaPath: '#/oneOf/0/additionalProperties/oneOf/1/anyOf', params: {}, message: 'should match some schema in anyOf', schema: validate.schema.oneOf[0].additionalProperties.oneOf[1].anyOf, parentSchema: validate.schema.oneOf[0].additionalProperties.oneOf[1], data: data1 };
                    if (vErrors === null) vErrors = [err];
                    else vErrors.push(err);
                    errors++;
                } else {
                    errors = errs__3;
                    if (vErrors !== null) {
                        if (errs__3) vErrors.length = errs__3;
                        else vErrors = null;
                    }
                }
                var valid3 = errors === errs_3;
                if (valid3 && prevValid2) valid2 = false;
                else { if (valid3) valid2 = prevValid2 = true; }
                if (!valid2) {
                    var err = { keyword: 'oneOf', dataPath: (dataPath || '') + '[\'' + key1 + '\']', schemaPath: '#/oneOf/0/additionalProperties/oneOf', params: {}, message: 'should match exactly one schema in oneOf', schema: validate.schema.oneOf[0].additionalProperties.oneOf, parentSchema: validate.schema.oneOf[0].additionalProperties, data: data1 };
                    if (vErrors === null) vErrors = [err];
                    else vErrors.push(err);
                    errors++;
                } else {
                    errors = errs__2;
                    if (vErrors !== null) {
                        if (errs__2) vErrors.length = errs__2;
                        else vErrors = null;
                    }
                }
                var valid2 = errors === errs_2;
            }
        } else {
            var err = { keyword: 'type', dataPath: (dataPath || '') + "", schemaPath: '#/oneOf/0/type', params: { type: 'object' }, message: 'should be object', schema: validate.schema.oneOf[0].type, parentSchema: validate.schema.oneOf[0], data: data };
            if (vErrors === null) vErrors = [err];
            else vErrors.push(err);
            errors++;
        }
        var valid1 = errors === errs_1;
        if (valid1) valid0 = prevValid0 = true;
        var errs_1 = errors;
        if (typeof data === "string") {
            if (ucs2length(data) < 1) {
                var err = { keyword: 'minLength', dataPath: (dataPath || '') + "", schemaPath: '#/oneOf/1/minLength', params: { limit: 1 }, message: 'should NOT be shorter than 1 characters', schema: 1, parentSchema: validate.schema.oneOf[1], data: data };
                if (vErrors === null) vErrors = [err];
                else vErrors.push(err);
                errors++;
            }
        } else {
            var err = { keyword: 'type', dataPath: (dataPath || '') + "", schemaPath: '#/oneOf/1/type', params: { type: 'string' }, message: 'should be string', schema: validate.schema.oneOf[1].type, parentSchema: validate.schema.oneOf[1], data: data };
            if (vErrors === null) vErrors = [err];
            else vErrors.push(err);
            errors++;
        }
        var valid1 = errors === errs_1;
        if (valid1 && prevValid0) valid0 = false;
        else {
            if (valid1) valid0 = prevValid0 = true;
            var errs_1 = errors;
            var errs__1 = errors;
            var valid1 = false;
            var errs_2 = errors;
            var errs_3 = errors;
            if (Array.isArray(data)) {
                if (data.length < 1) {
                    var err = { keyword: 'minItems', dataPath: (dataPath || '') + "", schemaPath: '#/definitions/common.nonEmptyArrayOfUniqueStringValues/minItems', params: { limit: 1 }, message: 'should NOT have less than 1 items', schema: 1, parentSchema: refVal[2], data: data };
                    if (vErrors === null) vErrors = [err];
                    else vErrors.push(err);
                    errors++;
                }
                var valid3 = true;
                if (data.length > 1) {
                    var i = data.length,
                        j;
                    outer: for (; i--;) { for (j = i; j--;) { if (equal(data[i], data[j])) { valid3 = false; break outer; } } }
                }
                if (!valid3) {
                    var err = { keyword: 'uniqueItems', dataPath: (dataPath || '') + "", schemaPath: '#/definitions/common.nonEmptyArrayOfUniqueStringValues/uniqueItems', params: { i: i, j: j }, message: 'should NOT have duplicate items (items ## ' + j + ' and ' + i + ' are identical)', schema: true, parentSchema: refVal[2], data: data };
                    if (vErrors === null) vErrors = [err];
                    else vErrors.push(err);
                    errors++;
                }
                var errs__3 = errors;
                var valid3;
                for (var i3 = 0; i3 < data.length; i3++) {
                    var data1 = data[i3];
                    var errs_4 = errors;
                    if (typeof data1 === "string") {
                        if (ucs2length(data1) < 1) {
                            var err = { keyword: 'minLength', dataPath: (dataPath || '') + '[' + i3 + ']', schemaPath: '#/definitions/common.nonEmptyArrayOfUniqueStringValues/items/minLength', params: { limit: 1 }, message: 'should NOT be shorter than 1 characters', schema: 1, parentSchema: refVal[2].items, data: data1 };
                            if (vErrors === null) vErrors = [err];
                            else vErrors.push(err);
                            errors++;
                        }
                    } else {
                        var err = { keyword: 'type', dataPath: (dataPath || '') + '[' + i3 + ']', schemaPath: '#/definitions/common.nonEmptyArrayOfUniqueStringValues/items/type', params: { type: 'string' }, message: 'should be string', schema: refVal[2].items.type, parentSchema: refVal[2].items, data: data1 };
                        if (vErrors === null) vErrors = [err];
                        else vErrors.push(err);
                        errors++;
                    }
                    var valid4 = errors === errs_4;
                }
            } else {
                var err = { keyword: 'type', dataPath: (dataPath || '') + "", schemaPath: '#/definitions/common.nonEmptyArrayOfUniqueStringValues/type', params: { type: 'array' }, message: 'should be array', schema: refVal[2].type, parentSchema: refVal[2], data: data };
                if (vErrors === null) vErrors = [err];
                else vErrors.push(err);
                errors++;
            }
            var valid3 = errors === errs_3;
            var valid2 = errors === errs_2;
            valid1 = valid1 || valid2;
            if (!valid1) {
                var err = { keyword: 'anyOf', dataPath: (dataPath || '') + "", schemaPath: '#/oneOf/2/anyOf', params: {}, message: 'should match some schema in anyOf', schema: validate.schema.oneOf[2].anyOf, parentSchema: validate.schema.oneOf[2], data: data };
                if (vErrors === null) vErrors = [err];
                else vErrors.push(err);
                errors++;
            } else {
                errors = errs__1;
                if (vErrors !== null) {
                    if (errs__1) vErrors.length = errs__1;
                    else vErrors = null;
                }
            }
            var valid1 = errors === errs_1;
            if (valid1 && prevValid0) valid0 = false;
            else {
                if (valid1) valid0 = prevValid0 = true;
                var valid1 = true;
                if (valid1 && prevValid0) valid0 = false;
                else { if (valid1) valid0 = prevValid0 = true; }
            }
        }
        if (!valid0) {
            var err = { keyword: 'oneOf', dataPath: (dataPath || '') + "", schemaPath: '#/oneOf', params: {}, message: 'should match exactly one schema in oneOf', schema: validate.schema.oneOf, parentSchema: validate.schema, data: data };
            if (vErrors === null) vErrors = [err];
            else vErrors.push(err);
            errors++;
        } else {
            errors = errs__0;
            if (vErrors !== null) {
                if (errs__0) vErrors.length = errs__0;
                else vErrors = null;
            }
        }
View Code

規則:

1.數據可以為字元串、對象、數組

2.字元串必須為非空字元串

3.數組必須是非空數組,元素必須是非空字元串且不能重覆

4.如果是對象則至少要有2個鍵,鍵的規則滿足2、3

 

refVal3

if ((data && typeof data === "object" && !Array.isArray(data))) {
            var errs__0 = errors;
            var valid1 = true;
            for (var key0 in data) {
                var isAdditional0 = !(false || validate.schema.properties[key0]);
                if (isAdditional0) {
                    valid1 = false;
                    var err = { keyword: 'additionalProperties', dataPath: (dataPath || '') + "", schemaPath: '#/additionalProperties', params: { additionalProperty: '' + key0 + '' }, message: 'should NOT have additional properties', schema: false, parentSchema: validate.schema, data: data };
                    if (vErrors === null) vErrors = [err];
                    else vErrors.push(err);
                    errors++;
                }
            }
            var data1 = data.exprContextCritical;
            if (data1 !== undefined) {
                var errs_1 = errors;
                if (typeof data1 !== "boolean") {
                    var err = { keyword: 'type', dataPath: (dataPath || '') + '.exprContextCritical', schemaPath: '#/properties/exprContextCritical/type', params: { type: 'boolean' }, message: 'should be boolean', schema: validate.schema.properties.exprContextCritical.type, parentSchema: validate.schema.properties.exprContextCritical, data: data1 };
                    if (vErrors === null) vErrors = [err];
                    else vErrors.push(err);
                    errors++;
                }
                var valid1 = errors === errs_1;
            }
            var data1 = data.exprContextRecursive;
            if (data1 !== undefined) {
                var errs_1 = errors;
                if (typeof data1 !== "boolean") {
                    var err = { keyword: 'type', dataPath: (dataPath || '') + '.exprContextRecursive', schemaPath: '#/properties/exprContextRecursive/type', params: { type: 'boolean' }, message: 'should be boolean', schema: validate.schema.properties.exprContextRecursive.type, parentSchema: validate.schema.properties.exprContextRecursive, data: data1 };
                    if (vErrors === null) vErrors = [err];
                    else vErrors.push(err);
                    errors++;
                }
                var valid1 = errors === errs_1;
            }
            if (data.exprContextRegExp !== undefined) { var errs_1 = errors; var valid1 = errors === errs_1; }
            var data1 = data.exprContextRequest;
            if (data1 !== undefined) {
                var errs_1 = errors;
                if (typeof data1 !== "string") {
                    var err = { keyword: 'type', dataPath: (dataPath || '') + '.exprContextRequest', schemaPath: '#/properties/exprContextRequest/type', params: { type: 'string' }, message: 'should be string', schema: validate.schema.properties.exprContextRequest.type, parentSchema: validate.schema.properties.exprContextRequest, data: data1 };
                    if (vErrors === null) vErrors = [err];
                    else vErrors.push(err);
                    errors++;
                }
                var valid1 = errors === errs_1;
            }
            var data1 = data.loaders;
            if (data1 !== undefined) {
                var errs_1 = errors;
                var errs__1 = errors;
                var valid1 = false;
                var errs_2 = errors;
                if (!refVal4(data1, (dataPath || '') + '.loaders', data, 'loaders', rootData)) {
                    if (vErrors === null) vErrors = refVal4.errors;
                    else vErrors = vErrors.concat(refVal4.errors);
                    errors = vErrors.length;
                }
                var valid2 = errors === errs_2;
                valid1 = valid1 || valid2;
                if (!valid1) {
                    var err = { keyword: 'anyOf', dataPath: (dataPath || '') + '.loaders', schemaPath: '#/properties/loaders/anyOf', params: {}, message: 'should match some schema in anyOf', schema: validate.schema.properties.loaders.anyOf, parentSchema: validate.schema.properties.loaders, data: data1 };
                    if (vErrors === null) vErrors = [err];
                    else vErrors.push(err);
                    errors++;
                } else {
                    errors = errs__1;
                    if (vErrors !== null) {
                        if (errs__1) vErrors.length = errs__1;
                        else vErrors = null;
                    }
                }
                var valid1 = errors === errs_1;
            }
            if (data.noParse !== undefined) { var errs_1 = errors; var valid1 = errors === errs_1; }
            if (data.rules !== undefined) {
                var errs_1 = errors;
                var errs_2 = errors;
                if (!refVal[4](data.rules, (dataPath || '') + '.rules', data, 'rules', rootData)) {
                    if (vErrors === null) vErrors = refVal[4].errors;
                    else vErrors = vErrors.concat(refVal[4].errors);
                    errors = vErrors.length;
                }
                var valid2 = errors === errs_2;
                var valid1 = errors === errs_1;
            }
            var data1 = data.unknownContextCritical;
            if (data1 !== undefined) {
                var errs_1 = errors;
                if (typeof data1 !== "boolean") {
                    var err = { keyword: 'type', dataPath: (dataPath || '') + '.unknownContextCritical', schemaPath: '#/properties/unknownContextCritical/type', params: { type: 'boolean' }, message: 'should be boolean', schema: validate.schema.properties.unknownContextCritical.type, parentSchema: validate.schema.properties.unknownContextCritical, data: data1 };
                    if (vErrors === null) vErrors = [err];
                    else vErrors.push(err);
                    errors++;
                }
                var valid1 = errors === errs_1;
            }
            var data1 = data.unknownContextRecursive;
            if (data1 !== undefined) {
                var errs_1 = errors;
                if (typeof data1 !== "boolean") {
                    var err = { keyword: 'type', dataPath: (dataPath || '') + '.unknownContextRecursive', schemaPath: '#/properties/unknownContextRecursive/type', params: { type: 'boolean' }, message: 'should be boolean', schema: validate.schema.properties.unknownContextRecursive.type, parentSchema: validate.schema.properties.unknownContextRecursive, data: data1 };
                    if (vErrors === null) vErrors = [err];
                    else vErrors.push(err);
                    errors++;
                }
                var valid1 = errors === errs_1;
            }
            if (data.unknownContextRegExp !== undefined) { var errs_1 = errors; var valid1 = errors === errs_1; }
            var data1 = data.unknownContextRequest;
            if (data1 !== undefined) {
                var errs_1 = errors;
                if (typeof data1 !== "string") {
                    var err = { keyword: 'type', dataPath: (dataPath || '') + '.unknownContextRequest', schemaPath: '#/properties/unknownContextRequest/type', params: { type: 'string' }, message: 'should be string', schema: validate.schema.properties.unknownContextRequest.type, parentSchema: validate.schema.properties.unknownContextRequest, data: data1 };
                    if (vErrors === null) vErrors = [err];
                    else vErrors.push(err);
                    errors++;
                }
                var valid1 = errors === errs_1;
            }
            if (data.unsafeCache !== undefined) { var errs_1 = errors; var valid1 = errors === errs_1; }
            var data1 = data.wrappedContextCritical;
            if (data1 !== undefined) {
                var errs_1 = errors;
                if (typeof data1 !== "boolean") {
                    var err = { keyword: 'type', dataPath: (dataPath || '') + '.wrappedContextCritical', schemaPath: '#/properties/wrappedContextCritical/type', params: { type: 'boolean' }, message: 'should be boolean', schema: validate.schema.properties.wrappedContextCritical.type, parentSchema: validate.schema.properties.wrappedContextCritical, data: data1 };
                    if (vErrors === null) vErrors = [err];
                    else vErrors.push(err);
                    errors++;
                }
                var valid1 = errors === errs_1;
            }
            var data1 = data.wrappedContextRecursive;
            if (data1 !== undefined) {
                var errs_1 = errors;
                if (typeof data1 !== "boolean") {
                    var err = { keyword: 'type', dataPath: (dataPath || '') + '.wrappedContextRecursive', schemaPath: '#/properties/wrappedContextRecursive/type', params: { type: 'boolean' }, message: 'should be boolean', schema: validate.schema.properties.wrappedContextRecursive.type, parentSchema: validate.schema.properties.wrappedContextRecursive, data: data1 };
                    if (vErrors === null) vErrors = [err];
                    else vErrors.push(err);
                    errors++;
                }
                var valid1 = errors === errs_1;
            }
            var data1 = data.strictExportPresence;
            if (data1 !== undefined) {
                var errs_1 = errors;
                if (typeof data1 !== "boolean") {
                    var err = { keyword: 'type', dataPath: (dataPath || '') + '.strictExportPresence', schemaPath: '#/properties/strictExportPresence/type', params: { type: 'boolean' }, message: 'should be boolean', schema: validate.schema.properties.strictExportPresence.type, parentSchema: validate.schema.properties.strictExportPresence, data: data1 };
                    if (vErrors === null) vErrors = [err];
                    else vErrors.push(err);
                    errors++;
                }
                var valid1 = errors === errs_1;
            }
            var data1 = data.strictThisContextOnImports;
            if (data1 !== undefined) {
                var errs_1 = errors;
                if (typeof data1 !== "boolean") {
                    var err = { keyword: 'type', dataPath: (dataPath || '') + '.strictThisContextOnImports', schemaPath: '#/properties/strictThisContextOnImports/type', params: { type: 'boolean' }, message: 'should be boolean', schema: validate.schema.properties.strictThisContextOnImports.type, parentSchema: validate.schema.properties.strictThisContextOnImports, data: data1 };
                    if (vErrors === null) vErrors = [err];
                    else vErrors.push(err);
                    errors++;
                }
                var valid1 = errors === errs_1;
            }
        } else {
            var err = { keyword: 'type', dataPath: (dataPath || '') + "", schemaPath: '#/type', params: { type: 'object' }, message: 'should be object', schema: validate.schema.type, parentSchema: validate.sche

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • mvc/mvvm "阮大神博客" mvc 分為三層,其實M層是數據模型層,它是真正的後端數據在前端js中的一個映射模型,他們的關係是:數據模型層和視圖層有映射關係,model改變,view展示也會更改,當view產生用戶操作或會反饋給controller,controller更改model,這個時候 ...
  • 1.首先先要下載artTemplate.js,這個可以在官網下載也可以在GitHob進行下載。 2.現在是編寫一個存放html標簽的編寫模板,使用<script type="text/html" id="site_template"></script>裝載,裡面的id是你到時候將確認將數據傳給誰的綁 ...
  • WebpackOptionsDefaulter模塊 通過參數檢測後,會根據單/多配置進行處理,本文基於單配置,所以會進行到如下代碼: 模塊的作用是進行預設值的設置,流程圖如下: 進入該模塊: 可以看到,這個模塊的內容是用ES6的新語法寫的,很好理解,因為這個模塊是只是針對webpack的預設設置,所 ...
  • 最近學習vue.js,下麵是筆記: 重點在3. 可能出現的問題: 1,首先我這邊歷經了慘痛的教訓後,建議各位vue學友,一定要使用Administrator,系統管理員身份登錄,不要使用二級管理員,很容易在安裝腳手架或者其他工具時,出現許可權問題,,登錄Administrator操作電腦後很多亂七八糟 ...
  • 前言 通常,jQuery的函數ajax進行Ajax調用。函數ajax只能做一個Ajax調用。當Ajax調用成功時,執行回調函數。可選地,當Ajax調用返回錯誤時,調用另一個回調函數。但是,該功能不能根據這些請求的結果進行多個Ajax請求和註冊回調函數。一種情況是,網頁使多個Ajax請求在禁用用戶交互 ...
  • 今天看到一個關於foo的一個面試題,趕腳特別有意思 ...
  • 1. 寫在前面 往常都是利用 Python/.NET 語言實現爬蟲,然現在作為一名前端開發人員,自然需要熟練 NodeJS。下麵利用 NodeJS 語言實現一個糗事百科的爬蟲。另外,本文使用的部分代碼是 es6 語法。 實現該爬蟲所需要的依賴庫如下。 1. request: 利用 get 或者 po ...
  • 前兩天有一個原來的同事問我文字描邊怎麼做,那麼今天我們就來說說文字描邊這個樣式怎麼實現. 一.文字描邊 -webkit-text-stroke 文字描邊 參數:參數1 描邊大小 參數2 描邊顏色 註意: webkit內核有效 只能使用在谷歌 ,safir有效 二.實例 上圖的效果我們怎樣來實現呢? ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...