You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
458 lines
12 KiB
458 lines
12 KiB
const fs = require('fs')
|
|
const path = require('path')
|
|
|
|
const {
|
|
hasOwn,
|
|
getPlatforms,
|
|
getH5Options,
|
|
getFlexDirection,
|
|
getNetworkTimeout,
|
|
normalizePath
|
|
} = require('@dcloudio/uni-cli-shared')
|
|
|
|
const {
|
|
addPageUsingComponents
|
|
} = require('@dcloudio/uni-cli-shared/lib/pages')
|
|
|
|
const compilerVersion = require('@dcloudio/webpack-uni-pages-loader/package.json')['uni-app'].compilerVersion
|
|
|
|
const PLATFORMS = getPlatforms()
|
|
|
|
const removePlatformStyle = function (style) {
|
|
Object.keys(style).forEach(name => {
|
|
if (PLATFORMS.includes(name)) {
|
|
delete style[name]
|
|
}
|
|
})
|
|
}
|
|
|
|
const getPageComponents = function (inputDir, pagesJson) {
|
|
const firstPagePath = pagesJson.pages[0].path
|
|
const pages = pagesJson.pages
|
|
|
|
// 解析分包
|
|
if (pagesJson.subPackages && pagesJson.subPackages.length) {
|
|
pagesJson.subPackages.forEach(({
|
|
root,
|
|
pages: subPages
|
|
}) => {
|
|
if (root && subPages.length) {
|
|
subPages.forEach(subPage => {
|
|
subPage.path = normalizePath(path.join(root, subPage.path))
|
|
pages.push(subPage)
|
|
})
|
|
}
|
|
})
|
|
}
|
|
|
|
const tabBarList = (pagesJson.tabBar && pagesJson.tabBar.list) || []
|
|
tabBarList.forEach(item => { // 添加全部属性,方便 Vue 响应式
|
|
item.text = item.text || ''
|
|
item.iconPath = item.iconPath || ''
|
|
item.selectedIconPath = item.selectedIconPath || ''
|
|
item.redDot = false
|
|
item.badge = ''
|
|
})
|
|
|
|
if (tabBarList.length) { // 添加全部属性,方便 Vue 响应式
|
|
pagesJson.tabBar.color = pagesJson.tabBar.color || '#999'
|
|
pagesJson.tabBar.selectedColor = pagesJson.tabBar.selectedColor || '#007aff'
|
|
pagesJson.tabBar.backgroundColor = pagesJson.tabBar.backgroundColor || '#f7f7fa'
|
|
pagesJson.tabBar.borderStyle = pagesJson.tabBar.borderStyle || 'black'
|
|
}
|
|
|
|
const globalStyle = Object.assign({}, pagesJson.globalStyle || {})
|
|
|
|
Object.assign(
|
|
globalStyle,
|
|
globalStyle['app-plus'] || {},
|
|
globalStyle.h5 || {}
|
|
)
|
|
|
|
if (process.env.UNI_SUB_PLATFORM) {
|
|
Object.assign(globalStyle, globalStyle[process.env.UNI_SUB_PLATFORM] || {})
|
|
}
|
|
|
|
process.UNI_H5_PAGES_JSON = {
|
|
pages: {},
|
|
globalStyle
|
|
}
|
|
|
|
removePlatformStyle(process.UNI_H5_PAGES_JSON.globalStyle)
|
|
|
|
return pages.map(page => {
|
|
const name = page.path.replace(/\//g, '-')
|
|
const pagePath = normalizePath(path.resolve(inputDir, page.path))
|
|
const props = page.style || {}
|
|
const isEntry = firstPagePath === page.path
|
|
const tabBarIndex = tabBarList.findIndex(tabBarPage => tabBarPage.pagePath === page.path)
|
|
const isTabBar = tabBarIndex !== -1
|
|
|
|
let isNVue = false
|
|
if (process.env.UNI_USING_NVUE_COMPILER) {
|
|
if (!fs.existsSync(pagePath + '.vue') && fs.existsSync(pagePath + '.nvue')) {
|
|
isNVue = true
|
|
}
|
|
}
|
|
// 解析 titleNView,pullToRefresh
|
|
const h5Options = Object.assign({}, props['app-plus'] || {}, props.h5 || {})
|
|
|
|
if (process.env.UNI_SUB_PLATFORM) {
|
|
Object.assign(h5Options, props[process.env.UNI_SUB_PLATFORM] || {})
|
|
Object.assign(props, props[process.env.UNI_SUB_PLATFORM] || {})
|
|
}
|
|
|
|
removePlatformStyle(h5Options)
|
|
|
|
if (hasOwn(h5Options, 'titleNView')) {
|
|
props.titleNView = h5Options.titleNView
|
|
}
|
|
if (hasOwn(h5Options, 'pullToRefresh')) {
|
|
props.pullToRefresh = h5Options.pullToRefresh
|
|
}
|
|
|
|
let windowTop = 44
|
|
const pageStyle = Object.assign({}, globalStyle, props)
|
|
const titleNViewTypeList = {
|
|
none: 'default',
|
|
auto: 'transparent',
|
|
always: 'float'
|
|
}
|
|
let titleNView = pageStyle.titleNView
|
|
titleNView = Object.assign({}, {
|
|
type: pageStyle.navigationStyle === 'custom' ? 'none' : 'default'
|
|
}, pageStyle.transparentTitle in titleNViewTypeList ? {
|
|
type: titleNViewTypeList[pageStyle.transparentTitle],
|
|
backgroundColor: 'rgba(0,0,0,0)'
|
|
} : null, typeof titleNView === 'object' ? titleNView : (typeof titleNView === 'boolean' ? {
|
|
type: titleNView ? 'default' : 'none'
|
|
} : null))
|
|
if (titleNView.type === 'none' || titleNView.type === 'transparent') {
|
|
windowTop = 0
|
|
}
|
|
|
|
// 删除 app-plus 平台配置
|
|
delete props['app-plus']
|
|
delete props.h5
|
|
|
|
if (process.env.UNI_SUB_PLATFORM) {
|
|
delete props[process.env.UNI_SUB_PLATFORM]
|
|
}
|
|
|
|
process.UNI_H5_PAGES_JSON.pages[page.path] = props
|
|
|
|
// 缓存usingComponents
|
|
addPageUsingComponents(page.path, props.usingComponents)
|
|
|
|
return {
|
|
name,
|
|
route: page.path,
|
|
path: pagePath,
|
|
props,
|
|
isNVue,
|
|
isEntry,
|
|
isTabBar,
|
|
tabBarIndex,
|
|
isQuit: isEntry || isTabBar,
|
|
windowTop
|
|
}
|
|
}).filter(pageComponents => !!pageComponents)
|
|
}
|
|
|
|
const genRegisterPageVueComponentsCode = function (pageComponents) {
|
|
return pageComponents
|
|
.map(({
|
|
name,
|
|
path,
|
|
isNVue,
|
|
isQuit,
|
|
isEntry,
|
|
isTabBar
|
|
}) => {
|
|
const ext = isNVue ? '.nvue' : '.vue'
|
|
|
|
return `Vue.component('${name}', resolve=>{
|
|
const component = {
|
|
component:require.ensure([], () => resolve(require('${path}${ext}')), '${name}'),
|
|
delay:__uniConfig['async'].delay,
|
|
timeout: __uniConfig['async'].timeout
|
|
}
|
|
if(__uniConfig['async']['loading']){
|
|
component.loading={
|
|
name:'SystemAsyncLoading',
|
|
render(createElement){
|
|
return createElement(__uniConfig['async']['loading'])
|
|
}
|
|
}
|
|
}
|
|
if(__uniConfig['async']['error']){
|
|
component.error={
|
|
name:'SystemAsyncError',
|
|
render(createElement){
|
|
return createElement(__uniConfig['async']['error'])
|
|
}
|
|
}
|
|
}
|
|
return component
|
|
})`
|
|
})
|
|
.join('\n')
|
|
}
|
|
|
|
const genPageRoutes = function (pageComponents) {
|
|
let id = 1
|
|
return pageComponents
|
|
.map(({
|
|
name,
|
|
route,
|
|
props,
|
|
isNVue,
|
|
isQuit,
|
|
isEntry,
|
|
isTabBar,
|
|
windowTop,
|
|
tabBarIndex
|
|
}) => {
|
|
return `
|
|
{
|
|
path: '/${isEntry ? '' : route}',${isEntry ? '\nalias:\'/' + route + '\',' : ''}
|
|
component: {
|
|
render (createElement) {
|
|
return createElement(
|
|
'Page',
|
|
{
|
|
props: Object.assign({
|
|
${isQuit ? 'isQuit:true,\n' : ''}
|
|
${isEntry ? 'isEntry:true,\n' : ''}
|
|
${isTabBar ? 'isTabBar:true,\n' : ''}
|
|
${isTabBar ? ('tabBarIndex:' + tabBarIndex) : ''}
|
|
},__uniConfig.globalStyle,${JSON.stringify(props)})
|
|
},
|
|
[
|
|
createElement('${name}', {
|
|
slot: 'page'
|
|
})
|
|
]
|
|
)
|
|
}
|
|
},
|
|
meta:{${isQuit ? '\nid:' + (id++) + ',' : ''}
|
|
name:'${name}',
|
|
isNVue:${isNVue},
|
|
pagePath:'${route}'${isQuit ? ',\nisQuit:true' : ''}${isEntry ? ',\nisEntry:true' : ''}${isTabBar ? ',\nisTabBar:true' : ''}${tabBarIndex !== -1 ? (',\ntabBarIndex:' + tabBarIndex) : ''},
|
|
windowTop:${windowTop}
|
|
}
|
|
}`
|
|
})
|
|
}
|
|
|
|
const genSystemRoutes = function () {
|
|
return [
|
|
`
|
|
{
|
|
path: '/preview-image',
|
|
component: {
|
|
render (createElement) {
|
|
return createElement(
|
|
'Page',
|
|
{
|
|
props:{
|
|
navigationStyle:'custom'
|
|
}
|
|
},
|
|
[
|
|
createElement('system-preview-image', {
|
|
slot: 'page'
|
|
})
|
|
]
|
|
)
|
|
}
|
|
},
|
|
meta:{
|
|
name:'preview-image',
|
|
pagePath:'/preview-image'
|
|
}
|
|
}
|
|
`,
|
|
`
|
|
{
|
|
path: '/choose-location',
|
|
component: {
|
|
render (createElement) {
|
|
return createElement(
|
|
'Page',
|
|
{
|
|
props:{
|
|
navigationStyle:'custom'
|
|
}
|
|
},
|
|
[
|
|
createElement('system-choose-location', {
|
|
slot: 'page'
|
|
})
|
|
]
|
|
)
|
|
}
|
|
},
|
|
meta:{
|
|
name:'choose-location',
|
|
pagePath:'/choose-location'
|
|
}
|
|
}
|
|
`,
|
|
`
|
|
{
|
|
path: '/open-location',
|
|
component: {
|
|
render (createElement) {
|
|
return createElement(
|
|
'Page',
|
|
{
|
|
props:{
|
|
navigationStyle:'custom'
|
|
}
|
|
},
|
|
[
|
|
createElement('system-open-location', {
|
|
slot: 'page'
|
|
})
|
|
]
|
|
)
|
|
}
|
|
},
|
|
meta:{
|
|
name:'open-location',
|
|
pagePath:'/open-location'
|
|
}
|
|
}
|
|
`
|
|
]
|
|
}
|
|
|
|
function filterPages (pagesJson, includes) {
|
|
const pages = []
|
|
let subPackages = pagesJson.subPackages || []
|
|
if (!Array.isArray(subPackages)) {
|
|
subPackages = []
|
|
}
|
|
includes.forEach(includePagePath => {
|
|
let page = pagesJson.pages.find(page => page.path === includePagePath)
|
|
if (!page) {
|
|
for (let i = 0; i < subPackages.length; i++) {
|
|
const {
|
|
root,
|
|
pages: subPages
|
|
} = subPackages[i]
|
|
page = subPages.find(subPage => normalizePath(path.join(root, subPage.path)) === includePagePath)
|
|
if (page) {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
if (!page) {
|
|
console.error(`${includePagePath} is not found`)
|
|
}
|
|
pages.push(page)
|
|
})
|
|
pagesJson.pages = pages
|
|
}
|
|
|
|
function genLayoutComponentsCode (pagesJson) {
|
|
const code = []
|
|
const {
|
|
leftWindow,
|
|
rightWindow
|
|
} = pagesJson
|
|
if (leftWindow && leftWindow.path) {
|
|
code.push(
|
|
`import LeftWindow from './${leftWindow.path}';
|
|
${leftWindow.style ? ('LeftWindow.style=' + JSON.stringify(leftWindow.style)) : ''}
|
|
Vue.component('VUniLeftWindow',LeftWindow);`
|
|
)
|
|
}
|
|
|
|
if (rightWindow && rightWindow.path) {
|
|
code.push(
|
|
`
|
|
import RightWindow from './${rightWindow.path}';
|
|
${rightWindow.style ? ('RightWindow.style=' + JSON.stringify(rightWindow.style)) : ''}
|
|
Vue.component('VUniRightWindow',RightWindow);`
|
|
)
|
|
}
|
|
return code.join('\n')
|
|
}
|
|
|
|
module.exports = function (pagesJson, manifestJson, loader) {
|
|
const inputDir = process.env.UNI_INPUT_DIR
|
|
|
|
global.uniPlugin.configurePages.forEach(configurePages => {
|
|
configurePages(pagesJson, manifestJson, loader)
|
|
})
|
|
|
|
if (loader.resourceQuery) {
|
|
const loaderUtils = require('loader-utils')
|
|
const params = loaderUtils.parseQuery(loader.resourceQuery)
|
|
if (params.pages) {
|
|
try {
|
|
const pages = JSON.parse(params.pages)
|
|
if (Array.isArray(pages)) {
|
|
filterPages(pagesJson, pages)
|
|
}
|
|
} catch (e) {}
|
|
}
|
|
}
|
|
|
|
const pageComponents = getPageComponents(inputDir, pagesJson)
|
|
|
|
pagesJson.globalStyle = process.UNI_H5_PAGES_JSON.globalStyle
|
|
delete pagesJson.pages
|
|
delete pagesJson.subPackages
|
|
|
|
const h5 = getH5Options(manifestJson)
|
|
|
|
const networkTimeoutConfig = getNetworkTimeout(manifestJson)
|
|
|
|
let qqMapKey = 'XVXBZ-NDMC4-JOGUS-XGIEE-QVHDZ-AMFV2'
|
|
|
|
const sdkConfigs = h5.sdkConfigs || {}
|
|
if (
|
|
sdkConfigs.maps &&
|
|
sdkConfigs.maps.qqmap &&
|
|
sdkConfigs.maps.qqmap.key
|
|
) {
|
|
qqMapKey = sdkConfigs.maps.qqmap.key
|
|
}
|
|
|
|
let minWidth = 768
|
|
|
|
if (
|
|
manifestJson &&
|
|
manifestJson.h5 &&
|
|
manifestJson.h5.responsive &&
|
|
manifestJson.h5.responsive.minWidth
|
|
) {
|
|
minWidth = parseInt(manifestJson.h5.responsive.minWidth) || minWidth
|
|
}
|
|
|
|
return `
|
|
import Vue from 'vue'
|
|
${genLayoutComponentsCode(pagesJson)}
|
|
global['____${h5.appid}____'] = true;
|
|
delete global['____${h5.appid}____'];
|
|
global.__uniConfig = ${JSON.stringify(pagesJson)};
|
|
global.__uniConfig.compilerVersion = '${compilerVersion}';
|
|
global.__uniConfig.responsive = { minWidth: ${minWidth} };
|
|
global.__uniConfig.router = ${JSON.stringify(h5.router)};
|
|
global.__uniConfig.publicPath = ${JSON.stringify(h5.publicPath)};
|
|
global.__uniConfig['async'] = ${JSON.stringify(h5.async)};
|
|
global.__uniConfig.debug = ${manifestJson.debug === true};
|
|
global.__uniConfig.networkTimeout = ${JSON.stringify(networkTimeoutConfig)};
|
|
global.__uniConfig.sdkConfigs = ${JSON.stringify(sdkConfigs)};
|
|
global.__uniConfig.qqMapKey = ${JSON.stringify(qqMapKey)};
|
|
global.__uniConfig.nvue = ${JSON.stringify({ 'flex-direction': getFlexDirection(manifestJson['app-plus']) })}
|
|
global.__uniConfig.__webpack_chunk_load__ = __webpack_chunk_load__
|
|
${genRegisterPageVueComponentsCode(pageComponents)}
|
|
global.__uniRoutes=[${genPageRoutes(pageComponents).concat(genSystemRoutes()).join(',')}]
|
|
global.UniApp && new global.UniApp();
|
|
`
|
|
}
|
|
|