pagesJson.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.uniPagesJsonPlugin = void 0;
  4. const uni_cli_shared_1 = require("@dcloudio/uni-cli-shared");
  5. const utils_1 = require("../utils");
  6. function uniPagesJsonPlugin() {
  7. return (0, uni_cli_shared_1.defineUniPagesJsonPlugin)((opts) => {
  8. return {
  9. name: 'uni:h5-pages-json',
  10. enforce: 'pre',
  11. transform(code, id, opt) {
  12. if (opts.filter(id)) {
  13. const { resolvedConfig } = opts;
  14. const ssr = (0, utils_1.isSSR)(opt);
  15. if (process.env.UNI_APP_X === 'true') {
  16. // 调整换行符,确保 parseTree 的loc正确
  17. code = code.replace(/\r\n/g, '\n');
  18. try {
  19. (0, uni_cli_shared_1.checkPagesJson)((0, uni_cli_shared_1.preUVueJson)(code), process.env.UNI_INPUT_DIR);
  20. }
  21. catch (err) {
  22. if (err.loc) {
  23. const error = (0, uni_cli_shared_1.createRollupError)('uni:app-pages', 'pages.json', err, code);
  24. this.error(error);
  25. }
  26. else {
  27. throw err;
  28. }
  29. }
  30. }
  31. return {
  32. code: registerGlobalCode(resolvedConfig, ssr) +
  33. generatePagesJsonCode(ssr, code, resolvedConfig),
  34. map: { mappings: '' },
  35. };
  36. }
  37. },
  38. };
  39. });
  40. }
  41. exports.uniPagesJsonPlugin = uniPagesJsonPlugin;
  42. function generatePagesJsonCode(ssr, jsonStr, config) {
  43. const globalName = getGlobal(ssr);
  44. const pagesJson = (0, uni_cli_shared_1.normalizePagesJson)(jsonStr, process.env.UNI_PLATFORM);
  45. const { importLayoutComponentsCode, defineLayoutComponentsCode } = generateLayoutComponentsCode(globalName, pagesJson);
  46. const definePagesCode = generatePagesDefineCode(pagesJson, config);
  47. const uniRoutesCode = generateRoutes(globalName, pagesJson, config);
  48. const uniConfigCode = generateConfig(globalName, pagesJson, config);
  49. const cssCode = generateCssCode(config);
  50. const vueType = process.env.UNI_APP_X === 'true' ? 'uvue' : 'nvue';
  51. return `
  52. import { defineAsyncComponent, resolveComponent, createVNode, withCtx, openBlock, createBlock } from 'vue'
  53. import { PageComponent, useI18n, setupWindow, setupPage } from '@dcloudio/uni-h5'
  54. import { appId, appName, appVersion, appVersionCode, debug, networkTimeout, router, async, sdkConfigs, qqMapKey, googleMapKey, aMapKey, bMapKey, aMapSecurityJsCode, aMapServiceHost, ${vueType}, locale, fallbackLocale, darkmode, themeConfig } from './${uni_cli_shared_1.MANIFEST_JSON_JS}'
  55. const locales = import.meta.glob('./locale/*.json', { eager: true })
  56. ${importLayoutComponentsCode}
  57. const extend = Object.assign
  58. ${cssCode}
  59. ${uniConfigCode}
  60. ${defineLayoutComponentsCode}
  61. ${definePagesCode}
  62. ${uniRoutesCode}
  63. ${config.command === 'serve' ? hmrCode : ''}
  64. export {}
  65. `;
  66. }
  67. const hmrCode = `if(import.meta.hot){
  68. import.meta.hot.on('invalidate', (data) => {
  69. import.meta.hot.invalidate()
  70. })
  71. }`;
  72. function getGlobal(ssr) {
  73. return ssr ? 'global' : 'window';
  74. }
  75. // 兼容 wx 对象
  76. function registerGlobalCode(config, ssr) {
  77. const name = getGlobal(ssr);
  78. const enableTreeShaking = (0, uni_cli_shared_1.isEnableTreeShaking)((0, uni_cli_shared_1.parseManifestJsonOnce)(process.env.UNI_INPUT_DIR));
  79. if (enableTreeShaking && config.command === 'build' && !ssr) {
  80. // 非 SSR 的发行模式,补充全局 uni 对象
  81. return `import { upx2px, getApp } from '@dcloudio/uni-h5';${name}.uni = {};${name}.wx = {};${name}.rpx2px = upx2px`;
  82. }
  83. return `
  84. import {uni,upx2px,getCurrentPages,getApp,UniServiceJSBridge,UniViewJSBridge} from '@dcloudio/uni-h5'
  85. ${name}.getApp = getApp
  86. ${name}.getCurrentPages = getCurrentPages
  87. ${name}.wx = uni
  88. ${name}.uni = uni
  89. ${name}.UniViewJSBridge = UniViewJSBridge
  90. ${name}.UniServiceJSBridge = UniServiceJSBridge
  91. ${name}.rpx2px = upx2px
  92. ${name}.__setupPage = (com)=>setupPage(com)
  93. `;
  94. }
  95. function generateCssCode(config) {
  96. const define = config.define;
  97. const cssFiles = [uni_cli_shared_1.H5_FRAMEWORK_STYLE_PATH + 'base.css'];
  98. if (config.isProduction) {
  99. cssFiles.push(uni_cli_shared_1.H5_FRAMEWORK_STYLE_PATH + 'shadow.css');
  100. }
  101. // if (define.__UNI_FEATURE_PAGES__) {
  102. cssFiles.push(uni_cli_shared_1.H5_FRAMEWORK_STYLE_PATH + 'async.css');
  103. // }
  104. if (define.__UNI_FEATURE_RESPONSIVE__) {
  105. cssFiles.push(uni_cli_shared_1.H5_FRAMEWORK_STYLE_PATH + 'layout.css');
  106. }
  107. if (define.__UNI_FEATURE_NAVIGATIONBAR__) {
  108. cssFiles.push(uni_cli_shared_1.H5_FRAMEWORK_STYLE_PATH + 'pageHead.css');
  109. }
  110. if (define.__UNI_FEATURE_TABBAR__) {
  111. cssFiles.push(uni_cli_shared_1.H5_FRAMEWORK_STYLE_PATH + 'tabBar.css');
  112. }
  113. // x 项目直接集成 uvue.css
  114. if (process.env.UNI_APP_X === 'true') {
  115. cssFiles.push(uni_cli_shared_1.H5_FRAMEWORK_STYLE_PATH + 'uvue.css');
  116. }
  117. else {
  118. if (define.__UNI_FEATURE_NVUE__) {
  119. cssFiles.push(uni_cli_shared_1.H5_FRAMEWORK_STYLE_PATH + 'nvue.css');
  120. }
  121. }
  122. if (define.__UNI_FEATURE_PULL_DOWN_REFRESH__) {
  123. cssFiles.push(uni_cli_shared_1.H5_FRAMEWORK_STYLE_PATH + 'pageRefresh.css');
  124. }
  125. if (define.__UNI_FEATURE_NAVIGATIONBAR_SEARCHINPUT__) {
  126. cssFiles.push(uni_cli_shared_1.BASE_COMPONENTS_STYLE_PATH + 'input.css');
  127. }
  128. const enableTreeShaking = (0, uni_cli_shared_1.isEnableTreeShaking)((0, uni_cli_shared_1.parseManifestJsonOnce)(process.env.UNI_INPUT_DIR));
  129. if (config.command === 'serve' || !enableTreeShaking) {
  130. // 开发模式或禁用摇树优化,自动添加所有API相关css
  131. Object.keys(uni_cli_shared_1.API_DEPS_CSS).forEach((name) => {
  132. const styles = uni_cli_shared_1.API_DEPS_CSS[name];
  133. styles.forEach((style) => {
  134. if (!cssFiles.includes(style)) {
  135. cssFiles.push(style);
  136. }
  137. });
  138. });
  139. }
  140. return cssFiles.map((file) => `import '${file}'`).join('\n');
  141. }
  142. function generateLayoutComponentsCode(globalName, pagesJson) {
  143. const windowNames = {
  144. topWindow: -1,
  145. leftWindow: -2,
  146. rightWindow: -3,
  147. };
  148. let importLayoutComponentsCode = '';
  149. let defineLayoutComponentsCode = `${globalName}.__uniLayout = ${globalName}.__uniLayout || {}\n`;
  150. Object.keys(windowNames).forEach((name) => {
  151. const windowConfig = pagesJson[name];
  152. if (windowConfig && windowConfig.path) {
  153. importLayoutComponentsCode += `import ${name} from './${windowConfig.path}'\n`;
  154. defineLayoutComponentsCode += `${globalName}.__uniConfig.${name}.component = setupWindow(${name},${windowNames[name]})\n`;
  155. }
  156. });
  157. return {
  158. importLayoutComponentsCode,
  159. defineLayoutComponentsCode,
  160. };
  161. }
  162. function generatePageDefineCode(pageOptions) {
  163. let pagePathWithExtname = (0, uni_cli_shared_1.normalizePagePath)(pageOptions.path, 'h5');
  164. if (!pagePathWithExtname) {
  165. // 不存在时,仍引用,此时编译会报错文件不存在
  166. pagePathWithExtname = pageOptions.path + '.vue';
  167. }
  168. const pageIdent = (0, uni_cli_shared_1.normalizeIdentifier)(pageOptions.path);
  169. return `const ${pageIdent}Loader = ()=>import('./${pagePathWithExtname}').then(com => setupPage(com.default || com))
  170. const ${pageIdent} = defineAsyncComponent(extend({loader:${pageIdent}Loader},AsyncComponentOptions))`;
  171. }
  172. function generatePagesDefineCode(pagesJson, _config) {
  173. const { pages } = pagesJson;
  174. return (`const AsyncComponentOptions = {
  175. delay: async.delay,
  176. timeout: async.timeout,
  177. suspensible: async.suspensible
  178. }
  179. if(async.loading){
  180. AsyncComponentOptions.loadingComponent = {
  181. name:'SystemAsyncLoading',
  182. render(){
  183. return createVNode(resolveComponent(async.loading))
  184. }
  185. }
  186. }
  187. if(async.error){
  188. AsyncComponentOptions.errorComponent = {
  189. name:'SystemAsyncError',
  190. render(){
  191. return createVNode(resolveComponent(async.error))
  192. }
  193. }
  194. }
  195. ` + pages.map((pageOptions) => generatePageDefineCode(pageOptions)).join('\n'));
  196. }
  197. function generatePageRoute({ path, meta }, _config) {
  198. const { isEntry } = meta;
  199. const alias = isEntry ? `\n alias:'/${path}',` : '';
  200. // 目前单页面未处理 query=>props
  201. return `{
  202. path:'/${isEntry ? '' : path}',${alias}
  203. component:{setup(){ const app = getApp(); const query = app && app.$route && app.$route.query || {}; return ()=>renderPage(${(0, uni_cli_shared_1.normalizeIdentifier)(path)},query)}},
  204. loader: ${(0, uni_cli_shared_1.normalizeIdentifier)(path)}Loader,
  205. meta: ${JSON.stringify(meta)}
  206. }`;
  207. }
  208. function generatePagesRoute(pagesRouteOptions, config) {
  209. return pagesRouteOptions.map((pageOptions) => generatePageRoute(pageOptions, config));
  210. }
  211. function generateRoutes(globalName, pagesJson, config) {
  212. return `
  213. function renderPage(component,props){
  214. return (openBlock(), createBlock(PageComponent, null, {page: withCtx(() => [createVNode(component, extend({},props,{ref: "page"}), null, 512 /* NEED_PATCH */)]), _: 1 /* STABLE */}))
  215. }
  216. ${globalName}.__uniRoutes=[${[
  217. ...generatePagesRoute((0, uni_cli_shared_1.normalizePagesRoute)(pagesJson), config),
  218. ].join(',')}].map(uniRoute=>(uniRoute.meta.route = (uniRoute.alias || uniRoute.path).slice(1),uniRoute))`;
  219. }
  220. function generateConfig(globalName, pagesJson, config) {
  221. delete pagesJson.pages;
  222. delete pagesJson.subPackages;
  223. delete pagesJson.subpackages;
  224. pagesJson.compilerVersion = process.env.UNI_COMPILER_VERSION;
  225. const isX = process.env.UNI_APP_X === 'true';
  226. const vueType = isX ? 'uvue' : 'nvue';
  227. return `${isX ? `${globalName}.__uniX = true` : ''}
  228. ${globalName}.__uniConfig=extend(${JSON.stringify(pagesJson)},{
  229. appId,
  230. appName,
  231. appVersion,
  232. appVersionCode,
  233. async,
  234. debug,
  235. networkTimeout,
  236. sdkConfigs,
  237. qqMapKey,
  238. bMapKey,
  239. googleMapKey,
  240. aMapKey,
  241. aMapSecurityJsCode,
  242. aMapServiceHost,
  243. ${vueType},
  244. locale,
  245. fallbackLocale,
  246. locales:Object.keys(locales).reduce((res,name)=>{const locale=name.replace(/\\.\\/locale\\/(uni-app.)?(.*).json/,'$2');extend(res[locale]||(res[locale]={}),locales[name].default);return res},{}),
  247. router,
  248. darkmode,
  249. themeConfig,
  250. })
  251. `;
  252. }