first commit

This commit is contained in:
2026-09-08 20:28:54 +08:00
commit 2ada8d3d5a
37380 changed files with 4886169 additions and 0 deletions
@@ -0,0 +1,96 @@
const {
initI18nOptions
} = require('@dcloudio/uni-cli-shared/lib/i18n')
function parseRoutes (config) {
const __uniRoutes = []
/* eslint-disable no-mixed-operators */
const tabBarList = ((config.tabBar && config.tabBar.list) || []).map(
item => item.pagePath
)
Object.keys(config.page).forEach(function (pagePath) {
const isTabBar = tabBarList.indexOf(pagePath) !== -1
const isQuit = isTabBar || config.pages[0] === pagePath
const isNVue = !!config.page[pagePath].nvue
const route = {
path: '/' + pagePath,
meta: {},
window: config.page[pagePath].window || {}
}
if (isQuit) {
route.meta.isQuit = true
}
if (isNVue) {
route.meta.isNVue = true
}
if (isTabBar) {
route.meta.isTabBar = true
}
__uniRoutes.push(route)
})
return __uniRoutes
}
const GLOBALS = [
'global',
'window',
'document',
'frames',
'self',
'location',
'navigator',
'localStorage',
'history',
'Caches',
'screen',
'alert',
'confirm',
'prompt',
'fetch',
'XMLHttpRequest',
'WebSocket',
'webkit',
'print'
]
const globalStatement = GLOBALS.map(g => `${g}:void 0`).join(',')
module.exports = function definePages (appJson) {
const __uniRoutes = parseRoutes(appJson)
delete appJson.page
delete appJson.usingComponents
// 保留nvueCompiler
// delete appJson.nvueCompiler
// 保留renderer
// delete appJson.renderer
if (process.env.UNI_AUTOMATOR_WS_ENDPOINT) {
appJson.automator = true
}
const i18nOptions = initI18nOptions(
process.env.UNI_PLATFORM,
process.env.UNI_INPUT_DIR,
false,
true
)
if (i18nOptions) {
appJson.locale = ''
appJson.fallbackLocale = i18nOptions.locale
appJson.locales = i18nOptions.locales
}
return {
name: 'app-config-service.js',
content: `
var isReady=false;var onReadyCallbacks=[];
var isServiceReady=false;var onServiceReadyCallbacks=[];
var __uniConfig = ${JSON.stringify(appJson, null)};
var __uniRoutes = ${JSON.stringify(__uniRoutes)};
__uniConfig.onReady=function(callback){if(__uniConfig.ready){callback()}else{onReadyCallbacks.push(callback)}};Object.defineProperty(__uniConfig,"ready",{get:function(){return isReady},set:function(val){isReady=val;if(!isReady){return}const callbacks=onReadyCallbacks.slice(0);onReadyCallbacks.length=0;callbacks.forEach(function(callback){callback()})}});
__uniConfig.onServiceReady=function(callback){if(__uniConfig.serviceReady){callback()}else{onServiceReadyCallbacks.push(callback)}};Object.defineProperty(__uniConfig,"serviceReady",{get:function(){return isServiceReady},set:function(val){isServiceReady=val;if(!isServiceReady){return}const callbacks=onServiceReadyCallbacks.slice(0);onServiceReadyCallbacks.length=0;callbacks.forEach(function(callback){callback()})}});
service.register("uni-app-config",{create(a,b,c){if(!__uniConfig.viewport){var d=b.weex.config.env.scale,e=b.weex.config.env.deviceWidth,f=Math.ceil(e/d);Object.assign(__uniConfig,{viewport:f,defaultFontSize:Math.round(f/20)})}return{instance:{__uniConfig:__uniConfig,__uniRoutes:__uniRoutes,${globalStatement}}}}});
`
}
}
@@ -0,0 +1,40 @@
const fs = require('fs')
const {
parseTheme
} = require('@dcloudio/uni-cli-shared/lib/theme')
function generatePageCode (pages, pageOptions) {
return pages.map(pagePath => {
if (pageOptions[pagePath].nvue) {
return ''
}
return `__definePage('${pagePath}',function(){return Vue.extend(require('${pagePath}.vue?mpType=page').default)})`
}).join('\n')
}
function generateUniConfig (appJson, isAppView) {
return isAppView ? `window.__uniConfig = ${JSON.stringify(
{
window: parseTheme(appJson.window),
darkmode: appJson.darkmode
}
, null)};` : ''
}
function generatePolyfill () {
return fs.readFileSync(require.resolve('@dcloudio/uni-cli-shared/lib/uni-polyfill.js'), { encoding: 'utf8' })
}
module.exports = function definePages (appJson, isAppView) {
return {
name: 'define-pages.js',
content: `
${generatePolyfill()}
${generateUniConfig(appJson, isAppView)}
if(uni.restoreGlobal){
uni.restoreGlobal(weex,plus,setTimeout,clearTimeout,setInterval,clearInterval)
}
${generatePageCode(appJson.pages, appJson.page)}
`
}
}
@@ -0,0 +1,689 @@
const fs = require('fs')
const fsExtra = require('fs-extra')
const path = require('path')
const merge = require('merge')
const {
normalizePath,
getFlexDirection
} = require('@dcloudio/uni-cli-shared')
const {
getTheme,
hasTheme,
parseTheme
} = require('@dcloudio/uni-cli-shared/lib/theme')
const {
compileI18nJsonStr
} = require('@dcloudio/uni-i18n')
const {
initI18nOptions
} = require('@dcloudio/uni-cli-shared/lib/i18n')
const {
hasOwn,
parseStyle
} = require('../../util')
const wxPageOrientationMapping = {
auto: [
'portrait-primary',
'portrait-secondary',
'landscape-primary',
'landscape-secondary'
],
portrait: ['portrait-primary', 'portrait-secondary'],
landscape: ['landscape-primary', 'landscape-secondary']
}
function parseConfig (appJson) {
return {
name: 'app-config.js',
content: `__registerConfig(${JSON.stringify(appJson)});`
}
}
const _toString = Object.prototype.toString
function isPlainObject (obj) {
return _toString.call(obj) === '[object Object]'
}
function normalizeNetworkTimeout (appJson) {
if (!isPlainObject(appJson.networkTimeout)) {
appJson.networkTimeout = {
request: 60000,
connectSocket: 60000,
uploadFile: 60000,
downloadFile: 60000
}
} else {
if (typeof appJson.networkTimeout.request === 'undefined') {
appJson.networkTimeout.request = 60000
}
if (typeof appJson.networkTimeout.connectSocket === 'undefined') {
appJson.networkTimeout.connectSocket = 60000
}
if (typeof appJson.networkTimeout.uploadFile === 'undefined') {
appJson.networkTimeout.uploadFile = 60000
}
if (typeof appJson.networkTimeout.downloadFile === 'undefined') {
appJson.networkTimeout.downloadFile = 60000
}
}
}
function updateFileFlag (appJson) {
// 已经不再根据文件识别,理论可废弃此处的逻辑
if (process.env.UNI_USING_V3 || process.env.UNI_USING_V3_NATIVE) {
return
}
const nvueCompilerFilePath = path.resolve(
process.env.UNI_OUTPUT_DIR,
'__uniappnvuecompiler.js'
)
const nvueCompilerExists = fs.existsSync(nvueCompilerFilePath)
if (appJson.nvueCompiler === 'uni-app') {
if (!nvueCompilerExists) {
fsExtra.outputFile(nvueCompilerFilePath, '')
}
} else {
if (nvueCompilerExists) {
fs.unlinkSync(nvueCompilerFilePath)
}
}
const rendererFilePath = path.resolve(
process.env.UNI_OUTPUT_DIR,
'__uniapprenderer.js'
)
const rendererExists = fs.existsSync(rendererFilePath)
if (appJson.renderer === 'native') {
if (!rendererExists) {
fsExtra.outputFile(rendererFilePath, '')
}
} else {
if (rendererExists) {
fs.unlinkSync(rendererFilePath)
}
}
}
function _initTheme (appJson, userManifestJson) {
const manifestJson = userManifestJson[process.env.UNI_PLATFORM] || {}
appJson.darkmode = manifestJson.darkmode || false
const themeLocation = manifestJson.themeLocation || 'theme.json'
if (themeLocation && hasTheme(themeLocation)) {
appJson.themeConfig = getTheme()
}
return appJson
}
module.exports = function (pagesJson, userManifestJson, isAppView) {
const {
app
} = require('../mp')(pagesJson, userManifestJson)
const manifest = {
name: 'manifest'
}
const appJson = app.content
_initTheme(appJson, userManifestJson)
const parsedThemeAppJsonWindow = parseTheme(appJson.window)
const navigationBarTextStyle =
(pagesJson.pages[0].style && pagesJson.pages[0].style.navigationBarTextStyle) ||
(pagesJson.globalStyle && pagesJson.globalStyle.navigationBarTextStyle) ||
'black'
const navigationBarBackgroundColor = (parsedThemeAppJsonWindow && parsedThemeAppJsonWindow.navigationBarBackgroundColor) || '#000000'
const TABBAR_HEIGHT = 50
let manifestJson = JSON.parse(
fs.readFileSync(path.resolve(__dirname, './manifest.json'), 'utf8')
)
// 状态栏
manifestJson.plus.statusbar = {
immersed: 'supportedDevice',
style: navigationBarTextStyle === 'white' ? 'light' : 'dark',
background: navigationBarBackgroundColor
}
// 用户配置覆盖默认配置
manifestJson = merge.recursive(
true,
manifestJson, {
id: userManifestJson.appid || '',
name: userManifestJson.name || '',
description: userManifestJson.description || '',
version: {
name: userManifestJson.versionName,
code: userManifestJson.versionCode
},
locale: userManifestJson.locale,
uniStatistics: userManifestJson.uniStatistics
}, {
plus: userManifestJson['app-plus']
}
)
initUniStatistics(manifestJson)
const splashscreenOptions =
userManifestJson['app-plus'] && userManifestJson['app-plus'].splashscreen
const hasAlwaysShowBeforeRender =
splashscreenOptions &&
hasOwn(splashscreenOptions, 'alwaysShowBeforeRender')
// 转换为老版本配置
if (manifestJson.plus.modules) {
manifestJson.permissions = manifestJson.plus.modules
delete manifestJson.plus.modules
}
const distribute = manifestJson.plus.distribute
if (distribute) {
if (distribute.android) {
manifestJson.plus.distribute.google = distribute.android
delete manifestJson.plus.distribute.android
}
if (distribute.ios) {
manifestJson.plus.distribute.apple = distribute.ios
delete manifestJson.plus.distribute.ios
}
if (distribute.sdkConfigs) {
manifestJson.plus.distribute.plugins = distribute.sdkConfigs
delete manifestJson.plus.distribute.sdkConfigs
}
if (manifestJson.plus.darkmode) {
if (!(distribute.google || (distribute.google = {})).defaultNightMode) {
distribute.google.defaultNightMode = 'auto'
}
if (!(distribute.apple || (distribute.apple = {})).UIUserInterfaceStyle) {
distribute.apple.UIUserInterfaceStyle = 'Automatic'
}
}
}
// 屏幕启动方向
if (manifestJson.plus.screenOrientation) {
// app平台优先使用 manifest 配置
manifestJson.screenOrientation = manifestJson.plus.screenOrientation
delete manifestJson.plus.screenOrientation
} else if (appJson.window && appJson.window.pageOrientation) {
// 兼容微信小程序
const pageOrientationValue =
wxPageOrientationMapping[appJson.window.pageOrientation]
if (pageOrientationValue) {
manifestJson.screenOrientation = pageOrientationValue
}
}
// 全屏配置
manifestJson.fullscreen = manifestJson.plus.fullscreen
// 地图坐标系
if (manifestJson.permissions && manifestJson.permissions.Maps) {
manifestJson.permissions.Maps.coordType = 'gcj02'
}
if (!manifestJson.permissions) {
manifestJson.permissions = {}
}
const nvuePages = process.env.UNI_USING_V3_NATIVE
? pagesJson.pages
: pagesJson.nvue && pagesJson.nvue.pages
if (nvuePages && nvuePages.length) {
const pages = {}
nvuePages.forEach(({
path,
style
}) => {
pages[path] = {
window: parseStyle(style),
nvue: true
}
})
appJson.nvue = {
pages
}
if (process.env.UNI_USING_V3_NATIVE) {
appJson.nvue.entryPagePath = nvuePages[0]
} else if (pagesJson.nvue.entryPagePath) {
appJson.nvue.entryPagePath = pagesJson.nvue.entryPagePath
}
// nvue 权限
manifestJson.permissions.UniNView = {
description: 'UniNView原生渲染'
}
} else if (process.env.UNI_USING_V8) {
// nvue 权限
manifestJson.permissions.UniNView = {
description: 'UniNView原生渲染'
}
}
// 启动页面配置
if (process.env.NODE_ENV === 'development') {
const condition = pagesJson.condition
if (condition && Array.isArray(condition.list) && condition.list.length) {
const list = condition.list
let current = parseInt(condition.current) || 0
if (current < 0) {
current = 0
}
if (current >= list.length) {
current = 0
}
manifestJson.plus.arguments = JSON.stringify(list[current])
}
}
// 允许内联播放视频
manifestJson.plus.allowsInlineMediaPlayback = true
const addRenderAlways = function () {
// "render": "always"
if (!manifestJson.plus.launchwebview) {
manifestJson.plus.launchwebview = {
render: 'always'
}
} else if (!manifestJson.plus.launchwebview.render) {
manifestJson.plus.launchwebview.render = 'always'
}
}
if (appJson.tabBar && appJson.tabBar.list && appJson.tabBar.list.length) {
// 安全区配置 仅包含 tabBar 的时候才配置
if (!manifestJson.plus.safearea) {
manifestJson.plus.safearea = {
background: parseTheme(appJson.tabBar).backgroundColor || '#FFFFFF',
bottom: {
offset: 'auto'
}
}
}
if (!process.env.UNI_USING_COMPONENTS) {
// 非自定义组件模式下,仍旧添加 render always
addRenderAlways()
}
} else {
addRenderAlways()
}
let flexDir = false
if (process.env.UNI_USING_NVUE_COMPILER) {
appJson.nvueCompiler = 'uni-app'
flexDir = getFlexDirection(manifestJson.plus)
} else {
appJson.nvueCompiler = 'weex'
}
appJson.nvueStyleCompiler = process.env.UNI_USING_NVUE_STYLE_COMPILER
? 'uni-app'
: 'weex'
if (manifestJson.plus.renderer === 'native') {
appJson.renderer = 'native'
} else {
appJson.renderer = 'auto'
}
updateFileFlag(appJson)
appJson.splashscreen = {
alwaysShowBeforeRender: false, // 是否启用白屏检测 关闭 splash
autoclose: false // 是否 uni-app 框架关闭 splash
}
// 强制白屏检测
if (manifestJson.plus.splashscreen) {
if (
!hasAlwaysShowBeforeRender &&
manifestJson.plus.splashscreen.autoclose === false
) {
// 兼容旧版本仅配置了 autoclose 为 false
manifestJson.plus.splashscreen.alwaysShowBeforeRender = false
}
if (manifestJson.plus.splashscreen.alwaysShowBeforeRender) {
// 白屏检测
if (!manifestJson.plus.splashscreen.target) {
manifestJson.plus.splashscreen.target = 'id:1'
}
manifestJson.plus.splashscreen.autoclose = true
manifestJson.plus.splashscreen.delay = 0
appJson.splashscreen.alwaysShowBeforeRender = true
} else {
// 不启用白屏检测
delete manifestJson.plus.splashscreen.target
if (manifestJson.plus.splashscreen.autoclose) {
// 启用 uni-app 框架关闭 splash
manifestJson.plus.splashscreen.autoclose = false // 原 5+ autoclose 改为 false
appJson.splashscreen.autoclose = true
}
}
delete manifestJson.plus.splashscreen.alwaysShowBeforeRender
}
appJson.appname = manifestJson.name
if (!manifestJson.plus.distribute) {
manifestJson.plus.distribute = {
plugins: {}
}
}
if (!manifestJson.plus.distribute.plugins) {
manifestJson.plus.distribute.plugins = {}
}
// 录音支持 mp3
manifestJson.plus.distribute.plugins.audio = {
mp3: {
description: 'Android平台录音支持MP3格式文件'
}
}
// 有效值为 close,none
if (!['close', 'none'].includes(manifestJson.plus.popGesture + '')) {
manifestJson.plus.popGesture = 'close'
}
// 检查原生混淆选项
const confusion = manifestJson.plus.confusion
if (confusion && confusion.resources) {
const resources = {}
const nvuePages = (appJson.nvue && appJson.nvue.pages) || {}
for (const key in confusion.resources) {
if (path.extname(key) === '.js') {
// 支持 js 混淆,过滤掉
// 静态 js 文件
if (
key.indexOf('hybrid/html') === 0 ||
key.indexOf('static/') === 0 ||
key.indexOf('/static/') !== -1
) {
resources[key] = confusion.resources[key]
}
continue
}
if (!/\.nvue$/.test(key)) {
throw new Error(`原生混淆仅支持 nvue 页面,错误的页面路径:${key}`)
} else {
resources[key.replace(/\.nvue$/, '.js')] = confusion.resources[key]
}
if (
!Object.keys(nvuePages).find(path => {
const subNVues = nvuePages[path].window.subNVues || []
// TODO
return (
path.replace(/\.html$/, '.nvue') === key ||
path.replace(/\.html$/, '.nvue') + '.nvue' === key ||
subNVues.find(({
path
}) => path === key.replace(/\.nvue$/, ''))
)
}) &&
!pagesJson.pages.find(({
style = {}
}) => {
style = Object.assign(style, style['app-plus'])
const subNVues = style.subNVues || []
return subNVues.find(
({
path
}) => path === key.replace(/\.nvue$/, '')
)
})
) {
throw new Error(`原生混淆页面未在项目内使用,错误的页面路径:${key}`)
}
}
confusion.resources = resources
}
// uni-app
const uniApp = require('../../../package.json')['uni-app']
manifestJson.plus['uni-app'] = uniApp
// 控制页类型
const control =
process.env.UNI_USING_V3 || process.env.UNI_USING_V3_NATIVE
? 'uni-v3'
: process.env.UNI_USING_V8
? 'v8'
: 'webview'
manifestJson.plus['uni-app'].control = control
manifestJson.plus['uni-app'].nvueCompiler = appJson.nvueCompiler
// v3 + native 时强制 auto
manifestJson.plus['uni-app'].renderer = process.env.UNI_USING_V3_NATIVE
? 'auto'
: appJson.renderer
if (flexDir) {
manifestJson.plus['uni-app'].nvue = {
'flex-direction': flexDir
}
}
// 检查 webview 版本 || 下载 X5 后启动
const plusWebview = manifestJson.plus.webView
if (plusWebview) {
manifestJson.plus['uni-app'].webView = plusWebview
delete manifestJson.plus.webView
}
// 记录编译器版本号
appJson.compilerVersion = uniApp.compilerVersion
if (process.env.UNI_USING_V8) {
let entryPagePath = appJson.pages[0]
let conditionPagePath = false
if (manifestJson.plus.arguments) {
try {
const args = JSON.parse(manifestJson.plus.arguments)
if (args && (args.path || args.pathName)) {
entryPagePath = conditionPagePath = args.path || args.pathName
}
} catch (e) { }
}
let isNVueEntryPage = appJson.nvue && appJson.nvue.entryPagePath
conditionPagePath =
process.env.UNI_CLI_LAUNCH_PAGE_PATH || conditionPagePath
if (conditionPagePath && appJson.nvue) {
isNVueEntryPage = `${conditionPagePath}.html` in appJson.nvue.pages
}
manifestJson.plus.useragent.value = 'uni-app'
manifestJson.launch_path = '__uniappview.html'
Object.assign(manifestJson.plus.launchwebview, {
id: '1',
kernel: 'WKWebview',
'uni-app': 'auto'
})
if (process.env.UNI_USING_NATIVE) {
appJson.entryPagePath = appJson.nvue.entryPagePath
// networkTimeout
normalizeNetworkTimeout(appJson)
appJson.page = Object.create(null)
appJson.pages = Object.keys(appJson.nvue.pages).map(pagePath => {
const newPagePath = pagePath.replace('.html', '')
appJson.page[newPagePath] = {
window: appJson.nvue.pages[pagePath].window,
nvue: true
}
return newPagePath
})
delete appJson.nvue
delete manifestJson.plus.launchwebview.kernel
manifestJson.launch_path = ''
Object.assign(manifestJson.plus.launchwebview, {
uniNView: {
path: appJson.entryPagePath
}
})
} else if (isNVueEntryPage) {
// 非纯 nvue 项目首页为 nvue 页面
manifestJson.plus.launchwebview.id = '2'
manifestJson.plus.launchwebview.render = 'always'
}
// 带 tab
if (
pagesJson.tabBar &&
pagesJson.tabBar.list &&
pagesJson.tabBar.list.length
) {
const tabBar = (manifestJson.plus.tabBar = Object.assign({},
parseTheme(pagesJson.tabBar)
))
const borderStyles = {
black: 'rgba(0,0,0,0.4)',
white: 'rgba(255,255,255,0.4)'
}
let borderStyle = tabBar.borderStyle
if (!borderStyle) {
borderStyle = 'black'
}
if (borderStyle in borderStyles) {
tabBar.borderStyle = borderStyles[borderStyle]
}
if (!tabBar.selectedColor) {
tabBar.selectedColor = '#0062cc'
}
tabBar.height = `${parseFloat(tabBar.height) || TABBAR_HEIGHT}px`
// 非纯 nvue 项目首页为 nvue 页面
if (!process.env.UNI_USING_NATIVE && isNVueEntryPage) {
manifestJson.plus.launchwebview.id = '2'
} else {
// 首页是 tabBar 页面
const item = tabBar.list.find(
page =>
page.pagePath ===
(process.env.UNI_USING_NATIVE
? appJson.entryPagePath
: entryPagePath)
)
if (item) {
tabBar.child = ['lauchwebview']
tabBar.selected = tabBar.list.indexOf(item)
}
}
const i18nOptions = initI18nOptions(
process.env.UNI_PLATFORM,
process.env.UNI_INPUT_DIR,
true,
true
)
if (i18nOptions) {
manifestJson = JSON.parse(
compileI18nJsonStr(JSON.stringify(manifestJson), i18nOptions)
)
manifestJson.fallbackLocale = i18nOptions.locale
}
}
}
if (!process.env.UNI_USING_COMPONENTS) {
manifestJson.plus.launchwebview.kernel = 'UIWebview'
}
manifest.content = manifestJson
const subPackages = []
// 分包合并
if (appJson.subPackages && appJson.subPackages.length) {
appJson.subPackages.forEach(subPackage => {
if (subPackage.pages && subPackage.pages.length) {
subPackage.pages.forEach(page => {
appJson.pages.push(normalizePath(path.join(subPackage.root, page)))
})
subPackages.push({
root: subPackage.root
})
}
})
}
delete appJson.subPackages
// TODO 处理纯原生
if (process.env.UNI_USING_NATIVE) {
manifest.name = 'manifest.json'
manifest.content = JSON.stringify(manifest.content)
return [manifest, parseConfig(appJson)]
}
if (process.env.UNI_USING_V3 || process.env.UNI_USING_V3_NATIVE) {
if (process.env.UNI_USING_V3 && process.env.UNI_OPT_SUBPACKAGES) {
appJson.subPackages = subPackages
}
return require('./index.v3')(
appJson,
manifestJson, {
manifest,
pagesJson,
normalizeNetworkTimeout
},
isAppView
)
}
return [app, manifest]
}
function initUniStatistics (manifestJson) {
// 根节点配置了统计
if (manifestJson.uniStatistics) {
manifestJson.plus.uniStatistics = merge.recursive(
true,
manifestJson.uniStatistics,
manifestJson.plus.uniStatistics
)
delete manifestJson.uniStatistics
}
if (!process.env.UNI_CLOUD_PROVIDER) {
return
}
let spaces = []
try {
spaces = JSON.parse(process.env.UNI_CLOUD_PROVIDER)
} catch (e) { }
if (!Array.isArray(spaces) || !spaces.length) {
return
}
const space = spaces[0]
if (!space) {
return
}
const uniStatistics = manifestJson.plus && manifestJson.plus.uniStatistics
if (!uniStatistics) {
return
}
if (uniStatistics.version === 2 || uniStatistics.version === '2') {
if (uniStatistics.uniCloud && uniStatistics.uniCloud.spaceId) {
return
}
uniStatistics.uniCloud = {
provider: space.provider,
spaceId: space.spaceId,
clientSecret: space.clientSecret,
endpoint: space.endpoint
}
}
}
@@ -0,0 +1,113 @@
const path = require('path')
const {
normalizePath
} = require('@dcloudio/uni-cli-shared')
const {
parsePages,
addPageUsingComponents
} = require('@dcloudio/uni-cli-shared/lib/pages')
const {
parseStyle
} = require('../../util')
const definePages = require('./define-pages')
const appConfigService = require('./app-config-service')
function getTabBarPages (appJson) {
return appJson.tabBar &&
appJson.tabBar.list &&
appJson.tabBar.list.length &&
appJson.tabBar.list
}
function isTabBarPage (pathName, tabBarPages) {
return Array.isArray(tabBarPages) && tabBarPages.find(item => item.pagePath === pathName)
}
function parseEntryPagePath (appJson, manifestJson) {
const argsJsonStr = manifestJson.plus.arguments
if (argsJsonStr) {
try {
const args = JSON.parse(argsJsonStr)
const pathName = args.path || args.pathName
const entryPageQuery = (args.query ? ('?' + args.query) : '')
if (pathName && appJson.pages[0] !== pathName) {
appJson.entryPagePath = pathName
appJson.entryPageQuery = entryPageQuery
if (!isTabBarPage(pathName, getTabBarPages(appJson))) {
appJson.realEntryPagePath = appJson.pages[0]
}
}
} catch (e) {}
}
if (!appJson.entryPagePath) {
appJson.entryPagePath = appJson.pages[0]
}
}
module.exports = function (appJson, manifestJson, {
pagesJson,
manifest,
normalizeNetworkTimeout
}, isAppView) {
parseEntryPagePath(appJson, manifestJson)
// timeout
normalizeNetworkTimeout(appJson)
appJson.page = Object.create(null)
const addPage = function (pagePath, windowOptions, nvue) {
// 缓存页面级usingComponents
addPageUsingComponents(pagePath, windowOptions.usingComponents)
delete windowOptions.usingComponents
appJson.page[pagePath] = {
window: windowOptions,
nvue
}
}
parsePages(pagesJson, function (page) {
addPage(page.path, parseStyle(page.style), !!page.nvue)
}, function (root, page) {
addPage(normalizePath(path.join(root, page.path)), parseStyle(page.style, root), !!page.nvue)
})
// nvue 权限
manifestJson.permissions.UniNView = {
description: 'UniNView原生渲染'
}
manifestJson.plus.launchwebview.id = '1' // 首页 id 固定 为 1
// 删除首页 style 中的 uni-app 配置(不注入 app-view.js
delete manifestJson.plus.launchwebview['uni-app']
const entryPagePath = appJson.entryPagePath
if (!appJson.page[entryPagePath]) {
console.error(
`pages.json condition['list'][current]['path']: ${entryPagePath} 需在 pages 数组中`
)
process.exit(0)
}
if (appJson.page[entryPagePath].nvue) { // 首页是 nvue
manifestJson.launch_path = '' // 首页地址为空
manifestJson.plus.launchwebview.uniNView = {
path: entryPagePath + '.js' + (appJson.entryPageQuery || '')
}
const tabBar = manifestJson.plus.tabBar
if (tabBar && isTabBarPage(entryPagePath, tabBar.list)) {
tabBar.child = ['lauchwebview']
}
} else {
manifestJson.plus.launch_path = '__uniappview.html' // 首页地址固定
}
// nvue 首页启动模式
manifestJson.plus['uni-app'].nvueLaunchMode = manifestJson.plus.nvueLaunchMode === 'fast' ? 'fast' : 'normal'
delete manifestJson.plus.nvueLaunchMode
manifest.name = 'manifest.json'
manifest.content = JSON.stringify(manifest.content)
delete appJson.nvue
return [manifest, definePages(appJson, isAppView), appConfigService(appJson)]
}
@@ -0,0 +1,35 @@
{
"@platforms": [
"android",
"iPhone",
"iPad"
],
"id": "__WEAPP_ID",
"name": "__WEAPP_NAME",
"version": {
"name": "1.0",
"code": ""
},
"description": "",
"launch_path": "__uniappservice.html",
"developer": {
"name": "",
"email": "",
"url": ""
},
"permissions": {},
"plus": {
"useragent": {
"value": "uni-app appservice",
"concatenate": true
},
"splashscreen": {
"target":"id:1",
"autoclose": true,
"waiting": true,
"alwaysShowBeforeRender":true
},
"popGesture": "close",
"launchwebview": {}
}
}
@@ -0,0 +1,3 @@
module.exports = function createTabBarNView () {
}
+471
View File
@@ -0,0 +1,471 @@
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
}
}
// 解析 titleNViewpullToRefresh
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 tempTencentMapKey = sdkConfigs.maps && sdkConfigs.maps.tencent && sdkConfigs.maps.tencent.key
const tempQQMapKey = sdkConfigs.maps && sdkConfigs.maps.qqmap && sdkConfigs.maps.qqmap.key
const qqMapKey = tempTencentMapKey || tempQQMapKey
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();
`
}
@@ -0,0 +1,148 @@
const fs = require('fs')
const path = require('path')
const {
parsePages,
getPlatformProject
} = require('@dcloudio/uni-cli-shared')
const {
updateAppJsonUsingComponents
} = require('@dcloudio/uni-cli-shared/lib/cache')
const {
hasOwn,
parseStyle,
parseTabBar,
NON_APP_JSON_KEYS
} = require('../util')
function defaultCopy (name, value, json) {
json[name] = value
}
const pagesJson2AppJson = {
globalStyle: function (name, value, json) {
json.window = parseStyle(value)
if (json.window.usingComponents) {
json.usingComponents = json.window.usingComponents
delete json.window.usingComponents
}
},
tabBar: function (name, value, json) {
json.tabBar = parseTabBar(value)
},
preloadRule: defaultCopy,
entryPagePath: defaultCopy
}
function copyToJson (json, fromJson, options) {
Object.keys(options).forEach(name => {
if (hasOwn(fromJson, name)) {
options[name](name, fromJson[name], json)
}
})
}
function parseCondition (pagesJson) {
const condition = pagesJson.condition
const launchPagePath = process.env.UNI_CLI_LAUNCH_PAGE_PATH || ''
const launchPageQuery = process.env.UNI_CLI_LAUNCH_PAGE_QUERY || ''
const launchPageOptions = {
title: launchPagePath,
page: launchPagePath,
pageQuery: launchPageQuery
}
const compileModeJson = {
modes: []
}
if (condition && Array.isArray(condition.list) && condition.list.length) {
compileModeJson.modes = condition.list.map(item => {
return {
title: item.name,
page: item.path,
pageQuery: item.query
}
})
delete pagesJson.condition
}
if (launchPagePath) {
compileModeJson.modes = [launchPageOptions]
}
const miniIdeDir = path.join(process.env.UNI_OUTPUT_DIR, '.mini-ide')
if (!fs.existsSync(miniIdeDir)) {
fs.mkdirSync(miniIdeDir, { recursive: true })
fs.writeFileSync(
path.join(miniIdeDir, 'compileMode.json'),
JSON.stringify(compileModeJson, null, 2)
)
}
}
const projectKeys = ['component2', 'enableAppxNg']
module.exports = function (pagesJson, manifestJson) {
const app = {
pages: [],
subPackages: []
}
const subPackages = {}
parsePages(pagesJson, function (page) {
app.pages.push(page.path)
}, function (root, page, subPackage) {
if (!subPackages[root]) {
subPackages[root] = {
root,
pages: []
}
Object.keys(subPackage).forEach(name => {
if (['root', 'pages'].indexOf(name) === -1) {
subPackages[root][name] = subPackage[name]
}
})
}
subPackages[root].pages.push(page.path)
})
Object.keys(subPackages).forEach(root => {
app.subPackages.push(subPackages[root])
})
copyToJson(app, pagesJson, pagesJson2AppJson)
const platformJson = manifestJson['mp-alipay'] || {}
Object.keys(platformJson).forEach(key => {
if (!projectKeys.includes(key) && !NON_APP_JSON_KEYS.includes(key)) {
// usingComponents 是编译模式开关,需要过滤,不能拷贝到 app
app[key] = platformJson[key]
}
})
if (app.usingComponents) {
updateAppJsonUsingComponents(app.usingComponents)
}
const projectName = getPlatformProject()
let project = {}
const projectPath = path.resolve(process.env.UNI_INPUT_DIR, projectName)
if (fs.existsSync(projectPath)) {
project = require(projectPath)
} else {
project.component2 = hasOwn(platformJson, 'component2') ? platformJson.component2 : true
project.enableAppxNg = hasOwn(platformJson, 'enableAppxNg') ? platformJson.enableAppxNg : true
}
parseCondition(pagesJson)
return [{
name: 'app',
content: app
}, {
name: 'mini.project',
content: project
}]
}
@@ -0,0 +1,29 @@
module.exports = function (pagesJson, manifestJson) {
const {
app,
project
} = require('../mp')(pagesJson, manifestJson, require('./project.swan.json'))
const content = project.content
const miniprogram = content.condition && content.condition.miniprogram
if (miniprogram && Array.isArray(miniprogram.list) && miniprogram.list.length) {
content['compilation-args'].options = miniprogram.list.map((item) => {
return {
id: item.id,
text: item.name,
extra: {
index: item.pathName,
query: item.query
}
}
})
delete content.condition
}
project.name = 'project.swan'
return [
app,
project
]
}
@@ -0,0 +1,13 @@
{
"appid": "",
"compilation-args": {
"selected": -3
},
"appInfo": {},
"appkey": "",
"condition": {},
"setting": {
"urlCheck": true
},
"libVersion": ""
}
@@ -0,0 +1,10 @@
module.exports = function (pagesJson, manifestJson) {
const {
app,
project
} = require('../mp')(pagesJson, manifestJson, require('./project.config.json'))
const [key, value] = ['component2', true]
app.content = app.content || {}
app.content[key] = key in pagesJson ? pagesJson[key] : value
return [app, project]
}
@@ -0,0 +1,11 @@
{
"setting": {
"urlCheck": true,
"es6": false,
"postcss": false,
"minified": false,
"newFeature": true
},
"appid": "testAppId",
"projectname": ""
}
@@ -0,0 +1,11 @@
module.exports = function (pagesJson, manifestJson) {
const {
app,
project
} = require('../mp')(pagesJson, manifestJson, require('./project.config.json'))
// 暂不支持分包,兼容引擎判断
if (app.content.subPackages && !app.content.subPackages.length) {
delete app.content.subPackages
}
return [app, project]
}
@@ -0,0 +1,11 @@
{
"setting": {
"urlCheck": true,
"es6": false,
"postcss": false,
"minified": false,
"newFeature": true
},
"appid": "testAppId",
"projectname": ""
}
@@ -0,0 +1,7 @@
module.exports = function (pagesJson, manifestJson) {
const {
app,
project
} = require('../mp')(pagesJson, manifestJson, require('./project.config.json'))
return [app, project]
}
@@ -0,0 +1,6 @@
{
"description": "项目配置文件。",
"libVersion": "0.6.0",
"appid": "touristappid",
"projectname": ""
}
@@ -0,0 +1,7 @@
module.exports = function (pagesJson, manifestJson) {
const {
app,
project
} = require('../mp')(pagesJson, manifestJson, require('./project.config.json'))
return [app, project]
}
@@ -0,0 +1,11 @@
{
"setting": {
"urlCheck": true,
"es6": false,
"postcss": false,
"minified": false,
"newFeature": true
},
"appid": "testAppId",
"projectname": ""
}
@@ -0,0 +1,17 @@
module.exports = function (pagesJson, manifestJson) {
const {
app,
project
} = require('../mp')(pagesJson, manifestJson, require('./project.config.json'))
if (app.content && app.content.subPackages && app.content.subPackages.length === 0) {
delete app.content.subPackages
}
if (project) {
project.content.qqappid = project.content.appid
project.content.qqLibVersion = project.content.libVersion
delete project.content.appid
delete project.content.libVersion
}
return [app, project]
}
@@ -0,0 +1,36 @@
{
"description": "项目配置文件。",
"packOptions": {
"ignore": []
},
"setting": {
"urlCheck": true,
"es6": false,
"postcss": false,
"minified": false,
"newFeature": true,
"nodeModules": false
},
"compileType": "miniprogram",
"libVersion": "1.6.3",
"appid": "touristappid",
"projectname": "",
"condition": {
"search": {
"current": -1,
"list": []
},
"conversation": {
"current": -1,
"list": []
},
"game": {
"current": -1,
"list": []
},
"miniprogram": {
"current": -1,
"list": []
}
}
}
@@ -0,0 +1,10 @@
module.exports = function (pagesJson, manifestJson) {
const {
app,
project
} = require('../mp')(pagesJson, manifestJson, require('./project.config.json'))
const [key, value] = ['component2', true]
app.content = app.content || {}
app.content[key] = key in pagesJson ? pagesJson[key] : value
return [app, project]
}
@@ -0,0 +1,11 @@
{
"setting": {
"urlCheck": true,
"es6": false,
"postcss": false,
"minified": false,
"newFeature": true
},
"appid": "testAppId",
"projectname": ""
}
@@ -0,0 +1,7 @@
module.exports = function (pagesJson, manifestJson) {
const {
app,
project
} = require('../mp')(pagesJson, manifestJson, require('./project.config.json'))
return [app, project]
}
@@ -0,0 +1,36 @@
{
"description": "项目配置文件。",
"packOptions": {
"ignore": []
},
"setting": {
"urlCheck": true,
"es6": false,
"postcss": false,
"minified": false,
"newFeature": true,
"bigPackageSizeSupport": true
},
"compileType": "miniprogram",
"libVersion": "",
"appid": "touristappid",
"projectname": "",
"condition": {
"search": {
"current": -1,
"list": []
},
"conversation": {
"current": -1,
"list": []
},
"game": {
"current": -1,
"list": []
},
"miniprogram": {
"current": -1,
"list": []
}
}
}
@@ -0,0 +1,7 @@
module.exports = function (pagesJson, manifestJson) {
const {
app,
project
} = require('../mp')(pagesJson, manifestJson, require('./project.config.json'))
return [app, project]
}
@@ -0,0 +1,11 @@
{
"setting": {
"urlCheck": true,
"es6": false,
"postcss": false,
"minified": false,
"newFeature": true
},
"appid": "testAppId",
"projectname": ""
}
+396
View File
@@ -0,0 +1,396 @@
const fs = require('fs')
const path = require('path')
const merge = require('merge')
const {
parsePages,
normalizePath,
getPlatformProject,
isSupportSubPackages
} = require('@dcloudio/uni-cli-shared')
const {
updateAppJsonUsingComponents
} = require('@dcloudio/uni-cli-shared/lib/cache')
const {
darkmode,
hasTheme
} = require('@dcloudio/uni-cli-shared/lib/theme')
const {
hasOwn,
parseStyle,
trimMPJson,
NON_APP_JSON_KEYS
} = require('../util')
const uniI18n = require('@dcloudio/uni-cli-i18n')
function defaultCopy (name, value, json) {
json[name] = value
}
function isPlainObject (a) {
if (a === null) {
return false
}
return typeof a === 'object'
}
function deepCopy (name, value, json) {
if (isPlainObject(value) && isPlainObject(json[name])) {
json[name] = merge.recursive(true, json[name], value)
} else {
defaultCopy(name, value, json)
}
}
const pagesJson2AppJson = {
globalStyle: function (name, value, json) {
json.window = parseStyle(value)
if (json.window.usingComponents || json.window.usingSwanComponents) {
// 暂定 usingComponents 优先级高于 usingSwanComponents
json.usingComponents = Object.assign({}, json.window.usingSwanComponents, json.window.usingComponents)
delete json.window.usingComponents
delete json.window.usingSwanComponents
} else {
json.usingComponents = {}
}
},
tabBar: function (name, value, json, fromJson) {
if (value && value.list && value.list.length) {
if (value.list.length < 2) {
console.error(
uniI18n.__('pagesLoader.pagesTabbarMinItem2', {
0: 'tabBar.list'
})
)
}
const pages = json.pages
value.list.forEach((page, index) => {
if (!pages.includes(page.pagePath)) {
if (
!(
fromJson &&
fromJson.nvue &&
fromJson.nvue.pages &&
fromJson.nvue.pages.find(
({
path
}) => path === page.pagePath + '.html'
)
)
) {
console.error(
uniI18n.__('pagesLoader.needInPagesNode', {
0: `pages.json tabBar['list'][${index}]['pagePath'] "${page.pagePath}"`
})
)
}
}
})
}
json[name] = value
},
preloadRule: defaultCopy,
workers: defaultCopy,
plugins: defaultCopy,
entryPagePath: defaultCopy
}
const manifestJson2AppJson = {
networkTimeout: defaultCopy,
debug: defaultCopy
}
function parseCondition (projectJson, pagesJson) {
if (process.env.NODE_ENV === 'development') {
// 仅开发期间 condition 生效
// 启动Condition
const condition = getCondition(pagesJson)
if (condition) {
if (!projectJson.condition) {
projectJson.condition = {}
}
projectJson.condition.miniprogram = condition
}
}
}
const pagesJson2ProjectJson = {}
const manifestJson2ProjectJson = {
name: function (name, value, json) {
if (!value) {
value = path.basename(process.env.UNI_INPUT_DIR)
if (value === 'src') {
value = path.basename(path.dirname(process.env.UNI_INPUT_DIR))
}
}
json.projectname = value
}
}
const platformJson2ProjectJson = {
appid: defaultCopy,
setting: deepCopy,
miniprogramRoot: defaultCopy,
cloudfunctionRoot: defaultCopy,
qcloudRoot: defaultCopy,
pluginRoot: defaultCopy,
compileType: defaultCopy,
libVersion: defaultCopy,
projectname: defaultCopy,
packOptions: deepCopy,
debugOptions: deepCopy,
scripts: deepCopy,
cloudbaseRoot: defaultCopy
}
function copyToJson (json, fromJson, options) {
Object.keys(options).forEach(name => {
if (hasOwn(fromJson, name)) {
options[name](name, fromJson[name], json, fromJson)
}
})
}
function getCondition (pagesJson) {
const condition = pagesJson.condition
const launchPagePath = process.env.UNI_CLI_LAUNCH_PAGE_PATH || ''
const launchPageQuery = process.env.UNI_CLI_LAUNCH_PAGE_QUERY || ''
const launchPageOptions = {
id: 0,
name: launchPagePath, // 模式名称
pathName: launchPagePath, // 启动页面,必选
query: launchPageQuery // 启动参数,在页面的onLoad函数里面得到。
}
if (condition) {
let current = -1
if (Array.isArray(condition.list) && condition.list.length) {
condition.list.forEach(function (item, index) {
item.id = item.id || index
if (item.path) {
item.pathName = item.path
delete item.path
}
if (launchPagePath) {
if (
item.pathName === launchPagePath &&
item.query === launchPageQuery
) {
// 指定了入口页
current = index
}
}
})
if (launchPagePath) {
if (current !== -1) {
// 已存在
condition.current = current
} else {
// 不存在
condition.list.push(
Object.assign(launchPageOptions, {
id: condition.list.length
})
)
condition.current = condition.list.length - 1
}
}
return condition
}
}
if (launchPagePath) {
pagesJson.condition = {
current: 0,
list: [launchPageOptions]
}
return pagesJson.condition
}
return false
}
function weixinSkyline (config) {
return config.renderer === 'skyline' && config.lazyCodeLoading === 'requiredComponents'
}
function openES62ES5 (config) {
if (!config.setting) {
config.setting = {}
}
if (!config.setting.es6) {
config.setting.es6 = true
}
}
module.exports = function (pagesJson, manifestJson, project = {}) {
const app = {
pages: [],
subPackages: []
}
const subPackages = {}
parsePages(
pagesJson,
function (page) {
app.pages.push(page.path)
},
function (root, page, subPackage) {
if (!isSupportSubPackages()) {
// 不支持分包
app.pages.push(normalizePath(path.join(root, page.path)))
} else {
if (!subPackages[root]) {
subPackages[root] = {
root,
pages: []
}
Object.keys(subPackage).forEach(name => {
if (['root', 'pages'].indexOf(name) === -1) {
subPackages[root][name] = subPackage[name]
}
})
}
subPackages[root].pages.push(page.path)
}
}
)
Object.keys(subPackages).forEach(root => {
app.subPackages.push(subPackages[root])
})
copyToJson(app, pagesJson, pagesJson2AppJson)
copyToJson(app, manifestJson, manifestJson2AppJson)
if (app.usingComponents) {
updateAppJsonUsingComponents(app.usingComponents)
}
const themeLocation = (manifestJson[process.env.UNI_PLATFORM] || {}).themeLocation
if (darkmode() && hasTheme(themeLocation)) {
app.themeLocation = themeLocation || 'theme.json'
}
const projectName = getPlatformProject()
const projectPath =
projectName &&
path.resolve(process.env.VUE_CLI_CONTEXT || process.cwd(), projectName)
if (projectPath && fs.existsSync(projectPath)) {
// 自定义 project.config.json
const platform = process.env.UNI_PLATFORM
// app-plus时不需要处理平台配置到 app 中
if (platform !== 'app-plus' && hasOwn(manifestJson, platform)) {
const platformJson = manifestJson[platform] || {}
const projectKeys = Object.keys(platformJson2ProjectJson)
Object.keys(platformJson).forEach(key => {
if (
!projectKeys.includes(key) && !NON_APP_JSON_KEYS.includes(key)
) {
// usingComponents 是编译模式开关,需要过滤,不能拷贝到 app
app[key] = platformJson[key]
}
})
}
if (
platform === 'mp-weixin' ||
platform === 'mp-qq'
) {
// 微信不需要生成,其他平台做拷贝
return {
app: {
name: 'app',
content: trimMPJson(app)
}
}
}
return {
app: {
name: 'app',
content: trimMPJson(app)
},
project: {
name: 'project.config',
content: require(projectPath)
}
}
} else {
parseCondition(project, pagesJson)
copyToJson(project, pagesJson, pagesJson2ProjectJson)
copyToJson(project, manifestJson, manifestJson2ProjectJson)
const platform = process.env.UNI_PLATFORM
// app-plus时不需要处理平台配置到 app 中
if (platform !== 'app-plus' && hasOwn(manifestJson, platform)) {
const platformJson = manifestJson[platform] || {}
copyToJson(project, platformJson, platformJson2ProjectJson)
const projectKeys = Object.keys(platformJson2ProjectJson)
Object.keys(platformJson).forEach(key => {
if (
!projectKeys.includes(key) && !NON_APP_JSON_KEYS.includes(key)
) {
// usingComponents 是编译模式开关,需要过滤,不能拷贝到 app
app[key] = platformJson[key]
}
})
}
// 引用了原生小程序组件,自动开启 ES6=>ES5
const wxcomponentsPath = path.resolve(
process.env.UNI_INPUT_DIR,
'./wxcomponents'
)
if (fs.existsSync(wxcomponentsPath)) {
const wxcomponentsFiles = fs.readdirSync(wxcomponentsPath)
if (wxcomponentsFiles.length) {
if (!project.setting) {
project.setting = {}
}
project.setting.es6 = true
}
}
// 使用了微信小程序手势系统,自动开启 ES6=>ES5
platform === 'mp-weixin' && weixinSkyline(manifestJson[platform]) && openES62ES5(project)
if (process.env.UNI_AUTOMATOR_WS_ENDPOINT) {
if (!project.setting) {
project.setting = {}
}
// automator时,强制不检测域名
project.setting.urlCheck = false
}
if (!project.appid) {
project.appid = 'touristappid'
}
return {
app: {
name: 'app',
content: trimMPJson(app)
},
project: {
name: 'project.config',
content: project
}
}
}
}
@@ -0,0 +1,3 @@
module.exports = function (pagesJson, manifestJson, loader) {
return require('@dcloudio/uni-quickapp-native/lib/manifest')(pagesJson, manifestJson, loader)
}
@@ -0,0 +1,36 @@
/**
* webpack-uni-pages-loader 待重构,需要将平台特有逻辑,收敛到各自包内
* @param {Object} pagesJson
* @param {Object} manifestJson
*/
module.exports = function (pagesJson, manifestJson) {
const {
app,
project
} = require('../mp')(pagesJson, manifestJson, require('./project.config.json'))
const baseJson = {
appType: 'webapp', // 华为IDE V3.0.2+ 需要此属性,否则无法导入
minPlatformVersion: 1070
}
manifestJson.name && (baseJson.name = manifestJson.name)
manifestJson.versionName && (baseJson.versionName = manifestJson.versionName)
manifestJson.versionCode && (baseJson.versionCode = manifestJson.versionCode)
const options = Object.assign({}, manifestJson['quickapp-webview'] || {})
if (process.env.UNI_SUB_PLATFORM) {
Object.assign(options, manifestJson[process.env.UNI_SUB_PLATFORM] || {})
}
Object.assign(app.content, baseJson, options)
if (!app.content.package) {
app.content.package = manifestJson.name
}
project.name = 'quickapp.config'
return [
app,
project
]
}
@@ -0,0 +1,36 @@
{
"description": "项目配置文件。",
"packOptions": {
"ignore": []
},
"setting": {
"urlCheck": true,
"es6": false,
"postcss": false,
"minified": false,
"newFeature": true
},
"compileType": "miniprogram",
"libVersion": "",
"appid": "touristappid",
"projectname": "",
"quickappRoot": "./",
"condition": {
"search": {
"current": -1,
"list": []
},
"conversation": {
"current": -1,
"list": []
},
"game": {
"current": -1,
"list": []
},
"miniprogram": {
"current": -1,
"list": []
}
}
}