diff --git a/packages/plugin-rax-app/src/Loaders/RouteLoader.ts b/packages/plugin-rax-app/src/Loaders/RouteLoader.ts index 0c0bb7354..f5d4c7630 100644 --- a/packages/plugin-rax-app/src/Loaders/RouteLoader.ts +++ b/packages/plugin-rax-app/src/Loaders/RouteLoader.ts @@ -1,9 +1,10 @@ import { getOptions } from 'loader-utils'; import { join, dirname } from 'path'; import { formatPath } from '@builder/app-helpers'; -import { pathHelper } from 'miniapp-builder-shared'; +import { pathHelper, checkIsMiniappPlatform } from 'miniapp-builder-shared'; import { MINIAPP_PLATFORMS } from '../constants'; + interface ITabBarItem { text?: string; pageName?: string; @@ -43,6 +44,7 @@ export default function (appJSON) { const { target, mpa } = options; const initialStaticConfig: IStaticConfig = transformAppConfig(appJSON); const isRootAppJsonPath = this.resourcePath === join(this.rootContext, 'src', 'app.json'); + const isMiniappPlatform = checkIsMiniappPlatform(target); const staticConfig = { ...initialStaticConfig, @@ -67,6 +69,13 @@ export default function (appJSON) { target, ); const { routes, ...otherConfig } = staticConfig; + if (isMiniappPlatform) { + return ` + const staticConfig = ${JSON.stringify(staticConfig)}; + export default staticConfig; + `; + } + return ` ${normalImportExpression} const staticConfig = ${JSON.stringify(otherConfig)}; diff --git a/packages/plugin-rax-miniapp/package.json b/packages/plugin-rax-miniapp/package.json index bf357380d..640383523 100644 --- a/packages/plugin-rax-miniapp/package.json +++ b/packages/plugin-rax-miniapp/package.json @@ -21,7 +21,11 @@ "rax": "^1.0.0" }, "dependencies": { + "@builder/app-helpers": "^2.3.4", + "copy-webpack-plugin": "^5.0.4", "fs-extra": "^9.0.1", + "webpack-sources": "^2.0.0", + "webpack-virtual-modules": "^0.4.3", "miniapp-runtime-config": "^0.4.0", "webpack-sources": "^2.0.0", "miniapp-builder-shared": "^0.3.0", diff --git a/packages/plugin-rax-miniapp/src/index.js b/packages/plugin-rax-miniapp/src/index.js index c82129f5e..8dbaa5b87 100644 --- a/packages/plugin-rax-miniapp/src/index.js +++ b/packages/plugin-rax-miniapp/src/index.js @@ -17,7 +17,7 @@ const { GET_RAX_APP_WEBPACK_CONFIG, MINIAPP_COMPILED_DIR, MINIAPP_BUILD_TYPES } module.exports = (api) => { const { getValue, context, registerTask, onGetWebpackConfig } = api; const { userConfig } = context; - const { targets, inlineStyle, vendor } = userConfig; + const { targets, inlineStyle } = userConfig; const miniappStandardList = [ MINIAPP, @@ -89,51 +89,33 @@ module.exports = (api) => { nativeRoutes, }); } else if (buildType === MINIAPP_BUILD_TYPES.RUNTIME) { - const { subPackages, disableCopyNpm = true } = userConfig[target] || {}; - if (vendor && subPackages) { - const { shareMemory } = subPackages; - const originalSplitChunks = config.optimization.get('splitChunks'); - const { vendor: originalVendor = {} } = originalSplitChunks.cacheGroups || {}; - - if (shareMemory) { - config.optimization.runtimeChunk({ name: 'webpack-runtime' }); - } - config.optimization.splitChunks({ - ...originalSplitChunks, - cacheGroups: { - ...originalSplitChunks.cacheGroups, - vendor: { - ...originalVendor, - chunks: 'all', - name: 'vendors', - minChunks: 2, - test({ context: filepath }) { - // If shareMemory is true, every common files should be splited to vendors.js - if (shareMemory) { - return true; - } - if (typeof originalVendor.test === 'function') { - return originalVendor.test(filepath); - } - if (originalVendor.test instanceof RegExp) { - return originalVendor.test.test(filepath); - } - if (typeof originalVendor.test === 'string') { - return new RegExp(originalVendor.test).test(filepath); - } - return false; - }, - }, + const { disableCopyNpm = true } = userConfig[target] || {}; + + const originalSplitChunks = config.optimization.get('splitChunks'); + const { vendor: originalVendor = {} } = originalSplitChunks.cacheGroups || {}; + config.optimization.runtimeChunk({ name: 'webpack-runtime' }); + + config.optimization.splitChunks({ + ...originalSplitChunks, + cacheGroups: { + ...originalSplitChunks.cacheGroups, + vendor: { + ...originalVendor, + chunks: 'all', + name: 'vendors', + minChunks: 2, + test() { return true; }, }, - }); - if (config.plugins.has('MiniCssExtractPlugin')) { - config.plugin('MiniCssExtractPlugin').tap((options) => [ - { - ...options[0], - ignoreOrder: true, - }, - ]); - } + }, + }); + + if (config.plugins.has('MiniCssExtractPlugin')) { + config.plugin('MiniCssExtractPlugin').tap((options) => [ + { + ...options[0], + ignoreOrder: true, + }, + ]); } setConfig(config, { diff --git a/packages/plugin-rax-miniapp/src/setEntry.js b/packages/plugin-rax-miniapp/src/setEntry.js index 40db91145..bd4c292c5 100644 --- a/packages/plugin-rax-miniapp/src/setEntry.js +++ b/packages/plugin-rax-miniapp/src/setEntry.js @@ -1,6 +1,8 @@ const fs = require('fs-extra'); const path = require('path'); -const { pathHelper: { getBundlePath } } = require('miniapp-builder-shared'); + +const { getAppConfig, filterNativePages, pathHelper: { getBundlePath } } = require('miniapp-builder-shared'); +const getVirtualModules = require('./virtualModule/page'); module.exports = (config, { context, target, routes }) => { const { rootDir, userConfig } = context; @@ -10,14 +12,30 @@ module.exports = (config, { context, target, routes }) => { routes.forEach(({ source }) => { const subAppRoot = path.dirname(source); const subAppEntryConfig = config.entry(getBundlePath(subAppRoot)); + subAppEntryConfig.add(path.join(rootDir, 'src', source)); + + // TODO: get app config + const subAppConfig = getAppConfig(rootDir, target, null, subAppRoot); + const filteredRoutes = filterNativePages(subAppConfig.routes, [], { rootDir, target }); + const virtualModules = getVirtualModules(filteredRoutes, { rootDir }); + virtualModules.forEach((value, key) => { + config.plugin(`webpack-virtual-modules-${key}`).use(value); + const pageEntry = path.join(rootDir, 'src', key); + config.entry(key).add(pageEntry); + }); }); } else { - // SPA const appEntry = moduleResolve(formatPath(path.join(rootDir, './src/app'))); const entryConfig = config.entry(getBundlePath()); - entryConfig.add(appEntry); + + const virtualModules = getVirtualModules(appConfig.routes, { rootDir }); + virtualModules.forEach((value, key) => { + config.plugin(`webpack-virtual-modules-${key}`).use(value); + const pageEntry = path.join(rootDir, 'src', key); + config.entry(key).add(pageEntry); + }); } }; diff --git a/packages/plugin-rax-miniapp/src/virtualModule/page.js b/packages/plugin-rax-miniapp/src/virtualModule/page.js new file mode 100644 index 000000000..a08c120d3 --- /dev/null +++ b/packages/plugin-rax-miniapp/src/virtualModule/page.js @@ -0,0 +1,51 @@ +const VirtualModulesPlugin = require('webpack-virtual-modules'); +const { join } = require('path'); + +function getVirtualModules(routes, { rootDir }) { + const result = new Map(); + routes.forEach((route) => { + const virtualPath = join(rootDir, 'src', route.source); + result.set(`${route.source}.bundle`, new VirtualModulesPlugin({ + [`${virtualPath}.bundle`]: `import { createElement, render } from 'rax'; + import DriverUniversal from 'driver-universal'; + import PageComponent from '${virtualPath}'; + function Component(props) { + return createElement(PageComponent, { pageConfig: ${JSON.stringify(route)}, ...props }) + } + if (window.__pagesRenderInfo) { + window.__pagesRenderInfo.push({ + path: '${route.source}', + component: Component, + setDocument: window.__setDocument || (value => document = value) + }); + } else { + window.__pagesRenderInfo = [{ + path: '${route.source}', + component: Component, + setDocument: window.__setDocument || (value => document = value) + }]; + window.__render = function (pageComponent) { + const rootEl = document.createElement('div'); + rootEl.setAttribute('id', 'root'); + const pageInstance = render(createElement(pageComponent, { + history, + location: history.location, + ...pageProps, + }), rootEl, { + driver: DriverUniversal + }); + + document.body.appendChild(rootEl); + document.__unmount = function() { + return pageInstance._internal.unmountComponent.bind(pageInstance._internal); + } + }; + } +` })); + }); + + return result; +} + + +module.exports = getVirtualModules;