const path = require('path')
|
|
const {
|
hyphenate,
|
isComponent
|
} = require('./util')
|
|
const {
|
removeExt
|
} = require('@dcloudio/uni-cli-shared/lib/util')
|
|
const {
|
getAutoComponents
|
} = require('@dcloudio/uni-cli-shared/lib/pages')
|
|
const {
|
updateUsingAutoImportComponents
|
} = require('@dcloudio/uni-cli-shared/lib/cache')
|
|
function formatSource (source) {
|
if (source.indexOf('@/') === 0) { // 根目录
|
source = source.replace('@/', '')
|
} else { // node_modules
|
if (process.env.UNI_PLATFORM === 'mp-alipay') {
|
if (source.indexOf('@') === 0) {
|
source = source.replace('@', 'npm-scope-')
|
}
|
}
|
source = 'node-modules/' + source
|
}
|
return removeExt(source)
|
}
|
|
function getWebpackChunkName (source) {
|
return formatSource(source)
|
}
|
|
function updateMPUsingAutoImportComponents (autoComponents, options) {
|
if (!options.resourcePath) {
|
return
|
}
|
const resourcePath = options.resourcePath.replace(path.extname(options.resourcePath), '')
|
if (resourcePath === 'App') {
|
return
|
}
|
const usingAutoImportComponents = Object.create(null)
|
autoComponents.forEach(({
|
name,
|
source
|
}) => {
|
// 自定义组件统一格式化为 kebab-case
|
usingAutoImportComponents[hyphenate(name)] = '/' + formatSource(source)
|
})
|
updateUsingAutoImportComponents(resourcePath, usingAutoImportComponents) // 更新json
|
}
|
|
function generateAutoComponentsCode (autoComponents, dynamic = false) {
|
const components = []
|
autoComponents.forEach(({
|
name,
|
source
|
}) => {
|
// 统一转换为驼峰命名
|
name = name.replace(/-(\w)/g, (_, str) => str.toUpperCase())
|
if (dynamic) {
|
components.push(
|
`'${name}': function(){return import(/* webpackChunkName: "${getWebpackChunkName(source)}" */'${source}')}`
|
)
|
} else {
|
components.push(`'${name}': require('${source}').default`)
|
}
|
})
|
if (process.env.NODE_ENV === 'production') {
|
return `var components = {${components.join(',')}}`
|
}
|
return `var components;
|
try{
|
components = {${components.join(',')}}
|
}catch(e){
|
if(e.message.indexOf('Cannot find module') !== -1 && e.message.indexOf('.vue') !== -1){
|
console.error(e.message)
|
console.error('1. 排查组件名称拼写是否正确')
|
console.error('2. 排查组件是否符合 easycom 规范,文档:https://uniapp.dcloud.net.cn/collocation/pages?id=easycom')
|
console.error('3. 若组件不符合 easycom 规范,需手动引入,并在 components 中注册该组件')
|
} else {
|
throw e
|
}
|
}`
|
}
|
|
function compileTemplate (source, options, compile) {
|
const res = compile(source, options)
|
const autoComponents = getAutoComponents([...(options.isUnaryTag.autoComponents || [])])
|
if (autoComponents.length) {
|
// console.log('检测到的自定义组件:' + JSON.stringify(autoComponents))
|
res.components = generateAutoComponentsCode(autoComponents, options.mp)
|
} else {
|
res.components = 'var components;'
|
}
|
if (options.mp) { // 小程序 更新 json 每次编译都要调整,保证热更新时增减组件一致
|
updateMPUsingAutoImportComponents(autoComponents || [], options)
|
}
|
return res
|
}
|
|
const compilerModule = {
|
preTransformNode (el, options) {
|
if (el.tag === 'match-media' && process.env.UNI_PLATFORM !== 'mp-weixin') {
|
el.tag = 'uni-match-media'
|
}
|
if (process.env.UNI_PLATFORM === 'quickapp-native') {
|
// 排查所有标签
|
(options.isUnaryTag.autoComponents || (options.isUnaryTag.autoComponents = new Set())).add(el.tag)
|
} else if (isComponent(el.tag) && el.tag !== 'App') { // App.vue
|
// 挂在 isUnaryTag 上边,可以保证外部访问到
|
(options.isUnaryTag.autoComponents || (options.isUnaryTag.autoComponents = new Set())).add(el.tag)
|
}
|
}
|
}
|
module.exports = {
|
compileTemplate,
|
module: compilerModule
|
}
|