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 {
|
getTheme
|
} = require('@dcloudio/uni-cli-shared/lib/theme')
|
|
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]
|
}
|
})
|
delete style.app
|
delete style.web
|
}
|
|
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 || ''
|
pagesJson.tabBar.borderStyle = pagesJson.tabBar.borderStyle || 'black'
|
}
|
|
const globalStyle = Object.assign({}, pagesJson.globalStyle || {})
|
|
Object.assign(
|
globalStyle,
|
globalStyle.app || globalStyle['app-plus'] || {},
|
globalStyle.web || 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 || props['app-plus'] || {}, props.web || 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
|
delete props['app-plus']
|
delete props.web
|
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,
|
topWindow: pageStyle.topWindow,
|
leftWindow: pageStyle.leftWindow,
|
rightWindow: pageStyle.rightWindow,
|
maxWidth: pageStyle.maxWidth
|
}
|
}).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(${JSON.stringify(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,
|
topWindow,
|
leftWindow,
|
rightWindow,
|
maxWidth
|
}) => {
|
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' : ''}
|
${topWindow === false ? 'topWindow:false,\n' : ''}${leftWindow === false ? 'leftWindow:false,\n' : ''}${rightWindow === false ? 'rightWindow:false,\n' : ''}
|
${isTabBar ? ('tabBarIndex:' + tabBarIndex) : ''}
|
},__uniConfig.globalStyle,${JSON.stringify(props)})
|
},
|
[
|
createElement('${name}', {
|
slot: 'page'
|
})
|
]
|
)
|
}
|
},
|
meta:{${isQuit ? '\nid:' + (id++) + ',' : ''}
|
name:'${name}',
|
isNVue:${isNVue},maxWidth:${maxWidth || 0},${topWindow === false ? 'topWindow:false,\n' : ''}${leftWindow === false ? 'leftWindow:false,\n' : ''}${rightWindow === false ? 'rightWindow:false,\n' : ''}
|
pagePath:'${route}'${isQuit ? ',\nisQuit:true' : ''}${isEntry ? ',\nisEntry:true' : ''}${isTabBar ? ',\nisTabBar:true' : ''}${tabBarIndex !== -1 ? (',\ntabBarIndex:' + tabBarIndex) : ''},
|
windowTop:${windowTop}
|
}
|
}`
|
})
|
}
|
|
const genSystemRoutes = function () {
|
return [
|
`
|
{
|
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 {
|
topWindow,
|
leftWindow,
|
rightWindow
|
} = pagesJson
|
if (topWindow && topWindow.path) {
|
code.push(
|
`import TopWindow from './${topWindow.path}';
|
${topWindow.style ? ('TopWindow.style=' + JSON.stringify(topWindow.style)) : ''}
|
Vue.component('VUniTopWindow',TopWindow);`
|
)
|
}
|
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)
|
|
const sdkConfigs = h5.sdkConfigs || {}
|
|
const qqMapKey = sdkConfigs.maps && sdkConfigs.maps.qqmap && sdkConfigs.maps.qqmap.key
|
const googleMapKey = sdkConfigs.maps && sdkConfigs.maps.google && sdkConfigs.maps.google.key
|
const aMapKey = sdkConfigs.maps && sdkConfigs.maps.amap && sdkConfigs.maps.amap.key
|
const aMapSecurityJsCode =
|
sdkConfigs.maps && sdkConfigs.maps.amap && sdkConfigs.maps.amap.securityJsCode
|
const aMapServiceHost =
|
sdkConfigs.maps && sdkConfigs.maps.amap && sdkConfigs.maps.amap.serviceHost
|
|
let locale = manifestJson.locale
|
locale = locale && locale.toUpperCase() !== 'AUTO' ? locale : ''
|
|
return `
|
import Vue from 'vue'
|
${genLayoutComponentsCode(pagesJson)}
|
const locales = ${fs.existsSync(path.resolve(process.env.UNI_INPUT_DIR, 'locale')) ? 'require.context(\'./locale\', false, /.json$/)' : '{keys(){return []}}'}
|
global['____${h5.appid}____'] = true;
|
delete global['____${h5.appid}____'];
|
global.__uniConfig = ${JSON.stringify(pagesJson)};
|
global.__uniConfig.compilerVersion = '${compilerVersion}';
|
global.__uniConfig.darkmode = ${JSON.stringify(h5.darkmode || false)};
|
global.__uniConfig.themeConfig = ${JSON.stringify(getTheme())};
|
global.__uniConfig.uniPlatform = '${process.env.UNI_PLATFORM}';
|
global.__uniConfig.appId = '${process.env.UNI_APP_ID}';
|
global.__uniConfig.appName = '${process.env.UNI_APP_NAME}';
|
global.__uniConfig.appVersion = '${process.env.UNI_APP_VERSION_NAME}';
|
global.__uniConfig.appVersionCode = '${process.env.UNI_APP_VERSION_CODE}';
|
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.googleMapKey = ${JSON.stringify(googleMapKey)};
|
global.__uniConfig.aMapKey = ${JSON.stringify(aMapKey)};
|
global.__uniConfig.aMapSecurityJsCode = ${JSON.stringify(aMapSecurityJsCode)};
|
global.__uniConfig.aMapServiceHost = ${JSON.stringify(aMapServiceHost)};
|
global.__uniConfig.locale = ${JSON.stringify(locale)};
|
global.__uniConfig.fallbackLocale = ${JSON.stringify(manifestJson.fallbackLocale)};
|
global.__uniConfig.locales = locales.keys().reduce((res,key)=>{const locale=key.replace(/\\.\\/(uni-app.)?(.*).json/,'$2');const messages = locales(key);Object.assign(res[locale]||(res[locale]={}),messages.common||messages);return res},{});
|
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();
|
`
|
}
|