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

refactor(v3): uni-migration

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