mp.js 9.9 KB
Newer Older
fxy060608's avatar
fxy060608 已提交
1 2
const fs = require('fs')
const path = require('path')
3
const merge = require('merge')
fxy060608's avatar
fxy060608 已提交
4 5 6 7 8 9 10 11 12 13 14 15

const {
  parsePages,
  normalizePath,
  getPlatformProject,
  isSupportSubPackages
} = require('@dcloudio/uni-cli-shared')

const {
  updateAppJsonUsingComponents
} = require('@dcloudio/uni-cli-shared/lib/cache')

fxy060608's avatar
fxy060608 已提交
16 17 18 19
const {
  darkmode,
  hasTheme
} = require('@dcloudio/uni-cli-shared/lib/theme')
fxy060608's avatar
fxy060608 已提交
20

fxy060608's avatar
fxy060608 已提交
21 22 23
const {
  hasOwn,
  parseStyle,
24 25
  trimMPJson,
  NON_APP_JSON_KEYS
fxy060608's avatar
fxy060608 已提交
26
} = require('../util')
fxy060608's avatar
fxy060608 已提交
27

d-u-a's avatar
d-u-a 已提交
28 29
const uniI18n = require('@dcloudio/uni-cli-i18n')

fxy060608's avatar
fxy060608 已提交
30 31 32 33
function defaultCopy (name, value, json) {
  json[name] = value
}

34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
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)
  }
}

fxy060608's avatar
fxy060608 已提交
49
const pagesJson2AppJson = {
fxy060608's avatar
fxy060608 已提交
50 51
  globalStyle: function (name, value, json) {
    json.window = parseStyle(value)
52 53 54
    if (json.window.usingComponents || json.window.usingSwanComponents) {
      // 暂定 usingComponents 优先级高于 usingSwanComponents
      json.usingComponents = Object.assign({}, json.window.usingSwanComponents, json.window.usingComponents)
fxy060608's avatar
fxy060608 已提交
55
      delete json.window.usingComponents
56
      delete json.window.usingSwanComponents
fxy060608's avatar
fxy060608 已提交
57
    } else {
fxy060608's avatar
fxy060608 已提交
58
      json.usingComponents = {}
fxy060608's avatar
fxy060608 已提交
59 60
    }
  },
fxy060608's avatar
fxy060608 已提交
61
  tabBar: function (name, value, json, fromJson) {
fxy060608's avatar
fxy060608 已提交
62 63
    if (value && value.list && value.list.length) {
      if (value.list.length < 2) {
fxy060608's avatar
fxy060608 已提交
64
        console.error(
fxy060608's avatar
fxy060608 已提交
65 66 67
          uniI18n.__('pagesLoader.pagesTabbarMinItem2', {
            0: 'tabBar.list'
          })
fxy060608's avatar
fxy060608 已提交
68
        )
fxy060608's avatar
fxy060608 已提交
69 70 71 72 73 74 75 76 77
      }
      const pages = json.pages
      value.list.forEach((page, index) => {
        if (!pages.includes(page.pagePath)) {
          if (
            !(
              fromJson &&
              fromJson.nvue &&
              fromJson.nvue.pages &&
fxy060608's avatar
fxy060608 已提交
78
              fromJson.nvue.pages.find(
fxy060608's avatar
fxy060608 已提交
79 80 81
                ({
                  path
                }) => path === page.pagePath + '.html'
fxy060608's avatar
fxy060608 已提交
82
              )
fxy060608's avatar
fxy060608 已提交
83 84
            )
          ) {
fxy060608's avatar
fxy060608 已提交
85 86 87 88 89
            console.error(
              uniI18n.__('pagesLoader.needInPagesNode', {
                0: `pages.json tabBar['list'][${index}]['pagePath'] "${page.pagePath}"`
              })
            )
fxy060608's avatar
fxy060608 已提交
90 91 92 93 94 95
          }
        }
      })
    }
    json[name] = value
  },
fxy060608's avatar
fxy060608 已提交
96
  preloadRule: defaultCopy,
fxy060608's avatar
fxy060608 已提交
97 98
  workers: defaultCopy,
  plugins: defaultCopy
fxy060608's avatar
fxy060608 已提交
99 100 101
}

const manifestJson2AppJson = {
fxy060608's avatar
fxy060608 已提交
102 103
  networkTimeout: defaultCopy,
  debug: defaultCopy
fxy060608's avatar
fxy060608 已提交
104 105
}

fxy060608's avatar
fxy060608 已提交
106
function parseCondition (projectJson, pagesJson) {
fxy060608's avatar
fxy060608 已提交
107 108
  if (process.env.NODE_ENV === 'development') {
    // 仅开发期间 condition 生效
fxy060608's avatar
fxy060608 已提交
109 110 111 112 113
    // 启动Condition
    const condition = getCondition(pagesJson)
    if (condition) {
      if (!projectJson.condition) {
        projectJson.condition = {}
fxy060608's avatar
fxy060608 已提交
114
      }
fxy060608's avatar
fxy060608 已提交
115
      projectJson.condition.miniprogram = condition
fxy060608's avatar
fxy060608 已提交
116 117 118 119
    }
  }
}

fxy060608's avatar
fxy060608 已提交
120 121
const pagesJson2ProjectJson = {}

fxy060608's avatar
fxy060608 已提交
122
const manifestJson2ProjectJson = {
fxy060608's avatar
fxy060608 已提交
123
  name: function (name, value, json) {
fxy060608's avatar
fxy060608 已提交
124 125 126 127 128 129
    if (!value) {
      value = path.basename(process.env.UNI_INPUT_DIR)
      if (value === 'src') {
        value = path.basename(path.dirname(process.env.UNI_INPUT_DIR))
      }
    }
fxy060608's avatar
fxy060608 已提交
130
    json.projectname = value
fxy060608's avatar
fxy060608 已提交
131 132 133 134
  }
}

const platformJson2ProjectJson = {
fxy060608's avatar
fxy060608 已提交
135
  appid: defaultCopy,
136
  setting: deepCopy,
fxy060608's avatar
fxy060608 已提交
137 138 139 140 141 142 143
  miniprogramRoot: defaultCopy,
  cloudfunctionRoot: defaultCopy,
  qcloudRoot: defaultCopy,
  pluginRoot: defaultCopy,
  compileType: defaultCopy,
  libVersion: defaultCopy,
  projectname: defaultCopy,
144 145 146
  packOptions: deepCopy,
  debugOptions: deepCopy,
  scripts: deepCopy,
147
  cloudbaseRoot: defaultCopy
fxy060608's avatar
fxy060608 已提交
148 149 150 151 152 153 154 155 156 157
}

function copyToJson (json, fromJson, options) {
  Object.keys(options).forEach(name => {
    if (hasOwn(fromJson, name)) {
      options[name](name, fromJson[name], json, fromJson)
    }
  })
}

fxy060608's avatar
fxy060608 已提交
158 159
function getCondition (pagesJson) {
  const condition = pagesJson.condition
fxy060608's avatar
fxy060608 已提交
160 161 162 163
  const launchPagePath = process.env.UNI_CLI_LAUNCH_PAGE_PATH || ''
  const launchPageQuery = process.env.UNI_CLI_LAUNCH_PAGE_QUERY || ''

  const launchPageOptions = {
fxy060608's avatar
fxy060608 已提交
164 165 166 167
    id: 0,
    name: launchPagePath, // 模式名称
    pathName: launchPagePath, // 启动页面,必选
    query: launchPageQuery // 启动参数,在页面的onLoad函数里面得到。
fxy060608's avatar
fxy060608 已提交
168 169 170 171 172 173 174 175 176 177 178
  }
  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) {
fxy060608's avatar
fxy060608 已提交
179 180 181 182 183
          if (
            item.pathName === launchPagePath &&
            item.query === launchPageQuery
          ) {
            // 指定了入口页
fxy060608's avatar
fxy060608 已提交
184 185 186 187 188
            current = index
          }
        }
      })
      if (launchPagePath) {
fxy060608's avatar
fxy060608 已提交
189 190
        if (current !== -1) {
          // 已存在
fxy060608's avatar
fxy060608 已提交
191
          condition.current = current
fxy060608's avatar
fxy060608 已提交
192 193 194 195 196 197 198
        } else {
          // 不存在
          condition.list.push(
            Object.assign(launchPageOptions, {
              id: condition.list.length
            })
          )
fxy060608's avatar
fxy060608 已提交
199 200 201 202 203 204 205
          condition.current = condition.list.length - 1
        }
      }
      return condition
    }
  }
  if (launchPagePath) {
fxy060608's avatar
fxy060608 已提交
206
    pagesJson.condition = {
fxy060608's avatar
fxy060608 已提交
207 208
      current: 0,
      list: [launchPageOptions]
fxy060608's avatar
fxy060608 已提交
209
    }
fxy060608's avatar
fxy060608 已提交
210
    return pagesJson.condition
fxy060608's avatar
fxy060608 已提交
211 212 213 214 215 216 217 218 219 220 221 222
  }
  return false
}

module.exports = function (pagesJson, manifestJson, project = {}) {
  const app = {
    pages: [],
    subPackages: []
  }

  const subPackages = {}

fxy060608's avatar
fxy060608 已提交
223 224 225
  parsePages(
    pagesJson,
    function (page) {
226
      app.pages.push(page.path)
fxy060608's avatar
fxy060608 已提交
227 228 229 230 231 232 233 234 235 236
    },
    function (root, page, subPackage) {
      if (!isSupportSubPackages()) {
        // 不支持分包
        app.pages.push(normalizePath(path.join(root, page.path)))
      } else {
        if (!subPackages[root]) {
          subPackages[root] = {
            root,
            pages: []
fxy060608's avatar
fxy060608 已提交
237
          }
fxy060608's avatar
fxy060608 已提交
238 239 240 241 242 243 244
          Object.keys(subPackage).forEach(name => {
            if (['root', 'pages'].indexOf(name) === -1) {
              subPackages[root][name] = subPackage[name]
            }
          })
        }
        subPackages[root].pages.push(page.path)
fxy060608's avatar
fxy060608 已提交
245 246
      }
    }
fxy060608's avatar
fxy060608 已提交
247
  )
fxy060608's avatar
fxy060608 已提交
248 249 250 251 252 253 254 255 256 257 258 259 260

  Object.keys(subPackages).forEach(root => {
    app.subPackages.push(subPackages[root])
  })

  copyToJson(app, pagesJson, pagesJson2AppJson)

  copyToJson(app, manifestJson, manifestJson2AppJson)

  if (app.usingComponents) {
    updateAppJsonUsingComponents(app.usingComponents)
  }

D
DCloud_LXH 已提交
261 262 263
  const themeLocation = (manifestJson[process.env.UNI_PLATFORM] || {}).themeLocation
  if (darkmode() && hasTheme(themeLocation)) {
    app.themeLocation = themeLocation || 'theme.json'
fxy060608's avatar
fxy060608 已提交
264 265
  }

fxy060608's avatar
fxy060608 已提交
266 267
  const projectName = getPlatformProject()

fxy060608's avatar
fxy060608 已提交
268 269 270
  const projectPath =
    projectName &&
    path.resolve(process.env.VUE_CLI_CONTEXT || process.cwd(), projectName)
fxy060608's avatar
fxy060608 已提交
271

fxy060608's avatar
fxy060608 已提交
272 273
  if (projectPath && fs.existsSync(projectPath)) {
    // 自定义 project.config.json
fxy060608's avatar
fxy060608 已提交
274 275 276 277 278 279 280 281 282 283
    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 (
284
          !projectKeys.includes(key) && !NON_APP_JSON_KEYS.includes(key)
fxy060608's avatar
fxy060608 已提交
285 286 287 288 289 290 291
        ) {
          // usingComponents 是编译模式开关,需要过滤,不能拷贝到 app
          app[key] = platformJson[key]
        }
      })
    }

fxy060608's avatar
fxy060608 已提交
292 293 294 295 296
    if (
      process.env.UNI_PLATFORM === 'mp-weixin' ||
      process.env.UNI_PLATFORM === 'mp-qq'
    ) {
      // 微信不需要生成,其他平台做拷贝
fxy060608's avatar
fxy060608 已提交
297 298 299
      return {
        app: {
          name: 'app',
fxy060608's avatar
fxy060608 已提交
300
          content: trimMPJson(app)
fxy060608's avatar
fxy060608 已提交
301 302 303 304 305 306
        }
      }
    }
    return {
      app: {
        name: 'app',
fxy060608's avatar
fxy060608 已提交
307
        content: trimMPJson(app)
fxy060608's avatar
fxy060608 已提交
308 309 310 311 312 313
      },
      project: {
        name: 'project.config',
        content: require(projectPath)
      }
    }
fxy060608's avatar
fxy060608 已提交
314 315
  } else {
    parseCondition(project, pagesJson)
fxy060608's avatar
fxy060608 已提交
316

fxy060608's avatar
fxy060608 已提交
317 318 319 320 321 322 323 324 325 326 327 328 329 330 331
    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 => {
fxy060608's avatar
fxy060608 已提交
332
        if (
fxy060608's avatar
fxy060608 已提交
333
          !projectKeys.includes(key) && ['usingComponents', 'optimization'].indexOf(key) === -1
fxy060608's avatar
fxy060608 已提交
334
        ) {
fxy060608's avatar
fxy060608 已提交
335 336 337 338 339 340 341
          // usingComponents 是编译模式开关,需要过滤,不能拷贝到 app
          app[key] = platformJson[key]
        }
      })
    }

    // 引用了原生小程序组件,自动开启 ES6=>ES5
fxy060608's avatar
fxy060608 已提交
342 343 344 345
    const wxcomponentsPath = path.resolve(
      process.env.UNI_INPUT_DIR,
      './wxcomponents'
    )
fxy060608's avatar
fxy060608 已提交
346 347 348 349 350 351 352 353 354 355
    if (fs.existsSync(wxcomponentsPath)) {
      const wxcomponentsFiles = fs.readdirSync(wxcomponentsPath)
      if (wxcomponentsFiles.length) {
        if (!project.setting) {
          project.setting = {}
        }
        project.setting.es6 = true
      }
    }

fxy060608's avatar
fxy060608 已提交
356 357 358 359 360 361 362 363
    if (process.env.UNI_AUTOMATOR_WS_ENDPOINT) {
      if (!project.setting) {
        project.setting = {}
      }
      // automator时,强制不检测域名
      project.setting.urlCheck = false
    }

fxy060608's avatar
fxy060608 已提交
364 365 366 367 368 369 370
    if (!project.appid) {
      project.appid = 'touristappid'
    }

    return {
      app: {
        name: 'app',
fxy060608's avatar
fxy060608 已提交
371
        content: trimMPJson(app)
fxy060608's avatar
fxy060608 已提交
372 373 374 375 376 377 378
      },
      project: {
        name: 'project.config',
        content: project
      }
    }
  }
D
DCloud_LXH 已提交
379
}