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项目了