FED

©FrontEndDev.org
2015 - 2024
web@2.22.0 api@2.20.0

coolie2.5.0加载vue文件的思路及方案

coolie 2.5.0 扩展日记

用coolie很多年了,非常感谢云大神提供这么好的工具,闲暇之余,对其稍作修改,支持构建vue文件

一个vue文件包含template, style, scrip 三个部分,本方案输出格式如下

构建前

<template>
	<div class="less-scoped">
        <p class="red">{{aaa}}</p>
    </div>
</template>

<script>
	exports.default = {
		data(){
			return {
				aaa : 123
			}
		}
	}
</script>

<style lang="less">
.less-scoped{
	.red{
		color : red;
	}
}
</style>

构建后,做了美化

/*coolie built*/
define("0", ["3"], function (e) {
    return e("3")
});
define("3", [], function (require, exports, module) {
    exports.render = function () {
        with(this) return _c("div", {
            staticClass: "index-user"
        }, [_c("p", {
            staticClass: "red"
        }, [_v(_s(aaa))])])
    };
    exports.staticRenderFns = [];
    exports.moduleid = "index-user";
    exports.style = ".index-user .red {\n  color: red;\n}\n";
    exports["default"] = {
        data: function () {
            return {
                aaa: 123
            }
        }
    }
});

如您所见 支持es6,less构建(没研究过官方的方案) 然后自己再封装一个loadVue的方法,将上面的对象改成vue所需的格式即可

下面说下修改方案: coolie-cil

cnpm install coolie
cnpm install babel-cli
cnpm install babel-preset-es2015
cnpm install vue-template-compiler
cnpm install less

src/parse/require-pipeline.js

/**
 * 模块入口类型
 * @type {{}}
 */
var moduleInTypeMap = {
    js: 'js',
    vue: 'js',
    image: 'file',
    file: 'file',
    text: 'text',
    html: 'html',
    json: 'json',
    css: 'css'
};

src/utils/reader.js

var babel = require('babel-core');
var less = require('less');
var compiler = require('vue-template-compiler');

// 读取文件前加入
file = file.replace('.vue.js', '.vue');

// 读取文件后加入
bf = encoding === 'binary' ? bf : bf.toString(encoding);

var _ext = file.split('.');
var ext = _ext[_ext.length - 1];
if (ext == 'vue') {
    var nameArr = file.split('/');
    var _len = nameArr.length;
    var moduleid = nameArr[_len - 2] + '-' + nameArr[_len - 1];
    moduleid = moduleid.replace('.vue', '');

    var style = bf.match(new RegExp(/<style[^>]*?>([\s\S]+)<\/style>/)) || '';
    if (style && style[1].replace(/\s+/g, "")) {
        style = style[1].replace(/\"/g, "'")
            .replace(/less-scoped/, moduleid)
        // .replace(/\"/g, "'")
        // .replace(/\r\n/g, '\\' + 'n')
        // .replace(/\n/g, '\\' + 'n');
    } else {
        style = '';
    }

    var template = bf.match(new RegExp(/<template[^>]*?>([\s\S]+)<\/template>/))[1]
        .replace(/less-scoped/, moduleid)
    // .replace(/\"/g, '\\\"')
    // .replace(/\r\n/g, '\\' + 'n')
    // .replace(/\n/g, '\\' + 'n');

    var render = compiler.compile(template);
    var staticRenderFns = '[';
    render.staticRenderFns.forEach(function (item, index) {
        staticRenderFns += '(function() {' + item + '}),';
    })
    staticRenderFns += ']';

    var script = bf.match(new RegExp(/<script[^>]*?>([\s\S]+)<\/script>/))[1];
    script = babel.transform(script, {
        // extends : './.babelrc',
        // minified : true
        // presets : ['es2015']
        // presets: [['es2015', { loose: true, modules: false }]],
        presets: [[__dirname + '/../../babel-preset-es2015', { loose: true, modules: false }]],
    }).code;

    // var css = style.replace(/\"/g, "'")
    //     .replace(/\r\n/g, '\\' + 'n')
    //     .replace(/\n/g, '\\' + 'n');
    less.render(style, function (e, css) {
        css = css.css.replace(/\"/g, "'")
            .replace(/\r\n/g, '\\' + 'n')
            .replace(/\n/g, '\\' + 'n');

        bf = 'define(function(require, exports, module) {' + "\n"
            + '    exports.render = (function() {' + render.render + ";})\n"
            + '    exports.staticRenderFns = ' + (staticRenderFns) + ";\n"
            // + '    exports.template = "' + template + "\";\n"
            + '    exports.moduleid = "' + moduleid + "\";\n"
            + '    exports.style = "' + css + "\";\n"
            + script + "\n"
            + '})';
    });

}