问题
在我们的 vue 项目中(特别是后台系统),总会出现一些需要多业务线共同开发同一个项目的场景,如果各业务团队向项目中提供一些公共业务组件,但是这些组件并不能和项目一起打包,因为项目中不能因为某个私有模块的频繁变更而重复构建发布。
^_^不建议在生产环境使用,代码包含eval
思路
在这种场景下我们需要将公共的业务组件部署到服务端,由客户端请求并渲染组件。
服务端解析.vue文件
使用vue-template-compiler 模板解析器,解析SFC(单文件组件)
const compile = require('vue-template-compiler')// 获取sfc组件的源码
const str = fs.readFileSync(path.resolve(__dirname, `../components/sfc.vue`), 'utf-8')
// vue-loader内置,现在用来解析SFC(单文件组件)
let sfc = compile.parseComponent(str)
// 获取sfc组件配置
let sfcOptions = getComponentOption(sfc)
getComponentOption 获取sfc组件配置
import { uuid } from 'utilscore'
import stylus from 'stylus'
import sass from 'sass'
import less from 'less'
const getComponentOption = sfc => {
// 生成data-u-id
const componentId = uuid(8, 16).toLocaleLowerCase()
// 标签添加data-u-id属性
const template = sfc.template ? tagToUuid(sfc.template.content, componentId) : ''
// 转化style(less、sass、stylus)
let styles = [] sfc.styles.forEach(sty => {
switch (sty.lang) {
case 'stylus':
stylus.render(sty.content, (err, css) => styles.push(formatStyl(sty, css, componentId)))
break;
case 'sass':
case 'scss':
styles.push(formatStyl(sty, sass.renderSync({ data: sty.content }).css.toString(), componentId))
break;
case 'less':
less.render(sty.content, (err, css) => styles.push(formatStyl(sty, css, componentId)))
break;
}
})
let options = {
script: sfc.script ? $require(null, sfc.script.content) : {},
styles,
template
}
return JSON.stringify(options, (k, v) => {
if(typeof(v) === 'function') {
let _fn = v.toString()
return /^function()/.test(_fn) ? _fn : fn.replace(/^/,'function ')
}
return v
})
}tagToUuid 给template 中的标签追加data-u-id
const tagToUuid = (tpl, id) => {
var pattern = /<[^/]("[^"]*"|'[^']*'|[^'">])*>/g
return tpl.replace(pattern, $1 => {
return $1.replace(/<([w-]+)/i, ($2, $3) => `<${$3} data-u-${id}`)
})
}formatStyl 处理样式的scoped










