From 10c4a910711c657d9a99698fff7d6fcba5ce7338 Mon Sep 17 00:00:00 2001 From: fxy060608 Date: Tue, 5 Nov 2019 21:29:32 +0800 Subject: [PATCH] feat(v3): uni-migration --- packages/uni-migration/lib/index.js | 3 +- .../transform/wxml-transformer/index.js | 4 +- .../transform/wxml-transformer/parser.js | 21 ++++ .../wxml-transformer/transform/generate.js | 41 +++++++ .../wxml-transformer/transform/index.js | 9 ++ .../wxml-transformer/transform/traverse.js | 101 ++++++++++++++++++ packages/uni-migration/package.json | 6 +- 7 files changed, 182 insertions(+), 3 deletions(-) create mode 100644 packages/uni-migration/lib/mp-weixin/transform/wxml-transformer/parser.js create mode 100644 packages/uni-migration/lib/mp-weixin/transform/wxml-transformer/transform/generate.js create mode 100644 packages/uni-migration/lib/mp-weixin/transform/wxml-transformer/transform/index.js create mode 100644 packages/uni-migration/lib/mp-weixin/transform/wxml-transformer/transform/traverse.js diff --git a/packages/uni-migration/lib/index.js b/packages/uni-migration/lib/index.js index abdc94846..1cd004a0e 100644 --- a/packages/uni-migration/lib/index.js +++ b/packages/uni-migration/lib/index.js @@ -17,6 +17,7 @@ module.exports = function migrate(input, out, options = { } migrater.transform(input, out, options).forEach(file => { console.log(`写入: ${file.path}`) - fs.outputFileSync(file.path, file.content) + console.log(`${file.content}`) + // fs.outputFileSync(file.path, file.content) }) } diff --git a/packages/uni-migration/lib/mp-weixin/transform/wxml-transformer/index.js b/packages/uni-migration/lib/mp-weixin/transform/wxml-transformer/index.js index 45525158e..86eec369a 100644 --- a/packages/uni-migration/lib/mp-weixin/transform/wxml-transformer/index.js +++ b/packages/uni-migration/lib/mp-weixin/transform/wxml-transformer/index.js @@ -1,6 +1,8 @@ const fs = require('fs') const path = require('path') +const parse = require('./parser') +const transform = require('./transform') module.exports = function transformWxml(filepath) { - return [fs.readFileSync(filepath, 'utf8')] + return transform(parse(fs.readFileSync(filepath, 'utf8'))) } diff --git a/packages/uni-migration/lib/mp-weixin/transform/wxml-transformer/parser.js b/packages/uni-migration/lib/mp-weixin/transform/wxml-transformer/parser.js new file mode 100644 index 000000000..5924fc57c --- /dev/null +++ b/packages/uni-migration/lib/mp-weixin/transform/wxml-transformer/parser.js @@ -0,0 +1,21 @@ +const { + Parser, + DomHandler +} = require('stricter-htmlparser2') + + +module.exports = function parse(sourceCode) { + const handler = new DomHandler() + new Parser(handler, { + xmlMode: false, + lowerCaseAttributeNames: false, + recognizeSelfClosing: true, + lowerCaseTags: false + }).end(sourceCode) + return { + type: 'tag', + name: 'root', + attribs: {}, + children: Array.isArray(handler.dom) ? handler.dom : [handler.dom] + } +} diff --git a/packages/uni-migration/lib/mp-weixin/transform/wxml-transformer/transform/generate.js b/packages/uni-migration/lib/mp-weixin/transform/wxml-transformer/transform/generate.js new file mode 100644 index 000000000..0382607d1 --- /dev/null +++ b/packages/uni-migration/lib/mp-weixin/transform/wxml-transformer/transform/generate.js @@ -0,0 +1,41 @@ +function genAttrs(node) { + const attribs = node.attribs + const attribsArr = Object.keys(attribs).map(name => `${name}="${attribs[name]}"`) + if (!attribsArr.length) { + return '' + } + return ' ' + attribsArr.join(' ') +} + +function genChildren(node) { + if (!node.children) { + return '' + } + return node.children.map(childNode => genElement(childNode)).join('') +} + +function genElement(node) { + if (node.type === 'text') { + return node.data + } else if (node.type === 'tag') { + const name = node.name + return `<${name}${genAttrs(node)}>${genChildren(node)}` + } + return '' +} + +function genWxs(wxs) { + return wxs.map(wxsNode => genElement(wxsNode)).join('') +} + +module.exports = function generate(node, state) { + if (node.children.length > 1) { + return [genChildren({ + type: 'tag', + name: 'view', + attribs: {}, + children: node.children + }), genWxs(state.wxs)] + } + return [genChildren(node), genWxs(state.wxs)] +} diff --git a/packages/uni-migration/lib/mp-weixin/transform/wxml-transformer/transform/index.js b/packages/uni-migration/lib/mp-weixin/transform/wxml-transformer/transform/index.js new file mode 100644 index 000000000..e164e60bd --- /dev/null +++ b/packages/uni-migration/lib/mp-weixin/transform/wxml-transformer/transform/index.js @@ -0,0 +1,9 @@ +const traverse = require('./traverse') +const generate = require('./generate') + +module.exports = function transform(ast) { + const state = { + wxs: [] + } + return generate(traverse(ast, state), state) +} diff --git a/packages/uni-migration/lib/mp-weixin/transform/wxml-transformer/transform/traverse.js b/packages/uni-migration/lib/mp-weixin/transform/wxml-transformer/transform/traverse.js new file mode 100644 index 000000000..f7f4969ef --- /dev/null +++ b/packages/uni-migration/lib/mp-weixin/transform/wxml-transformer/transform/traverse.js @@ -0,0 +1,101 @@ +const { + parse +} = require('mustache') + +const ATTRS = { + 'wx:if': 'v-if', + 'wx:elif': 'v-else-if', + 'wx:else': 'v-else' +} + +function parseMustache(expr) { + const tokens = parse(expr) + const isIdentifier = tokens.length === 1 + return tokens.map(token => { + if (token[0] === 'text') { + return `'${token[1]}'` + } else if (token[0] === 'name') { + if (isIdentifier) { + return token[1] + } + return `(${token[1]})` + } + }).join('+') +} + + +function transformDirective(name, value, attribs) { + if (ATTRS[name]) { + attribs[ATTRS[name]] = parseMustache(value) + return true + } +} + +const bindRE = /bind:?/ +const catchRE = /catch:?/ +const captureBindRE = /capture-bind:?/ +const captureCatchRE = /capture-catch:?/ + +function transformEvent(name, value, attribs) { + let event = name + if (name.indexOf('bind') === 0) { + event = name.replace(bindRE, '@') + } else if (name.indexOf('catch') === 0) { + event = name.replace(catchRE, '@') + '.stop' + } else if (name.indexOf('capture-bind') === 0) { + event = name.replace(captureBindRE, '@') + '.capture' + } else if (name.indexOf('capture-catch') === 0) { + event = name.replace(captureCatchRE, '@') + '.stop.capture' + } + if (event !== name) { + attribs[event] = value + return true + } +} + + +function transformAttr(name, value, attribs) { + delete attribs[name] + if (transformDirective(name, value, attribs)) { + return + } + if (transformEvent(name, value, attribs)) { + return + } + if (value.indexOf('{{') === -1) { + attribs[name] = value + return + } + attribs[':' + name] = parseMustache(value) +} + +function transformAttrs(node, state) { + const attribs = node.attribs + if (!attribs) { + return + } + Object.keys(attribs).forEach(name => { + transformAttr(name, attribs[name], attribs) + }) +} + +function transformChildren(node, state) { + node.children = node.children.filter(childNode => transformNode(childNode, state)) +} + +function transformNode(node, state) { + if (node.name === 'wxs') { + state.wxs.push(node) + return false + } + if (node.type === 'tag') { + transformAttrs(node, state) + transformChildren(node, state) + } + return true +} + +module.exports = function traverse(node, state) { + transformNode(node, state) + return node +} diff --git a/packages/uni-migration/package.json b/packages/uni-migration/package.json index cf7fe4dff..933139b39 100644 --- a/packages/uni-migration/package.json +++ b/packages/uni-migration/package.json @@ -16,5 +16,9 @@ }, "author": "fxy060608", "license": "Apache-2.0", - "gitHead": "6b0d55e296028761e3de4b561c1ad7c5fb7a23e2" + "gitHead": "6b0d55e296028761e3de4b561c1ad7c5fb7a23e2", + "dependencies": { + "mustache": "^3.1.0", + "stricter-htmlparser2": "^3.9.6" + } } -- GitLab