但是在实际项目中,项目入口在src/main.ts,具体是如何指定的呢?
已知,uni-app的构建指令是vue-cli-service uni-build,vue-cli-service默认会执行package.json中配置的所有vue-cli-plugin插件,uni-app项目配置了vue-cli-plugin-uni插件,当构建项目时,会执行该插件。
在vue-cli-plugin-uni源码包中,分别为不同平台指定了Vue配置。其中,
- 移动端:node_modules/@dcloudio/vue-cli-plugin-uni/lib/app-plus/index.js
- h5:node_modules/@dcloudio/vue-cli-plugin-uni/lib/h5/index.js
- 小程序:node_modules/@dcloudio/vue-cli-plugin-uni/lib/mp/index.js
在vue-cli-plugin-uni的入口文件中,根据执行vue-cli-service指令时传递的环境变量,选择性加载指定平台的Vue配置,再结合webpack配置提供给webpack。
// node_modules/@dcloudio/vue-cli-plugin-uni/index.js
...
const type = ['app-plus', 'h5'].includes(process.env.UNI_PLATFORM)
? process.env.UNI_PLATFORM
: 'mp'
const platformOptions = require('./lib/' + type)
let vueConfig = platformOptions.vueConfig
...
Object.assign(options, { // TODO 考虑非 HBuilderX 运行时,可以支持自定义输出目录
outputDir: process.env.UNI_OUTPUT_TMP_DIR || process.env.UNI_OUTPUT_DIR,
assetsDir
}, vueConfig) // 注意,此处目前是覆盖关系,后续考虑改为webpack merge逻辑
require('./lib/options')(options)
api.configureWebpack(require('./lib/configure-webpack')(platformOptions, manifestPlatformOptions, options, api))
api.chainWebpack(require('./lib/chain-webpack')(platformOptions, options, api))
...
此处只介绍小程序项目的配置,具体配置如下:
//node_modules/@dcloudio/vue-cli-plugin-uni/lib/mp/index.js
...
module.exports = {
...
webpackConfig (webpackConfig, vueOptions, api) {
...
return {
mode: process.env.NODE_ENV === 'production' ? 'production' : 'development',
entry () {
return process.UNI_ENTRY
},
...
module: {
rules: [{
test: path.resolve(process.env.UNI_INPUT_DIR, getMainEntry()),
use: [...]
},
...
]
},
}
}
}
项目入口由环境变量UNI_ENTRY指定,其是根据页面配置得出,默认页面配置文件为项目工作目录/pages.json。UNI_ENTRY的具体设置如下:
//node_modules/@dcloudio/uni-cli-shared/lib/pages.js
...
process.UNI_ENTRY = {
'common/main': path.resolve(process.env.UNI_INPUT_DIR, getMainEntry())
}
...
// pages
pagesJson.pages.forEach(page => {
process.UNI_ENTRY[page.path] = getMainJsPath(page.path)
})
// subPackages
if (Array.isArray(pagesJson.subPackages) && pagesJson.subPackages.length) {
pagesJson.subPackages.forEach(({
root,
pages
}) => {
Array.isArray(pages) && pages.forEach(page => {
if (root) {
const pagePath = normalizePath(path.join(root, page.path))
process.UNI_ENTRY[pagePath] = getMainJsPath(pagePath)
process.UNI_SUB_PACKAGES_ROOT[pagePath] = root
}
})
})
}
项目工作目录由环境变量UNI_INPUT_DIR指定,默认是src,其设置如下
// node_modules/@dcloudio/vue-cli-plugin-uni/lib/env.js
...
const defaultInputDir = 'src'
if (process.env.UNI_INPUT_DIR && process.env.UNI_INPUT_DIR.indexOf('./') === 0) {
process.env.UNI_INPUT_DIR = path.resolve(process.cwd(), process.env.UNI_INPUT_DIR)
}
process.env.UNI_INPUT_DIR = process.env.UNI_INPUT_DIR || path.resolve(process.cwd(), defaultInputDir)
...
getMainEntry方法的具体实现如下:
//node_modules/@dcloudio/uni-cli-shared/lib/pages.js
function getMainEntry () {
if (!mainEntry) {
mainEntry = fs.existsSync(path.resolve(process.env.UNI_INPUT_DIR, 'main.ts')) ? 'main.ts' : 'main.js'
}
return mainEntry
}
所以在未指定入口的情况下,uni-app默认指定src/main.ts或src/main.js为项目入口