Skip to content

Commit

Permalink
feat(cli): auto components
Browse files Browse the repository at this point in the history
  • Loading branch information
fxy060608 committed Dec 18, 2019
1 parent 93caa24 commit d0d1bbb
Show file tree
Hide file tree
Showing 30 changed files with 584 additions and 1,007 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,9 @@
"rollup-plugin-uglify": "^6.0.3",
"shell-exec": "^1.0.2",
"strip-json-comments": "^2.0.1",
"vue": "^2.6.8",
"vue": "^2.6.11",
"vue-router": "^3.0.1",
"vue-template-compiler": "^2.6.8",
"vue-template-compiler": "^2.6.11",
"webpack": "^4.18.0",
"webpack-bundle-analyzer": "^3.0.3",
"webpack-virtual-modules": "^0.1.10"
Expand Down
34 changes: 32 additions & 2 deletions packages/uni-cli-shared/lib/pages.js
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ function getGlobalUsingComponentsCode () {
return ''
}
return generateGlobalUsingComponentsCode(usingComponents)
}
}

function getUsingComponentsCode (pagePath) {
const usingComponents = usingComponentsPages[pagePath]
Expand All @@ -325,6 +325,35 @@ function addPageUsingComponents (pagePath, usingComponents) {
usingComponentsPages[pagePath] = usingComponents
}
}
// 存储自动组件
const autoComponentMap = {}

function addAutoComponent (name) {
const options = process.UNI_AUTO_COMPONENTS
const opt = options.find(opt => opt.test(name))
if (!opt) { // 不匹配
return (autoComponentMap[name] = true) // cache
}
return (autoComponentMap[name] = {
name,
identifier: capitalize(camelize(name + '-auto-import')),
source: name.replace(opt.test, opt.replacement)
})
}

function getAutoComponents (autoComponents) {
const components = []
autoComponents.forEach(name => {
let autoComponent = autoComponentMap[name]
if (!autoComponent) {
autoComponent = addAutoComponent(name)
}
if (autoComponent !== true) {
components.push(autoComponent)
}
})
return components
}

module.exports = {
getMainEntry,
Expand All @@ -334,7 +363,8 @@ module.exports = {
getPagesJson,
parsePagesJson,
pagesJsonJsFileName,
addPageUsingComponents,
getAutoComponents,
addPageUsingComponents,
getUsingComponentsCode,
generateUsingComponentsCode,
getGlobalUsingComponentsCode,
Expand Down
11 changes: 8 additions & 3 deletions packages/uni-template-compiler/__tests__/demo.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
const compiler = require('../lib')
const res = compiler.compile(
`
<view class="custom-class"></view>
<view class="custom-class">
<uni-badge/>
<uni-badge/>
<uni-tag/>
<uni-tag/>
</view>
`, {
miniprogram: true,
resourcePath: '/User/fxy/Documents/test.wxml',
Expand All @@ -14,9 +19,9 @@ const res = compiler.compile(
mp: {
platform: 'app-plus'
},
filterModules: ['swipe'],
filterModules: ['swipe']
// service: true,
view: true
// view: true

})
console.log(require('util').inspect(res, {
Expand Down
12 changes: 12 additions & 0 deletions packages/uni-template-compiler/lib/auto-components.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const {
isComponent
} = require('./util')

module.exports = {
preTransformNode (el, options) {
if (isComponent(el.tag)) {
// 挂在 isReservedTag 上边,可以保证外部访问到
(options.isReservedTag.autoComponents || (options.isReservedTag.autoComponents = new Set())).add(el.tag)
}
}
}
25 changes: 21 additions & 4 deletions packages/uni-template-compiler/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,25 @@ const {
isComponent
} = require('./util')

function compileTemplate (source, options) {
const res = compile(source, options)
console.log(options)
const {
autoComponents
} = options.isReservedTag
if (autoComponents) {
console.log('检测到的自定义组件:' + [...autoComponents])
}
res.components = `{
'uni-badge': require('@components/uni-badge/uni-badge.vue').default,
'uni-tag': require('@components/uni-tag/uni-tag.vue').default
}`
return res
}

module.exports = {
compile (source, options = {}) {
(options.modules || (options.modules = [])).push(require('./auto-components'))
if (options.service) {
(options.modules || (options.modules = [])).push(require('./app/service'))
options.optimize = false // 启用 staticRenderFns
Expand All @@ -37,7 +54,7 @@ module.exports = {
options.getTagNamespace = () => false

try {
return compile(source, options)
return compileTemplate(source, options)
} catch (e) {
console.error(source)
throw e
Expand All @@ -47,15 +64,15 @@ module.exports = {
options.optimize = false // 暂不启用 staticRenderFns
options.isReservedTag = (tagName) => false // 均为组件
try {
return compile(source, options)
return compileTemplate(source, options)
} catch (e) {
console.error(source)
throw e
}
}

if (!options.mp) { // h5
return compile(source, options)
return compileTemplate(source, options)
}

(options.modules || (options.modules = [])).push(compilerModule)
Expand All @@ -64,7 +81,7 @@ module.exports = {
options.modules.push(compilerAlipayModule)
}

const res = compile(source, Object.assign(options, {
const res = compileTemplate(source, Object.assign(options, {
optimize: false
}))

Expand Down
53 changes: 34 additions & 19 deletions packages/uni-template-compiler/lib/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ const {
METHOD_RENDER_LIST
} = require('./constants')

function cached (fn) {
function cached(fn) {
const cache = Object.create(null)
return function cachedFn (str) {
return function cachedFn(str) {
const hit = cache[str]
return hit || (cache[str] = fn(str))
}
Expand All @@ -21,7 +21,7 @@ const camelize = cached((str) => {
return str.replace(camelizeRE, (_, c) => c ? c.toUpperCase() : '')
})

function getCode (node) {
function getCode(node) {
return babelGenerate(t.cloneDeep(node), {
compact: true,
jsescOption: {
Expand All @@ -31,11 +31,11 @@ function getCode (node) {
}).code
}

function traverseKey (ast, state) {
function traverseKey(ast, state) {
let forKey = false
babelTraverse(ast, {
noScope: true,
ObjectProperty (path) {
ObjectProperty(path) {
if (forKey) {
return
}
Expand All @@ -44,7 +44,7 @@ function traverseKey (ast, state) {
path.stop()
}
},
CallExpression (path) {
CallExpression(path) {
if (path.node.callee.name === METHOD_RENDER_LIST) {
path.stop()
}
Expand All @@ -53,15 +53,15 @@ function traverseKey (ast, state) {
return forKey
}

function traverseFilter (ast, state) {
function traverseFilter(ast, state) {
const filterModules = state.options.filterModules
if (!filterModules.length) {
return false
}
let isFilter = false
babelTraverse(ast, {
noScope: true,
Identifier (path) {
Identifier(path) {
if (filterModules.includes(path.node.name)) {
const parentNode = path.parent
if ( // t.msg || t['msg']
Expand All @@ -81,11 +81,11 @@ function traverseFilter (ast, state) {
return isFilter
}

function wrapper (code, reverse = false) {
function wrapper(code, reverse = false) {
return reverse ? `{{!(${code})}}` : `{{${code}}}`
}

function genCode (node, noWrapper = false, reverse = false, quotes = true) {
function genCode(node, noWrapper = false, reverse = false, quotes = true) {
if (t.isStringLiteral(node)) {
return reverse ? `!(${node.value})` : node.value
} else if (t.isIdentifier(node)) {
Expand All @@ -98,11 +98,11 @@ function genCode (node, noWrapper = false, reverse = false, quotes = true) {
return noWrapper ? code : wrapper(code, reverse)
}

function getForIndexIdentifier (id) {
function getForIndexIdentifier(id) {
return `__i${id}__`
}

function getForKey (forKey, forIndex, state) {
function getForKey(forKey, forIndex, state) {
if (forKey) {
if (t.isIdentifier(forKey)) {
if (forIndex !== forKey.name) { // 非 forIndex
Expand All @@ -121,7 +121,7 @@ function getForKey (forKey, forIndex, state) {
return ''
}

function processMemberProperty (node, state) {
function processMemberProperty(node, state) {
if (node.computed) {
const property = node.property
if (t.isNumericLiteral(property)) {
Expand All @@ -139,7 +139,7 @@ function processMemberProperty (node, state) {
}
}

function processMemberExpression (element, state) {
function processMemberExpression(element, state) {
// item['order']=>item.order
if (t.isMemberExpression(element)) {
element = t.cloneDeep(element)
Expand All @@ -152,27 +152,27 @@ function processMemberExpression (element, state) {

babelTraverse(element, {
noScope: true,
MemberExpression (path) {
MemberExpression(path) {
processMemberProperty(path.node, state)
}
})

babelTraverse(element, {
noScope: true,
MemberExpression (path) {
MemberExpression(path) {
if (t.isStringLiteral(path.node.property)) {
path.node.computed = false
}
},
StringLiteral (path) {
StringLiteral(path) {
path.replaceWith(t.identifier(path.node.value))
}
})
}
return element
}

function hasOwn (obj, key) {
function hasOwn(obj, key) {
return hasOwnProperty.call(obj, key)
}

Expand All @@ -182,9 +182,10 @@ const {
getTagName
} = require('./h5')

function isComponent (tagName) {
function isComponent(tagName) {
if (
tagName === 'block' ||
tagName === 'component' ||
tagName === 'template' ||
tagName === 'keep-alive'
) {
Expand All @@ -193,7 +194,21 @@ function isComponent (tagName) {
return !hasOwn(tags, getTagName(tagName.replace('v-uni-', '')))
}

function makeMap(str, expectsLowerCase) {
const map = Object.create(null)
const list = str.split(',')
for (let i = 0; i < list.length; i++) {
map[list[i]] = true
}
return expectsLowerCase ?
val => map[val.toLowerCase()] :
val => map[val]
}
module.exports = {
isUnaryTag: makeMap(
'image,area,base,br,col,embed,frame,hr,img,input,isindex,keygen,' +
'link,meta,param,source,track,wbr'
),
isComponent,
genCode,
getCode,
Expand Down
3 changes: 2 additions & 1 deletion packages/vue-cli-plugin-hbuilderx/build/vue-loader.conf.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const TAGS = [
const TAGS = [
'ad',
'text',
'image',
Expand Down Expand Up @@ -94,6 +94,7 @@ if (process.env.UNI_USING_NVUE_COMPILER) {

module.exports = {
preserveWhitespace: false,
isAppNVue: true,
compiler: require('weex-template-compiler'),
compilerOptions: {
modules
Expand Down
Loading

0 comments on commit d0d1bbb

Please sign in to comment.