提交 cc221698 编写于 作者: fxy060608's avatar fxy060608

refactor(v3): uni-migration

上级 90945f7f
......@@ -13,5 +13,7 @@ migrate('/Users/fxy/Downloads/wa-vantui_1.1/wxcomponents/vant',
// } = require('../lib/mp-weixin/transform/template-transformer')
// console.log(transformTemplate(
// `<view wx:for="{{ isSimple(columns) ? [columns] : columns }}" wx:for-item="item1" wx:key="{{ index }}"/>`
// `<view></view><wxs module="a">aasdf</wxs>`, {
// filename: 'index'
// }
// ))
......@@ -7,6 +7,24 @@ const migraters = {
'mp-weixin': require('./mp-weixin')
}
/**
* 先简单的 hack 一下,支持 vant 的 array.wxs
* @param {Object} src
* @param {Object} dest
*/
function hackVant(src, dest) {
if (src.indexOf('array.wxs') !== -1) {
fs.outputFileSync(
dest,
fs.readFileSync(src)
.toString()
.replace(`array.constructor === 'Array'`, 'Array.isArray(array)')
)
return true
}
return false
}
module.exports = function migrate(input, out, options = {
platform: 'mp-weixin'
}) {
......@@ -24,9 +42,16 @@ module.exports = function migrate(input, out, options = {
})
const styleExtname = options.extname.style
assets.forEach(asset => {
const src = path.resolve(input, asset)
const dest = path.resolve(out, asset.replace(styleExtname, '.css'))
console.log(`copy: ${dest}`)
fs.copySync(src, dest)
if (typeof asset === 'string') {
const src = path.resolve(input, asset)
const dest = path.resolve(out, asset.replace(styleExtname, '.css'))
console.log(`copy: ${dest}`)
if (!hackVant(src, dest)) {
fs.copySync(src, dest)
}
} else {
console.log(`write: ${path.resolve(out, asset.path)}`)
fs.outputFileSync(path.resolve(out, asset.path), asset.content)
}
})
}
const path = require('path')
const {
transformJsonFile
} = require('./json-transformer')
......@@ -23,12 +25,14 @@ module.exports = function transformFile(input, options) {
filepath + templateExtname
]
const [usingComponentsCode] = transformJsonFile(filepath + '.json', deps)
const [jsCode] = transformJsonFile(filepath + '.json', deps)
const [templateCode, wxsCode = ''] = transformTemplateFile(filepath + templateExtname)
const [templateCode, wxsCode = '', wxsFiles = []] = transformTemplateFile(filepath + templateExtname, {
filename: path.basename(filepath)
})
const styleCode = transformStyleFile(filepath + styleExtname, options, deps) || ''
const scriptCode = transformScriptFile(filepath + '.js', usingComponentsCode, options, deps)
const scriptCode = transformScriptFile(filepath + '.js', jsCode, options, deps)
return [
`<template>
......@@ -41,6 +45,7 @@ ${scriptCode}
<style>
${styleCode}
</style>`,
deps
deps,
wxsFiles
]
}
......@@ -3,11 +3,12 @@ const glob = require('glob')
const transformFile = require('./file-transformer')
function generateVueFile(input, out, options) {
const [content, deps] = transformFile(input, options)
const [content, deps, wxsFiles] = transformFile(input, options)
return {
path: path.resolve(out, path.basename(input).replace(options.extname.template, '.vue')),
content,
deps
deps,
wxsFiles
}
}
......@@ -28,12 +29,21 @@ function generateVueFolder(input, out, options) {
)
files.push(vueFile)
deps.push(...vueFile.deps)
const dirname = path.dirname(file)
vueFile.wxsFiles.forEach(wxsFile => {
wxsFile.path = path.join(dirname, wxsFile.path)
assets.push(wxsFile)
})
} else {
assets.push(file)
}
})
return [files, assets.filter(asset => {
return !deps.includes(path.resolve(input, asset))
if (typeof asset === 'string') {
return !deps.includes(path.resolve(input, asset))
}
return true
})]
}
......
const fs = require('fs')
const {
camelize,
capitalize
} = require('../util')
function transformJson(content) {
const {
usingComponents
} = JSON.parse(content)
if (!usingComponents) {
return ['{}']
return ['']
}
const usingComponentsCode = []
const importCode = []
const componentsCode = []
Object.keys(usingComponents).forEach(name => {
usingComponentsCode.push(`'${name}': require('${usingComponents[name]}.vue').default`)
const identifier = capitalize(camelize(name))
importCode.push(`import ${identifier} from '${usingComponents[name]}.vue'`)
componentsCode.push(`'${name}': ${identifier}`)
})
return [`{
${usingComponentsCode.join(',\n')}
}`]
return [`${importCode.join('\n')}
global['__wxVueOptions'] = {components:{${componentsCode.join(',')}}}
`]
}
module.exports = {
transformJson,
transformJsonFile(filepath, deps) {
if (!fs.existsSync(filepath)) {
return ['{}']
return ['']
}
deps.push(filepath)
return transformJson(fs.readFileSync(filepath, 'utf8').toString().trim())
......
......@@ -5,16 +5,16 @@ const {
normalizePath
} = require('../util')
function transformScript(content, route, usingComponentsCode) {
return `global['__wxRoute'].push('${route}')
global['__wxUsingComponents'].push(${usingComponentsCode})
function transformScript(content, route, code) {
return `${code}
global['__wxRoute'] = '${route}'
${content}
export default global['__wxComponents']['${route}']`
}
module.exports = {
transformScript,
transformScriptFile(filepath, usingComponentsCode, options, deps) {
transformScriptFile(filepath, code, options, deps) {
let content = ''
if (!fs.existsSync(filepath)) {
content = `
......@@ -29,6 +29,6 @@ Component({})
route = normalizePath(path.relative(options.base, filepath))
}
route = route.replace('.js', '')
return transformScript(content, route, usingComponentsCode, options)
return transformScript(content, route, code, options)
}
}
......@@ -4,13 +4,13 @@ const path = require('path')
const parse = require('./parser')
const transform = require('./transform')
function transformTemplate(content) {
return transform(parse(content))
function transformTemplate(content, options = {}) {
return transform(parse(content), options)
}
module.exports = {
transformTemplate,
transformTemplateFile(filepath) {
return transformTemplate(fs.readFileSync(filepath, 'utf8').toString().trim())
transformTemplateFile(filepath, options = {}) {
return transformTemplate(fs.readFileSync(filepath, 'utf8').toString().trim(), options)
}
}
......@@ -33,8 +33,28 @@ function genElement(node) {
return ''
}
function genWxs(wxs) {
return wxs.map(wxsNode => genElement(wxsNode)).join('').trim()
function genWxs(wxs, state) {
const wxsCode = []
const wxsFiles = []
wxs.forEach(wxsNode => {
const {
src,
module
} = wxsNode.attribs
if (!module) {
return
}
if (!src) {
wxsNode.attribs.src = './' + (state.filename ? (state.filename + '-' + module) : module) + '.wxs'
wxsFiles.push({
path: wxsNode.attribs.src,
content: genChildren(wxsNode)
})
}
wxsNode.children.length = 0
wxsCode.push(genElement(wxsNode))
})
return [wxsCode.join('').trim(), wxsFiles]
}
function shouldWrapper(node) {
......@@ -56,7 +76,7 @@ function shouldWrapper(node) {
module.exports = function generate(node, state) {
if (shouldWrapper(node)) {
return [`<view>${genChildren(node).trim()}</view>`, genWxs(state.wxs)]
return [`<view>${genChildren(node).trim()}</view>`, ...genWxs(state.wxs, state)]
}
return [genChildren(node).trim(), genWxs(state.wxs)]
return [genChildren(node).trim(), ...genWxs(state.wxs, state)]
}
const traverse = require('./traverse')
const generate = require('./generate')
module.exports = function transform(ast) {
module.exports = function transform(ast, options) {
const state = {
wxs: []
wxs: [],
filename: options.filename
}
return generate(traverse(ast, state), state)
}
const isWin = /^win/.test(process.platform)
const normalizePath = path => (isWin ? path.replace(/\\/g, '/') : path)
const normalizePath = path => (isWin ? path.replace(/\\/g, '/') : path)
const camelizeRE = /-(\w)/g
function camelize(str) {
return str.replace(camelizeRE, (_, c) => c ? c.toUpperCase() : '')
}
/**
* Capitalize a string.
*/
function capitalize(str) {
return str.charAt(0).toUpperCase() + str.slice(1)
}
module.exports = {
camelize,
capitalize,
normalizePath
}
......@@ -61,6 +61,10 @@ function parseProperties (properties, vueComponentOptions) {
vueComponentOptions.props = props;
}
function parseComponents (vueComponentOptions) {
vueComponentOptions.components = global['__wxVueOptions'].components;
}
function parseOptions (options, vueComponentOptions) {
if (!options) {
return
......@@ -72,6 +76,10 @@ function parseMethods (methods, vueComponentOptions) {
if (!methods) {
return
}
if (methods.$emit) {
console.warn(`Method "$emit" conflicts with an existing Vue instance method`);
delete methods.$emit;
}
vueComponentOptions.methods = methods;
}
......@@ -233,6 +241,8 @@ function parseComponent (mpComponentOptions) {
}
};
parseComponents(vueComponentOptions);
parseData(data, vueComponentOptions);
parseOptions(options, vueComponentOptions);
parseMethods(methods, vueComponentOptions);
......@@ -288,15 +298,14 @@ function getDate () {
return new (Function.prototype.bind.apply(Date, args))()
}
global['__wxRoute'] = [];
global['__wxRoute'] = '';
global['__wxComponents'] = Object.create(null);
global['__wxVueOptions'] = Object.create(null);
function Component (options) {
const componentOptions = parseComponent(options);
componentOptions.mixins.unshift(polyfill);
if (!global['__wxComponents']) {
global['__wxComponents'] = Object.create(null);
}
global['__wxComponents'][global['__wxRoute'].pop()] = componentOptions;
global['__wxComponents'][global['__wxRoute']] = componentOptions;
}
function Behavior (options) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册