Compile quick app json, it should compile after all files build done

@param {Object} file the file to process
@param {Object} options the compile options
@return {{content: string}}
function compile(file, options) {
    if (!file.compileReady && !file.owner.processed) {
        return {content: file.content};
    }

    let {
        getAllPageConfigFiles,
        sourceDir,
        designWidth
    } = options;
    let obj = JSON.parse(file.content.toString());

    // normalize router info
    let routerInfo = normalizeRouteInfo(obj.pages);
    delete obj.pages;
    obj.router = routerInfo;

    // normalize debug info
    normalizeDebugConfig(obj);

    // init designWidth
    if (designWidth) {
        obj.config || (obj.config = {});
        if (!obj.config.designWidth) {
            obj.config.designWidth = designWidth;
        }
    }

    // normalize window config info
    let displayInfo = obj.display;
    let displayConfig = normalizeWindowConfig(obj.window);
    // the display config has higher priority than window config
    displayConfig && (displayInfo = Object.assign(displayConfig, displayInfo));
    displayInfo && (obj.display = displayInfo);
    delete obj.window;

    // normalize display pages info
    if (displayInfo && displayInfo.pages) {
        displayInfo.pages = normalizeDisplayPages(displayInfo.pages);
    }

    // normalize features
    let features = getUsedAPIFeatures(obj.features, options);
    features && (obj.features = features);

    // merge the page display config defined in page
    let pageConfigFiles = getAllPageConfigFiles();
    let currDisplayPages = (displayInfo && displayInfo.pages) || {};
    pageConfigFiles.forEach(item => {
        addDisplayPageConfig(currDisplayPages, sourceDir, item);
    });
    if (Object.keys(currDisplayPages).length) {
        displayInfo || (obj.display = {});
        obj.display.pages = currDisplayPages;
    }

    return {
        content: JSON.stringify(obj, null, 4)
    };
}