From 8026a3f3f30a8e23ca53efcb15fea5860238088e Mon Sep 17 00:00:00 2001 From: ClarkXia Date: Fri, 6 Mar 2020 14:58:47 +0800 Subject: [PATCH] feat: support mpa (#82) * feat: support mpa * fix: generate empty routes file * fix: set mpa plugin as build-in * fix: register mpa config * chore: example link of codesandbox --- README.md | 1 + README_zh-CN.md | 1 + examples/basic-mpa/build.json | 4 ++ examples/basic-mpa/package.json | 20 ++++++++++ examples/basic-mpa/public/dashboard.html | 14 +++++++ examples/basic-mpa/public/index.html | 13 ++++++ examples/basic-mpa/sandbox.config.json | 6 +++ examples/basic-mpa/src/pages/Dashboard/app.ts | 10 +++++ .../basic-mpa/src/pages/Dashboard/index.tsx | 18 +++++++++ .../src/pages/Dashboard/models/counter.ts | 18 +++++++++ examples/basic-mpa/src/pages/Home/app.ts | 10 +++++ examples/basic-mpa/src/pages/Home/index.tsx | 15 +++++++ examples/basic-mpa/tsconfig.json | 40 +++++++++++++++++++ packages/icejs/src/index.ts | 3 +- packages/plugin-mpa/README.md | 30 ++++++++++++++ packages/plugin-mpa/package.json | 28 +++++++++++++ packages/plugin-mpa/src/index.ts | 25 ++++++++++++ packages/plugin-mpa/tsconfig.json | 8 ++++ packages/plugin-router/src/index.ts | 10 ++++- packages/plugin-router/src/module.tsx | 2 +- tsconfig.json | 1 + 21 files changed, 273 insertions(+), 4 deletions(-) create mode 100644 examples/basic-mpa/build.json create mode 100644 examples/basic-mpa/package.json create mode 100644 examples/basic-mpa/public/dashboard.html create mode 100644 examples/basic-mpa/public/index.html create mode 100644 examples/basic-mpa/sandbox.config.json create mode 100644 examples/basic-mpa/src/pages/Dashboard/app.ts create mode 100644 examples/basic-mpa/src/pages/Dashboard/index.tsx create mode 100644 examples/basic-mpa/src/pages/Dashboard/models/counter.ts create mode 100644 examples/basic-mpa/src/pages/Home/app.ts create mode 100644 examples/basic-mpa/src/pages/Home/index.tsx create mode 100644 examples/basic-mpa/tsconfig.json create mode 100644 packages/plugin-mpa/README.md create mode 100644 packages/plugin-mpa/package.json create mode 100644 packages/plugin-mpa/src/index.ts create mode 100644 packages/plugin-mpa/tsconfig.json diff --git a/README.md b/README.md index 2472c1248..00541798a 100644 --- a/README.md +++ b/README.md @@ -107,6 +107,7 @@ Finally, To start developing your application run `npm run start`. The applicati - [hello-world](https://codesandbox.io/s/github/ice-lab/icejs/tree/master/examples/hello-world) - [basic-spa](https://codesandbox.io/s/github/ice-lab/icejs/tree/master/examples/basic-spa) - [basic-store](https://codesandbox.io/s/github/ice-lab/icejs/tree/master/examples/basic-store) +- [basic-mpa](https://codesandbox.io/s/github/ice-lab/icejs/tree/master/examples/basic-mpa) - [basic-request](https://codesandbox.io/s/github/ice-lab/icejs/tree/master/examples/basic-request) - [icestark-child](https://codesandbox.io/s/github/ice-lab/icejs/tree/master/examples/icestark-child) - [icestark-layout](https://codesandbox.io/s/github/ice-lab/icejs/tree/master/examples/icestark-layout) diff --git a/README_zh-CN.md b/README_zh-CN.md index 7831aa678..b3649646d 100644 --- a/README_zh-CN.md +++ b/README_zh-CN.md @@ -107,6 +107,7 @@ createApp(appConfig) - [hello-world](https://codesandbox.io/s/github/ice-lab/icejs/tree/master/examples/hello-world) - [basic-spa](https://codesandbox.io/s/github/ice-lab/icejs/tree/master/examples/basic-spa) - [basic-store](https://codesandbox.io/s/github/ice-lab/icejs/tree/master/examples/basic-store) +- [basic-mpa](https://codesandbox.io/s/github/ice-lab/icejs/tree/master/examples/basic-mpa) - [basic-request](https://codesandbox.io/s/github/ice-lab/icejs/tree/master/examples/basic-request) - [icestark-child](https://codesandbox.io/s/github/ice-lab/icejs/tree/master/examples/icestark-child) - [icestark-layout](https://codesandbox.io/s/github/ice-lab/icejs/tree/master/examples/icestark-layout) diff --git a/examples/basic-mpa/build.json b/examples/basic-mpa/build.json new file mode 100644 index 000000000..c723ab840 --- /dev/null +++ b/examples/basic-mpa/build.json @@ -0,0 +1,4 @@ +{ + "mpa": true, + "plugins": [] +} diff --git a/examples/basic-mpa/package.json b/examples/basic-mpa/package.json new file mode 100644 index 000000000..e9d8fdde7 --- /dev/null +++ b/examples/basic-mpa/package.json @@ -0,0 +1,20 @@ +{ + "name": "exmaple-basic-mpa", + "description": "", + "dependencies": { + "ice.js": "^1.0.11", + "react": "^16.4.1", + "react-dom": "^16.4.1" + }, + "devDependencies": { + "@types/react": "^16.9.13", + "@types/react-dom": "^16.9.4" + }, + "scripts": { + "start": "icejs start", + "build": "icejs build" + }, + "engines": { + "node": ">=8.0.0" + } +} diff --git a/examples/basic-mpa/public/dashboard.html b/examples/basic-mpa/public/dashboard.html new file mode 100644 index 000000000..2d5423689 --- /dev/null +++ b/examples/basic-mpa/public/dashboard.html @@ -0,0 +1,14 @@ + + + + + + + mpa-dashboard + + + +
dashboard content of html template
+
+ + diff --git a/examples/basic-mpa/public/index.html b/examples/basic-mpa/public/index.html new file mode 100644 index 000000000..407c28d75 --- /dev/null +++ b/examples/basic-mpa/public/index.html @@ -0,0 +1,13 @@ + + + + + + + mpa-index + + + +
+ + diff --git a/examples/basic-mpa/sandbox.config.json b/examples/basic-mpa/sandbox.config.json new file mode 100644 index 000000000..19b69053c --- /dev/null +++ b/examples/basic-mpa/sandbox.config.json @@ -0,0 +1,6 @@ +{ + "template": "node", + "container": { + "port": 3333 + } +} diff --git a/examples/basic-mpa/src/pages/Dashboard/app.ts b/examples/basic-mpa/src/pages/Dashboard/app.ts new file mode 100644 index 000000000..b647eeef1 --- /dev/null +++ b/examples/basic-mpa/src/pages/Dashboard/app.ts @@ -0,0 +1,10 @@ +import { createApp } from 'ice' +import Dashboard from './index' + +const appConfig = { + router: { + routes: [{ path: '/', component: Dashboard }], + }, +} + +createApp(appConfig) diff --git a/examples/basic-mpa/src/pages/Dashboard/index.tsx b/examples/basic-mpa/src/pages/Dashboard/index.tsx new file mode 100644 index 000000000..b73ddd44b --- /dev/null +++ b/examples/basic-mpa/src/pages/Dashboard/index.tsx @@ -0,0 +1,18 @@ +import * as React from 'react' +import { store } from 'ice/Dashboard' + +const Dashboard = () => { + const [pageState, pageActions] = store.useModel('counter') + return ( + <> +

Dashboard Page...

+
+ + {pageState.count} + +
+ + ) +} + +export default Dashboard diff --git a/examples/basic-mpa/src/pages/Dashboard/models/counter.ts b/examples/basic-mpa/src/pages/Dashboard/models/counter.ts new file mode 100644 index 000000000..bd24bcc34 --- /dev/null +++ b/examples/basic-mpa/src/pages/Dashboard/models/counter.ts @@ -0,0 +1,18 @@ +const delay = (time) => new Promise((resolve) => setTimeout(() => resolve(), time)); + +export default { + state: { + count: 0 + }, + + actions: { + increment(prevState) { + return { count: prevState.count + 1 } + }, + + async decrement(prevState) { + await delay(10); + return { count: prevState.count - 1 } + }, + }, +}; diff --git a/examples/basic-mpa/src/pages/Home/app.ts b/examples/basic-mpa/src/pages/Home/app.ts new file mode 100644 index 000000000..ad841d7f3 --- /dev/null +++ b/examples/basic-mpa/src/pages/Home/app.ts @@ -0,0 +1,10 @@ +import { createApp } from 'ice' +import Home from './index' + +const appConfig = { + router: { + routes: [{ path: '/', component: Home }], + }, +} + +createApp(appConfig) diff --git a/examples/basic-mpa/src/pages/Home/index.tsx b/examples/basic-mpa/src/pages/Home/index.tsx new file mode 100644 index 000000000..8e04766b4 --- /dev/null +++ b/examples/basic-mpa/src/pages/Home/index.tsx @@ -0,0 +1,15 @@ +import React from 'react' + +const Home = () => { + return ( + <> +

Home Page

+ + ); +} + +Home.pageConfig = { + title: 'Home Page', +}; + +export default Home diff --git a/examples/basic-mpa/tsconfig.json b/examples/basic-mpa/tsconfig.json new file mode 100644 index 000000000..a55356b61 --- /dev/null +++ b/examples/basic-mpa/tsconfig.json @@ -0,0 +1,40 @@ +{ + "compileOnSave": false, + "buildOnSave": false, + "compilerOptions": { + "baseUrl": ".", + "outDir": "build", + "module": "esnext", + "target": "es6", + "jsx": "react", + "moduleResolution": "node", + "allowSyntheticDefaultImports": true, + "lib": [ + "es6", + "dom" + ], + "sourceMap": true, + "allowJs": true, + "rootDir": "./", + "forceConsistentCasingInFileNames": true, + "noImplicitReturns": true, + "noImplicitThis": true, + "noImplicitAny": false, + "importHelpers": true, + "strictNullChecks": true, + "suppressImplicitAnyIndexErrors": true, + "noUnusedLocals": true, + "skipLibCheck": true, + "paths": { + "@/*": [ + "./src/*" + ], + "ice": [ + ".ice/index.ts" + ], + "ice/*": [ + ".ice/pages/*" + ] + } + } +} diff --git a/packages/icejs/src/index.ts b/packages/icejs/src/index.ts index 71f6f8cbb..b5f5145c3 100644 --- a/packages/icejs/src/index.ts +++ b/packages/icejs/src/index.ts @@ -8,7 +8,8 @@ const getBuiltInPlugins = (userConfig) => { 'build-plugin-ice-helpers', 'build-plugin-ice-logger', 'build-plugin-ice-config', - 'build-plugin-ice-request' + 'build-plugin-ice-request', + 'build-plugin-ice-mpa' ] return builtInPlugins.filter(plugin => { diff --git a/packages/plugin-mpa/README.md b/packages/plugin-mpa/README.md new file mode 100644 index 000000000..6cc43bb0e --- /dev/null +++ b/packages/plugin-mpa/README.md @@ -0,0 +1,30 @@ +# plugin-ice-mpa + +> plugin for icejs to support mpa + +## Usage + +modify build options to enable mpa + +`build.json`: + +```json +{ + "mpa": true +} +``` + +config router in each `app.[t|j]s` under `src/pages` + +```js +import { createApp } from 'ice' +import Dashboard from './index' + +const appConfig = { + router: { + routes: [{ path: '/', component: Dashboard }], + }, +} + +createApp(appConfig) +``` \ No newline at end of file diff --git a/packages/plugin-mpa/package.json b/packages/plugin-mpa/package.json new file mode 100644 index 000000000..7f5bc41b7 --- /dev/null +++ b/packages/plugin-mpa/package.json @@ -0,0 +1,28 @@ +{ + "name": "build-plugin-ice-mpa", + "version": "1.0.0", + "description": "enable mpa project for icejs framework", + "author": "ice-admin@alibaba-inc.com", + "homepage": "", + "license": "MIT", + "main": "lib/index.js", + "directories": { + "lib": "lib" + }, + "files": [ + "lib" + ], + "publishConfig": { + "registry": "http://registry.npmjs.com/" + }, + "repository": { + "type": "git", + "url": "git@gitlab.alibaba-inc.com:ice/ice.js.git" + }, + "scripts": { + "test": "echo \"Error: run tests from root\" && exit 1" + }, + "devDependencies": { + "@alib/build-scripts": "^0.1.16" + } +} diff --git a/packages/plugin-mpa/src/index.ts b/packages/plugin-mpa/src/index.ts new file mode 100644 index 000000000..8b3778989 --- /dev/null +++ b/packages/plugin-mpa/src/index.ts @@ -0,0 +1,25 @@ +import { IPlugin } from '@alib/build-scripts'; + +const plugin: IPlugin = ({ context, applyMethod, registerUserConfig, modifyUserConfig }) => { + const { rootDir, userConfig } = context; + + if (userConfig.mpa) { + const pages = applyMethod('getPages', rootDir); + + const mpaEntry = {}; + pages.forEach((pageName) => { + const entryName = pageName.toLocaleLowerCase(); + mpaEntry[entryName] = `src/pages/${pageName}/app`; + }); + // modify entry + modifyUserConfig('entry', mpaEntry); + } + + // register mpa in build.json + registerUserConfig({ + name: 'mpa', + validation: 'boolean', + }); +}; + +export default plugin; \ No newline at end of file diff --git a/packages/plugin-mpa/tsconfig.json b/packages/plugin-mpa/tsconfig.json new file mode 100644 index 000000000..51e250398 --- /dev/null +++ b/packages/plugin-mpa/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.settings.json", + "compilerOptions": { + "baseUrl": "./", + "rootDir": "src", + "outDir": "lib" + } +} diff --git a/packages/plugin-router/src/index.ts b/packages/plugin-router/src/index.ts index d5792d23d..9d9bb8983 100644 --- a/packages/plugin-router/src/index.ts +++ b/packages/plugin-router/src/index.ts @@ -8,18 +8,24 @@ import walker from './collector/walker'; const TEM_ROUTER_COMPATIBLE = '$ice/routes'; const TEM_ROUTER_SETS = [TEM_ROUTER_COMPATIBLE]; -const plugin: IPlugin = ({ context,onGetWebpackConfig, getValue, applyMethod, registerUserConfig }) => { +const plugin: IPlugin = ({ context, onGetWebpackConfig, getValue, applyMethod, registerUserConfig }) => { const { rootDir, userConfig, command } = context; // [enum] js or ts + const isMpa = userConfig.mpa; const projectType = getValue('PROJECT_TYPE'); // .tmp path const iceTempPath = getValue('ICE_TEMP'); const routersTempPath = path.join(iceTempPath, `routes.${projectType}`); const routerOptions = (userConfig.router || {}) as IRouterOptions; const { configPath } = routerOptions; - const routeConfigPath = configPath + let routeConfigPath = configPath ? path.join(rootDir, configPath) : path.join(rootDir, `src/routes.${projectType}`); + if (isMpa) { + // if is mpa use empty router file + fse.writeFileSync(routersTempPath, 'export default [];', 'utf-8'); + routeConfigPath = routersTempPath + } const hasRouteFile = fse.existsSync(routeConfigPath); // copy types diff --git a/packages/plugin-router/src/module.tsx b/packages/plugin-router/src/module.tsx index d4ecbfb05..21ccb16f2 100644 --- a/packages/plugin-router/src/module.tsx +++ b/packages/plugin-router/src/module.tsx @@ -7,7 +7,7 @@ const module = ({ setRenderRouter, appConfig, modifyRoutes, wrapperRouteComponen const { router = {} } = appConfig; // plugin-router 内置确保了 defaultRoutes 最先被添加 modifyRoutes(() => { - return formatRoutes(defaultRoutes, ''); + return formatRoutes(router.routes || defaultRoutes, ''); }); wrapperRouteComponent(wrapperPage); if (router.modifyRoutes) { diff --git a/tsconfig.json b/tsconfig.json index 36fd708e2..cd3d88ee4 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,6 +10,7 @@ { "path": "packages/plugin-store" }, { "path": "packages/plugin-icestark" }, { "path": "packages/plugin-config" }, + { "path": "packages/plugin-mpa" }, { "path": "packages/create-ice" }, { "path": "packages/icejs" } ]