requirejs + vue 項目搭建2

上篇是年後的項目搭建的,時間比較倉促,感受有點lowcss

1.gulp-vue 文件對公用js的有依賴,之後別的同事拿去搭其餘項目,估計會被噴html

2.不支持vue-loader同樣寫模版語言和es6語法vue

最近h5端的項目,用了webpack+vue-router,用jade+es6+stylus瞬間感受本身高大上了,es6用起來,感受也是爽爽噠。(其實語法用的也很少,也就import,一些簡單的新方法,主要是箭頭函數,不再用self=this了)因此考慮進行一次升級,使在web端能夠簡單支持vue require的加載,由於webpack打包配置仍是太麻煩了node

vue的支持,template html字符串,咱們能夠經過模版nodejs模版編譯生成html字符串,轉成eqport的template屬性進行支持.想了各類方式,沒有實現css的支持,有啥好像方法,能夠留言交流webpack

下面是gulp插件的代碼,參照的vue-loaderes6

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支持web

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項目了vue-router

相關文章
相關標籤/搜索