requirejs + vue 项目搭建2

上篇是年后的项目搭建的,时间比较仓促,感觉有点low

1.gulp-vue 文件对公用js的有依赖,以后别的同事拿去搭其他项目,估计会被喷

2.不支持vue-loader一样写模版语言和es6语法

最近h5端的项目,用了webpack+vue-router,用jade+es6+stylus瞬间感觉自己高大上了,es6用起来,感觉也是爽爽哒。(其实语法用的也不多,也就import,一些简单的新方法,主要是箭头函数,再也不用self=this了)所以考虑进行一次升级,使在web端可以简单支持vue require的加载,因为webpack打包配置还是太麻烦了

vue的支持,template html字符串,我们可以通过模版nodejs模版编译生成html字符串,转成eqport的template属性进行支持.想了各种方式,没有实现css的支持,有啥好像方法,可以留言交流

下面是gulp插件的代码,参照的vue-loader

var through = require('through2');
var gutil = require('gulp-util');

var parse5 = require('parse5');
var deindent = require('de-indent');
var validateTemplate = require('vue-template-validator');
var jade = require('jade');

module.exports = function(opt){
    function run (file, encoding, callback) {
        if (file.isNull()) {
            return callback(null, file);
        }

        if (file.isStream()) {
            return callback(new gutil.PluginError('gulp-vue', 'doesn\'t support Streams'));
        }
        file.contents = new Buffer(vueWrite(file, file.contents.toString()));
        file.path = file.path + '.js';
        callback(null, file);
    }
    return through.obj(run);
}

var getHTML = {//暂时只做了jade模版的支持,需要别的模版对该对象进行扩展
    'jade' : function (content) {
        return jade.compile(content, {})({})
    },
    'default': function (content) {
        return content;
    }
};
var splitRE = /\r?\n/g
var emptyRE = /^\s*$/
var commentSymbols = {
    'iced': '#',
    'iced-jsx': '#',
    'iced-redux': '#',
    'coffee': '#',
    'coffee-jsx': '#',
    'coffee-redux': '#',
    'purs': '--',
    'ulmus': '--'
}

var vueWrite = function (file, content) {
    var output = {
        template: [],
        style: [],
        script: []
    }
    var fragment = parse5.parseFragment(content, {
        locationInfo: true
    });
    fragment.childNodes.forEach(function (node) {
        var type = node.tagName
        var lang = (getAttribute(node, 'lang') || 'default').toLowerCase();
        
        var warnings = null
        if (!output[type]) {
            return
        }
        // node count check
        if ((type === 'script' || type === 'template') && output[type].length > 0) {
            throw new Error(
                '[glup-vue] Only one <script> or <template> tag is allowed inside a Vue component.'
            )
        }
        // skip empty script/style tags
        if (type !== 'template' && (!node.childNodes || !node.childNodes.length)) {
            return
        }
        // template content is nested inside the content fragment
        if (type === 'template') {
            node = node.content
            if (!lang) {
                warnings = validateTemplate(node, content)
            }
        }
        // extract part
        var start = node.childNodes[0].__location.startOffset
        var end = node.childNodes[node.childNodes.length - 1].__location.endOffset
        var result
        if (type === 'script') {
            //将非script的内容进行当行注释,保持原文件行数,方便js错误查看
            result = commentScript(content.slice(0, start), lang) +
                deindent(content.slice(start, end)) +
                commentScript(content.slice(end), lang)
        } else {
            result = deindent(content.slice(start, end))
        }
        output[type] = {
            lang: lang,
            content: result,
            warnings: warnings
        }
    })
    var lang = output.template.lang;
    if (!getHTML[lang]) {
        throw new Error(
            '[glup-vue] ' + lang + ' html engine not support'
        )
    }
    /*
        return output.script.content 
            + "\n;exports.default.template = '" + getHTML[lang](output.template.content, {}).replace(/(\\*)'/g, function (a, b) {
            return (b||"").replace('\\', '\\\\') + "\\'"
        }).replace(/\n/g, '\\\n') + "'";
        */
    //try { 
        /*return output.script.content 
            + "\n;exports.default.template = '" + getHTML[lang](output.template.content, {}).replace(/(\\*)'/g, function (a, b) {
            return (b||"").replace('\\', '\\\\') + "\\'"
        }).replace(/\n/g, '\\\n') + "'";*/
        //对生成的html,'号进行替换,没有做多测试案例,可能有点小bug
        return output.script.content 
            + "\n;exports.default.template = '" + getHTML[lang](output.template.content, {}).replace(/(\\*)'/g, function (a, b) {
            return (b||"").replace('\\', '\\\\') + "\\'"
        }).replace(/\n/g, '\\\n') + "';";
    //} catch (e) { 
        //console.log('message', e.message); 
    //} 

}

function commentScript (content, lang) {
  var symbol = getCommentSymbol(lang)
  var lines = content.split(splitRE)
  return lines.map(function (line, index) {
    // preserve EOL
    if (index === lines.length - 1 && emptyRE.test(line)) {
      return ''
    } else {
      return symbol + (emptyRE.test(line) ? '' : ' ' + line)
    }
  })
  .join('\n')
}

function getCommentSymbol (lang) {
  return commentSymbols[lang] || '//'
}

function getAttribute (node, name) {
  if (node.attrs) {
    var i = node.attrs.length
    var attr
    while (i--) {
      attr = node.attrs[i]
      if (attr.name === name) {
        return attr.value
      }
    }
  }
}

本来想把requirejs加载的支持代码拼接在上面,但是测试发现,拼接后babel语法报错了,所以把这块逻辑放到了gulp构建文件里面,并加入了sourcemaps支持

var gulp = require('gulp');
var vuefile = require("./gulp-vue");
var sourcemaps = require('gulp-sourcemaps');
var babel = require('gulp-babel');
var inject = require("gulp-inject-string");
gulp.task('default', () => {
    return gulp.src('src/js/**/*.vue')
        .pipe(sourcemaps.init())
        .pipe(vuefile())
        .pipe(babel({
            presets: ['es2015']
        }))
        .pipe(inject.wrap('define(function (require) {var exports = {};', ';return exports.default;\n});'))
        .pipe(sourcemaps.write('.'))
        .pipe(gulp.dest('dist/js/'));
});

这样我们就可以用requirejs+vue搭建项目了,这个方式缺陷就是css需要通过别的方式加载,也不支持写在vue文件当中。基于这个,我就可以修改我的 electron + vue项目了

 

posted @ 2016-08-05 10:20  游云  阅读(4568)  评论(1编辑  收藏  举报