File size: 5,456 Bytes
4cadbaf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.compileTemplate = void 0;
const assetUrl_1 = __importDefault(require("./templateCompilerModules/assetUrl"));
const srcset_1 = __importDefault(require("./templateCompilerModules/srcset"));
const consolidate = require('consolidate');
const transpile = require('vue-template-es2015-compiler');
function compileTemplate(options) {
    const { preprocessLang } = options;
    const preprocessor = preprocessLang && consolidate[preprocessLang];
    if (preprocessor) {
        return actuallyCompile(Object.assign({}, options, {
            source: preprocess(options, preprocessor)
        }));
    }
    else if (preprocessLang) {
        return {
            ast: {},
            code: `var render = function () {}\n` + `var staticRenderFns = []\n`,
            source: options.source,
            tips: [
                `Component ${options.filename} uses lang ${preprocessLang} for template. Please install the language preprocessor.`
            ],
            errors: [
                `Component ${options.filename} uses lang ${preprocessLang} for template, however it is not installed.`
            ]
        };
    }
    else {
        return actuallyCompile(options);
    }
}
exports.compileTemplate = compileTemplate;
function preprocess(options, preprocessor) {
    const { source, filename, preprocessOptions } = options;
    const finalPreprocessOptions = Object.assign({
        filename
    }, preprocessOptions);
    // Consolidate exposes a callback based API, but the callback is in fact
    // called synchronously for most templating engines. In our case, we have to
    // expose a synchronous API so that it is usable in Jest transforms (which
    // have to be sync because they are applied via Node.js require hooks)
    let res, err;
    preprocessor.render(source, finalPreprocessOptions, (_err, _res) => {
        if (_err)
            err = _err;
        res = _res;
    });
    if (err)
        throw err;
    return res;
}
function actuallyCompile(options) {
    const { source, compiler, compilerOptions = {}, transpileOptions = {}, transformAssetUrls, transformAssetUrlsOptions, isProduction = process.env.NODE_ENV === 'production', isFunctional = false, optimizeSSR = false, prettify = true } = options;
    const compile = optimizeSSR && compiler.ssrCompile ? compiler.ssrCompile : compiler.compile;
    let finalCompilerOptions = compilerOptions;
    if (transformAssetUrls) {
        const builtInModules = [
            transformAssetUrls === true
                ? assetUrl_1.default(undefined, transformAssetUrlsOptions)
                : assetUrl_1.default(transformAssetUrls, transformAssetUrlsOptions),
            srcset_1.default(transformAssetUrlsOptions)
        ];
        finalCompilerOptions = Object.assign({}, compilerOptions, {
            modules: [...builtInModules, ...(compilerOptions.modules || [])],
            filename: options.filename
        });
    }
    const { ast, render, staticRenderFns, tips, errors } = compile(source, finalCompilerOptions);
    if (errors && errors.length) {
        return {
            ast,
            code: `var render = function () {}\n` + `var staticRenderFns = []\n`,
            source,
            tips,
            errors
        };
    }
    else {
        const finalTranspileOptions = Object.assign({}, transpileOptions, {
            transforms: Object.assign({}, transpileOptions.transforms, {
                stripWithFunctional: isFunctional
            })
        });
        const toFunction = (code) => {
            return `function (${isFunctional ? `_h,_vm` : ``}) {${code}}`;
        };
        // transpile code with vue-template-es2015-compiler, which is a forked
        // version of Buble that applies ES2015 transforms + stripping `with` usage
        let code = transpile(`var __render__ = ${toFunction(render)}\n` +
            `var __staticRenderFns__ = [${staticRenderFns.map(toFunction)}]`, finalTranspileOptions) + `\n`;
        // #23 we use __render__ to avoid `render` not being prefixed by the
        // transpiler when stripping with, but revert it back to `render` to
        // maintain backwards compat
        code = code.replace(/\s__(render|staticRenderFns)__\s/g, ' $1 ');
        if (!isProduction) {
            // mark with stripped (this enables Vue to use correct runtime proxy
            // detection)
            code += `render._withStripped = true`;
            if (prettify) {
                try {
                    code = require('prettier').format(code, {
                        semi: false,
                        parser: 'babel'
                    });
                }
                catch (e) {
                    if (e.code === 'MODULE_NOT_FOUND') {
                        tips.push('The `prettify` option is on, but the dependency `prettier` is not found.\n' +
                            'Please either turn off `prettify` or manually install `prettier`.');
                    }
                    tips.push(`Failed to prettify component ${options.filename} template source after compilation.`);
                }
            }
        }
        return {
            ast,
            code,
            source,
            tips,
            errors
        };
    }
}