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
This commit is contained in:
ClarkXia 2020-03-06 14:58:47 +08:00 committed by GitHub
parent 36b8f21b4d
commit 8026a3f3f3
21 changed files with 273 additions and 4 deletions

View File

@ -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)

View File

@ -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)

View File

@ -0,0 +1,4 @@
{
"mpa": true,
"plugins": []
}

View File

@ -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"
}
}

View File

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="ie=edge,chrome=1" />
<meta name="viewport" content="width=device-width" />
<title>mpa-dashboard</title>
</head>
<body>
<div>dashboard content of html template</div>
<div id="ice-container"></div>
</body>
</html>

View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="ie=edge,chrome=1" />
<meta name="viewport" content="width=device-width" />
<title>mpa-index</title>
</head>
<body>
<div id="ice-container"></div>
</body>
</html>

View File

@ -0,0 +1,6 @@
{
"template": "node",
"container": {
"port": 3333
}
}

View File

@ -0,0 +1,10 @@
import { createApp } from 'ice'
import Dashboard from './index'
const appConfig = {
router: {
routes: [{ path: '/', component: Dashboard }],
},
}
createApp(appConfig)

View File

@ -0,0 +1,18 @@
import * as React from 'react'
import { store } from 'ice/Dashboard'
const Dashboard = () => {
const [pageState, pageActions] = store.useModel('counter')
return (
<>
<h2>Dashboard Page...</h2>
<div>
<button type="button" onClick={pageActions.increment}>+</button>
<span>{pageState.count}</span>
<button type="button" onClick={pageActions.decrement}>-</button>
</div>
</>
)
}
export default Dashboard

View File

@ -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 }
},
},
};

View File

@ -0,0 +1,10 @@
import { createApp } from 'ice'
import Home from './index'
const appConfig = {
router: {
routes: [{ path: '/', component: Home }],
},
}
createApp(appConfig)

View File

@ -0,0 +1,15 @@
import React from 'react'
const Home = () => {
return (
<>
<h2>Home Page</h2>
</>
);
}
Home.pageConfig = {
title: 'Home Page',
};
export default Home

View File

@ -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/*"
]
}
}
}

View File

@ -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 => {

View File

@ -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)
```

View File

@ -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"
}
}

View File

@ -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;

View File

@ -0,0 +1,8 @@
{
"extends": "../../tsconfig.settings.json",
"compilerOptions": {
"baseUrl": "./",
"rootDir": "src",
"outDir": "lib"
}
}

View File

@ -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

View File

@ -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) {

View File

@ -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" }
]