├── CHANGELOG.md
├── packages
├── plugin-ssr
│ ├── README.md
│ ├── __tests__
│ │ └── plugin-ssr.test.js
│ ├── tsconfig.json
│ └── package.json
├── plugin-helpers
│ ├── src
│ │ ├── _helpers.ts
│ │ └── index.ts
│ ├── helpers
│ │ ├── cookie.ts
│ │ ├── urlParse.ts
│ │ └── index.ts
│ ├── __tests__
│ │ └── index.test.js
│ ├── tsconfig.json
│ ├── README.md
│ └── package.json
├── plugin-logger
│ ├── src
│ │ ├── types
│ │ │ └── index.ts
│ │ ├── _logger.ts
│ │ ├── module.ts
│ │ └── index.ts
│ ├── logger
│ │ └── index.ts
│ ├── tsconfig.json
│ ├── README.md
│ └── package.json
├── plugin-rematch
│ ├── src
│ │ ├── _store.ts
│ │ ├── template
│ │ │ └── store.ts.ejs
│ │ ├── module.tsx
│ │ ├── generateStore.ts
│ │ └── index.ts
│ ├── __tests__
│ │ └── index.test.js
│ ├── tsconfig.json
│ └── package.json
├── plugin-config
│ ├── src
│ │ ├── _config.ts
│ │ └── index.ts
│ ├── __tests__
│ │ └── plugin-config.test.js
│ ├── tsconfig.json
│ ├── config
│ │ └── index.ts
│ ├── README.md
│ └── package.json
├── plugin-service
│ ├── src
│ │ ├── _ice.ts
│ │ └── index.ts
│ ├── __tests__
│ │ └── plugin-service.test.js
│ ├── tsconfig.json
│ ├── package.json
│ └── README.md
├── plugin-router
│ ├── src
│ │ ├── runtime
│ │ │ └── _routes.ts
│ │ ├── types
│ │ │ ├── collector.ts
│ │ │ ├── index.ts
│ │ │ ├── base.ts
│ │ │ └── router.ts
│ │ └── module.tsx
│ ├── templates
│ │ ├── index.ts
│ │ ├── history.ts
│ │ ├── useSearchParams.ts
│ │ ├── withSearchParams.tsx
│ │ └── react-router-dom.ts
│ ├── __tests__
│ │ └── plugin-router.test.js
│ ├── tsconfig.json
│ └── package.json
├── plugin-core
│ ├── src
│ │ ├── generator
│ │ │ └── templates
│ │ │ │ ├── page
│ │ │ │ └── index.ts.ejs
│ │ │ │ └── app
│ │ │ │ ├── components
│ │ │ │ └── index.ts.ejs
│ │ │ │ ├── lazy.ts.ejs
│ │ │ │ ├── index.ts.ejs
│ │ │ │ ├── appConfig.ts.ejs
│ │ │ │ └── types.ts.ejs
│ │ ├── types
│ │ │ └── base.ts
│ │ ├── utils
│ │ │ ├── formatPath.ts
│ │ │ ├── removeExportData.ts
│ │ │ ├── getPages.ts
│ │ │ ├── checkExportData.ts
│ │ │ ├── generateExports.ts
│ │ │ └── getRoutes.ts
│ │ ├── _components.tsx
│ │ └── module.tsx
│ ├── tsconfig.json
│ └── package.json
├── plugin-react-app
│ ├── src
│ │ ├── userConfig
│ │ │ ├── externals.js
│ │ │ ├── library.js
│ │ │ ├── filename.js
│ │ │ ├── libraryExport.js
│ │ │ ├── libraryTarget.js
│ │ │ ├── modules.js
│ │ │ ├── extensions.js
│ │ │ ├── minify.js
│ │ │ ├── publicPath.js
│ │ │ ├── devPublicPath.js
│ │ │ ├── sourcemap.js
│ │ │ ├── terserOptions.js
│ │ │ ├── vendor.js
│ │ │ ├── define.js
│ │ │ ├── babelPlugins.js
│ │ │ ├── lessLoaderOptions.js
│ │ │ ├── sassLoaderOptions.js
│ │ │ ├── alias.js
│ │ │ ├── devServer.js
│ │ │ ├── postcssrc.js
│ │ │ ├── outputDir.js
│ │ │ ├── cssLoaderOptions.js
│ │ │ ├── ignoreHtmlTemplate.js
│ │ │ ├── mock.js
│ │ │ ├── targets.js
│ │ │ ├── outputAssetsPath.js
│ │ │ ├── eslint.js
│ │ │ ├── compileDependencies.js
│ │ │ ├── hash.js
│ │ │ ├── babelPresets.js
│ │ │ └── proxy.js
│ │ ├── utils
│ │ │ ├── polyfillLoader.js
│ │ │ ├── formatWinPath.js
│ │ │ ├── getFilePath.js
│ │ │ ├── collect.js
│ │ │ ├── babelPluginCorejsLock.js
│ │ │ ├── updateMiniCssLoaderPath.js
│ │ │ └── getCertificate.js
│ │ ├── cliOption
│ │ │ ├── analyzer.js
│ │ │ ├── analyzerPort.js
│ │ │ ├── disableReload.js
│ │ │ └── https.js
│ │ └── config
│ │ │ ├── option.config.js
│ │ │ └── default.config.js
│ ├── README.md
│ └── package.json
├── icejs
│ ├── __tests__
│ │ └── cli.test.js
│ ├── tsconfig.json
│ ├── bin
│ │ ├── build.js
│ │ ├── test.js
│ │ ├── child-process-start.js
│ │ └── ice-cli.js
│ ├── src
│ │ └── index.ts
│ ├── README.md
│ └── package.json
├── create-ice
│ ├── __tests__
│ │ └── index.test.js
│ ├── tsconfig.json
│ ├── README.md
│ ├── package.json
│ └── src
│ │ └── index.ts
├── plugin-icestark
│ ├── src
│ │ ├── runtime
│ │ │ ├── _history.ts
│ │ │ ├── Layout.tsx
│ │ │ ├── _Router.tsx
│ │ │ └── removeLayout.ts
│ │ ├── types
│ │ │ ├── base.ts
│ │ │ └── index.ts
│ │ └── index.ts
│ ├── tsconfig.json
│ ├── package.json
│ └── README.md
├── plugin-store
│ ├── __tests__
│ │ └── plugin-store.test.js
│ ├── tsconfig.json
│ ├── src
│ │ ├── _store.ts
│ │ ├── template
│ │ │ ├── types.ts.ejs
│ │ │ ├── pageStore.ts.ejs
│ │ │ ├── appStore.ts.ejs
│ │ │ └── pageComponent.tsx.ejs
│ │ └── module.tsx
│ ├── package.json
│ └── README.md
├── plugin-request
│ ├── __tests__
│ │ └── plugin-request.test.js
│ ├── src
│ │ ├── _axiosInstance.ts
│ │ ├── types
│ │ │ ├── index.ts
│ │ │ └── base.ts
│ │ ├── module.ts
│ │ └── index.ts
│ ├── request
│ │ └── axiosInstance.ts
│ ├── tsconfig.json
│ ├── package.json
│ └── README.md
└── plugin-mpa
│ ├── tsconfig.json
│ ├── README.md
│ ├── package.json
│ └── src
│ └── index.ts
├── examples
├── basic-mpa
│ ├── build.json
│ ├── sandbox.config.json
│ ├── src
│ │ └── pages
│ │ │ ├── Dashboard
│ │ │ ├── routes.ts
│ │ │ ├── app.ts
│ │ │ ├── index.tsx
│ │ │ └── models
│ │ │ │ └── counter.ts
│ │ │ └── Home
│ │ │ ├── app.ts
│ │ │ └── index.tsx
│ ├── public
│ │ ├── index.html
│ │ └── dashboard.html
│ ├── package.json
│ └── tsconfig.json
├── basic-ssr
│ ├── build.json
│ ├── src
│ │ ├── pages
│ │ │ ├── Home
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── NotFound
│ │ │ │ └── index.tsx
│ │ │ ├── About
│ │ │ │ └── index.tsx
│ │ │ └── Dashboard
│ │ │ │ └── index.tsx
│ │ ├── config.ts
│ │ ├── layouts
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── app.ts
│ │ ├── models
│ │ │ └── user.ts
│ │ └── routes.ts
│ ├── sandbox.config.json
│ ├── public
│ │ └── index.html
│ ├── mock
│ │ └── index.ts
│ ├── package.json
│ └── tsconfig.json
├── icestark-child
│ ├── src
│ │ ├── global.css
│ │ ├── app.ts
│ │ └── pages
│ │ │ ├── Dashboard
│ │ │ └── index.tsx
│ │ │ ├── About
│ │ │ ├── _layout.tsx
│ │ │ └── index.tsx
│ │ │ └── index.tsx
│ ├── sandbox.config.json
│ ├── build.json
│ ├── public
│ │ └── index.html
│ ├── package.json
│ └── tsconfig.json
├── icestark-layout
│ ├── src
│ │ ├── global.scss
│ │ ├── pages
│ │ │ ├── Home
│ │ │ │ └── index.tsx
│ │ │ ├── Dashboard
│ │ │ │ └── index.tsx
│ │ │ └── 404.tsx
│ │ └── app.tsx
│ ├── sandbox.config.json
│ ├── build.json
│ ├── public
│ │ └── index.html
│ ├── package.json
│ └── tsconfig.json
├── basic-request
│ ├── src
│ │ ├── global.scss
│ │ ├── routes.ts
│ │ ├── app.ts
│ │ └── pages
│ │ │ └── Home
│ │ │ └── index.tsx
│ ├── README.md
│ ├── sandbox.config.json
│ ├── public
│ │ └── index.html
│ ├── mock
│ │ └── index.js
│ ├── package.json
│ └── tsconfig.json
├── basic-rml
│ ├── build.json
│ ├── src
│ │ ├── global.scss
│ │ ├── app.ts
│ │ ├── routes.ts
│ │ └── pages
│ │ │ └── Home
│ │ │ └── index.rml
│ ├── README.md
│ ├── sandbox.config.json
│ ├── public
│ │ └── index.html
│ ├── package.json
│ └── tsconfig.json
├── basic-service
│ ├── src
│ │ ├── global.scss
│ │ ├── routes.ts
│ │ ├── app.ts
│ │ ├── pages
│ │ │ └── Home
│ │ │ │ ├── index.tsx
│ │ │ │ └── components
│ │ │ │ └── User
│ │ │ │ ├── index.tsx
│ │ │ │ └── service.ts
│ │ ├── components
│ │ │ └── Fetch
│ │ │ │ └── index.tsx
│ │ └── services
│ │ │ └── todo.ts
│ ├── build.json
│ ├── README.md
│ ├── sandbox.config.json
│ ├── public
│ │ └── index.html
│ ├── package.json
│ ├── mock
│ │ └── index.js
│ └── tsconfig.json
├── basic-store
│ ├── src
│ │ ├── global.scss
│ │ ├── pages
│ │ │ ├── Home
│ │ │ │ ├── model.ts
│ │ │ │ └── index.tsx
│ │ │ ├── NotFound
│ │ │ │ └── index.tsx
│ │ │ └── About
│ │ │ │ ├── model.ts
│ │ │ │ └── index.tsx
│ │ ├── app.ts
│ │ ├── layouts
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── models
│ │ │ ├── counter.ts
│ │ │ └── user.ts
│ │ └── routes.ts
│ ├── build.json
│ ├── README.md
│ ├── sandbox.config.json
│ ├── public
│ │ └── index.html
│ ├── package.json
│ └── tsconfig.json
├── hello-world
│ ├── src
│ │ ├── global.scss
│ │ ├── pages
│ │ │ └── Home
│ │ │ │ └── index.tsx
│ │ ├── routes.ts
│ │ ├── app.ts
│ │ └── components
│ │ │ └── Guide
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ ├── README.md
│ ├── sandbox.config.json
│ ├── public
│ │ └── index.html
│ ├── package.json
│ └── tsconfig.json
├── with-rematch
│ ├── build.json
│ ├── README.md
│ ├── sandbox.config.json
│ ├── src
│ │ ├── app.ts
│ │ ├── routes.ts
│ │ ├── pages
│ │ │ ├── 404.tsx
│ │ │ ├── Rematch
│ │ │ │ ├── index.tsx
│ │ │ │ └── Child.tsx
│ │ │ └── index.tsx
│ │ └── stores
│ │ │ └── user.ts
│ ├── public
│ │ └── index.html
│ ├── package.json
│ └── tsconfig.json
├── basic-spa
│ ├── sandbox.config.json
│ ├── build.json
│ ├── src
│ │ ├── layouts
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ ├── pages
│ │ │ ├── About
│ │ │ │ ├── components
│ │ │ │ │ ├── Child.tsx
│ │ │ │ │ └── Todo.tsx
│ │ │ │ └── index.tsx
│ │ │ ├── NotFound
│ │ │ │ └── index.tsx
│ │ │ ├── Dashboard
│ │ │ │ └── index.tsx
│ │ │ └── Home
│ │ │ │ └── index.tsx
│ │ ├── config.ts
│ │ ├── app.tsx
│ │ └── routes.ts
│ ├── public
│ │ └── index.html
│ ├── package.json
│ ├── tsconfig.json
│ └── mock
│ │ └── index.js
└── with-fusion-design
│ ├── README.md
│ ├── sandbox.config.json
│ ├── src
│ ├── global.scss
│ ├── routes.ts
│ ├── app.ts
│ └── pages
│ │ └── Home
│ │ └── index.tsx
│ ├── build.json
│ ├── public
│ └── index.html
│ ├── package.json
│ └── tsconfig.json
├── .commitlintrc.js
├── lerna.json
├── scripts
├── fn
│ ├── shell.ts
│ └── getPackages.ts
├── sync.ts
├── dependency-check.ts
├── rollback.ts
├── owner.ts
└── build.ts
├── tsconfig.settings.json
├── .eslintignore
├── .editorconfig
├── .gitignore
├── README.md
├── .github
├── ISSUE_TEMPLATE.md
├── workflows
│ └── ci.yml
└── GIT_COMMIT_SPECIFIC.md
├── tsconfig.json
├── .eslintrc.js
└── LICENSE
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # CHANGELOG for icejs
2 |
--------------------------------------------------------------------------------
/packages/plugin-ssr/README.md:
--------------------------------------------------------------------------------
1 | # plugin-ssr
2 |
--------------------------------------------------------------------------------
/examples/basic-mpa/build.json:
--------------------------------------------------------------------------------
1 | {
2 | "mpa": true,
3 | "plugins": []
4 | }
5 |
--------------------------------------------------------------------------------
/examples/basic-ssr/build.json:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": [],
3 | "ssr": true
4 | }
5 |
--------------------------------------------------------------------------------
/examples/basic-ssr/src/pages/Home/index.module.scss:
--------------------------------------------------------------------------------
1 | .title {
2 | color: red;
3 | }
4 |
--------------------------------------------------------------------------------
/packages/plugin-helpers/src/_helpers.ts:
--------------------------------------------------------------------------------
1 | const helpers = {};
2 | export { helpers };
3 |
--------------------------------------------------------------------------------
/examples/icestark-child/src/global.css:
--------------------------------------------------------------------------------
1 | body {
2 | -webkit-font-smoothing: antialiased;
3 | }
--------------------------------------------------------------------------------
/examples/icestark-layout/src/global.scss:
--------------------------------------------------------------------------------
1 | body {
2 | -webkit-font-smoothing: antialiased;
3 | }
--------------------------------------------------------------------------------
/.commitlintrc.js:
--------------------------------------------------------------------------------
1 | const { commitlint } = require('@ice/spec');
2 |
3 | module.exports = commitlint;
4 |
--------------------------------------------------------------------------------
/examples/basic-request/src/global.scss:
--------------------------------------------------------------------------------
1 | body {
2 | -webkit-font-smoothing: antialiased;
3 | }
4 |
5 |
--------------------------------------------------------------------------------
/examples/basic-rml/build.json:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": [
3 | "build-plugin-ice-rml"
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/examples/basic-rml/src/global.scss:
--------------------------------------------------------------------------------
1 | body {
2 | -webkit-font-smoothing: antialiased;
3 | }
4 |
5 |
--------------------------------------------------------------------------------
/examples/basic-service/src/global.scss:
--------------------------------------------------------------------------------
1 | body {
2 | -webkit-font-smoothing: antialiased;
3 | }
4 |
5 |
--------------------------------------------------------------------------------
/examples/basic-store/src/global.scss:
--------------------------------------------------------------------------------
1 | body {
2 | -webkit-font-smoothing: antialiased;
3 | }
4 |
5 |
--------------------------------------------------------------------------------
/examples/hello-world/src/global.scss:
--------------------------------------------------------------------------------
1 | body {
2 | -webkit-font-smoothing: antialiased;
3 | }
4 |
5 |
--------------------------------------------------------------------------------
/packages/plugin-logger/src/types/index.ts:
--------------------------------------------------------------------------------
1 | export interface ILogger {
2 | level: string;
3 | }
4 |
--------------------------------------------------------------------------------
/packages/plugin-rematch/src/_store.ts:
--------------------------------------------------------------------------------
1 | const stores = {};
2 |
3 | export {
4 | stores,
5 | };
6 |
--------------------------------------------------------------------------------
/examples/basic-service/build.json:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": [
3 | "build-plugin-ice-service"
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/examples/with-rematch/build.json:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": [
3 | "build-plugin-ice-rematch"
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/packages/plugin-logger/logger/index.ts:
--------------------------------------------------------------------------------
1 | import * as logger from 'loglevel';
2 |
3 | export default logger;
--------------------------------------------------------------------------------
/examples/basic-rml/README.md:
--------------------------------------------------------------------------------
1 | # rml with icejs
2 |
3 | https://github.com/ice-lab/icejs/tree/master/examples
4 |
--------------------------------------------------------------------------------
/examples/basic-store/build.json:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": [],
3 | "router": {
4 | "lazy": false
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/examples/with-rematch/README.md:
--------------------------------------------------------------------------------
1 | # with rematch
2 |
3 | https://github.com/ice-lab/icejs/tree/master/examples
4 |
--------------------------------------------------------------------------------
/packages/plugin-helpers/helpers/cookie.ts:
--------------------------------------------------------------------------------
1 | import * as cookie from 'cookie';
2 |
3 | export {
4 | cookie
5 | };
--------------------------------------------------------------------------------
/packages/plugin-config/src/_config.ts:
--------------------------------------------------------------------------------
1 | const config = {
2 | default: {},
3 | };
4 |
5 | export default config;
6 |
--------------------------------------------------------------------------------
/examples/basic-service/README.md:
--------------------------------------------------------------------------------
1 | # service for icejs
2 |
3 | https://github.com/ice-lab/icejs/tree/master/examples
4 |
--------------------------------------------------------------------------------
/examples/basic-store/src/pages/Home/model.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | state: {
3 | title: 'Home Page'
4 | },
5 | };
6 |
--------------------------------------------------------------------------------
/examples/hello-world/README.md:
--------------------------------------------------------------------------------
1 | # Hello World with icejs
2 |
3 | https://github.com/ice-lab/icejs/tree/master/examples
4 |
--------------------------------------------------------------------------------
/packages/plugin-service/src/_ice.ts:
--------------------------------------------------------------------------------
1 | // eslint-disable-next-line
2 | export const request = function(params: any) {};
3 |
--------------------------------------------------------------------------------
/examples/basic-mpa/sandbox.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "template": "node",
3 | "container": {
4 | "port": 3333
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/examples/basic-request/README.md:
--------------------------------------------------------------------------------
1 | # data fetching with icejs
2 |
3 | https://github.com/ice-lab/icejs/tree/master/examples
4 |
--------------------------------------------------------------------------------
/examples/basic-rml/sandbox.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "template": "node",
3 | "container": {
4 | "port": 3333
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/examples/basic-spa/sandbox.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "template": "node",
3 | "container": {
4 | "port": 3333
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/examples/basic-ssr/sandbox.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "template": "node",
3 | "container": {
4 | "port": 3333
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/examples/basic-store/README.md:
--------------------------------------------------------------------------------
1 | # store management with icejs
2 |
3 | https://github.com/ice-lab/icejs/tree/master/examples
4 |
--------------------------------------------------------------------------------
/examples/basic-store/sandbox.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "template": "node",
3 | "container": {
4 | "port": 3333
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/examples/hello-world/sandbox.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "template": "node",
3 | "container": {
4 | "port": 3333
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/examples/with-fusion-design/README.md:
--------------------------------------------------------------------------------
1 | # with fusion design
2 |
3 | https://github.com/ice-lab/icejs/tree/master/examples
4 |
--------------------------------------------------------------------------------
/packages/plugin-helpers/helpers/urlParse.ts:
--------------------------------------------------------------------------------
1 | import * as urlParse from 'url-parse';
2 |
3 | export {
4 | urlParse
5 | };
6 |
--------------------------------------------------------------------------------
/packages/plugin-router/src/runtime/_routes.ts:
--------------------------------------------------------------------------------
1 | // 注释:
2 | // 该文件仅用于 module.tsx 中引用 $ice/routes 的编译问题
3 | export default [];
4 |
--------------------------------------------------------------------------------
/examples/basic-request/sandbox.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "template": "node",
3 | "container": {
4 | "port": 3333
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/examples/basic-service/sandbox.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "template": "node",
3 | "container": {
4 | "port": 3333
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/examples/icestark-child/sandbox.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "template": "node",
3 | "container": {
4 | "port": 3333
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/examples/icestark-layout/sandbox.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "template": "node",
3 | "container": {
4 | "port": 3333
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/examples/with-rematch/sandbox.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "template": "node",
3 | "container": {
4 | "port": 3333
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/examples/with-fusion-design/sandbox.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "template": "node",
3 | "container": {
4 | "port": 3333
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/packages/plugin-core/src/generator/templates/page/index.ts.ejs:
--------------------------------------------------------------------------------
1 | <%- pageImports %>
2 |
3 | export {
4 | <%= pageExports %>
5 | }
6 |
--------------------------------------------------------------------------------
/examples/basic-mpa/src/pages/Dashboard/routes.ts:
--------------------------------------------------------------------------------
1 | import Index from './index';
2 |
3 | export default [{ path: '/', component: Index }];
4 |
--------------------------------------------------------------------------------
/packages/plugin-react-app/src/userConfig/externals.js:
--------------------------------------------------------------------------------
1 | module.exports = (config, value) => {
2 | config.merge({ externals: value });
3 | };
4 |
--------------------------------------------------------------------------------
/lerna.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1.2.1",
3 | "npmClient": "yarn",
4 | "useWorkspaces": true,
5 | "packages": [
6 | "packages/*"
7 | ]
8 | }
9 |
--------------------------------------------------------------------------------
/examples/basic-rml/src/app.ts:
--------------------------------------------------------------------------------
1 | import { createApp, IAppConfig } from 'ice';
2 |
3 | const appConfig: IAppConfig = {
4 | };
5 |
6 | createApp(appConfig);
7 |
--------------------------------------------------------------------------------
/examples/icestark-layout/src/pages/Home/index.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 |
3 | export default function Home() {
4 | return
home page
;
5 | }
--------------------------------------------------------------------------------
/packages/icejs/__tests__/cli.test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const cli = require('..');
4 |
5 | describe('@ice/cli', () => {
6 | it('needs tests');
7 | });
8 |
--------------------------------------------------------------------------------
/packages/plugin-rematch/src/template/store.ts.ejs:
--------------------------------------------------------------------------------
1 | <%- importCodes %>
2 |
3 | const stores = { <%- storesString %> };
4 |
5 | export {
6 | stores,
7 | }
8 |
--------------------------------------------------------------------------------
/examples/with-fusion-design/src/global.scss:
--------------------------------------------------------------------------------
1 | // 引入默认全局样式
2 | @import '@alifd/next/reset.scss';
3 |
4 | body {
5 | -webkit-font-smoothing: antialiased;
6 | }
7 |
8 |
--------------------------------------------------------------------------------
/packages/plugin-core/src/generator/templates/app/components/index.ts.ejs:
--------------------------------------------------------------------------------
1 | import ErrorBoundary from './ErrorBoundary';
2 |
3 | export {
4 | ErrorBoundary
5 | };
6 |
--------------------------------------------------------------------------------
/packages/create-ice/__tests__/index.test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const plugin = require('..');
4 |
5 | describe('create-ice', () => {
6 | it('needs tests');
7 | });
8 |
--------------------------------------------------------------------------------
/packages/plugin-logger/src/_logger.ts:
--------------------------------------------------------------------------------
1 | const logger = {
2 | setLevel: (loglevel: string) => {
3 | console.log(loglevel);
4 | },
5 | };
6 | export default logger;
7 |
--------------------------------------------------------------------------------
/packages/plugin-react-app/src/userConfig/library.js:
--------------------------------------------------------------------------------
1 | module.exports = (config, library) => {
2 | if (library) {
3 | config.output.library(library);
4 | }
5 | };
6 |
--------------------------------------------------------------------------------
/packages/icejs/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.settings.json",
3 | "compilerOptions": {
4 | "rootDir": "src",
5 | "outDir": "lib"
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/packages/plugin-core/src/types/base.ts:
--------------------------------------------------------------------------------
1 | export interface IExportData {
2 | specifier?: string;
3 | source: string;
4 | exportName: string;
5 | extraExport?: boolean;
6 | }
--------------------------------------------------------------------------------
/packages/plugin-icestark/src/runtime/_history.ts:
--------------------------------------------------------------------------------
1 | export {
2 | createBrowserHistory,
3 | createHashHistory,
4 | createMemoryHistory,
5 | History
6 | } from 'history';
7 |
--------------------------------------------------------------------------------
/packages/plugin-react-app/src/userConfig/filename.js:
--------------------------------------------------------------------------------
1 | module.exports = (config, filename) => {
2 | if (filename) {
3 | config.output.filename(filename);
4 | }
5 | };
6 |
--------------------------------------------------------------------------------
/packages/plugin-rematch/__tests__/index.test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const plugin = require('..');
4 |
5 | describe('plugin-rematch', () => {
6 | it('needs tests');
7 | });
8 |
--------------------------------------------------------------------------------
/packages/plugin-ssr/__tests__/plugin-ssr.test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const pluginSsr = require('..');
4 |
5 | describe('plugin-ssr', () => {
6 | it('needs tests');
7 | });
8 |
--------------------------------------------------------------------------------
/examples/icestark-child/build.json:
--------------------------------------------------------------------------------
1 | {
2 | "sourcemap": true,
3 | "router": {
4 | "lazy": true
5 | },
6 | "plugins": [
7 | "build-plugin-icestark"
8 | ]
9 | }
10 |
--------------------------------------------------------------------------------
/packages/plugin-helpers/__tests__/index.test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const pluginHelpers = require('..');
4 |
5 | describe('plugin-helpers', () => {
6 | it('needs tests');
7 | });
8 |
--------------------------------------------------------------------------------
/packages/plugin-router/templates/index.ts:
--------------------------------------------------------------------------------
1 | export * from './react-router-dom';
2 | export * from './history';
3 | export * from './useSearchParams';
4 | export * from './withSearchParams';
5 |
--------------------------------------------------------------------------------
/packages/plugin-store/__tests__/plugin-store.test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const pluginStore = require('..');
4 |
5 | describe('plugin-store', () => {
6 | it('needs tests');
7 | });
8 |
--------------------------------------------------------------------------------
/packages/plugin-config/__tests__/plugin-config.test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const pluginConfig = require('..');
4 |
5 | describe('plugin-config', () => {
6 | it('needs tests');
7 | });
8 |
--------------------------------------------------------------------------------
/packages/plugin-react-app/src/userConfig/libraryExport.js:
--------------------------------------------------------------------------------
1 | module.exports = (config, libraryExport) => {
2 | if (libraryExport) {
3 | config.output.libraryExport(libraryExport);
4 | }
5 | };
--------------------------------------------------------------------------------
/packages/plugin-react-app/src/userConfig/libraryTarget.js:
--------------------------------------------------------------------------------
1 | module.exports = (config, libraryTarget) => {
2 | if (libraryTarget) {
3 | config.output.libraryTarget(libraryTarget);
4 | }
5 | };
--------------------------------------------------------------------------------
/examples/basic-rml/src/routes.ts:
--------------------------------------------------------------------------------
1 | import Home from '@/pages/Home/index.rml';
2 |
3 | export default [
4 | {
5 | path: '/',
6 | exact: true,
7 | component: Home
8 | },
9 | ];
10 |
--------------------------------------------------------------------------------
/examples/with-fusion-design/src/routes.ts:
--------------------------------------------------------------------------------
1 | import Home from '@/pages/Home';
2 |
3 | export default [
4 | {
5 | path: '/',
6 | exact: true,
7 | component: Home
8 | }
9 | ];
10 |
--------------------------------------------------------------------------------
/examples/with-rematch/src/app.ts:
--------------------------------------------------------------------------------
1 | import { createApp } from 'ice';
2 |
3 | const appConfig = {
4 | app: {
5 | rootId: 'ice-container'
6 | }
7 | };
8 |
9 | createApp(appConfig);
10 |
--------------------------------------------------------------------------------
/packages/plugin-icestark/src/runtime/Layout.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 |
3 | const Layout = ({ children }) => (
4 | <>
5 | {children}
6 | >
7 | );
8 |
9 | export default Layout;
--------------------------------------------------------------------------------
/packages/plugin-request/__tests__/plugin-request.test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const pluginRequest = require('..');
4 |
5 | describe('plugin-request', () => {
6 | it('needs tests');
7 | });
8 |
--------------------------------------------------------------------------------
/packages/plugin-router/__tests__/plugin-router.test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const pluginRouter = require('..');
4 |
5 | describe('@ice/plugin-router', () => {
6 | it('needs tests');
7 | });
8 |
--------------------------------------------------------------------------------
/packages/plugin-service/__tests__/plugin-service.test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const pluginService = require('..');
4 |
5 | describe('plugin-service', () => {
6 | it('needs tests');
7 | });
8 |
--------------------------------------------------------------------------------
/packages/create-ice/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.settings.json",
3 | "compilerOptions": {
4 | "baseUrl": "./",
5 | "rootDir": "src",
6 | "outDir": "lib"
7 | },
8 | }
9 |
--------------------------------------------------------------------------------
/packages/plugin-mpa/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.settings.json",
3 | "compilerOptions": {
4 | "baseUrl": "./",
5 | "rootDir": "src",
6 | "outDir": "lib"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/packages/plugin-react-app/src/utils/polyfillLoader.js:
--------------------------------------------------------------------------------
1 | module.exports = (content) => {
2 | return `
3 | import "core-js/stable";
4 | import "regenerator-runtime/runtime";
5 | ${content}
6 | `;
7 | };
8 |
--------------------------------------------------------------------------------
/packages/plugin-ssr/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.settings.json",
3 | "compilerOptions": {
4 | "baseUrl": "./",
5 | "rootDir": "src",
6 | "outDir": "lib"
7 | },
8 | }
9 |
--------------------------------------------------------------------------------
/examples/hello-world/src/pages/Home/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Guide from '@/components/Guide';
3 |
4 | const Home = () => {
5 | return ;
6 | };
7 |
8 | export default Home;
9 |
--------------------------------------------------------------------------------
/examples/hello-world/src/routes.ts:
--------------------------------------------------------------------------------
1 | import Home from '@/pages/Home';
2 |
3 | const routerConfig = [
4 | {
5 | path: '/',
6 | component: Home
7 | }
8 | ];
9 |
10 | export default routerConfig;
--------------------------------------------------------------------------------
/examples/icestark-layout/src/pages/Dashboard/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export default function Dashboard() {
4 | return (
5 |
6 | Dashboard page
7 |
8 | );
9 | }
--------------------------------------------------------------------------------
/packages/plugin-request/src/_axiosInstance.ts:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 |
3 | const DEFAULE_CONFIG = {};
4 |
5 | const axiosInstance = axios.create(DEFAULE_CONFIG);
6 |
7 | export default axiosInstance;
8 |
--------------------------------------------------------------------------------
/examples/basic-request/src/routes.ts:
--------------------------------------------------------------------------------
1 | import Home from '@/pages/Home';
2 |
3 | const routerConfig = [
4 | {
5 | path: '/',
6 | component: Home
7 | }
8 | ];
9 |
10 | export default routerConfig;
--------------------------------------------------------------------------------
/examples/basic-service/src/routes.ts:
--------------------------------------------------------------------------------
1 | import Home from '@/pages/Home';
2 |
3 | const routerConfig = [
4 | {
5 | path: '/',
6 | component: Home
7 | }
8 | ];
9 |
10 | export default routerConfig;
--------------------------------------------------------------------------------
/scripts/fn/shell.ts:
--------------------------------------------------------------------------------
1 | import * as execa from 'execa';
2 |
3 | export async function run(command: string) {
4 | console.log(`[RUN]: ${command}`);
5 | return execa.command(command, { stdio: 'inherit' });
6 | }
7 |
--------------------------------------------------------------------------------
/examples/basic-service/src/app.ts:
--------------------------------------------------------------------------------
1 | import { createApp, IAppConfig } from 'ice';
2 |
3 | const appConfig: IAppConfig = {
4 | app: {
5 | rootId: 'ice-container',
6 | }
7 | };
8 |
9 | createApp(appConfig);
10 |
--------------------------------------------------------------------------------
/examples/basic-store/src/app.ts:
--------------------------------------------------------------------------------
1 | import { createApp, IAppConfig } from 'ice';
2 |
3 | const appConfig: IAppConfig = {
4 | app: {
5 | rootId: 'ice-container',
6 | },
7 | };
8 |
9 | createApp(appConfig);
10 |
--------------------------------------------------------------------------------
/examples/hello-world/src/app.ts:
--------------------------------------------------------------------------------
1 | import { createApp, IAppConfig } from 'ice';
2 |
3 | const appConfig: IAppConfig = {
4 | app: {
5 | rootId: 'ice-container',
6 | },
7 | };
8 |
9 | createApp(appConfig);
10 |
--------------------------------------------------------------------------------
/examples/with-fusion-design/src/app.ts:
--------------------------------------------------------------------------------
1 | import { createApp, IAppConfig } from 'ice';
2 |
3 | const appConfig: IAppConfig = {
4 | app: {
5 | rootId: 'ice-container'
6 | }
7 | };
8 |
9 | createApp(appConfig);
10 |
--------------------------------------------------------------------------------
/examples/basic-ssr/src/config.ts:
--------------------------------------------------------------------------------
1 | const config = {
2 | dev: {
3 | baseURL: 'http://localhost:3333/api'
4 | },
5 | prod: {
6 | baseURL: 'http://example.com/api'
7 | }
8 | };
9 |
10 | export default config;
11 |
--------------------------------------------------------------------------------
/packages/plugin-request/src/types/index.ts:
--------------------------------------------------------------------------------
1 | import { AxiosRequestConfig } from 'axios';
2 | import { IInterceptors } from './base';
3 |
4 | export interface IRequest extends AxiosRequestConfig {
5 | interceptors?: IInterceptors;
6 | }
--------------------------------------------------------------------------------
/packages/plugin-router/templates/history.ts:
--------------------------------------------------------------------------------
1 | // https://github.com/ReactTraining/history/blob/master/modules/index.js
2 | export {
3 | createBrowserHistory,
4 | createHashHistory,
5 | createMemoryHistory
6 | } from 'history';
7 |
--------------------------------------------------------------------------------
/packages/plugin-icestark/src/runtime/_Router.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 |
3 | // eslint-disable-next-line
4 | const IceRouter = ({ type, routes, basename, history }) => {
5 | return (
);
6 | };
7 |
8 | export { IceRouter };
9 |
--------------------------------------------------------------------------------
/packages/plugin-react-app/src/utils/formatWinPath.js:
--------------------------------------------------------------------------------
1 | module.exports = (outputPath) => {
2 | const isWin = process.platform === 'win32';
3 | // js\index.js => js/index.js
4 | return isWin ? outputPath.replace(/\\/g, '/') : outputPath;
5 | };
6 |
--------------------------------------------------------------------------------
/packages/plugin-react-app/src/userConfig/modules.js:
--------------------------------------------------------------------------------
1 | module.exports = (config, modules) => {
2 | if (Array.isArray(modules)) {
3 | modules.forEach((module) => {
4 | config.resolve.modules
5 | .add(module);
6 | });
7 | }
8 | };
9 |
--------------------------------------------------------------------------------
/examples/basic-mpa/src/pages/Dashboard/app.ts:
--------------------------------------------------------------------------------
1 | import { createApp, IAppConfig } from 'ice';
2 | import routes from './routes';
3 |
4 | const appConfig: IAppConfig = {
5 | router: {
6 | routes
7 | },
8 | };
9 |
10 | createApp(appConfig);
11 |
--------------------------------------------------------------------------------
/examples/basic-rml/src/pages/Home/index.rml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/packages/plugin-core/src/utils/formatPath.ts:
--------------------------------------------------------------------------------
1 | import * as path from 'path';
2 |
3 | function formatPath(pathStr: string): string {
4 | return process.platform === 'win32' ? pathStr.split(path.sep).join('/') : pathStr;
5 | }
6 |
7 | export default formatPath;
8 |
--------------------------------------------------------------------------------
/packages/plugin-helpers/helpers/index.ts:
--------------------------------------------------------------------------------
1 | import { urlParse } from './urlParse';
2 | import { cookie } from './cookie';
3 |
4 | const helpers = {
5 | cookie, urlParse
6 | };
7 |
8 | // TODO: 只留一个
9 | export {
10 | helpers
11 | };
12 | export default helpers;
13 |
--------------------------------------------------------------------------------
/packages/plugin-react-app/src/userConfig/extensions.js:
--------------------------------------------------------------------------------
1 | module.exports = (config, extensions) => {
2 | if (Array.isArray(extensions)) {
3 | extensions.forEach((extension) => {
4 | config.resolve.extensions
5 | .add(extension);
6 | });
7 | }
8 | };
9 |
--------------------------------------------------------------------------------
/examples/basic-spa/build.json:
--------------------------------------------------------------------------------
1 | {
2 | "ignoreHtmlTemplate": true,
3 | "plugins": [],
4 | "modeConfig": {
5 | "prod": {
6 | "ignoreHtmlTemplate": false
7 | }
8 | },
9 | "eslint": {
10 | "disable": false,
11 | "quiet": true
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/packages/plugin-logger/src/module.ts:
--------------------------------------------------------------------------------
1 | import logger from '$ice/logger';
2 |
3 | const module = ({ appConfig }) => {
4 | if (appConfig.logger && appConfig.logger.level) {
5 | logger.setLevel(appConfig.logger.level);
6 | }
7 | };
8 |
9 | export default module;
10 |
--------------------------------------------------------------------------------
/packages/plugin-request/request/axiosInstance.ts:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 |
3 | // https://github.com/axios/axios#request-config
4 | const DEFAULE_CONFIG = {
5 | };
6 |
7 | const axiosInstance = axios.create(DEFAULE_CONFIG);
8 |
9 | export default axiosInstance;
10 |
--------------------------------------------------------------------------------
/packages/plugin-service/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.settings.json",
3 | "compilerOptions": {
4 | "baseUrl": "./",
5 | "rootDir": "src",
6 | "outDir": "lib",
7 | "paths": {
8 | "ice": ["./src/_ice"]
9 | }
10 | },
11 | }
12 |
--------------------------------------------------------------------------------
/examples/basic-mpa/src/pages/Home/app.ts:
--------------------------------------------------------------------------------
1 | import { createApp, IAppConfig } from 'ice';
2 | import Home from './index';
3 |
4 | const appConfig: IAppConfig = {
5 | router: {
6 | routes: [{ path: '/', component: Home }],
7 | },
8 | };
9 |
10 | createApp(appConfig);
11 |
--------------------------------------------------------------------------------
/examples/icestark-layout/build.json:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": [
3 | "build-plugin-icestark",
4 | ["build-plugin-fusion", {
5 | "themePackage": "@icedesign/theme",
6 | "themeConfig": {
7 | "nextPrefix": "next-fd-"
8 | }
9 | }]
10 | ]
11 | }
12 |
--------------------------------------------------------------------------------
/packages/plugin-react-app/src/userConfig/minify.js:
--------------------------------------------------------------------------------
1 | module.exports = (config, value, context) => {
2 | const { command } = context;
3 | // minify always be false in dev mode
4 | const minify = command === 'start' ? false : value;
5 | config.optimization.minimize(minify);
6 | };
7 |
--------------------------------------------------------------------------------
/packages/plugin-rematch/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.settings.json",
3 | "compilerOptions": {
4 | "baseUrl": "./",
5 | "rootDir": "src",
6 | "outDir": "lib",
7 | "paths": {
8 | "$ice/store": ["./src/_store"]
9 | }
10 | },
11 | }
12 |
--------------------------------------------------------------------------------
/packages/plugin-store/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.settings.json",
3 | "compilerOptions": {
4 | "baseUrl": "./",
5 | "rootDir": "src",
6 | "outDir": "lib",
7 | "paths": {
8 | "$ice/store": ["./src/_store"]
9 | }
10 | },
11 | }
12 |
--------------------------------------------------------------------------------
/examples/basic-mpa/src/pages/Home/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const Home = () => {
4 | return (
5 | <>
6 | Home Page
7 | >
8 | );
9 | };
10 |
11 | Home.pageConfig = {
12 | title: 'Home Page',
13 | };
14 |
15 | export default Home;
16 |
--------------------------------------------------------------------------------
/packages/plugin-core/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.settings.json",
3 | "compilerOptions": {
4 | "baseUrl": "./",
5 | "rootDir": "src",
6 | "outDir": "lib",
7 | "paths": {
8 | "$ice/components": ["./src/_components"]
9 | }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/packages/plugin-router/templates/useSearchParams.ts:
--------------------------------------------------------------------------------
1 | import { useLocation } from 'react-router-dom';
2 | import * as queryString from 'query-string';
3 |
4 | export const useSearchParams = () => {
5 | const location = useLocation();
6 | return queryString.parse(location.search);
7 | };
8 |
--------------------------------------------------------------------------------
/examples/basic-spa/src/layouts/index.module.scss:
--------------------------------------------------------------------------------
1 | .title {
2 | height: 70px;
3 | display: flex;
4 | align-items: center;
5 | justify-content: center;
6 | }
7 |
8 | .main {
9 | display: flex;
10 | justify-content: center;
11 | flex-direction: column;
12 | align-items: center;
13 | }
--------------------------------------------------------------------------------
/examples/basic-ssr/src/layouts/index.module.scss:
--------------------------------------------------------------------------------
1 | .title {
2 | height: 70px;
3 | display: flex;
4 | align-items: center;
5 | justify-content: center;
6 | }
7 |
8 | .main {
9 | display: flex;
10 | justify-content: center;
11 | flex-direction: column;
12 | align-items: center;
13 | }
--------------------------------------------------------------------------------
/examples/basic-store/src/layouts/index.module.scss:
--------------------------------------------------------------------------------
1 | .title {
2 | height: 70px;
3 | display: flex;
4 | align-items: center;
5 | justify-content: center;
6 | }
7 |
8 | .main {
9 | display: flex;
10 | justify-content: center;
11 | flex-direction: column;
12 | align-items: center;
13 | }
--------------------------------------------------------------------------------
/tsconfig.settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "jsx": "react",
5 | "experimentalDecorators": true,
6 | "declaration": true,
7 | "sourceMap": false,
8 | "skipLibCheck": true,
9 | "forceConsistentCasingInFileNames": true
10 | },
11 | }
12 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | # 忽略目录
2 | build/
3 | test/
4 | tests/
5 | node_modules/
6 | dist/
7 | out/
8 |
9 | # node 覆盖率文件
10 | coverage/
11 |
12 | # 忽略测试文件
13 | /packages/*/__tests__
14 | /packages/*/lib/
15 |
16 | # 忽略第三方包
17 | /vendor/loader.js
18 |
19 | # 忽略文件
20 | **/*-min.js
21 | **/*.min.js
22 |
23 | workspace/
24 |
--------------------------------------------------------------------------------
/examples/icestark-child/src/app.ts:
--------------------------------------------------------------------------------
1 | import { createApp, IAppConfig } from 'ice';
2 |
3 | const appConfig: IAppConfig = {
4 | app: {
5 | rootId: 'ice-container'
6 | },
7 | logger: {
8 | level: 'warn'
9 | },
10 | icestark: {
11 | type: 'child'
12 | },
13 | };
14 |
15 | createApp(appConfig);
16 |
--------------------------------------------------------------------------------
/packages/plugin-core/src/_components.tsx:
--------------------------------------------------------------------------------
1 | // 该文件仅用于 module.tsx 中引用 $ice/components 的编译问题
2 | interface IProps {
3 | children?: any;
4 | Fallback?: any;
5 | onError?: Function;
6 | };
7 |
8 | // eslint-disable-next-line
9 | export const ErrorBoundary = ({Fallback, onError, children}: IProps) => Fallback;
10 |
--------------------------------------------------------------------------------
/packages/plugin-react-app/src/cliOption/analyzer.js:
--------------------------------------------------------------------------------
1 | const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
2 |
3 | module.exports = (config, analyzer) => {
4 | if (analyzer) {
5 | config.plugin('webpack-bundle-analyzer')
6 | .use(BundleAnalyzerPlugin, [{ analyzerPort: '9000' }]);
7 | }
8 | };
9 |
--------------------------------------------------------------------------------
/examples/basic-service/src/pages/Home/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Fetch from '@/components/Fetch';
3 | import User from './components/User';
4 |
5 | const Home = () => {
6 | return (
7 | <>
8 |
9 |
10 | >
11 | );
12 | };
13 |
14 | export default Home;
15 |
--------------------------------------------------------------------------------
/examples/icestark-child/src/pages/Dashboard/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Link } from 'ice';
3 |
4 | const Dashboard = () => {
5 | return (
6 | <>
7 | Dashboard Page...
8 | About
9 | >
10 | );
11 | };
12 |
13 | export default Dashboard;
14 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | indent_style = space
6 | indent_size = 2
7 | charset = utf-8
8 | trim_trailing_whitespace = true
9 | insert_final_newline = true
10 |
11 | [*.md]
12 | trim_trailing_whitespace = false
13 |
14 | [makefile]
15 | indent_style = tab
16 | indent_size = 4
17 |
--------------------------------------------------------------------------------
/packages/plugin-config/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.settings.json",
3 | "compilerOptions": {
4 | "baseUrl": "./",
5 | "rootDir": "src",
6 | "outDir": "lib",
7 | "paths": {
8 | "@/config": ["./src/_config"]
9 | }
10 | },
11 | "exclude": [
12 | "config/*"
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/packages/plugin-logger/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.settings.json",
3 | "compilerOptions": {
4 | "baseUrl": "./",
5 | "rootDir": "src",
6 | "outDir": "lib",
7 | "paths": {
8 | "$ice/logger": ["./src/_logger"]
9 | }
10 | },
11 | "exclude": [
12 | "logger/*"
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/packages/plugin-react-app/src/cliOption/analyzerPort.js:
--------------------------------------------------------------------------------
1 | module.exports = (config, port) => {
2 | if (port && config.plugins.get('webpack-bundle-analyzer')) {
3 | config.plugin('webpack-bundle-analyzer').tap(([args]) => {
4 | const newArgs = {...args, analyzerPort: port };
5 | return [newArgs];
6 | });
7 | }
8 | };
9 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Dependencies
2 | node_modules
3 | jspm_packages
4 |
5 | # Only keep yarn.lock in the root
6 | package-lock.json
7 | */**/yarn.lock
8 |
9 | # Logs
10 | *.log
11 |
12 | # Packages
13 | packages/*/lib/
14 |
15 | # temp folder .ice
16 | examples/*/.ice
17 |
18 | .eslintcache
19 | docs/.vuepress/dist/
20 |
21 | build
22 |
--------------------------------------------------------------------------------
/packages/create-ice/README.md:
--------------------------------------------------------------------------------
1 | # create-ice
2 |
3 | create icejs project.
4 |
5 | ## Usage
6 |
7 | ```bash
8 | $ npm init ice
9 | # or with template
10 | $ npm init ice
11 | # or use yarn
12 | $ yarn create ice
13 |
14 | $ cd
15 | $ npm install
16 | $ npm start
17 | ```
--------------------------------------------------------------------------------
/packages/plugin-helpers/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.settings.json",
3 | "compilerOptions": {
4 | "baseUrl": "./",
5 | "rootDir": "src",
6 | "outDir": "lib",
7 | "paths": {
8 | "$ice/helpers": ["./src/_helpers"]
9 | }
10 | },
11 | "exclude": [
12 | "helpers/*"
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/packages/plugin-router/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.settings.json",
3 | "compilerOptions": {
4 | "baseUrl": "./",
5 | "rootDir": "src",
6 | "outDir": "lib",
7 | "paths": {
8 | "$ice/routes": ["./src/runtime/_routes"]
9 | },
10 | },
11 | "exclude": [
12 | "templates"
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/packages/plugin-request/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.settings.json",
3 | "compilerOptions": {
4 | "baseUrl": "./",
5 | "rootDir": "src",
6 | "outDir": "lib",
7 | "paths": {
8 | "$ice/axiosInstance": ["./src/_axiosInstance"]
9 | }
10 | },
11 | "exclude": [
12 | "request/*"
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/scripts/sync.ts:
--------------------------------------------------------------------------------
1 | import * as spawn from 'cross-spawn';
2 | import getPackages from './fn/getPackages';
3 |
4 | (async function () {
5 | const { packageNames } = await getPackages();
6 | const npmClient = 'tnpm';
7 | console.log('syncing packages...');
8 | spawn.sync(npmClient, ['sync', ...packageNames], { stdio: 'inherit' });
9 | })();
10 |
--------------------------------------------------------------------------------
/examples/basic-store/src/pages/NotFound/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Link } from 'ice';
3 |
4 | const NotFound = () => {
5 | return (
6 | <>
7 | 404 Page...
8 | home
9 | About
10 | >
11 | );
12 | };
13 |
14 | export { NotFound };
15 |
--------------------------------------------------------------------------------
/packages/plugin-store/src/_store.ts:
--------------------------------------------------------------------------------
1 | import { createStore, IcestoreDispatch, IcestoreRootState } from '@ice/store';
2 |
3 | const models = {};
4 |
5 | const store = createStore(models);
6 |
7 | export default store;
8 | export type IRootDispatch = IcestoreDispatch;
9 | export type IRootState = IcestoreRootState;
10 |
11 |
--------------------------------------------------------------------------------
/examples/hello-world/src/components/Guide/index.module.scss:
--------------------------------------------------------------------------------
1 | .container {
2 | min-height: 600px;
3 | overflow: hidden;
4 | text-align: center;
5 | background-color: #fff;
6 | }
7 |
8 | .title {
9 | font-size: 40px;
10 | text-align: center;
11 | }
12 |
13 | .description {
14 | margin-top: 40px;
15 | }
16 |
17 | .action {
18 | margin-top: 40px;
19 | }
--------------------------------------------------------------------------------
/examples/with-fusion-design/build.json:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": [
3 | [
4 | "build-plugin-fusion",
5 | {
6 | "themePackage": "@alifd/theme-design-pro"
7 | }
8 | ],
9 | [
10 | "build-plugin-moment-locales",
11 | {
12 | "locales": [
13 | "zh-cn"
14 | ]
15 | }
16 | ]
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------
/examples/icestark-child/src/pages/About/_layout.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export default function BasicLayout({
4 | children,
5 | }: {
6 | children: React.ReactNode;
7 | }) {
8 | return (
9 |
10 |
11 | Header
12 | {children}
13 |
14 |
15 | );
16 | }
17 |
--------------------------------------------------------------------------------
/packages/plugin-core/src/generator/templates/app/lazy.ts.ejs:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 |
3 | function lazy(dynamicImport, isRouteComponent?: Boolean): any {
4 | if (isRouteComponent) {
5 | return {
6 | __LAZY__: true,
7 | dynamicImport,
8 | };
9 | } else {
10 | return React.lazy(dynamicImport);
11 | }
12 | }
13 |
14 |
15 | export { lazy };
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # icejs has been [moved into the alibaba/ice](https://github.com/alibaba/ice).
2 |
3 | The move makes it much easier to release and develop in sync with the rest of ice!
4 |
5 | This repo will be made read-only, as all of the issues/labels have been moved over as well. Please report any bugs and open pull requests over on the [alibaba/ice](https://github.com/alibaba/ice/issues).
6 |
--------------------------------------------------------------------------------
/examples/basic-rml/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | RML Example
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/examples/basic-ssr/src/layouts/index.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import styles from './index.module.scss';
3 |
4 | const Layout = ({ children }) => {
5 | return (
6 |
7 |
SSR
8 |
9 | {children}
10 |
11 |
12 | );
13 | };
14 |
15 | export default Layout;
--------------------------------------------------------------------------------
/packages/plugin-react-app/src/userConfig/publicPath.js:
--------------------------------------------------------------------------------
1 | const updateMiniCssLoaderPath = require('../utils/updateMiniCssLoaderPath');
2 |
3 | module.exports = (config, value, context) => {
4 | const { command, userConfig } = context;
5 | if (command === 'build') {
6 | config.output.publicPath(value);
7 | updateMiniCssLoaderPath(config, value, userConfig);
8 | }
9 | };
10 |
--------------------------------------------------------------------------------
/examples/basic-mpa/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | icejs · mpa example
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/examples/basic-spa/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | icejs · spa example
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/examples/basic-spa/src/pages/About/components/Child.tsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect } from 'react';
2 |
3 | const Child = () => {
4 | function getData() {
5 | throw new Error('test Error');
6 | }
7 |
8 | useEffect(() => {
9 | getData();
10 | }, []);
11 |
12 | return (
13 |
14 | Child
15 |
16 | );
17 | };
18 |
19 | export default Child;
20 |
--------------------------------------------------------------------------------
/examples/basic-ssr/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | icejs · ssr example
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/packages/plugin-helpers/README.md:
--------------------------------------------------------------------------------
1 | # plugin-ice-helpers
2 |
3 | Use builtin helpers in icejs.
4 |
5 | ## Usage
6 |
7 | ```js
8 | import { helpers } from 'ice';
9 |
10 | const { cookie, urlParse } = helpers;
11 | ```
12 |
13 | ## Helpers
14 |
15 | ### cookie
16 |
17 | https://www.npmjs.com/package/cookie
18 |
19 | ### urlParse
20 |
21 | https://www.npmjs.com/package/url-parse
22 |
--------------------------------------------------------------------------------
/packages/plugin-react-app/src/userConfig/devPublicPath.js:
--------------------------------------------------------------------------------
1 | const updateMiniCssLoaderPath = require('../utils/updateMiniCssLoaderPath');
2 |
3 | module.exports = (config, value, context) => {
4 | const { command, userConfig } = context;
5 | if (command === 'start') {
6 | config.output.publicPath(value);
7 | updateMiniCssLoaderPath(config, value, userConfig);
8 | }
9 | };
10 |
--------------------------------------------------------------------------------
/examples/basic-spa/src/layouts/index.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import styles from './index.module.scss';
3 |
4 | const Layout = ({ children }) => {
5 | return (
6 |
7 |
SPA
8 |
9 | {children}
10 |
11 |
12 | );
13 | };
14 |
15 | export default Layout;
16 |
--------------------------------------------------------------------------------
/examples/basic-store/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | icejs · store example
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/examples/basic-request/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | icejs · request example
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/examples/basic-service/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | icejs · service example
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/examples/basic-store/src/layouts/index.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import styles from './index.module.scss';
3 |
4 | const Layout = ({ children }) => {
5 | return (
6 |
7 |
Header
8 |
9 | {children}
10 |
11 |
12 | );
13 | };
14 |
15 | export default Layout;
16 |
--------------------------------------------------------------------------------
/examples/hello-world/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | icejs · hello world example
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/packages/plugin-icestark/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.settings.json",
3 | "compilerOptions": {
4 | "baseUrl": "./",
5 | "rootDir": "src",
6 | "outDir": "lib",
7 | "paths": {
8 | "$ice/Router": ["./src/runtime/_Router"],
9 | "$ice/history": ["./src/runtime/_history"],
10 | "$ice/Layout": ["./src/runtime/Layout"]
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/packages/plugin-react-app/src/userConfig/sourcemap.js:
--------------------------------------------------------------------------------
1 | module.exports = (config, sourcemap, context) => {
2 | const { command } = context;
3 | if (command === 'build' && sourcemap) {
4 | config.devtool('source-map');
5 | config.optimization
6 | .minimizer('TerserPlugin')
7 | .tap(([options]) => [
8 | { ...options, sourceMap: true },
9 | ]);
10 | }
11 | };
12 |
--------------------------------------------------------------------------------
/examples/icestark-child/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | icejs · icestark child example
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/examples/with-rematch/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | icejs · with rematch example
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | **Do you want to request a *feature* or report a *bug*?**
2 |
3 | **What is the current behavior?**
4 |
5 | If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem.
6 |
7 | * icejs version:
8 | * Node verson:
9 | * Platform:
10 | * `build.json`:
11 | * `src/app.(ts|js)`:
12 |
13 | **What is the expected behavior?**
14 |
--------------------------------------------------------------------------------
/examples/icestark-layout/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | icejs · icestark layout example
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/packages/plugin-core/src/generator/templates/app/index.ts.ejs:
--------------------------------------------------------------------------------
1 | <%- iceImports %>
2 |
3 | export { createApp, history } from './createApp';
4 | export * from './types';
5 | export * from './lazy';
6 | export * from './components';
7 |
8 | export const APP_MODE = (global as any).__app_mode__ || process.env.APP_MODE;
9 |
10 | <% if (iceExports) { %>
11 | export {
12 | <%- iceExports %>
13 | }
14 | <% } %>
15 |
--------------------------------------------------------------------------------
/examples/with-fusion-design/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | icejs · with fusion design example
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/packages/plugin-icestark/src/runtime/removeLayout.ts:
--------------------------------------------------------------------------------
1 | function removeLayout(routes) {
2 | let modifiedRoutes = [];
3 | routes.forEach((route) => {
4 | if (route.path === '/' && route.children) {
5 | modifiedRoutes = [...modifiedRoutes, ...route.children];
6 | } else {
7 | modifiedRoutes.push(route);
8 | }
9 | });
10 | return modifiedRoutes;
11 | }
12 |
13 | export default removeLayout;
--------------------------------------------------------------------------------
/examples/with-rematch/src/routes.ts:
--------------------------------------------------------------------------------
1 | import Page404 from '@/pages/404';
2 | import PageRematch from '@/pages/Rematch/index';
3 | import Page from '@/pages/index';
4 |
5 | export default [
6 | {
7 | path: '/rematch',
8 | exact: true,
9 | component: PageRematch
10 | },
11 | {
12 | path: '/',
13 | exact: true,
14 | component: Page
15 | },
16 | {
17 | component: Page404
18 | },
19 | ];
20 |
--------------------------------------------------------------------------------
/packages/plugin-config/config/index.ts:
--------------------------------------------------------------------------------
1 | import config from '@/config';
2 |
3 | interface Config {
4 | readonly [propName: string]: any;
5 | }
6 |
7 | const userConfig: Config = {
8 | ...(config.default || {}),
9 | // webpack will automatically convert global to window when target is web
10 | ...(config[(global as any).__app_mode__ || process.env.APP_MODE] || {}),
11 | };
12 |
13 | export default userConfig;
14 |
--------------------------------------------------------------------------------
/packages/plugin-react-app/src/userConfig/terserOptions.js:
--------------------------------------------------------------------------------
1 | module.exports = (config, terserOptions, context) => {
2 | const { command } = context;
3 | if (command === 'build' && terserOptions && config.optimization.minimizers.get('TerserPlugin')) {
4 | config.optimization.minimizer('TerserPlugin').tap(([options]) => [
5 | {
6 | ...options,
7 | ...terserOptions,
8 | },
9 | ]);
10 | }
11 | };
--------------------------------------------------------------------------------
/packages/plugin-react-app/src/utils/getFilePath.js:
--------------------------------------------------------------------------------
1 | const pathExists = require('path-exists');
2 |
3 | /**
4 | * Check path if it is exist
5 | * @param filePaths path array of file
6 | */
7 |
8 | module.exports = (filePaths) => {
9 | let i = 0;
10 | while (i < filePaths.length) {
11 | if (pathExists.sync(filePaths[i])) {
12 | return filePaths[i];
13 | }
14 | i += 1;
15 | }
16 | return '';
17 | };
18 |
--------------------------------------------------------------------------------
/packages/plugin-react-app/src/userConfig/vendor.js:
--------------------------------------------------------------------------------
1 | module.exports = (config, vendor) => {
2 | if (!vendor) {
3 | config.optimization.splitChunks({ cacheGroups: {} });
4 | } else {
5 | config.optimization.splitChunks({ cacheGroups: {
6 | vendor: {
7 | test: /[\\/]node_modules[\\/]/,
8 | name: 'vendor',
9 | chunks: 'initial',
10 | minChunks: 2,
11 | },
12 | } });
13 | }
14 | };
15 |
--------------------------------------------------------------------------------
/examples/basic-mpa/public/dashboard.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | icejs · mpa example
8 |
9 |
10 |
11 | dashboard content of html template
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/examples/basic-request/mock/index.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | 'GET /api/repo': {
3 | name: 'icejs',
4 | url: 'http://github.com/ice-lab/ice.js'
5 | },
6 |
7 | 'GET /api/user': {
8 | name: 'taoxiaobao',
9 | age: '21'
10 | },
11 |
12 | 'DELETE /api/user/123': {
13 | user: 123
14 | },
15 |
16 | 'POST /api/users/:id': (req, res) => {
17 | const { id } = req.params;
18 | res.send({ id });
19 | },
20 | };
21 |
--------------------------------------------------------------------------------
/examples/basic-spa/src/pages/NotFound/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Link } from 'ice';
3 |
4 | const Home = (props) => {
5 | console.log('render 404', props);
6 |
7 | return (
8 | <>
9 | 404 Page...
10 | home
11 | About
12 | Dashboard
13 | >
14 | );
15 | };
16 |
17 | export default Home;
18 |
--------------------------------------------------------------------------------
/examples/icestark-layout/src/pages/404.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Link } from 'ice';
3 |
4 | const Home = (props) => {
5 | console.log('render home', props);
6 |
7 | return (
8 | <>
9 | 404040404 Page...
10 | home
11 | About
12 | Dashboard
13 | >
14 | );
15 | };
16 |
17 | export default Home;
18 |
--------------------------------------------------------------------------------
/examples/with-fusion-design/src/pages/Home/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Button } from '@alifd/next';
3 |
4 | const Dashboard = () => {
5 | return (
6 | <>
7 | icejs with fusion design
8 | Primary
9 | secondary
10 | Normal
11 | >
12 | );
13 | };
14 |
15 | export default Dashboard;
16 |
--------------------------------------------------------------------------------
/examples/with-rematch/src/pages/404.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Link } from 'ice';
3 |
4 | const Home = (props) => {
5 | console.log('render home', props);
6 |
7 | return (
8 | <>
9 | 404040404 Page...
10 | home
11 | About
12 | Dashboard
13 | >
14 | );
15 | };
16 |
17 | export default Home;
18 |
--------------------------------------------------------------------------------
/examples/with-rematch/src/stores/user.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | state: {
3 | stars: 0
4 | },
5 | reducers: {
6 | updateStars(state, count) {
7 | return {...state, stars: state.stars + count};
8 | },
9 | },
10 | effects: (dispatch) => ({
11 | async updateStarsAsync(count) {
12 | await new Promise(resolve => setTimeout(resolve, 1000));
13 | dispatch.user.updateStars(count);
14 | },
15 | }),
16 | };
17 |
--------------------------------------------------------------------------------
/examples/basic-ssr/src/pages/NotFound/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Link, logger } from 'ice';
3 |
4 | const Home = (props) => {
5 | logger.info('render 404', props);
6 |
7 | return (
8 | <>
9 | 404 Page...
10 | home
11 | about
12 | dashboard
13 | >
14 | );
15 | };
16 |
17 | export default Home;
18 |
--------------------------------------------------------------------------------
/examples/basic-spa/src/pages/About/components/Todo.tsx:
--------------------------------------------------------------------------------
1 | /* eslint @typescript-eslint/explicit-member-accessibility:0 */
2 | import React, { PureComponent } from 'react';
3 |
4 | class Todo extends PureComponent {
5 | componentDidMount() {
6 | throw new Error('test error boundary');
7 | }
8 |
9 | render() {
10 | return (
11 |
12 | TODO Component
13 |
14 | );
15 | }
16 | }
17 |
18 | export default Todo;
19 |
--------------------------------------------------------------------------------
/examples/basic-store/src/pages/About/model.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | state: {
3 | title: ''
4 | },
5 |
6 | reducers: {
7 | update (prevState, payload) {
8 | return {
9 | ...prevState,
10 | ...payload,
11 | };
12 | },
13 | },
14 |
15 | effects: (dispatch) => ({
16 | async getPageTitle () {
17 | dispatch.default.update({
18 | title: 'About Page'
19 | });
20 | },
21 | }),
22 | };
23 |
--------------------------------------------------------------------------------
/examples/icestark-child/src/pages/About/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Link } from 'ice';
3 |
4 | const Child = () => {
5 | return (
6 |
7 | Child
8 |
9 | );
10 | };
11 |
12 | const About = () => {
13 | return (
14 | <>
15 | About Page
16 |
17 | About
18 | Home
19 | >
20 | );
21 | };
22 |
23 | export default About;
24 |
--------------------------------------------------------------------------------
/packages/plugin-router/src/types/collector.ts:
--------------------------------------------------------------------------------
1 | export interface ICollectItem {
2 | routePath: string;
3 | component: string;
4 | filePath: string;
5 | isLayoutLike: boolean;
6 | exact?: string;
7 | routePathAmend?: string;
8 | children?: ICollectItem[];
9 | }
10 |
11 | export interface IIgore {
12 | pattern: RegExp;
13 | attributes?: string;
14 | }
15 | export type IgnoreType = string | IIgore;
16 | export type IgnoreOptions = IgnoreType | IgnoreType[];
17 |
--------------------------------------------------------------------------------
/examples/basic-mpa/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "exmaple-basic-mpa",
3 | "description": "",
4 | "dependencies": {
5 | "ice.js": "^1.0.11",
6 | "react": "^16.4.1",
7 | "react-dom": "^16.4.1"
8 | },
9 | "devDependencies": {
10 | "@types/react": "^16.9.13",
11 | "@types/react-dom": "^16.9.4"
12 | },
13 | "scripts": {
14 | "start": "icejs start",
15 | "build": "icejs build"
16 | },
17 | "engines": {
18 | "node": ">=8.0.0"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/examples/basic-spa/src/config.ts:
--------------------------------------------------------------------------------
1 | // config runtime APP_MODE
2 | // eslint-disable-next-line @typescript-eslint/camelcase
3 | window.__app_mode__ = 'build';
4 |
5 | const config = {
6 | dev: {
7 | appId: 'dev-id',
8 | API_URL: `http://localhost:${process.env.SERVER_PORT}`,
9 | },
10 | build: {
11 | API_URL: 'http://github.com/api'
12 | },
13 | default: {
14 | 'appId': 'default-id',
15 | 'sercet': 'hahjhjhj'
16 | }
17 | };
18 |
19 | export default config;
--------------------------------------------------------------------------------
/packages/plugin-react-app/src/userConfig/define.js:
--------------------------------------------------------------------------------
1 | module.exports = (config, define) => {
2 | if (config.plugins.get('DefinePlugin')) {
3 | const defineVariables = {};
4 | // JSON.stringify define values
5 | Object.keys(define).forEach((defineKey) => {
6 | defineVariables[defineKey] = JSON.stringify(define[defineKey]);
7 | });
8 | config
9 | .plugin('DefinePlugin')
10 | .tap((args) => [Object.assign(...args, defineVariables)]);
11 | }
12 | };
13 |
--------------------------------------------------------------------------------
/packages/plugin-react-app/src/userConfig/babelPlugins.js:
--------------------------------------------------------------------------------
1 | module.exports = (config, babelPlugins) => {
2 | ['jsx', 'tsx'].forEach((rule) => {
3 | config.module
4 | .rule(rule)
5 | .use('babel-loader')
6 | .tap((options) => {
7 | const { plugins = [] } = options;
8 | return {
9 | ...options,
10 | plugins: [
11 | ...plugins,
12 | ...babelPlugins,
13 | ],
14 | };
15 | });
16 | });
17 | };
--------------------------------------------------------------------------------
/packages/plugin-store/src/template/types.ts.ejs:
--------------------------------------------------------------------------------
1 | import { IcestoreRootState, IcestoreDispatch } from '@ice/store';
2 | import { appModel } from '.';
3 |
4 | export type IRootDispatch = IcestoreDispatch;
5 | export type IRootState = IcestoreRootState;
6 |
7 | interface IInitialStates {
8 | [key: string]: any;
9 | }
10 |
11 | export interface IStore {
12 | initialStates?: IInitialStates;
13 | getInitialStates?: (initialData) => IInitialStates;
14 | }
15 |
--------------------------------------------------------------------------------
/examples/basic-ssr/mock/index.ts:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | 'GET /api/user': {
3 | status: 'SUCCESS',
4 | data: {
5 | user: {
6 | name: 'Jack Ma',
7 | id: 10001,
8 | }
9 | },
10 | },
11 | 'GET /api/profile': {
12 | status: 'SUCCESS',
13 | data: {
14 | profile: {
15 | id: 10001,
16 | name: 'Jack Ma',
17 | edu: 'Hangzhou Normal University',
18 | address: 'Hangzhou'
19 | }
20 | },
21 | },
22 | };
23 |
--------------------------------------------------------------------------------
/examples/hello-world/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "example-hello-world",
3 | "description": "hello world",
4 | "dependencies": {
5 | "ice.js": "^1.0.0",
6 | "react": "^16.4.1",
7 | "react-dom": "^16.4.1"
8 | },
9 | "devDependencies": {
10 | "@types/react": "^16.9.20",
11 | "@types/react-dom": "^16.9.5"
12 | },
13 | "scripts": {
14 | "start": "icejs start",
15 | "build": "icejs build"
16 | },
17 | "engines": {
18 | "node": ">=8.0.0"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/examples/basic-service/src/components/Fetch/index.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import todoService from '@/services/todo';
3 |
4 | const Fetch = () => {
5 | async function handleRequest() {
6 | const data = await todoService.getAll();
7 | console.log('getAllResult', data);
8 | }
9 |
10 | return (
11 |
12 |
13 | 请求数据
14 |
15 |
16 | );
17 | };
18 |
19 | export default Fetch;
20 |
--------------------------------------------------------------------------------
/examples/basic-ssr/src/pages/About/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Link, logger } from 'ice';
3 |
4 | const About = (props) => {
5 | logger.info('About props', props);
6 | return (
7 | <>
8 | {props.title}
9 | dashboard
10 | home
11 | >
12 | );
13 | };
14 |
15 | About.getInitialProps = async () => {
16 | return { title: 'About Page...' };
17 | };
18 |
19 | export default About;
20 |
--------------------------------------------------------------------------------
/examples/with-rematch/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "example-with-rematch",
3 | "version": "1.0.0",
4 | "description": "with rematch",
5 | "dependencies": {
6 | "react": "^16.4.1",
7 | "react-dom": "^16.4.1"
8 | },
9 | "devDependencies": {
10 | "@types/react": "^16.9.13",
11 | "@types/react-dom": "^16.9.4"
12 | },
13 | "scripts": {
14 | "start": "icejs start",
15 | "build": "icejs build"
16 | },
17 | "engines": {
18 | "node": ">=8.0.0"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/packages/plugin-core/src/generator/templates/app/appConfig.ts.ejs:
--------------------------------------------------------------------------------
1 | // expose appConfig object
2 | // using appConfig in other files or application
3 | // example:
4 | // import { getAppConfig } from '$ice/appConfig';
5 | // const appConfig = getAppConfig();
6 | let appConfig;
7 |
8 | function setAppConfig(appConfigData) {
9 | appConfig = appConfigData;
10 | }
11 |
12 | function getAppConfig() {
13 | return appConfig;
14 | }
15 |
16 | export {
17 | setAppConfig,
18 | getAppConfig
19 | }
20 |
--------------------------------------------------------------------------------
/packages/plugin-store/src/template/pageStore.ts.ejs:
--------------------------------------------------------------------------------
1 | <% if (importStr) { %>
2 | import { createStore } from '@ice/store';
3 | <%- importStr %>
4 | <% } %>
5 |
6 | <% if (importStr && isSingleModel) { %>
7 | const model = { default: <%- modelsStr %> }
8 | const store = createStore(model);
9 | export default store;
10 | <% } %>
11 |
12 | <% if (importStr && !isSingleModel) { %>
13 | const models = { <%- modelsStr %> }
14 | const store = createStore(models);
15 | export default store;
16 | <% } %>
17 |
--------------------------------------------------------------------------------
/examples/basic-ssr/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "exmaple-basic-ssr",
3 | "description": "",
4 | "dependencies": {
5 | "ice.js": "^1.0.11",
6 | "react": "^16.4.1",
7 | "react-dom": "^16.4.1"
8 | },
9 | "devDependencies": {
10 | "@types/react": "^16.9.13",
11 | "@types/react-dom": "^16.9.4"
12 | },
13 | "scripts": {
14 | "start": "icejs start --mode dev",
15 | "build": "icejs build --mode prod"
16 | },
17 | "engines": {
18 | "node": ">=8.0.0"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/examples/icestark-child/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "example-icestark-child",
3 | "description": "icestark child",
4 | "dependencies": {
5 | "ice.js": "^1.0.11",
6 | "react": "^16.4.1",
7 | "react-dom": "^16.4.1"
8 | },
9 | "devDependencies": {
10 | "@types/react": "^16.9.13",
11 | "@types/react-dom": "^16.9.4"
12 | },
13 | "scripts": {
14 | "start": "icejs start",
15 | "build": "icejs build"
16 | },
17 | "engines": {
18 | "node": ">=8.0.0"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/examples/icestark-child/src/pages/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Link } from 'ice';
3 |
4 | const Home = (props) => {
5 | return (
6 | <>
7 | Home Page...{props.a}
8 | About
9 | Dashboard
10 | >
11 | );
12 | };
13 |
14 | Home.getInitialProps = async () => {
15 | return { a: 1 };
16 | };
17 |
18 | Home.pageConfig = {
19 | title: 'Home Page'
20 | };
21 |
22 | export default Home;
23 |
--------------------------------------------------------------------------------
/packages/plugin-core/src/utils/removeExportData.ts:
--------------------------------------------------------------------------------
1 | function removeExportData(exportList, removeExportName: string | string[]) {
2 | const removeExportNames = Array.isArray(removeExportName) ? removeExportName : [removeExportName];
3 | return exportList.filter(({ exportName, specifier }) => {
4 | const needRemove = removeExportNames.includes(exportName)
5 | || !exportName && removeExportNames.includes(specifier);
6 | return !needRemove;
7 | });
8 | }
9 |
10 | export default removeExportData;
--------------------------------------------------------------------------------
/examples/basic-request/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "example-basic-request",
3 | "description": "data fetching with icejs",
4 | "dependencies": {
5 | "ice.js": "^1.0.0",
6 | "react": "^16.4.1",
7 | "react-dom": "^16.4.1"
8 | },
9 | "devDependencies": {
10 | "@types/react": "^16.9.20",
11 | "@types/react-dom": "^16.9.5"
12 | },
13 | "scripts": {
14 | "start": "icejs start",
15 | "build": "icejs build"
16 | },
17 | "engines": {
18 | "node": ">=8.0.0"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/examples/basic-store/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "example-basic-store",
3 | "description": "store management with icejs",
4 | "dependencies": {
5 | "ice.js": "^1.0.0",
6 | "react": "^16.4.1",
7 | "react-dom": "^16.4.1"
8 | },
9 | "devDependencies": {
10 | "@types/react": "^16.9.20",
11 | "@types/react-dom": "^16.9.5"
12 | },
13 | "scripts": {
14 | "start": "icejs start",
15 | "build": "icejs build"
16 | },
17 | "engines": {
18 | "node": ">=8.0.0"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/packages/plugin-icestark/src/types/base.ts:
--------------------------------------------------------------------------------
1 | import { AppConfig } from '@ice/stark';
2 |
3 | export interface IAppRouter {
4 | ErrorComponent?: React.ComponentType;
5 | LoadingComponent?: React.ComponentType;
6 | NotFoundComponent?: React.ComponentType;
7 | shouldAssetsRemove?: (
8 | assetUrl?: string,
9 | element?: HTMLElement | HTMLLinkElement | HTMLStyleElement | HTMLScriptElement,
10 | ) => boolean;
11 | }
12 |
13 | export interface IGetApps {
14 | (): AppConfig[] | Promise;
15 | }
--------------------------------------------------------------------------------
/packages/plugin-icestark/src/types/index.ts:
--------------------------------------------------------------------------------
1 | import { IGetApps, IAppRouter } from './base';
2 |
3 | export interface IIceStark {
4 | type: 'framework' | 'child';
5 | getApps?: IGetApps;
6 | appRouter?: IAppRouter;
7 | removeRoutesLayout?: boolean;
8 | AppRoute?: React.ComponentType;
9 | Layout?: React.ComponentType;
10 | registerAppEnter?: (mountNode: HTMLElement, App: React.ComponentType, resolve: (value?: unknown) => void) => void;
11 | registerAppLeave?: (mountNode: HTMLElement) => void;
12 | }
13 |
--------------------------------------------------------------------------------
/packages/plugin-react-app/src/userConfig/lessLoaderOptions.js:
--------------------------------------------------------------------------------
1 | module.exports = (config, lessLoaderOptions) => {
2 | if (lessLoaderOptions) {
3 | [
4 | 'less',
5 | 'less-module',
6 | ].forEach(rule => {
7 | if (config.module.rules.get(rule)) {
8 | config.module
9 | .rule(rule)
10 | .use('less-loader')
11 | .tap((options) => ({
12 | ...options,
13 | ...lessLoaderOptions,
14 | }));
15 | }
16 | });
17 | }
18 | };
--------------------------------------------------------------------------------
/packages/plugin-react-app/src/userConfig/sassLoaderOptions.js:
--------------------------------------------------------------------------------
1 | module.exports = (config, sassLoaderOptions) => {
2 | if (sassLoaderOptions) {
3 | [
4 | 'scss',
5 | 'scss-module',
6 | ].forEach(rule => {
7 | if (config.module.rules.get(rule)) {
8 | config.module
9 | .rule(rule)
10 | .use('sass-loader')
11 | .tap((options) => ({
12 | ...options,
13 | ...sassLoaderOptions,
14 | }));
15 | }
16 | });
17 | }
18 | };
--------------------------------------------------------------------------------
/packages/plugin-router/templates/withSearchParams.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { useLocation } from 'react-router-dom';
3 | import * as queryString from 'query-string';
4 |
5 | export const withSearchParams = Component => {
6 | const SearchParamsWrappered = props => {
7 | const location = useLocation();
8 | const searchParams = queryString.parse(location.search);
9 | return ;
10 | };
11 | return SearchParamsWrappered;
12 | };
13 |
--------------------------------------------------------------------------------
/packages/plugin-service/src/index.ts:
--------------------------------------------------------------------------------
1 | import * as path from 'path';
2 | import * as fse from 'fs-extra';
3 |
4 | export default async (api) => {
5 | const { getValue, applyMethod } = api;
6 |
7 | const srcPath = path.join(__dirname, 'service');
8 | const distPath = path.join(getValue('ICE_TEMP'), 'service');
9 |
10 | // move service to .ice/service
11 | await fse.copy(srcPath, distPath);
12 | applyMethod('addIceExport', { source: './service/createService', exportName: 'createService' });
13 | };
14 |
15 |
--------------------------------------------------------------------------------
/examples/basic-rml/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "example-basic-rml",
3 | "description": "rml with icejs",
4 | "dependencies": {
5 | "ice.js": "^1.0.0",
6 | "react": "^16.4.1",
7 | "react-dom": "^16.4.1"
8 | },
9 | "devDependencies": {
10 | "@types/react": "^16.9.20",
11 | "@types/react-dom": "^16.9.5",
12 | "build-plugin-rml": "^1.1.0"
13 | },
14 | "scripts": {
15 | "start": "icejs start",
16 | "build": "icejs build"
17 | },
18 | "engines": {
19 | "node": ">=8.0.0"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/examples/basic-ssr/src/app.ts:
--------------------------------------------------------------------------------
1 | import { createApp, IAppConfig, config, request } from 'ice';
2 |
3 | const appConfig: IAppConfig = {
4 | app: {
5 | getInitialData: async () => {
6 | const res = await request('/user');
7 | return res;
8 | }
9 | },
10 | router: {
11 | type: 'browser'
12 | },
13 | request: {
14 | baseURL: config.baseURL
15 | },
16 | store: {
17 | getInitialStates: (initialData) => {
18 | return initialData.data;
19 | }
20 | }
21 | };
22 |
23 | createApp(appConfig);
24 |
--------------------------------------------------------------------------------
/examples/with-rematch/src/pages/Rematch/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { connect } from 'ice';
3 | import Child from './Child';
4 | // import Child2 from './Child2';
5 |
6 | const Home = (props) => {
7 | const { userState } = props;
8 | return (
9 | <>
10 | page stars: {userState.stars}
11 |
12 | {/* */}
13 | >
14 | );
15 | };
16 |
17 | const mapState = state => ({
18 | userState: state.user,
19 | });
20 |
21 | export default connect(mapState)(Home);
22 |
--------------------------------------------------------------------------------
/packages/plugin-react-app/src/userConfig/alias.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 |
3 | module.exports = (config, alias, context) => {
4 | const { rootDir } = context;
5 | const aliasWithRoot = {};
6 | Object.keys(alias).forEach((key) => {
7 | if (path.isAbsolute(alias[key])) {
8 | aliasWithRoot[key] = alias[key];
9 | } else {
10 | aliasWithRoot[key] = path.resolve(rootDir, alias[key]);
11 | }
12 | });
13 | config.merge({
14 | resolve: {
15 | alias: aliasWithRoot,
16 | },
17 | });
18 | };
19 |
--------------------------------------------------------------------------------
/packages/plugin-mpa/README.md:
--------------------------------------------------------------------------------
1 | # plugin-ice-mpa
2 |
3 | > plugin for icejs to support mpa
4 |
5 | ## Usage
6 |
7 | modify build options to enable mpa
8 |
9 | `build.json`:
10 |
11 | ```json
12 | {
13 | "mpa": true
14 | }
15 | ```
16 |
17 | config router in each `app.[t|j]s` under `src/pages`
18 |
19 | ```js
20 | import { createApp } from 'ice'
21 | import Dashboard from './index'
22 |
23 | const appConfig = {
24 | router: {
25 | routes: [{ path: '/', component: Dashboard }],
26 | },
27 | }
28 |
29 | createApp(appConfig)
30 | ```
--------------------------------------------------------------------------------
/examples/basic-service/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "example-basic-service",
3 | "description": "service for icejs",
4 | "dependencies": {
5 | "ice.js": "^1.0.0",
6 | "react": "^16.4.1",
7 | "build-plugin-ice-service": "*",
8 | "react-dom": "^16.4.1"
9 | },
10 | "devDependencies": {
11 | "@types/react": "^16.9.20",
12 | "@types/react-dom": "^16.9.5"
13 | },
14 | "scripts": {
15 | "start": "icejs start",
16 | "build": "icejs build"
17 | },
18 | "engines": {
19 | "node": ">=8.0.0"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | on: [push]
4 |
5 | jobs:
6 | build:
7 |
8 | runs-on: ubuntu-latest
9 |
10 | strategy:
11 | matrix:
12 | node-version: [10.x]
13 |
14 | steps:
15 | - uses: actions/checkout@v2
16 | - name: Use Node.js ${{ matrix.node-version }}
17 | uses: actions/setup-node@v1
18 | with:
19 | node-version: ${{ matrix.node-version }}
20 | - run: npm run setup
21 | - run: npm run lint
22 | - run: npm run dependency:check
23 | env:
24 | CI: true
25 |
--------------------------------------------------------------------------------
/examples/basic-spa/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "exmaple-basic-spa",
3 | "description": "",
4 | "dependencies": {
5 | "ice.js": "^1.0.11",
6 | "react": "^16.4.1",
7 | "react-dom": "^16.4.1"
8 | },
9 | "devDependencies": {
10 | "@types/react": "^16.9.13",
11 | "@types/react-dom": "^16.9.4"
12 | },
13 | "scripts": {
14 | "start": "icejs start --mode dev",
15 | "build": "icejs build --mode prod",
16 | "test": "icejs test --jest-watchAll"
17 | },
18 | "engines": {
19 | "node": ">=8.0.0"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/packages/plugin-core/src/utils/getPages.ts:
--------------------------------------------------------------------------------
1 | import * as path from 'path';
2 | import * as fse from 'fs-extra';
3 |
4 | function getPages(rootDir: string): string[] {
5 | const pagesPath = path.join(rootDir, 'src/pages');
6 | return fse.existsSync(pagesPath) ? fse.readdirSync(pagesPath)
7 | .filter((page) => {
8 | // filter .xxx and _xxx
9 | return !/^[._]/.test(page);
10 | })
11 | .map((page) => {
12 | const { name } = path.parse(page);
13 | return name;
14 | }) : [];
15 | }
16 |
17 | export default getPages;
18 |
--------------------------------------------------------------------------------
/packages/plugin-react-app/src/userConfig/devServer.js:
--------------------------------------------------------------------------------
1 | const defaultConfig = require('../config/default.config');
2 |
3 | module.exports = (config, devServer, context) => {
4 | const { userConfig } = context;
5 | // make sure to use config proxy instead of config devServer.proxy
6 | if (userConfig.proxy && devServer.proxy) {
7 | console.log('use config proxy instead of devServer.proxy');
8 | delete devServer.proxy;
9 | }
10 | // merge default devServer
11 | config.merge({ devServer: { ...defaultConfig.devServer, ...devServer } });
12 | };
13 |
--------------------------------------------------------------------------------
/packages/plugin-react-app/src/userConfig/postcssrc.js:
--------------------------------------------------------------------------------
1 | module.exports = (config, postcssrc) => {
2 | if (postcssrc) {
3 | // remove postcss-loader options, use postcss config file
4 | [
5 | 'scss',
6 | 'scss-module',
7 | 'css',
8 | 'css-module',
9 | 'less',
10 | 'less-module',
11 | ].forEach(rule => {
12 | if (config.module.rules.get(rule)) {
13 | config.module
14 | .rule(rule)
15 | .use('postcss-loader')
16 | .tap(() => ({}));
17 | }
18 | });
19 | }
20 | };
--------------------------------------------------------------------------------
/packages/plugin-store/src/template/appStore.ts.ejs:
--------------------------------------------------------------------------------
1 | <% if (importStr) { %>
2 | import { createStore, Models } from '@ice/store';
3 | <%- importStr %>
4 |
5 | interface AppModel extends Models {
6 | <% modelsStr.split(',').forEach(function(model){ %>
7 | <% if (model) { %>
8 | <%- model %>: typeof <%- model %>;
9 | <% } %>
10 | <% }); %>
11 | }
12 |
13 | const appModel: AppModel = { <%- modelsStr %> };
14 | const store = createStore(appModel);
15 |
16 | export { appModel };
17 | export default store;
18 | <% } %>
19 |
--------------------------------------------------------------------------------
/scripts/dependency-check.ts:
--------------------------------------------------------------------------------
1 | import * as execa from 'execa';
2 | import getPackages from './fn/getPackages';
3 |
4 | // eslint-disable-next-line
5 | const chalk = require('chalk');
6 |
7 | (async () => {
8 | const { packageDirs } = await getPackages();
9 | packageDirs.forEach((pkgDir) => {
10 | execa.commandSync(`dependency-check ${pkgDir} --missing`, {
11 | cwd: pkgDir,
12 | stdio: 'inherit'
13 | });
14 | });
15 | })().catch((e) => {
16 | console.log(chalk.red('\n ⚠️ ⚠️ ⚠️ 依赖检查失败\n\n'), e);
17 | process.exit(128);
18 | });
19 |
--------------------------------------------------------------------------------
/packages/plugin-react-app/README.md:
--------------------------------------------------------------------------------
1 | # plugin-react-app
2 |
3 | > The basic webpack configuration for ice project
4 |
5 | ## Usage
6 |
7 | ### registerUserConfig
8 |
9 | `build.json`
10 |
11 | ```json
12 | {
13 | "entry": "",
14 | "alias": {},
15 | "publicPath": "",
16 | //...
17 | }
18 | ```
19 |
20 | ### registerCliOption
21 |
22 | ```bash
23 | --port
24 | --https
25 | # ...
26 | ```
27 |
28 | ### webpack config
29 |
30 | - TypeScript
31 | - css/sass/less/CSS Modules
32 | - mock
33 | - proxy
34 | - public/
35 |
36 | ## License
37 |
38 | MIT
39 |
--------------------------------------------------------------------------------
/packages/plugin-router/templates/react-router-dom.ts:
--------------------------------------------------------------------------------
1 | // https://github.com/ReactTraining/react-router/tree/master/packages/react-router-dom
2 | export {
3 | // components
4 | Link,
5 | NavLink,
6 | Prompt,
7 | Redirect,
8 | Route,
9 | Switch,
10 | // BrowserRouter,
11 | // HashRouter,
12 | // MemoryRouter,
13 | // StaticRouter,
14 |
15 | // static method
16 | withRouter,
17 | matchPath,
18 | generatePath,
19 |
20 | // hooks
21 | useHistory,
22 | useLocation,
23 | useParams,
24 | useRouteMatch
25 | } from 'react-router-dom';
26 |
--------------------------------------------------------------------------------
/packages/plugin-react-app/src/userConfig/outputDir.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 |
3 | module.exports = (config, outputDir, context) => {
4 | const { rootDir } = context;
5 | const outputPath = path.resolve(rootDir, outputDir);
6 | config.output.path(outputPath);
7 | // copy public folder to outputDir
8 | // copy-webpack-plugin patterns must be an array
9 | if (config.plugins.get('CopyWebpackPlugin')) {
10 | config.plugin('CopyWebpackPlugin').tap(([args]) => [[{
11 | ...(args[0] || {}),
12 | to: outputPath,
13 | }]]);
14 | }
15 | };
16 |
--------------------------------------------------------------------------------
/examples/basic-mpa/src/pages/Dashboard/index.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import { store } from 'ice/Dashboard';
3 |
4 | const Dashboard = () => {
5 | const [pageState, pageActions] = store.useModel('counter');
6 | return (
7 | <>
8 | Dashboard Page...
9 |
10 | +
11 | {pageState.count}
12 | -
13 |
14 | >
15 | );
16 | };
17 |
18 | export default Dashboard;
19 |
--------------------------------------------------------------------------------
/packages/plugin-react-app/src/cliOption/disableReload.js:
--------------------------------------------------------------------------------
1 | module.exports = (config, disableReload) => {
2 | if (disableReload) {
3 | config.plugins.delete('HotModuleReplacementPlugin');
4 |
5 | // remove css hot loader of scss/module-scss/css/module-css/less/module-less
6 | ['scss', 'scss-module', 'css', 'css-module', 'less', 'less-module'].forEach((rule) => {
7 | if (config.module.rules.get(rule)) {
8 | config.module.rule(rule).uses.delete('css-hot-loader');
9 | }
10 | });
11 | config.devServer.hot(false).inline(false);
12 | }
13 | };
14 |
--------------------------------------------------------------------------------
/packages/plugin-request/src/types/base.ts:
--------------------------------------------------------------------------------
1 | import { AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios';
2 |
3 | export interface IInterceptorRequest {
4 | onConfig?: (config: AxiosRequestConfig) => AxiosRequestConfig;
5 | onError?: (error: AxiosError) => Promise;
6 | }
7 |
8 | export interface IInterceptorResponse {
9 | onConfig?: (response: AxiosResponse) => AxiosResponse;
10 | onError?: (error: AxiosError) => Promise;
11 | }
12 |
13 | export interface IInterceptors {
14 | request?: IInterceptorRequest;
15 | response?: IInterceptorResponse;
16 | }
17 |
--------------------------------------------------------------------------------
/packages/plugin-react-app/src/cliOption/https.js:
--------------------------------------------------------------------------------
1 | const getCertificate = require('../utils/getCertificate');
2 |
3 | module.exports = async (config, https) => {
4 | let httpsConfig;
5 | if (https) {
6 | try {
7 | const cert = await getCertificate();
8 | httpsConfig = {
9 | key: cert.key,
10 | cert: cert.cert,
11 | };
12 | } catch (e) {
13 | console.log('HTTPS 证书生成失败,已转换为HTTP');
14 | }
15 | }
16 | if (httpsConfig) {
17 | config.devServer.https(httpsConfig);
18 | } else {
19 | config.devServer.https(false);
20 | }
21 | };
22 |
--------------------------------------------------------------------------------
/examples/basic-request/src/app.ts:
--------------------------------------------------------------------------------
1 | import { createApp, IAppConfig, history } from 'ice';
2 |
3 | const appConfig: IAppConfig = {
4 | app: {
5 | rootId: 'ice-container',
6 | },
7 | request: {
8 | baseURL: '/api',
9 | interceptors: {
10 | response: {
11 | // 可选的
12 | onConfig: (config) => {
13 | console.log({history});
14 | return config;
15 | },
16 | // 可选的
17 | onError: (error) => {
18 | return Promise.reject(error);
19 | }
20 | },
21 | }
22 | }
23 | };
24 |
25 | createApp(appConfig);
26 |
--------------------------------------------------------------------------------
/examples/with-rematch/src/pages/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Link, helpers } from 'ice';
3 |
4 | console.log('helpers from ice', helpers);
5 |
6 | const Home = (props) => {
7 | console.log('Home props', props);
8 | return (
9 | <>
10 | Home Page...{props.a}
11 | About
12 | Dashboard
13 | >
14 | );
15 | };
16 |
17 | Home.getInitialProps = async () => {
18 | return {a: 1};
19 | };
20 |
21 | Home.pageConfig = {
22 | title: 'hahah',
23 | };
24 |
25 | export default Home;
26 |
--------------------------------------------------------------------------------
/packages/plugin-react-app/src/userConfig/cssLoaderOptions.js:
--------------------------------------------------------------------------------
1 | module.exports = (config, cssLoaderOptions) => {
2 | if (cssLoaderOptions) {
3 | [
4 | 'scss',
5 | 'scss-module',
6 | 'css',
7 | 'css-module',
8 | 'less',
9 | 'less-module',
10 | ].forEach(rule => {
11 | if (config.module.rules.get(rule)) {
12 | config.module
13 | .rule(rule)
14 | .use('css-loader')
15 | .tap((options) => ({
16 | ...options,
17 | ...cssLoaderOptions,
18 | }));
19 | }
20 | });
21 | }
22 | };
--------------------------------------------------------------------------------
/examples/basic-mpa/src/pages/Dashboard/models/counter.ts:
--------------------------------------------------------------------------------
1 | export const delay = (time) => new Promise((resolve) => setTimeout(() => resolve(), time));
2 |
3 | export default {
4 | state: {
5 | count: 0
6 | },
7 |
8 | reducers: {
9 | increment (prevState) {
10 | return { count: prevState.count + 1 };
11 | },
12 | decrement (prevState) {
13 | return { count: prevState.count - 1 };
14 | }
15 | },
16 |
17 | effects: (dispatch) => ({
18 | async decrementAsync () {
19 | await delay(10);
20 | dispatch.counter.decrement();
21 | },
22 | }),
23 | };
24 |
--------------------------------------------------------------------------------
/examples/basic-ssr/src/models/user.ts:
--------------------------------------------------------------------------------
1 | export const delay = (time) => new Promise((resolve) => setTimeout(() => resolve(), time));
2 |
3 | export default {
4 | state: {
5 | name: '',
6 | id: ''
7 | },
8 |
9 | reducers: {
10 | update (prevState, payload) {
11 | return {
12 | ...prevState,
13 | ...payload,
14 | };
15 | },
16 | },
17 |
18 | effects: (dispatch) => ({
19 | async getUserInfo () {
20 | await delay(1000);
21 | dispatch.user.update({
22 | name: 'taobao',
23 | id: '123',
24 | });
25 | },
26 | }),
27 | };
28 |
--------------------------------------------------------------------------------
/examples/basic-ssr/src/pages/Dashboard/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Link, logger } from 'ice';
3 |
4 | const Dashboard = (props) => {
5 | logger.info('Dashboard props', props);
6 | return (
7 | <>
8 | {props.title}
9 | about
10 | >
11 | );
12 | };
13 |
14 | Dashboard.getInitialProps = async () => {
15 | return new Promise((resolve) => {
16 | setTimeout(() => {
17 | resolve({ title: 'Dashboard Page xxxx...' });
18 | }, 1 * 1000);
19 | });
20 | // return { title: 'Dashboard Page...' }
21 | };
22 |
23 | export default Dashboard;
24 |
--------------------------------------------------------------------------------
/examples/with-fusion-design/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "example-with-fusion-design",
3 | "description": "with fusion design",
4 | "dependencies": {
5 | "@alifd/next": "^1.19.4",
6 | "moment": "^2.24.0",
7 | "ice.js": "^1.0.0",
8 | "react": "^16.4.1",
9 | "react-dom": "^16.4.1"
10 | },
11 | "devDependencies": {
12 | "@alifd/theme-design-pro": "^0.x",
13 | "build-plugin-fusion": "^0.1.0",
14 | "build-plugin-moment-locales": "^0.1.0"
15 | },
16 | "scripts": {
17 | "start": "icejs start",
18 | "build": "icejs build"
19 | },
20 | "engines": {
21 | "node": ">=8.0.0"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/packages/plugin-logger/README.md:
--------------------------------------------------------------------------------
1 | # plugin-logger
2 |
3 | Use builtin logger in icejs.
4 |
5 | ## Usage
6 |
7 | Set runtime options to `src/app.ts`:
8 |
9 | ```ts
10 | import { APP_MODE } from 'ice'
11 |
12 | const appConfig = {
13 | // set loglevel
14 | logger: {
15 | level: APP_MODE === 'development' ? 'error' : 'warn'
16 | }
17 | }
18 | ```
19 |
20 | Using a logger in the components
21 |
22 | ```js
23 | import { logger } from 'ice'
24 |
25 | const View = () => {
26 | // here
27 | logger.error('error message')
28 |
29 | return (
30 | // jsx code
31 | )
32 | }
33 | ```
34 |
35 | ## License
36 |
37 | MIT
38 |
--------------------------------------------------------------------------------
/packages/plugin-react-app/src/userConfig/ignoreHtmlTemplate.js:
--------------------------------------------------------------------------------
1 | module.exports = (config, ignoreHtmlTemplate, context) => {
2 | const { command, userConfig } = context;
3 | if (command === 'build' && ignoreHtmlTemplate) {
4 | const { entry } = userConfig;
5 | if (Object.prototype.toString.call(entry) === '[object Object]' && Object.keys(entry).length > 1) {
6 | // delete multi HtmlWebpackPlugin
7 | Object.keys(entry).forEach((entryKey) => {
8 | config.plugins.delete(`HtmlWebpackPlugin_${entryKey}`);
9 | });
10 | } else {
11 | config.plugins.delete('HtmlWebpackPlugin');
12 | }
13 | }
14 | };
15 |
--------------------------------------------------------------------------------
/examples/basic-store/src/models/counter.ts:
--------------------------------------------------------------------------------
1 | import { IRootDispatch } from 'ice';
2 |
3 | export const delay = (time) => new Promise((resolve) => setTimeout(() => resolve(), time));
4 |
5 | export default {
6 | state: {
7 | count: 0
8 | },
9 |
10 | reducers: {
11 | increment (prevState) {
12 | return { count: prevState.count + 1 };
13 | },
14 | decrement (prevState) {
15 | return { count: prevState.count - 1 };
16 | }
17 | },
18 |
19 | effects: (dispatch: IRootDispatch) => ({
20 | async decrementAsync () {
21 | await delay(10);
22 | dispatch.counter.decrement();
23 | },
24 | }),
25 | };
26 |
--------------------------------------------------------------------------------
/packages/plugin-react-app/src/config/option.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | https: {
3 | commands: ['start'],
4 | },
5 | analyzer: {
6 | commands: ['start', 'build'],
7 | },
8 | 'analyzer-port': {
9 | commands: ['start', 'build'],
10 | module: 'analyzerPort',
11 | },
12 | 'disable-reload': {
13 | commands: ['start'],
14 | module: 'disableReload',
15 | },
16 | 'disable-mock': {
17 | module: false,
18 | commands: ['start'],
19 | },
20 | 'disable-open': {
21 | module: false,
22 | commands: ['start'],
23 | },
24 | 'mode': {
25 | module: false,
26 | commands: ['start', 'build'],
27 | }
28 | };
--------------------------------------------------------------------------------
/examples/icestark-layout/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "example-icestark-layout",
3 | "description": "icestark layout",
4 | "dependencies": {
5 | "@alifd/next": "^1.19.12",
6 | "@icedesign/theme": "^1.2.0",
7 | "ice.js": "^1.0.11",
8 | "react": "^16.4.1",
9 | "react-dom": "^16.4.1"
10 | },
11 | "devDependencies": {
12 | "@types/react": "^16.9.13",
13 | "@types/react-dom": "^16.9.4",
14 | "build-plugin-fusion": "^0.1.0",
15 | "build-plugin-icestark": "^1.0.11"
16 | },
17 | "scripts": {
18 | "start": "icejs start",
19 | "build": "icejs build"
20 | },
21 | "engines": {
22 | "node": ">=8.0.0"
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/examples/basic-store/src/models/user.ts:
--------------------------------------------------------------------------------
1 | import { IRootDispatch } from 'ice';
2 |
3 | export const delay = (time) => new Promise((resolve) => setTimeout(() => resolve(), time));
4 |
5 | export default {
6 | state: {
7 | name: '',
8 | id: ''
9 | },
10 |
11 | reducers: {
12 | update (prevState, payload) {
13 | return {
14 | ...prevState,
15 | ...payload,
16 | };
17 | },
18 | },
19 |
20 | effects: (dispatch: IRootDispatch) => ({
21 | async getUserInfo () {
22 | await delay(1000);
23 | dispatch.user.update({
24 | name: 'taobao',
25 | id: '123',
26 | });
27 | },
28 | }),
29 | };
30 |
--------------------------------------------------------------------------------
/packages/plugin-rematch/src/module.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import { Provider } from 'react-redux';
3 | import { init } from '@rematch/core';
4 | import { stores } from '$ice/store';
5 |
6 | export default ({ addProvider, appConfig }) => {
7 | if (Object.keys(stores).length === 0) {
8 | return;
9 | }
10 |
11 | const { rematch = {} } = appConfig;
12 |
13 | // TODO: initialState 的传入根据 ssr 的实现可能要调整下
14 | const store = init({
15 | models: stores,
16 | ...rematch,
17 | });
18 |
19 | const StoreProvider = ({children}) => {
20 | return {children} ;
21 | };
22 | addProvider(StoreProvider);
23 | };
24 |
--------------------------------------------------------------------------------
/packages/plugin-react-app/src/userConfig/mock.js:
--------------------------------------------------------------------------------
1 | const webpackDevMock = require('webpack-dev-mock');
2 |
3 | module.exports = (config, mock, context) => {
4 | // dev mock
5 | const { commandArgs, command } = context;
6 | if (!commandArgs.disableMock && command === 'start' && mock) {
7 |
8 | const originalDevServeBefore = config.devServer.get('before');
9 | // replace devServer before function
10 | config.merge({ devServer: {
11 | before(app, server) {
12 | webpackDevMock(app);
13 | if (typeof originalDevServeBefore === 'function') {
14 | originalDevServeBefore(app, server);
15 | }
16 | },
17 | }});
18 | }
19 | };
20 |
--------------------------------------------------------------------------------
/examples/with-rematch/src/pages/Rematch/Child.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import { connect } from 'ice';
3 |
4 | const Home = (props) => {
5 | const { userState, userAction } = props;
6 | return (
7 | <>
8 |
9 |
stars: {userState.stars}
10 |
{
11 | userAction.updateStars(1);
12 | }}>新增一个 star
13 |
14 | >
15 | );
16 | };
17 |
18 | const mapState = models => ({
19 | userState: models.user,
20 | });
21 |
22 | const mapDispatch = actions => ({
23 | userAction: actions.user,
24 | });
25 |
26 | export default connect(
27 | mapState,
28 | mapDispatch,
29 | )(Home);
30 |
--------------------------------------------------------------------------------
/packages/plugin-store/src/module.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import AppStore from '$ice/store';
3 |
4 | export default ({ addProvider, appConfig, context }) => {
5 |
6 | const StoreProvider = ({children}) => {
7 | const storeConfig = appConfig.store || {};
8 | const initialStates = storeConfig.getInitialStates
9 | ? storeConfig.getInitialStates(context && context.initialData)
10 | : storeConfig.initialStates || {};
11 |
12 | return (
13 |
14 | {children}
15 |
16 | );
17 | };
18 |
19 | if (AppStore) {
20 | addProvider(StoreProvider);
21 | }
22 | };
23 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "files": [],
3 | "references": [
4 | { "path": "packages/plugin-core" },
5 | { "path": "packages/plugin-router" },
6 | { "path": "packages/plugin-helpers" },
7 | { "path": "packages/plugin-request" },
8 | { "path": "packages/plugin-service" },
9 | { "path": "packages/plugin-logger" },
10 | { "path": "packages/plugin-rematch" },
11 | { "path": "packages/plugin-store" },
12 | { "path": "packages/plugin-icestark" },
13 | { "path": "packages/plugin-config" },
14 | { "path": "packages/plugin-mpa" },
15 | { "path": "packages/plugin-ssr" },
16 | { "path": "packages/create-ice" },
17 | { "path": "packages/icejs" }
18 | ]
19 | }
20 |
--------------------------------------------------------------------------------
/packages/plugin-store/src/template/pageComponent.tsx.ejs:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | <%- pageComponentImport %>
3 |
4 | <% if(hasPageStore) { %>
5 | import store from './store';
6 | <% } %>
7 |
8 | const PageComponentName = <%= pageComponentExport %>;
9 |
10 | <% if(hasPageStore) { %>
11 | const PageProvider = store.Provider;
12 | const StoreWrapperedPage = (props) => {
13 | return (
14 |
15 |
16 |
17 | )
18 | }
19 | StoreWrapperedPage.pageConfig = PageComponentName.pageConfig || {};
20 | export default StoreWrapperedPage;
21 | <% } else { %>
22 | export default PageComponentName;
23 | <% } %>
24 |
--------------------------------------------------------------------------------
/scripts/rollback.ts:
--------------------------------------------------------------------------------
1 | import * as execa from 'execa';
2 | import getPackages from './fn/getPackages';
3 |
4 | // eslint-disable-next-line
5 | const chalk = require('chalk');
6 |
7 | (async () => {
8 | const { packageNames } = await getPackages();
9 | const args = process.argv;
10 | const rollbackVersion = args[2];
11 | packageNames.forEach((packageName) => {
12 | console.log(`rollback: ${packageName}@${rollbackVersion}`);
13 | execa.commandSync(`npm dist-tags add ${packageName}@${rollbackVersion} latest`, {
14 | stdio: 'inherit'
15 | });
16 | console.log();
17 | });
18 | })().catch((e) => {
19 | console.log(chalk.red('\n ⚠️ ⚠️ ⚠️ rollback failed\n\n'), e);
20 | process.exit(128);
21 | });
22 |
--------------------------------------------------------------------------------
/examples/basic-spa/src/app.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { createApp, APP_MODE, IAppConfig } from 'ice';
3 |
4 | const appConfig: IAppConfig = {
5 | app: {
6 | rootId: 'ice-container',
7 | errorBoundary: true,
8 | parseSearchParams: true
9 | },
10 | logger: {
11 | level: APP_MODE === 'build' ? 'error' : 'debug',
12 | },
13 | router: {
14 | basename: '/ice',
15 | type: 'hash',
16 | fallback: 加载中...
17 | },
18 | request: {
19 | timeout: 5000,
20 | baseURL: '/',
21 | interceptors: {
22 | request: {
23 | onConfig: (config) => {
24 | return config;
25 | }
26 | }
27 | }
28 | }
29 | };
30 |
31 | createApp(appConfig);
32 |
--------------------------------------------------------------------------------
/examples/basic-store/src/pages/Home/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Link, store as appStore } from 'ice';
3 | import { store as pageStore } from 'ice/Home';
4 |
5 | export default () => {
6 | const [counterState, counterActions] = appStore.useModel('counter');
7 | const [pageState] = pageStore.useModel('default');
8 |
9 | return (
10 | <>
11 | {pageState.title}
12 |
13 |
14 | +
15 | {counterState.count}
16 | -
17 |
18 |
19 | about
20 | >
21 | );
22 | };
23 |
--------------------------------------------------------------------------------
/packages/icejs/bin/build.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | const parse = require('yargs-parser');
3 | const { build } = require('@alib/build-scripts');
4 | const log = require('@alib/build-scripts/lib/utils/log');
5 | const getBuiltInPlugins = require('../lib/index');
6 |
7 | module.exports = async () => {
8 | process.env.NODE_ENV = 'production';
9 | const rawArgv = parse(process.argv.slice(2), {
10 | configuration: { 'strip-dashed': true },
11 | });
12 | // ignore _ in rawArgv
13 | delete rawArgv._;
14 | try {
15 | await build({
16 | args: { ...rawArgv },
17 | getBuiltInPlugins,
18 | });
19 | } catch (err) {
20 | log.error(err.message);
21 | console.error(err);
22 | process.exit(1);
23 | }
24 | };
25 |
--------------------------------------------------------------------------------
/packages/plugin-helpers/src/index.ts:
--------------------------------------------------------------------------------
1 | import * as path from 'path';
2 | import * as fse from 'fs-extra';
3 |
4 | export default async function ({
5 | getValue,
6 | applyMethod,
7 | onGetWebpackConfig,
8 | }) {
9 | const srcPath = path.join(__dirname, '../helpers');
10 | const distPath = path.join(getValue('ICE_TEMP'), 'helpers');
11 |
12 | onGetWebpackConfig((config: any) => {
13 | // add alias for module.ts use $ice/helpers
14 | config.resolve.alias.set('$ice/helpers', distPath);
15 | });
16 |
17 | // mv helpers to .ice/helpers
18 | await fse.copy(srcPath, distPath);
19 |
20 | // .ice/index.ts:
21 | // export * from './helpers';
22 | applyMethod('addIceExport', { source: './helpers', exportName: 'helpers' });
23 | }
24 |
--------------------------------------------------------------------------------
/packages/plugin-mpa/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "build-plugin-ice-mpa",
3 | "version": "1.2.1",
4 | "description": "enable mpa project for icejs framework",
5 | "author": "ice-admin@alibaba-inc.com",
6 | "homepage": "",
7 | "license": "MIT",
8 | "main": "lib/index.js",
9 | "directories": {
10 | "lib": "lib"
11 | },
12 | "files": [
13 | "lib"
14 | ],
15 | "publishConfig": {
16 | "registry": "http://registry.npmjs.com/"
17 | },
18 | "repository": {
19 | "type": "git",
20 | "url": "git@gitlab.alibaba-inc.com:ice/ice.js.git"
21 | },
22 | "scripts": {
23 | "test": "echo \"Error: run tests from root\" && exit 1"
24 | },
25 | "devDependencies": {
26 | "@alib/build-scripts": "^0.1.16"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/packages/icejs/src/index.ts:
--------------------------------------------------------------------------------
1 | const getBuiltInPlugins = (userConfig) => {
2 | // built-in plugins for icejs
3 | const builtInPlugins = [
4 | 'build-plugin-ice-core',
5 | 'build-plugin-react-app',
6 | 'build-plugin-ice-router',
7 | 'build-plugin-ice-helpers',
8 | 'build-plugin-ice-logger',
9 | 'build-plugin-ice-config',
10 | 'build-plugin-ice-request',
11 | 'build-plugin-ice-mpa'
12 | ];
13 |
14 | if (userConfig.ssr) {
15 | builtInPlugins.push('build-plugin-ice-ssr');
16 | }
17 |
18 | if (!Object.prototype.hasOwnProperty.call(userConfig, 'store') || userConfig.store !== false) {
19 | builtInPlugins.push('build-plugin-ice-store');
20 | }
21 |
22 | return builtInPlugins;
23 | };
24 |
25 | export = getBuiltInPlugins
26 |
--------------------------------------------------------------------------------
/examples/basic-ssr/src/routes.ts:
--------------------------------------------------------------------------------
1 | import Layout from '@/layouts';
2 | import Dashboard from '@/pages/Dashboard';
3 | import Home from '@/pages/Home';
4 | import About from '@/pages/About';
5 | import Notfound from '@/pages/NotFound';
6 |
7 | export default [
8 | {
9 | path: '/',
10 | component: Layout,
11 | children: [
12 | {
13 | path: '/dashboard',
14 | exact: true,
15 | component: Dashboard
16 | },
17 | {
18 | path: '/',
19 | exact: true,
20 | component: Home
21 | },
22 | {
23 | path: '/about',
24 | exact: true,
25 | component: About
26 | },
27 | {
28 | path: '*',
29 | component: Notfound
30 | }
31 | ]
32 | }
33 | ];
34 |
--------------------------------------------------------------------------------
/packages/plugin-core/src/generator/templates/app/types.ts.ejs:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | <%- iceIAppConfigTypesImports %>
3 | <%- iceTypesImports %>
4 |
5 | export interface IApp {
6 | rootId?: string;
7 | mountNode?: HTMLElement;
8 | addProvider?: ({ children }: { children: React.ReactNode }) => React.ComponentType;
9 | getInitialData?: () => Promise;
10 | ErrorBoundaryFallback?: React.ReactElement,
11 | onErrorBoundaryHander?: (error: Error, componentStack: string) => any;
12 | <% if (iceIAppConfigTypesImports) { %>
13 | <%- iceIAppTypes %>
14 | <% } %>
15 | [key: string]: any;
16 | }
17 |
18 | <% if (iceIAppConfigTypesImports) { %>
19 | export interface IAppConfig {
20 | app?: IApp
21 | <%- iceIAppConfigTypesExports %>
22 | }
23 | <% } %>
24 |
--------------------------------------------------------------------------------
/packages/plugin-mpa/src/index.ts:
--------------------------------------------------------------------------------
1 | import { IPlugin } from '@alib/build-scripts';
2 |
3 | const plugin: IPlugin = ({ context, applyMethod, registerUserConfig, modifyUserConfig }) => {
4 | const { rootDir, userConfig } = context;
5 |
6 | if (userConfig.mpa) {
7 | const pages = applyMethod('getPages', rootDir);
8 |
9 | const mpaEntry = {};
10 | pages.forEach((pageName) => {
11 | const entryName = pageName.toLocaleLowerCase();
12 | mpaEntry[entryName] = `src/pages/${pageName}/app`;
13 | });
14 | // modify entry
15 | modifyUserConfig('entry', mpaEntry);
16 | }
17 |
18 | // register mpa in build.json
19 | registerUserConfig({
20 | name: 'mpa',
21 | validation: 'boolean',
22 | });
23 | };
24 |
25 | export default plugin;
--------------------------------------------------------------------------------
/packages/plugin-core/src/utils/checkExportData.ts:
--------------------------------------------------------------------------------
1 | function checkExportData(currentList, exportData, apiName) {
2 | (Array.isArray(exportData) ? exportData : [exportData]).forEach((data) => {
3 | currentList.forEach(({ specifier, exportName }) => {
4 | // check exportName and specifier
5 | if (specifier || exportName) {
6 | const defaultSpecifierName = specifier || exportName;
7 | if ((exportName && exportName === data.exportName) || defaultSpecifierName === data.specifier) {
8 | throw new Error(`duplicate export data added by ${apiName},
9 | ${data.exportName ? `exportName: ${data.exportName}, ` : ''}specifier: ${data.specifier}
10 | `);
11 | }
12 | }
13 | });
14 | });
15 | }
16 |
17 | export default checkExportData;
18 |
--------------------------------------------------------------------------------
/packages/plugin-router/src/types/index.ts:
--------------------------------------------------------------------------------
1 | import {
2 | RouteProps as DefaultRouteProps,
3 | RouteComponentProps,
4 | } from 'react-router-dom';
5 | import { History } from 'history';
6 | import { RouteItemProps, IModifyRoutes } from './base';
7 |
8 | export interface IAppRouterProps {
9 | type?: 'hash' | 'browser' | 'memory';
10 | routes?: RouteItemProps[];
11 | basename?: string;
12 | modifyRoutes?: IModifyRoutes;
13 | fallback?: React.ReactNode;
14 | history?: History;
15 | }
16 |
17 | export interface IRouterConfig extends DefaultRouteProps {
18 | children?: IRouterConfig[];
19 | // disable string[]
20 | path?: string;
21 | // for rediect ability
22 | redirect?: string;
23 |
24 | component?: React.ComponentType> | React.ComponentType;
25 | }
26 |
--------------------------------------------------------------------------------
/examples/basic-spa/src/pages/Dashboard/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Link, useSearchParams, withSearchParams } from 'ice';
3 |
4 | @withSearchParams
5 | class Foo extends React.PureComponent {
6 | public render() {
7 | console.log('Foo:', this.props.searchParams);
8 | return (
9 | <>Foo>
10 | );
11 | }
12 | }
13 |
14 | const Bar = () => {
15 | const searchParams = useSearchParams();
16 | console.log('Bar:', searchParams);
17 | return (
18 | <>Bar>
19 | );
20 | };
21 |
22 | const Dashboard = (props) => {
23 | console.log('props:', props);
24 | return (
25 | <>
26 | Dashboard Page...
27 |
28 |
29 | About
30 | >
31 | );
32 | };
33 |
34 | export default Dashboard;
35 |
--------------------------------------------------------------------------------
/packages/plugin-react-app/src/userConfig/targets.js:
--------------------------------------------------------------------------------
1 | const formatWinPath = require('../utils/formatWinPath');
2 |
3 | module.exports = (config, targets) => {
4 | ['jsx', 'tsx'].forEach((rule) => {
5 | config.module
6 | .rule(rule)
7 | .use('babel-loader')
8 | .tap((options) => {
9 | const babelPresets = options.presets || [];
10 | const presets = babelPresets.map((preset) => {
11 | if (Array.isArray(preset) && formatWinPath(preset[0]).indexOf(formatWinPath('@babel/preset-env')) > -1) {
12 | return [
13 | preset[0],
14 | Object.assign(preset[1], { targets }),
15 | ];
16 | }
17 | return preset;
18 | });
19 | return Object.assign(options, { presets });
20 | });
21 | });
22 | };
23 |
--------------------------------------------------------------------------------
/examples/basic-store/src/routes.ts:
--------------------------------------------------------------------------------
1 | // import { lazy } from 'ice';
2 |
3 | import Layout from '@/layouts/index';
4 | import Home from '@/pages/Home';
5 | import About from '@/pages/About';
6 | import { NotFound } from '@/pages/NotFound';
7 |
8 | // const Home = lazy(() => import('@/pages/Home'));
9 | // const About =lazy(() => import('@/pages/About'));
10 | // const NotFound = lazy(() => import('@/pages/NotFound'));
11 |
12 | export default [
13 | {
14 | path: '/',
15 | component: Layout,
16 | children: [
17 | {
18 | path: '/',
19 | exact: true,
20 | component: Home
21 | },
22 | {
23 | path: '/about',
24 | component: About
25 | },
26 | {
27 | path: '*',
28 | component: NotFound,
29 | }
30 | ]
31 | }
32 | ];
33 |
--------------------------------------------------------------------------------
/scripts/owner.ts:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * npm run owner -- add sobear
4 | * npm run owner -- rm sobear
5 | * npm run owner -- ls
6 | */
7 | import * as spawn from 'cross-spawn';
8 | import getPackages from './fn/getPackages';
9 |
10 |
11 | (async function () {
12 | const args = process.argv;
13 | const action = args[2];
14 | const name = args[3];
15 | const { packageNames } = await getPackages();
16 |
17 | console.log(`npm owner ${action} ${name} to ${packageNames.join(',')}...`);
18 |
19 | packageNames.forEach((npmName) => {
20 | console.log(`\nnpm owner ${action} ${name || ''} ${npmName}: `);
21 | // https://www.npmjs.cn/cli/owner/
22 | const params = action === 'ls' ? ['owner', action, npmName] : ['owner', action, name, npmName];
23 | spawn.sync('npm', params, { stdio: 'inherit' });
24 | });
25 |
26 | })();
27 |
--------------------------------------------------------------------------------
/packages/plugin-core/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "build-plugin-ice-core",
3 | "version": "1.2.1",
4 | "description": "the core plugin for icejs.",
5 | "author": "ice-admin@alibaba-inc.com",
6 | "homepage": "",
7 | "license": "MIT",
8 | "main": "lib/index.js",
9 | "directories": {
10 | "lib": "lib",
11 | "test": "__tests__"
12 | },
13 | "files": [
14 | "lib"
15 | ],
16 | "publishConfig": {
17 | "registry": "http://registry.npmjs.com/"
18 | },
19 | "scripts": {
20 | "test": "echo \"Error: run tests from root\" && exit 1"
21 | },
22 | "dependencies": {
23 | "chokidar": "^3.3.1",
24 | "deepmerge": "^4.2.2",
25 | "ejs": "^3.0.1",
26 | "fs-extra": "^8.1.0",
27 | "globby": "^11.0.0",
28 | "prettier": "^2.0.2"
29 | },
30 | "gitHead": "07ac7bb07162aac8c90778dd1de4a2060f8df498"
31 | }
32 |
--------------------------------------------------------------------------------
/packages/plugin-react-app/src/userConfig/outputAssetsPath.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const { last } = require('lodash');
3 | const formatWinPath = require('../utils/formatWinPath');
4 |
5 | function getFilename(filePath) {
6 | return last((filePath || '').split('/'));
7 | }
8 | module.exports = (config, outputAssetsPath) => {
9 | const filename = getFilename(config.output.get('filename'));
10 | config.output.filename(formatWinPath(path.join(outputAssetsPath.js || '', filename)));
11 |
12 | if (config.plugins.get('MiniCssExtractPlugin')) {
13 | const options = config.plugin('MiniCssExtractPlugin').get('args')[0];
14 | config.plugin('MiniCssExtractPlugin').tap((args) => [Object.assign(...args, {
15 | filename: formatWinPath(path.join(outputAssetsPath.css || '', getFilename(options.filename))),
16 | })]);
17 | }
18 | };
19 |
--------------------------------------------------------------------------------
/packages/plugin-service/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "build-plugin-ice-service",
3 | "version": "1.2.1",
4 | "description": "service pulgin",
5 | "author": "ice-admin@alibaba-inc.com",
6 | "homepage": "https://github.com/ice-lab/icejs#readme",
7 | "license": "MIT",
8 | "main": "lib/index.js",
9 | "dependencies": {
10 | "fs-extra": "^8.1.0",
11 | "lodash.merge": "^4.6.2",
12 | "lodash.transform": "^4.6.0"
13 | },
14 | "directories": {
15 | "lib": "lib",
16 | "test": "__tests__"
17 | },
18 | "files": [
19 | "lib"
20 | ],
21 | "repository": {
22 | "type": "git",
23 | "url": "git+https://github.com/ice-lab/icejs.git"
24 | },
25 | "scripts": {
26 | "test": "echo \"Error: run tests from root\" && exit 1"
27 | },
28 | "bugs": {
29 | "url": "https://github.com/ice-lab/icejs/issues"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/examples/basic-service/src/pages/Home/components/User/index.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import localService from './service';
3 |
4 | const User = () => {
5 | async function handleGetTodo() {
6 | const data = await localService.getTodo({ id: '1' });
7 | console.log('getTodo-data', data);
8 | console.log({...localService.getTodo});
9 | }
10 |
11 | async function handleGetUser() {
12 | const data = await localService.getUser({ id: '1' });
13 | console.log('getUser-data', data);
14 | console.log({...localService.getUser});
15 | }
16 |
17 | return (
18 |
19 |
20 | 获取任务
21 |
22 |
23 | 获取用户
24 |
25 |
26 | );
27 | };
28 |
29 | export default User;
30 |
--------------------------------------------------------------------------------
/packages/plugin-logger/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "build-plugin-ice-logger",
3 | "version": "1.2.1",
4 | "description": "builtin logger in icejs",
5 | "author": "ice-admin@alibaba-inc.com",
6 | "homepage": "",
7 | "license": "MIT",
8 | "main": "lib/index.js",
9 | "directories": {
10 | "lib": "lib",
11 | "test": "__tests__"
12 | },
13 | "files": [
14 | "lib",
15 | "logger"
16 | ],
17 | "dependencies": {
18 | "fs-extra": "^8.1.0",
19 | "loglevel": "^1.6.6"
20 | },
21 | "devDependencies": {
22 | "@alib/build-scripts": "^0.1.13",
23 | "typescript": "^3.7.2"
24 | },
25 | "publishConfig": {
26 | "registry": "http://registry.npmjs.com/"
27 | },
28 | "scripts": {
29 | "test": "echo \"Error: run tests from root\" && exit 1"
30 | },
31 | "gitHead": "07ac7bb07162aac8c90778dd1de4a2060f8df498"
32 | }
33 |
--------------------------------------------------------------------------------
/examples/basic-spa/src/routes.ts:
--------------------------------------------------------------------------------
1 | import { lazy } from 'ice';
2 | import Layout from '@/layouts';
3 |
4 | const Dashboard = lazy(() => import('@/pages/Dashboard'));
5 | const Home = lazy(() => import('@/pages/Home'));
6 | const About = lazy(() => import('@/pages/About'));
7 | const Notfound = lazy(() => import('@/pages/NotFound'));
8 |
9 | export default [
10 | {
11 | path: '/',
12 | component: Layout,
13 | children: [
14 | {
15 | path: '/dashboard',
16 | exact: true,
17 | component: Dashboard
18 | },
19 | {
20 | path: '/about',
21 | exact: true,
22 | component: About
23 | },
24 | {
25 | path: '/',
26 | exact: true,
27 | component: Home
28 | },
29 | {
30 | path: '*',
31 | component: Notfound
32 | },
33 | ]
34 | }
35 | ];
36 |
--------------------------------------------------------------------------------
/packages/icejs/README.md:
--------------------------------------------------------------------------------
1 | # `icejs`
2 |
3 | > Command line tool and builtin plugin for icejs
4 |
5 | ## Install
6 |
7 | ```bash
8 | $ npm i ice.js -D
9 | ```
10 |
11 | ## Usage
12 |
13 | For example, with project a `package.json` like follows is recommended:
14 |
15 | ```json
16 | {
17 | "name": "my-app",
18 | "dependencies": {
19 | "ice.js": "^1.0.0"
20 | },
21 | "scripts": {
22 | "start": "icejs start",
23 | "build": "icejs build",
24 | }
25 | }
26 | ```
27 |
28 | ### Command line interface
29 |
30 | ```markdown
31 | Usage: icejs [options]
32 |
33 | Options:
34 | -V, --version output the version number
35 | -h, --help output usage information
36 |
37 | Commands:
38 | build [options] build project
39 | start [options] start server
40 | test [options] run tests with jest
41 | ```
42 |
43 | ## License
44 |
45 | MIT
46 |
--------------------------------------------------------------------------------
/packages/plugin-react-app/src/userConfig/eslint.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 |
3 | module.exports = (config, eslint, { rootDir }) => {
4 | if (typeof eslint === 'boolean' && eslint === false) {
5 | return config;
6 | }
7 | const { disable, ...args } = eslint;
8 | if (!disable) {
9 | const appSrc = path.join(rootDir, 'src');
10 | config.module
11 | .rule('eslint')
12 | .test(/\.(jsx?|tsx?)$/)
13 | .include
14 | .add(appSrc)
15 | .end()
16 | .enforce('pre')
17 | .use('eslint')
18 | .loader(require.resolve('eslint-loader'))
19 | .tap((options) => ({
20 | cache: true,
21 | eslintPath: require.resolve('eslint'),
22 | formatter: require.resolve('react-dev-utils/eslintFormatter'),
23 | ...options,
24 | ...args
25 | }));
26 | }
27 | };
28 |
--------------------------------------------------------------------------------
/packages/create-ice/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "create-ice",
3 | "version": "1.2.1",
4 | "description": "npm init ice",
5 | "author": "ice-admin@alibaba-inc.com",
6 | "homepage": "",
7 | "license": "MIT",
8 | "main": "lib/index.js",
9 | "bin": {
10 | "create-ice": "lib/index.js"
11 | },
12 | "directories": {
13 | "lib": "lib",
14 | "test": "__tests__"
15 | },
16 | "files": [
17 | "lib",
18 | "bin"
19 | ],
20 | "scripts": {
21 | "test": "echo \"Error: run tests from root\" && exit 1"
22 | },
23 | "dependencies": {
24 | "@iceworks/generate-project": "^1.0.0",
25 | "chalk": "^3.0.0",
26 | "fs-extra": "^8.1.0",
27 | "ice-npm-utils": "^1.4.0",
28 | "inquirer": "^7.0.4"
29 | },
30 | "publishConfig": {
31 | "registry": "http://registry.npmjs.com/"
32 | },
33 | "gitHead": "07ac7bb07162aac8c90778dd1de4a2060f8df498"
34 | }
35 |
--------------------------------------------------------------------------------
/examples/basic-service/mock/index.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | 'GET /todo_getAll': {
3 | 'errorCode': '0',
4 | 'errorMsg': '',
5 | 'data': [
6 | {
7 | 'id': '1',
8 | 'title': '安卓',
9 | 'dnoe': true
10 | },
11 | {
12 | 'id': '2',
13 | 'title': 'iOS',
14 | 'dnoe': true
15 | }
16 | ],
17 | 'success': true
18 | },
19 | 'GET /todo_getOne': {
20 | 'errorCode': '0',
21 | 'errorMsg': '',
22 | 'data': {
23 | 'id': '2222222',
24 | 'title': '安卓',
25 | 'dnoe': true
26 | },
27 | 'requestId': '@guid',
28 | 'success': true
29 | },
30 | 'POST /todo_add': {
31 | 'errorCode': '0',
32 | 'errorMsg': '',
33 | 'data': {
34 | 'id': '2222222',
35 | 'title': '安卓',
36 | 'dnoe': true
37 | },
38 | 'requestId': '@guid',
39 | 'success': true
40 | },
41 | };
42 |
--------------------------------------------------------------------------------
/packages/plugin-store/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "build-plugin-ice-store",
3 | "version": "1.2.1",
4 | "description": "builtin `icestore` in icejs",
5 | "author": "ice-admin@alibaba-inc.com",
6 | "homepage": "",
7 | "license": "MIT",
8 | "main": "lib/index.js",
9 | "directories": {
10 | "lib": "lib",
11 | "test": "__tests__"
12 | },
13 | "files": [
14 | "lib",
15 | "src/types"
16 | ],
17 | "publishConfig": {
18 | "registry": "http://registry.npmjs.com/"
19 | },
20 | "repository": {
21 | "type": "git",
22 | "url": "git@gitlab.alibaba-inc.com:ice/ice.js.git"
23 | },
24 | "scripts": {
25 | "test": "echo \"Error: run tests from root\" && exit 1"
26 | },
27 | "dependencies": {
28 | "@ice/store": "^1.3.1",
29 | "ejs": "^3.0.2",
30 | "fs-extra": "^8.1.0",
31 | "fs-readdir-recursive": "^1.1.0",
32 | "prettier": "^2.0.4"
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/examples/basic-spa/src/pages/Home/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Link, helpers, logger, config } from 'ice';
3 |
4 | logger.debug('helpers from ice', helpers.urlParse);
5 | logger.debug('logger from ice', logger.debug);
6 |
7 | logger.info('=== info ===');
8 | logger.warn('=== warn ===');
9 | logger.error('=== error ===');
10 | logger.debug('=== debug ===');
11 | logger.trace('=== trace ===');
12 |
13 | export default function Home(props) {
14 |
15 | logger.info('Home props', props);
16 | logger.info('render home config.appId', config.appId);
17 |
18 | return (
19 | <>
20 | Home Page...{props.count}
21 | About
22 | Dashboard
23 | >
24 | );
25 | }
26 |
27 | Home.getInitialProps = async () => {
28 | return { count: 1 };
29 | };
30 |
31 | Home.pageConfig = {
32 | title: 'Home Page'
33 | };
34 |
--------------------------------------------------------------------------------
/scripts/build.ts:
--------------------------------------------------------------------------------
1 | import * as glob from 'glob';
2 | import * as path from 'path';
3 | import * as fs from 'fs-extra';
4 | import { run } from './fn/shell';
5 |
6 | (async () => {
7 | await run('npm run clean');
8 | await run('npx tsc --build ./tsconfig.json');
9 |
10 | const fileParten = '*/src/**/!(*.ts|*.tsx)';
11 | console.log(`[COPY]: ${fileParten}`);
12 |
13 | const cwd = path.join(__dirname, '../packages');
14 | const files = glob.sync(fileParten, { cwd, nodir: true });
15 | // eslint-disable-next-line
16 | for (const file of files) {
17 | const from = path.join(cwd, file);
18 | const to = path.join(cwd, file.replace(/\/src\//, '/lib/'));
19 | // eslint-disable-next-line
20 | await fs.mkdirp(path.dirname(to));
21 | // eslint-disable-next-line
22 | await fs.copyFile(from, to);
23 | }
24 |
25 | })().catch((e) => {
26 | console.trace(e);
27 | process.exit(128);
28 | });
29 |
--------------------------------------------------------------------------------
/packages/plugin-ssr/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "build-plugin-ice-ssr",
3 | "version": "1.2.1",
4 | "description": "ssr plugin",
5 | "author": "ice-admin@alibaba-inc.com",
6 | "homepage": "",
7 | "license": "MIT",
8 | "main": "lib/index.js",
9 | "directories": {
10 | "lib": "lib",
11 | "test": "__tests__"
12 | },
13 | "files": [
14 | "lib",
15 | "src"
16 | ],
17 | "publishConfig": {
18 | "registry": "http://registry.npmjs.com/"
19 | },
20 | "repository": {
21 | "type": "git",
22 | "url": "git@gitlab.alibaba-inc.com:ice/ice.js.git"
23 | },
24 | "scripts": {
25 | "test": "echo \"Error: run tests from root\" && exit 1"
26 | },
27 | "dependencies": {
28 | "build-scripts-config": "^0.1.6",
29 | "chalk": "^3.0.0",
30 | "cheerio": "^1.0.0-rc.3",
31 | "ejs": "^3.0.1",
32 | "fs-extra": "^8.1.0",
33 | "html-minifier": "^4.0.0"
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/packages/plugin-config/README.md:
--------------------------------------------------------------------------------
1 | # `plugin-config`
2 |
3 | > Define application config in icejs
4 |
5 | ## Usage
6 |
7 | Set runtime options to `src/config.[t|j]s`:
8 |
9 | ```ts
10 | const config = {
11 | config: {
12 | // only working in development environment
13 | dev: {
14 |
15 | },
16 | // only working in production environment
17 | prod: {
18 |
19 | },
20 | // default configuration working in production environment and development environment
21 | default: {
22 | appId: 'secret'
23 | }
24 | }
25 | };
26 |
27 | export default config;
28 | ```
29 |
30 | Set `mode` options to `package.json`:
31 |
32 | ```json
33 | "scripts": {
34 | "start": "icejs start --mode dev",
35 | "build": "icejs build --mode prod"
36 | },
37 | ```
38 |
39 | ## Usage
40 |
41 | ```ts
42 | import { config } from 'ice'
43 |
44 | console.log(config)
45 | ```
46 |
47 | ## License
48 |
49 | MIT
50 |
--------------------------------------------------------------------------------
/packages/plugin-react-app/src/utils/collect.js:
--------------------------------------------------------------------------------
1 | const { collectDetail } = require('@alifd/fusion-collector');
2 |
3 | const collect = ({ command, rootDir, pkg, log }) => {
4 | if (Object.keys(pkg).length === 0) {
5 | // package.json is not exsist or package.json is empty
6 | return;
7 | }
8 | if (!process.env.DISABLE_COLLECT) {
9 | let kitVersion = '0.1.x'; // set default version;
10 | ['devDependencies', 'dependencies'].forEach((pkgKey) => {
11 | kitVersion = (pkg[pkgKey] && pkg[pkgKey]['@alib/build-scripts']) || kitVersion;
12 | });
13 | try {
14 | const options = {
15 | rootDir,
16 | kit: 'build-scripts',
17 | kitVersion,
18 | cmdType: process.stderr.isTTY ? command : `nontty-${command}`,
19 | };
20 | collectDetail(options);
21 | } catch (err) {
22 | log.warn('[collect error]', err);
23 | }
24 | }
25 | };
26 |
27 | module.exports = collect;
28 |
--------------------------------------------------------------------------------
/packages/plugin-react-app/src/utils/babelPluginCorejsLock.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 |
3 | const coreJSPath = path.dirname(require.resolve('core-js/package.json'));
4 | // eslint-disable-next-line no-unused-vars
5 | module.exports = ({ types }, { fileList }) => {
6 | return {
7 | visitor: {
8 | ImportDeclaration(nodePath, state) {
9 | const entryFile = fileList.find((filePath) => {
10 | // filePath may not have an extension
11 | return filePath.includes((state.filename || '').replace(/\.[^/.]+$/, ''));
12 | });
13 | if (entryFile) {
14 | const { node } = nodePath;
15 | // only replace core-js/modules/xxx added by @babel/preset-env
16 | if (node.source.value.startsWith('core-js/modules')) {
17 | node.source.value = node.source.value.replace('core-js/', `${coreJSPath}/`);
18 | }
19 | }
20 | },
21 | },
22 | };
23 | };
24 |
--------------------------------------------------------------------------------
/packages/plugin-request/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "build-plugin-ice-request",
3 | "version": "1.2.1",
4 | "description": "request for build-plugin-ice-request",
5 | "author": "ice-admin@alibaba-inc.com",
6 | "homepage": "",
7 | "license": "MIT",
8 | "main": "lib/index.js",
9 | "directories": {
10 | "lib": "lib",
11 | "test": "__tests__"
12 | },
13 | "files": [
14 | "lib",
15 | "request"
16 | ],
17 | "dependencies": {
18 | "axios": "^0.19.2",
19 | "fs-extra": "^8.1.0"
20 | },
21 | "pluginConfig": {
22 | "staticModule": true
23 | },
24 | "publishConfig": {
25 | "registry": "http://registry.npmjs.com/"
26 | },
27 | "repository": {
28 | "type": "git",
29 | "url": "git@gitlab.alibaba-inc.com:ice/ice.js.git"
30 | },
31 | "scripts": {
32 | "test": "echo \"Error: run tests from root\" && exit 1"
33 | },
34 | "gitHead": "e9bf7c3abd03d870a637d73b70b613942777132a"
35 | }
36 |
--------------------------------------------------------------------------------
/examples/hello-world/src/components/Guide/index.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import styles from './index.module.scss';
3 |
4 | const Guide = () => {
5 | return (
6 |
7 |
Welcome to icejs!
8 |
9 |
This is a awesome project, enjoy it!
10 |
11 |
30 |
31 | );
32 | };
33 |
34 | export default Guide;
35 |
--------------------------------------------------------------------------------
/examples/with-rematch/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "buildOnSave": false,
4 | "compilerOptions": {
5 | "baseUrl": ".",
6 | "outDir": "build",
7 | "module": "esnext",
8 | "target": "es6",
9 | "jsx": "react",
10 | "moduleResolution": "node",
11 | "allowSyntheticDefaultImports": true,
12 | "lib": [
13 | "es6",
14 | "dom"
15 | ],
16 | "sourceMap": true,
17 | "allowJs": true,
18 | "rootDir": "./",
19 | "forceConsistentCasingInFileNames": true,
20 | "noImplicitReturns": true,
21 | "noImplicitThis": true,
22 | "noImplicitAny": false,
23 | "importHelpers": true,
24 | "strictNullChecks": true,
25 | "suppressImplicitAnyIndexErrors": true,
26 | "noUnusedLocals": true,
27 | "skipLibCheck": true,
28 | "paths": {
29 | "@/*": [
30 | "./src/*"
31 | ],
32 | "ice": [
33 | ".ice/index"
34 | ]
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | const { eslint, tslint, deepmerge } = require('@ice/spec');
2 |
3 | const commonRules = {
4 | "react/jsx-filename-extension": 0,
5 | "no-underscore-dangle": 0,
6 | "class-methods-use-this": 0,
7 | "no-param-reassign": 0,
8 | "comma-dangle": 0,
9 | "prefer-object-spread": 0,
10 | // TODO: open rule indent, consider of MemberExpression
11 | "indent": 0,
12 | };
13 |
14 | const jsRules = deepmerge(eslint, {
15 | rules: {
16 | ...commonRules,
17 | },
18 | });
19 |
20 | const tsRules = deepmerge(tslint, {
21 | rules: {
22 | ...commonRules,
23 | "@typescript-eslint/no-explicit-any": 0,
24 | "@typescript-eslint/interface-name-prefix": 0,
25 | "@typescript-eslint/explicit-function-return-type": 0,
26 | },
27 | });
28 |
29 | delete tsRules.root;
30 |
31 | module.exports = {
32 | ...jsRules,
33 | overrides: [
34 | {
35 | ...tsRules,
36 | files: ['**/*.ts', '**/*.tsx'],
37 | },
38 | ],
39 | };
40 |
--------------------------------------------------------------------------------
/examples/icestark-layout/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "buildOnSave": false,
4 | "compilerOptions": {
5 | "baseUrl": ".",
6 | "outDir": "build",
7 | "module": "esnext",
8 | "target": "es6",
9 | "jsx": "react",
10 | "moduleResolution": "node",
11 | "allowSyntheticDefaultImports": true,
12 | "lib": [
13 | "es6",
14 | "dom"
15 | ],
16 | "sourceMap": true,
17 | "allowJs": true,
18 | "rootDir": "./",
19 | "forceConsistentCasingInFileNames": true,
20 | "noImplicitReturns": true,
21 | "noImplicitThis": true,
22 | "noImplicitAny": false,
23 | "importHelpers": true,
24 | "strictNullChecks": true,
25 | "suppressImplicitAnyIndexErrors": true,
26 | "noUnusedLocals": true,
27 | "skipLibCheck": true,
28 | "paths": {
29 | "@/*": [
30 | "./src/*"
31 | ],
32 | "ice": [
33 | ".ice/index.ts"
34 | ]
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/packages/plugin-config/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "build-plugin-ice-config",
3 | "version": "1.2.1",
4 | "description": "Define application config in icejs",
5 | "author": "ice-admin@alibaba-inc.com",
6 | "homepage": "",
7 | "license": "MIT",
8 | "main": "lib/index.js",
9 | "directories": {
10 | "lib": "lib",
11 | "test": "__tests__"
12 | },
13 | "files": [
14 | "lib",
15 | "config"
16 | ],
17 | "publishConfig": {
18 | "registry": "http://registry.npmjs.com/"
19 | },
20 | "repository": {
21 | "type": "git",
22 | "url": "git@gitlab.alibaba-inc.com:ice/ice.js.git"
23 | },
24 | "scripts": {
25 | "test": "echo \"Error: run tests from root\" && exit 1"
26 | },
27 | "gitHead": "07ac7bb07162aac8c90778dd1de4a2060f8df498",
28 | "dependencies": {
29 | "fs-extra": "^8.1.0"
30 | },
31 | "devDependencies": {
32 | "@alib/build-scripts": "^0.1.18",
33 | "@types/fs-extra": "^8.1.0"
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/packages/plugin-icestark/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "build-plugin-icestark",
3 | "version": "1.2.1",
4 | "description": "Easy use `icestark` in icejs.",
5 | "author": "ice-admin@alibaba-inc.com",
6 | "homepage": "",
7 | "license": "MIT",
8 | "main": "lib/index.js",
9 | "directories": {
10 | "lib": "lib",
11 | "test": "__tests__"
12 | },
13 | "files": [
14 | "lib",
15 | "src/types"
16 | ],
17 | "dependencies": {
18 | "@ice/stark": "^1.3.1",
19 | "@ice/stark-app": "^1.2.0",
20 | "fs-extra": "^8.1.0",
21 | "glob": "^7.1.6"
22 | },
23 | "devDependencies": {
24 | "@alib/build-scripts": "^0.1.13",
25 | "@types/glob": "^7.1.1",
26 | "react": "^16.12.0",
27 | "react-dom": "^16.12.0",
28 | "typescript": "^3.7.2"
29 | },
30 | "publishConfig": {
31 | "registry": "http://registry.npmjs.com/"
32 | },
33 | "scripts": {
34 | "test": "echo \"Error: run tests from root\" && exit 1"
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/packages/plugin-rematch/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "build-plugin-ice-rematch",
3 | "version": "1.2.1",
4 | "description": "Easy use `rematch` in icejs",
5 | "author": "ice-admin@alibaba-inc.com",
6 | "homepage": "",
7 | "license": "MIT",
8 | "main": "lib/index.js",
9 | "directories": {
10 | "lib": "lib",
11 | "test": "__tests__"
12 | },
13 | "files": [
14 | "lib"
15 | ],
16 | "scripts": {
17 | "test": "echo \"Error: run tests from root\" && exit 1"
18 | },
19 | "dependencies": {
20 | "@rematch/core": "^1.3.0",
21 | "@types/react": "^16.9.19",
22 | "@types/react-redux": "^7.1.7",
23 | "ejs": "^3.0.1",
24 | "fs-extra": "^8.1.0",
25 | "globby": "^11.0.0",
26 | "react": "^16.12.0",
27 | "react-dom": "^16.12.0",
28 | "react-redux": "^7.1.3"
29 | },
30 | "publishConfig": {
31 | "registry": "http://registry.npmjs.com/"
32 | },
33 | "gitHead": "07ac7bb07162aac8c90778dd1de4a2060f8df498"
34 | }
35 |
--------------------------------------------------------------------------------
/packages/plugin-router/src/types/base.ts:
--------------------------------------------------------------------------------
1 | import {
2 | RouteProps as DefaultRouteProps,
3 | RouteComponentProps,
4 | } from 'react-router-dom';
5 |
6 | interface IModifyFn {
7 | (routes: RouteItemProps[]): RouteItemProps[];
8 | }
9 |
10 | export interface IModifyRoutes {
11 | (modifyFn: IModifyFn): void;
12 | }
13 |
14 | export interface IRouteWrapper {
15 | (props: any): React.ComponentType;
16 | }
17 |
18 | export interface IDynamicImportComponent {
19 | __LAZY__: boolean;
20 | dynamicImport: () => Promise<{ default: React.ComponentType }>;
21 | }
22 |
23 | export interface RouteItemProps extends Omit {
24 | children?: RouteItemProps[];
25 | // disable string[]
26 | path?: string;
27 | // for rediect ability
28 | redirect?: string;
29 |
30 | component?: React.ComponentType> | React.ComponentType | IDynamicImportComponent;
31 |
32 | routeWrappers?: IRouteWrapper[];
33 | };
34 |
--------------------------------------------------------------------------------
/packages/create-ice/src/index.ts:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | import * as path from 'path';
3 | import { log } from 'ice-npm-utils';
4 | import * as fs from 'fs-extra';
5 | import create from './create';
6 |
7 | const pkgContent = fs.readJSONSync(path.join(__dirname, '..', 'package.json'));
8 | console.log('create-ice version:', pkgContent.version);
9 |
10 | (async function() {
11 | const args = process.argv;
12 | const dirname: string = args[2];
13 | const templateName: string = args[3];
14 |
15 | log.verbose('create-ice args', dirname, templateName);
16 |
17 | if (!dirname || dirname === '--help') {
18 | console.log('');
19 | console.log('init project');
20 | console.log('Examples:');
21 | console.log(' $ npm init ice ice-app');
22 | console.log(' $ npm init ice ice-app @alifd/fusion-design-pro');
23 | process.exit(0);
24 | }
25 |
26 | const dirPath = path.join(process.cwd(), dirname);
27 | await create(dirPath, templateName, dirname);
28 | })();
29 |
--------------------------------------------------------------------------------
/packages/plugin-react-app/src/utils/updateMiniCssLoaderPath.js:
--------------------------------------------------------------------------------
1 | module.exports = (config, value, userConfig) => {
2 | const shouldUseRelativeAssetPaths = value === './';
3 | const outputCssPath = userConfig.outputAssetsPath && userConfig.outputAssetsPath.css;
4 | // when publicPath is ./ assets in css will be resolve as ./assets/xxx
5 | // the actual path where assets exist is ../assets/xxx when output css path is `css`
6 | if (shouldUseRelativeAssetPaths && outputCssPath) {
7 | const pathArray = outputCssPath.split('/').length;
8 | const publicPath = `${[...Array(pathArray)].map(() => '..').join('/')}/`;
9 | // MiniCssExtractPlugin.loader will use output.publicPath as default
10 | ['scss', 'scss-module', 'css', 'css-module', 'less', 'less-module'].forEach((rule) => {
11 | if (config.module.rules.get(rule)) {
12 | config.module.rule(rule).use('MiniCssExtractPlugin.loader').tap(() => ({ publicPath }));
13 | }
14 | });
15 | }
16 | };
17 |
18 |
--------------------------------------------------------------------------------
/packages/plugin-rematch/src/generateStore.ts:
--------------------------------------------------------------------------------
1 | import * as path from 'path';
2 | import * as fse from 'fs-extra';
3 | import * as ejs from 'ejs';
4 |
5 | export default async function(targetPath, templatePath, storesDir) {
6 |
7 | let stores = [];
8 | try {
9 | // TODO: 过滤、嵌套
10 | stores = await fse.readdir(storesDir);
11 | stores = stores.map(item => path.parse(item).name);
12 | } catch(err) {
13 | console.error('read stores err', err);
14 | }
15 |
16 | let importCodes = '';
17 | let storesString = '';
18 | stores.forEach((storeFileName) => {
19 | importCodes += `\nimport ${storeFileName} from '${storesDir}/${storeFileName}';`;
20 | storesString += `${storeFileName},`;
21 | });
22 |
23 | // 遍历 stores 目录
24 | const templateContent = fse.readFileSync(templatePath, 'utf-8');
25 | const content = ejs.render(templateContent, {
26 | importCodes,
27 | storesString,
28 | });
29 |
30 | fse.writeFileSync(targetPath, content, 'utf-8');
31 | }
32 |
--------------------------------------------------------------------------------
/examples/with-fusion-design/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "buildOnSave": false,
4 | "compilerOptions": {
5 | "baseUrl": ".",
6 | "outDir": "build",
7 | "module": "esnext",
8 | "target": "es6",
9 | "jsx": "react",
10 | "moduleResolution": "node",
11 | "allowSyntheticDefaultImports": true,
12 | "lib": ["es6", "dom"],
13 | "sourceMap": true,
14 | "allowJs": true,
15 | "rootDir": "./",
16 | "forceConsistentCasingInFileNames": true,
17 | "noImplicitReturns": true,
18 | "noImplicitThis": true,
19 | "noImplicitAny": false,
20 | "importHelpers": true,
21 | "strictNullChecks": true,
22 | "suppressImplicitAnyIndexErrors": true,
23 | "noUnusedLocals": true,
24 | "skipLibCheck": true,
25 | "paths": {
26 | "@/*": ["./src/*"],
27 | "ice": [".ice/index.ts"],
28 | "ice/*": [".ice/pages/*"]
29 | }
30 | },
31 | "include": ["src/*", ".ice"],
32 | "exclude": ["node_modules", "build", "public"]
33 | }
--------------------------------------------------------------------------------
/packages/plugin-logger/src/index.ts:
--------------------------------------------------------------------------------
1 | import * as path from 'path';
2 | import * as fse from 'fs-extra';
3 | import { IPlugin } from '@alib/build-scripts';
4 |
5 | const plugin: IPlugin = async ({ getValue, applyMethod, onGetWebpackConfig }): Promise => {
6 | const exportName = 'logger';
7 | const distPath = path.join(getValue('ICE_TEMP'), exportName);
8 | await fse.copy(path.join(__dirname, `../${exportName}`), distPath);
9 | await fse.copy(path.join(__dirname, './types'), path.join(distPath, 'types'));
10 | // add ice exports
11 | applyMethod('addIceExport', { source: `./${exportName}`, exportName });
12 |
13 | // add iceTypes exports
14 | applyMethod('addIceAppConfigTypes', { source: `./${exportName}/types`, specifier: '{ ILogger }', exportName: `${exportName}?: ILogger` });
15 |
16 | onGetWebpackConfig((config) => {
17 | // add alias for module.ts use $ice/logger
18 | config.resolve.alias.set('$ice/logger', distPath);
19 | });
20 | };
21 |
22 | export default plugin;
23 |
--------------------------------------------------------------------------------
/packages/plugin-react-app/src/userConfig/compileDependencies.js:
--------------------------------------------------------------------------------
1 | module.exports = (config, compileDependencies) => {
2 | const matchExclude = (filepath) => {
3 | const deps = compileDependencies.map(dep => {
4 | if (dep instanceof RegExp) {
5 | return dep.source;
6 | } else if (typeof dep === 'string') {
7 | // add default node_modules
8 | const matchStr = `node_modules/?.+${dep}/`;
9 | return process.platform === 'win32' ? matchStr.replace(/\\/g, '\\\\') : matchStr;
10 | }
11 | return false;
12 | }).filter(Boolean);
13 | const matchReg = deps.length ? new RegExp(deps.join('|')) : null;
14 | if (matchReg && matchReg.test(filepath)) {
15 | return false;
16 | }
17 | // exclude node_modules as default
18 | return /node_modules/.test(filepath);
19 | };
20 |
21 | ['jsx', 'tsx'].forEach((rule) => {
22 | config.module
23 | .rule(rule)
24 | .exclude.clear()
25 | .add(matchExclude);
26 | });
27 | };
28 |
--------------------------------------------------------------------------------
/packages/plugin-core/src/module.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import { ErrorBoundary } from '$ice/components';
3 |
4 | const module = ({ addProvider, appConfig, wrapperRouteComponent }) => {
5 | const { ErrorBoundaryFallback, onErrorBoundaryHander } = appConfig.app;
6 |
7 | const wrapperComponent = (PageComponent) => {
8 | const { pageConfig = {} } = PageComponent;
9 | const StoreWrapperedComponent = (props) => {
10 | if (pageConfig.errorBoundary) {
11 | return (
12 |
13 |
14 |
15 | );
16 | }
17 | return ;
18 | };
19 | return StoreWrapperedComponent;
20 | };
21 |
22 | wrapperRouteComponent(wrapperComponent);
23 | if (appConfig.app && appConfig.app.addProvider) {
24 | addProvider(appConfig.app.addProvider);
25 | }
26 | };
27 |
28 | export default module;
29 |
--------------------------------------------------------------------------------
/examples/basic-mpa/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "buildOnSave": false,
4 | "compilerOptions": {
5 | "baseUrl": ".",
6 | "outDir": "build",
7 | "module": "esnext",
8 | "target": "es6",
9 | "jsx": "react",
10 | "moduleResolution": "node",
11 | "allowSyntheticDefaultImports": true,
12 | "lib": [
13 | "es6",
14 | "dom"
15 | ],
16 | "sourceMap": true,
17 | "allowJs": true,
18 | "rootDir": "./",
19 | "forceConsistentCasingInFileNames": true,
20 | "noImplicitReturns": true,
21 | "noImplicitThis": true,
22 | "noImplicitAny": false,
23 | "importHelpers": true,
24 | "strictNullChecks": true,
25 | "suppressImplicitAnyIndexErrors": true,
26 | "noUnusedLocals": true,
27 | "skipLibCheck": true,
28 | "paths": {
29 | "@/*": [
30 | "./src/*"
31 | ],
32 | "ice": [
33 | ".ice/index.ts"
34 | ],
35 | "ice/*": [
36 | ".ice/pages/*"
37 | ]
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/examples/basic-rml/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "buildOnSave": false,
4 | "compilerOptions": {
5 | "baseUrl": ".",
6 | "outDir": "build",
7 | "module": "esnext",
8 | "target": "es6",
9 | "jsx": "react",
10 | "moduleResolution": "node",
11 | "allowSyntheticDefaultImports": true,
12 | "lib": ["es6", "dom"],
13 | "sourceMap": true,
14 | "allowJs": true,
15 | "rootDir": "./",
16 | "forceConsistentCasingInFileNames": true,
17 | "noImplicitReturns": true,
18 | "noImplicitThis": true,
19 | "noImplicitAny": false,
20 | "importHelpers": true,
21 | "strictNullChecks": true,
22 | "suppressImplicitAnyIndexErrors": true,
23 | "noUnusedLocals": true,
24 | "skipLibCheck": true,
25 | "paths": {
26 | "@/*": ["./src/*"],
27 | "ice": [".ice/index.ts"],
28 | "ice/*": [".ice/pages/*"]
29 | }
30 | },
31 | "include": ["src/*", ".ice", "src/components/Guide"],
32 | "exclude": ["node_modules", "build", "public"]
33 | }
--------------------------------------------------------------------------------
/examples/basic-spa/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "buildOnSave": false,
4 | "compilerOptions": {
5 | "baseUrl": ".",
6 | "outDir": "build",
7 | "module": "esnext",
8 | "target": "es6",
9 | "jsx": "react",
10 | "moduleResolution": "node",
11 | "allowSyntheticDefaultImports": true,
12 | "lib": [
13 | "es6",
14 | "dom"
15 | ],
16 | "sourceMap": true,
17 | "allowJs": true,
18 | "rootDir": "./",
19 | "forceConsistentCasingInFileNames": true,
20 | "noImplicitReturns": true,
21 | "noImplicitThis": true,
22 | "noImplicitAny": false,
23 | "importHelpers": true,
24 | "strictNullChecks": true,
25 | "suppressImplicitAnyIndexErrors": true,
26 | "noUnusedLocals": true,
27 | "skipLibCheck": true,
28 | "paths": {
29 | "@/*": [
30 | "./src/*"
31 | ],
32 | "ice": [
33 | ".ice/index.ts"
34 | ],
35 | "ice/*": [
36 | ".ice/pages/*"
37 | ]
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/examples/basic-ssr/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "buildOnSave": false,
4 | "compilerOptions": {
5 | "baseUrl": ".",
6 | "outDir": "build",
7 | "module": "esnext",
8 | "target": "es6",
9 | "jsx": "react",
10 | "moduleResolution": "node",
11 | "allowSyntheticDefaultImports": true,
12 | "lib": [
13 | "es6",
14 | "dom"
15 | ],
16 | "sourceMap": true,
17 | "allowJs": true,
18 | "rootDir": "./",
19 | "forceConsistentCasingInFileNames": true,
20 | "noImplicitReturns": true,
21 | "noImplicitThis": true,
22 | "noImplicitAny": false,
23 | "importHelpers": true,
24 | "strictNullChecks": true,
25 | "suppressImplicitAnyIndexErrors": true,
26 | "noUnusedLocals": true,
27 | "skipLibCheck": true,
28 | "paths": {
29 | "@/*": [
30 | "./src/*"
31 | ],
32 | "ice": [
33 | ".ice/index.ts"
34 | ],
35 | "ice/*": [
36 | ".ice/pages/*"
37 | ]
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/examples/basic-request/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "buildOnSave": false,
4 | "compilerOptions": {
5 | "baseUrl": ".",
6 | "outDir": "build",
7 | "module": "esnext",
8 | "target": "es6",
9 | "jsx": "react",
10 | "moduleResolution": "node",
11 | "allowSyntheticDefaultImports": true,
12 | "lib": ["es6", "dom"],
13 | "sourceMap": true,
14 | "allowJs": true,
15 | "rootDir": "./",
16 | "forceConsistentCasingInFileNames": true,
17 | "noImplicitReturns": true,
18 | "noImplicitThis": true,
19 | "noImplicitAny": false,
20 | "importHelpers": true,
21 | "strictNullChecks": true,
22 | "suppressImplicitAnyIndexErrors": true,
23 | "noUnusedLocals": true,
24 | "skipLibCheck": true,
25 | "paths": {
26 | "@/*": ["./src/*"],
27 | "ice": [".ice/index.ts"],
28 | "ice/*": [".ice/pages/*"]
29 | }
30 | },
31 | "include": ["src/*", ".ice", "src/components/Guide"],
32 | "exclude": ["node_modules", "build", "public"]
33 | }
--------------------------------------------------------------------------------
/examples/basic-store/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "buildOnSave": false,
4 | "compilerOptions": {
5 | "baseUrl": ".",
6 | "outDir": "build",
7 | "module": "esnext",
8 | "target": "es6",
9 | "jsx": "react",
10 | "moduleResolution": "node",
11 | "allowSyntheticDefaultImports": true,
12 | "lib": ["es6", "dom"],
13 | "sourceMap": true,
14 | "allowJs": true,
15 | "rootDir": "./",
16 | "forceConsistentCasingInFileNames": true,
17 | "noImplicitReturns": true,
18 | "noImplicitThis": true,
19 | "noImplicitAny": false,
20 | "importHelpers": true,
21 | "strictNullChecks": true,
22 | "suppressImplicitAnyIndexErrors": true,
23 | "noUnusedLocals": true,
24 | "skipLibCheck": true,
25 | "paths": {
26 | "@/*": ["./src/*"],
27 | "ice": [".ice/index.ts"],
28 | "ice/*": [".ice/pages/*"]
29 | }
30 | },
31 | "include": ["src/*", ".ice", "src/components/Guide"],
32 | "exclude": ["node_modules", "build", "public"]
33 | }
--------------------------------------------------------------------------------
/examples/hello-world/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "buildOnSave": false,
4 | "compilerOptions": {
5 | "baseUrl": ".",
6 | "outDir": "build",
7 | "module": "esnext",
8 | "target": "es6",
9 | "jsx": "react",
10 | "moduleResolution": "node",
11 | "allowSyntheticDefaultImports": true,
12 | "lib": ["es6", "dom"],
13 | "sourceMap": true,
14 | "allowJs": true,
15 | "rootDir": "./",
16 | "forceConsistentCasingInFileNames": true,
17 | "noImplicitReturns": true,
18 | "noImplicitThis": true,
19 | "noImplicitAny": false,
20 | "importHelpers": true,
21 | "strictNullChecks": true,
22 | "suppressImplicitAnyIndexErrors": true,
23 | "noUnusedLocals": true,
24 | "skipLibCheck": true,
25 | "paths": {
26 | "@/*": ["./src/*"],
27 | "ice": [".ice/index.ts"],
28 | "ice/*": [".ice/pages/*"]
29 | }
30 | },
31 | "include": ["src/*", ".ice", "src/components/Guide"],
32 | "exclude": ["node_modules", "build", "public"]
33 | }
--------------------------------------------------------------------------------
/examples/icestark-child/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "buildOnSave": false,
4 | "compilerOptions": {
5 | "baseUrl": ".",
6 | "outDir": "build",
7 | "module": "esnext",
8 | "target": "es6",
9 | "jsx": "react",
10 | "moduleResolution": "node",
11 | "allowSyntheticDefaultImports": true,
12 | "lib": [
13 | "es6",
14 | "dom"
15 | ],
16 | "sourceMap": true,
17 | "allowJs": true,
18 | "rootDir": "./",
19 | "forceConsistentCasingInFileNames": true,
20 | "noImplicitReturns": true,
21 | "noImplicitThis": true,
22 | "noImplicitAny": false,
23 | "importHelpers": true,
24 | "strictNullChecks": true,
25 | "suppressImplicitAnyIndexErrors": true,
26 | "noUnusedLocals": true,
27 | "skipLibCheck": true,
28 | "paths": {
29 | "@/*": [
30 | "./src/*"
31 | ],
32 | "ice": [
33 | ".ice/index.ts"
34 | ]
35 | }
36 | },
37 | "include": [
38 | ".ice",
39 | "src"
40 | ]
41 | }
42 |
--------------------------------------------------------------------------------
/examples/basic-service/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "buildOnSave": false,
4 | "compilerOptions": {
5 | "baseUrl": ".",
6 | "outDir": "build",
7 | "module": "esnext",
8 | "target": "es6",
9 | "jsx": "react",
10 | "moduleResolution": "node",
11 | "allowSyntheticDefaultImports": true,
12 | "lib": ["es6", "dom"],
13 | "sourceMap": true,
14 | "allowJs": true,
15 | "rootDir": "./",
16 | "forceConsistentCasingInFileNames": true,
17 | "noImplicitReturns": true,
18 | "noImplicitThis": true,
19 | "noImplicitAny": false,
20 | "importHelpers": true,
21 | "strictNullChecks": true,
22 | "suppressImplicitAnyIndexErrors": true,
23 | "noUnusedLocals": true,
24 | "skipLibCheck": true,
25 | "paths": {
26 | "@/*": ["./src/*"],
27 | "ice": [".ice/index.ts"],
28 | "ice/*": [".ice/pages/*"],
29 | "$ice/*": [".ice/*"]
30 | }
31 | },
32 | "include": ["src/*", ".ice", "src/components/Guide"],
33 | "exclude": ["node_modules", "build", "public"]
34 | }
35 |
--------------------------------------------------------------------------------
/packages/plugin-react-app/src/userConfig/hash.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const formatWinPath = require('../utils/formatWinPath');
3 |
4 | module.exports = (config, hash, context) => {
5 | const { command } = context;
6 | // default is false
7 | if (hash) {
8 | // can not use [chunkhash] or [contenthash] for chunk in dev mode
9 | const hashStr = typeof hash === 'boolean' || command === 'start' ? 'hash:6' : hash;
10 | const fileName = config.output.get('filename');
11 | let pathArray = fileName.split('/');
12 | pathArray.pop(); // pop filename
13 | pathArray = pathArray.filter((v) => v);
14 | const outputPath = pathArray.length ? pathArray.join('/') : '';
15 | config.output.filename(formatWinPath(path.join(outputPath, `[name].[${hashStr}].js`)));
16 | if (config.plugins.get('MiniCssExtractPlugin')) {
17 | config.plugin('MiniCssExtractPlugin').tap((args) => [Object.assign(...args, {
18 | filename: formatWinPath(path.join(outputPath, `[name].[${hashStr}].css`)),
19 | })]);
20 | }
21 | }
22 | };
23 |
--------------------------------------------------------------------------------
/packages/plugin-helpers/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "build-plugin-ice-helpers",
3 | "version": "1.2.1",
4 | "description": "builtin helpers in icejs",
5 | "author": "ice-admin@alibaba-inc.com",
6 | "homepage": "",
7 | "license": "MIT",
8 | "main": "lib/index.js",
9 | "directories": {
10 | "lib": "lib",
11 | "test": "__tests__"
12 | },
13 | "files": [
14 | "lib",
15 | "helpers"
16 | ],
17 | "dependencies": {
18 | "@types/cookie": "^0.3.3",
19 | "@types/url-parse": "^1.4.3",
20 | "cookie": "^0.4.0",
21 | "fs-extra": "^8.1.0",
22 | "url-parse": "^1.4.7"
23 | },
24 | "devDependencies": {
25 | "@alib/build-scripts": "^0.1.13",
26 | "@types/fs-extra": "^8.0.1",
27 | "@types/glob": "^7.1.1",
28 | "@types/node": "^12.12.12",
29 | "typescript": "^3.7.2"
30 | },
31 | "publishConfig": {
32 | "registry": "http://registry.npmjs.com/"
33 | },
34 | "scripts": {
35 | "test": "echo \"Error: run tests from root\" && exit 1"
36 | },
37 | "gitHead": "07ac7bb07162aac8c90778dd1de4a2060f8df498"
38 | }
39 |
--------------------------------------------------------------------------------
/examples/basic-spa/src/pages/About/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Link, lazy, ErrorBoundary } from 'ice';
3 |
4 | const Todo = lazy(() => import('./components/Todo'));
5 | const Child = lazy(() => import('./components/Child'));
6 |
7 | const MyFallbackComponent = () => (
8 |
9 |
Oops! An error occured!
10 |
Here’s what we know…
11 |
12 | );
13 |
14 | const About = () => {
15 | const myErrorHandler = (error: Error, componentStack: string) => {
16 | // Do something with the error
17 | // E.g. log to an error logging client here
18 | console.log({error, componentStack});
19 | };
20 |
21 | return (
22 | <>
23 | About Page
24 |
25 |
26 |
27 |
28 |
29 |
30 | dashboard
31 | Home
32 | >
33 | );
34 | };
35 |
36 | export default About;
37 |
--------------------------------------------------------------------------------
/scripts/fn/getPackages.ts:
--------------------------------------------------------------------------------
1 |
2 | /* eslint no-restricted-syntax:0, no-await-in-loop:0, no-restricted-syntax:0 */
3 | import * as path from 'path';
4 | import * as fse from 'fs-extra';
5 | import * as _glob from 'glob';
6 | import * as pify from 'pify';
7 |
8 | const glob = pify(_glob);
9 |
10 | export default async function getPackages() {
11 | const packageNames = [];
12 | const packageDirs = [];
13 | const rootPkgPath = path.join(__dirname, '../../package.json');
14 | const rootPkgContent = fse.readJSONSync(rootPkgPath);
15 |
16 | for (const workspace of rootPkgContent.workspaces || []) {
17 | const dirs = await glob(workspace);
18 | for (const dir of dirs) {
19 | if (fse.existsSync(path.resolve(dir, 'package.json'))) {
20 | const pkgContent = fse.readJSONSync(path.resolve(dir, 'package.json'));
21 | packageNames.push(pkgContent.name);
22 | packageDirs.push(path.resolve(dir));
23 | } else {
24 | console.warn('Invalid workspace package:', dir);
25 | }
26 | }
27 | }
28 |
29 | return { packageNames, packageDirs };
30 | }
31 |
--------------------------------------------------------------------------------
/packages/plugin-request/src/module.ts:
--------------------------------------------------------------------------------
1 | import axiosInstance from '$ice/axiosInstance';
2 |
3 | const module = ({ appConfig }) => {
4 | if (appConfig.request) {
5 | const { request = {} } = appConfig;
6 | const { interceptors = {}, ...requestOptions } = request;
7 |
8 | Object.keys(requestOptions).forEach(key => {
9 | axiosInstance.defaults[key] = requestOptions[key];
10 | });
11 |
12 | // Add a request interceptor
13 | if (interceptors.request) {
14 | axiosInstance.interceptors.request.use(
15 | interceptors.request.onConfig || function(config){ return config; },
16 | interceptors.request.onError || function(error) { return Promise.reject(error); }
17 | );
18 | }
19 |
20 | // Add a response interceptor
21 | if (interceptors.response) {
22 | axiosInstance.interceptors.response.use(
23 | interceptors.response.onConfig || function(response){ return response; },
24 | interceptors.response.onError || function(error){ return Promise.reject(error); }
25 | );
26 | }
27 | }
28 | };
29 |
30 | export default module;
31 |
--------------------------------------------------------------------------------
/packages/plugin-core/src/utils/generateExports.ts:
--------------------------------------------------------------------------------
1 | import { IExportData } from '../types/base';
2 |
3 | function generateExports(exportList: IExportData[]) {
4 | const importStatements = [];
5 | const exportStatements = [];
6 | const extraExportStatements = [];
7 | exportList.forEach(data => {
8 | const { specifier, source, exportName, extraExport = false } = data;
9 | if (exportName && source) {
10 | const symbol = source.includes('types') ? ';' : ',';
11 | importStatements.push(`import ${specifier || exportName} from '${source}';`);
12 | const exportStr = `${exportName}${symbol}`;
13 | if (extraExport) {
14 | extraExportStatements.push(exportStr);
15 | } else {
16 | exportStatements.push(exportStr);
17 | }
18 | } else if (source) {
19 | importStatements.push(`export ${specifier || '*'} from '${source}';`);
20 | }
21 | });
22 | return {
23 | importStr: importStatements.join('\n'),
24 | exportStr: exportStatements.join('\n'),
25 | extraStr: extraExportStatements.join('\n')
26 | };
27 | }
28 |
29 | export default generateExports;
30 |
--------------------------------------------------------------------------------
/packages/plugin-request/src/index.ts:
--------------------------------------------------------------------------------
1 | import * as path from 'path';
2 | import * as fse from 'fs-extra';
3 |
4 | export default async function (api) {
5 | const { getValue, applyMethod, onGetWebpackConfig } = api;
6 | const srcPath = path.join(__dirname, '..', 'request');
7 | const distPath = path.join(getValue('ICE_TEMP'), 'request');
8 |
9 | // move requst to .ice/request
10 | await fse.copy(srcPath, distPath);
11 | await fse.copy(path.join(__dirname, 'types'), path.join(distPath, 'types'));
12 | // .ice/index.ts:
13 | // export * from './request';
14 | applyMethod('addIceExport', { source: './request/request', exportName: 'request' });
15 | applyMethod('addIceExport', { source: './request/useRequest', exportName: 'useRequest' });
16 |
17 | // add iceTypes exports
18 | applyMethod('addIceAppConfigTypes', { source: './request/types', specifier: '{ IRequest }', exportName: 'request?: IRequest' });
19 |
20 | onGetWebpackConfig((config) => {
21 | // add alias for module.ts use $ice/axiosInstance
22 | config.resolve.alias.set('$ice/axiosInstance', path.join(distPath, 'axiosInstance.ts'));
23 | });
24 | }
25 |
--------------------------------------------------------------------------------
/packages/plugin-router/src/types/router.ts:
--------------------------------------------------------------------------------
1 | import { History } from 'history';
2 | import { IgnoreOptions } from './collector';
3 | import { IRouterConfig } from '.';
4 | import { RouteItemProps } from './base';
5 |
6 | export interface RouterProps {
7 | routes: RouteItemProps[];
8 | type?: 'hash' | 'browser' | 'memory' | 'static';
9 | // common props for BrowserRouter & HashRouter & MemoryRouter
10 | basename?: string;
11 | getUserConfirmation?: ((message: string, callback: (ok: boolean) => void) => void);
12 | forceRefresh?: boolean;
13 | // for BrowserRouter
14 | keyLength?: number;
15 | // for HashRouter
16 | hashType?: 'slash' | 'noslash' | 'hashbang';
17 | // for MemoryRouter
18 | initialEntries?: string[];
19 | initialIndex?: number;
20 | fallback?: React.ReactNode;
21 | history: History;
22 | };
23 |
24 | export interface RoutesProps {
25 | routes: IRouterConfig[];
26 | fallback?: React.ReactNode;
27 | };
28 |
29 | export interface IRouterOptions {
30 | caseSensitive?: boolean;
31 | ignoreRoutes?: IgnoreOptions;
32 | ignorePaths?: IgnoreOptions;
33 | configPath?: string;
34 | lazy?: boolean;
35 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT LICENSE
2 |
3 | Copyright (c) 2018-present Alibaba Inc.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining
6 | a copy of this software and associated documentation files (the
7 | "Software"), to deal in the Software without restriction, including
8 | without limitation the rights to use, copy, modify, merge, publish,
9 | distribute, sublicense, and/or sell copies of the Software, and to
10 | permit persons to whom the Software is furnished to do so, subject to
11 | the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be
14 | included in all copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 |
--------------------------------------------------------------------------------
/packages/plugin-react-app/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "build-plugin-react-app",
3 | "version": "1.2.1",
4 | "description": "The basic webpack configuration for ice project",
5 | "author": "ice-admin@alibaba-inc.com",
6 | "main": "src/index.js",
7 | "scripts": {
8 | "test": "echo \"Error: no test specified\" && exit 1"
9 | },
10 | "keywords": [
11 | "plugin",
12 | "react"
13 | ],
14 | "license": "MIT",
15 | "dependencies": {
16 | "@alifd/fusion-collector": "^1.2.5",
17 | "@babel/plugin-transform-runtime": "^7.6.2",
18 | "build-scripts-config": "^0.1.0",
19 | "copy-webpack-plugin": "^5.0.4",
20 | "core-js": "^3.3.1",
21 | "eslint-loader": "^4.0.0",
22 | "fs-extra": "^8.1.0",
23 | "html-webpack-plugin": "^3.2.0",
24 | "lodash": "^4.17.15",
25 | "mkcert": "^1.2.0",
26 | "path-exists": "^4.0.0",
27 | "react-dev-utils": "^9.1.0",
28 | "regenerator-runtime": "^0.13.3",
29 | "webpack-bundle-analyzer": "^3.6.0",
30 | "webpack-dev-mock": "^0.1.5"
31 | },
32 | "devDependencies": {
33 | "webpack": "^4.41.1"
34 | },
35 | "gitHead": "07ac7bb07162aac8c90778dd1de4a2060f8df498"
36 | }
37 |
--------------------------------------------------------------------------------
/packages/plugin-icestark/src/index.ts:
--------------------------------------------------------------------------------
1 | import * as path from 'path';
2 | import * as glob from 'glob';
3 | import * as fse from 'fs-extra';
4 | import { IPlugin } from '@alib/build-scripts';
5 |
6 | const plugin: IPlugin = async ({ onGetWebpackConfig, getValue, applyMethod, context }) => {
7 | const { rootDir } = context;
8 | const iceTempPath = getValue('ICE_TEMP');
9 |
10 | const hasDefaultLayout = glob.sync(`${path.join(rootDir, 'src/layouts/index')}.@(ts?(x)|js?(x))`).length;
11 | onGetWebpackConfig((config) => {
12 | // set alias for default layout
13 | config.resolve.alias.set('$ice/Layout', hasDefaultLayout ? path.join(rootDir, 'src/layouts') : path.join(__dirname, 'runtime/Layout'));
14 | // set alias for icestark
15 | ['@ice/stark', '@ice/stark-app'].forEach((pkgName) => {
16 | config.resolve.alias.set(pkgName, require.resolve(pkgName));
17 | });
18 | });
19 |
20 | await fse.copy(path.join(__dirname, '..', 'src/types/index.ts'), path.join(iceTempPath, 'types/icestark.ts'));
21 | applyMethod('addIceAppConfigTypes', { source: './types/icestark', specifier: '{ IIceStark }', exportName: 'icestark?: IIceStark' });
22 | };
23 |
24 | export default plugin;
25 |
--------------------------------------------------------------------------------
/examples/basic-service/src/pages/Home/components/User/service.ts:
--------------------------------------------------------------------------------
1 | import { createService } from 'ice';
2 |
3 | export interface GetUserParams {
4 | id: string;
5 | }
6 |
7 | export interface GetTodoParams {
8 | id: string;
9 | }
10 |
11 | export interface Todo {
12 | id: string;
13 | title: string;
14 | done: boolean;
15 | }
16 |
17 | export interface User {
18 | id: string;
19 | name: string;
20 | age: number;
21 | }
22 |
23 | interface Types {
24 | getTodo(params: GetTodoParams): Todo;
25 | getUser(params: GetUserParams): User;
26 | }
27 |
28 | const getTodo = {
29 | options: {
30 | url: '/todo_getOne',
31 | },
32 | };
33 |
34 | const getUser = {
35 | isInit: true,
36 | options: {
37 | url: '/user_getOne',
38 | },
39 | };
40 |
41 | export default createService(
42 | {
43 | getTodo,
44 | getUser,
45 | },
46 | {
47 | options: {
48 | timeout: 3000,
49 | },
50 | dataHandler(response) {
51 | if (response.success) {
52 | return response.data;
53 | } else {
54 | console.error(response.errorMsg);
55 | }
56 | }
57 | },
58 | function(dataMap) {
59 | return dataMap.user;
60 | }
61 | );
62 |
--------------------------------------------------------------------------------
/packages/plugin-react-app/src/userConfig/babelPresets.js:
--------------------------------------------------------------------------------
1 | const formatWinPath = require('../utils/formatWinPath');
2 |
3 | module.exports = (config, babelPresets) => {
4 | ['jsx', 'tsx'].forEach((rule) => {
5 | config.module
6 | .rule(rule)
7 | .use('babel-loader')
8 | .tap((options) => {
9 | let extraPresets = [...babelPresets];
10 | const presets = options.presets.map((preset) => {
11 | const [presetPath] = Array.isArray(preset) ? preset : [preset];
12 | let matchedPreset = null;
13 | extraPresets = extraPresets.filter((babelPreset) => {
14 | const matched = formatWinPath(presetPath).indexOf(Array.isArray(babelPreset) ? babelPreset[0] : babelPreset) > -1;
15 | if (matched) {
16 | matchedPreset = babelPreset;
17 | }
18 | return !matched;
19 | });
20 | // replace current preset if match
21 | return matchedPreset || preset ;
22 | });
23 |
24 | return {
25 | ...options,
26 | presets: [
27 | ...presets,
28 | ...extraPresets,
29 | ],
30 | };
31 | });
32 | });
33 | };
--------------------------------------------------------------------------------
/examples/basic-store/src/pages/About/index.tsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect } from 'react';
2 | import { Link, store as appStore } from 'ice';
3 | import { store as pageStore } from 'ice/About';
4 |
5 | const About = (props) => {
6 | console.log(props);
7 | const [userState, userActions] = appStore.useModel('user');
8 | const [pageState, pageActions] = pageStore.useModel('default');
9 | const actionsState = appStore.useModelEffectsState('user');
10 |
11 | useEffect(() => {
12 | const fetchData = async () => {
13 | await pageActions.getPageTitle();
14 | await userActions.getUserInfo();
15 | };
16 |
17 | fetchData();
18 | }, [pageActions, userActions]);
19 |
20 | return (
21 | <>
22 | {pageState.title}
23 |
24 | {
25 | actionsState.getUserInfo.isLoading
26 | ? loading...
27 | :
28 |
Name: {userState.name}
29 |
id: {userState.id}
30 |
31 | }
32 |
33 | home
34 | >
35 | );
36 | };
37 |
38 | About.pageConfig = {
39 | title: 'About'
40 | };
41 |
42 | export default About;
43 |
--------------------------------------------------------------------------------
/examples/basic-ssr/src/pages/Home/index.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from 'react';
2 | import { request, Link, logger, store as appStore } from 'ice';
3 | import styles from './index.module.scss';
4 |
5 | export default function Home(props) {
6 | logger.info('Home props', props);
7 |
8 | const [dataSource, setData] = useState([]);
9 | useEffect(() => {
10 | setTimeout(() => {
11 | setData([4, 5, 6, 7]);
12 | }, 1 * 1000);
13 | }, []);
14 |
15 | const [userState] = appStore.useModel('user');
16 |
17 | return (
18 | <>
19 | {props.title}
20 |
21 |
name: {userState.name}
22 |
id: {userState.id}
23 |
address: {props.profile && props.profile.address}
24 |
data: {dataSource.join(' ')}
25 |
26 |
27 | about
28 | dashboard
29 | >
30 | );
31 | }
32 |
33 | Home.getInitialProps = async () => {
34 | const res = await request('/profile');
35 | return { ...res.data, title: 'Home Page...' };
36 | };
37 |
--------------------------------------------------------------------------------
/packages/plugin-core/src/utils/getRoutes.ts:
--------------------------------------------------------------------------------
1 | import * as path from 'path';
2 | import * as fse from 'fs-extra';
3 |
4 | interface IParams {
5 | rootDir: string;
6 | tempDir: string;
7 | configPath: string;
8 | projectType: string;
9 | isMpa: boolean;
10 | }
11 |
12 | interface IResult {
13 | routesPath: string;
14 | isConfigRoutes: boolean;
15 | }
16 |
17 | function getRoutes({ rootDir, tempDir, configPath, projectType, isMpa }: IParams): IResult {
18 | // if is mpa use empty router file
19 | if (isMpa) {
20 | const routesTempPath = path.join(tempDir, 'routes.ts');
21 | fse.writeFileSync(routesTempPath, 'export default [];', 'utf-8');
22 | configPath = routesTempPath;
23 | }
24 |
25 | const routesPath = configPath
26 | ? path.join(rootDir, configPath)
27 | : path.join(rootDir, `src/routes.${projectType}`);
28 |
29 | // 配置式路由
30 | const configPathExists = fse.existsSync(routesPath);
31 | if (configPathExists) {
32 | return {
33 | routesPath,
34 | isConfigRoutes: true
35 | };
36 | }
37 |
38 | // 约定式路由
39 | return {
40 | routesPath: path.join(tempDir, `routes.${projectType}`),
41 | isConfigRoutes: false
42 | };
43 | }
44 |
45 | export default getRoutes;
46 |
--------------------------------------------------------------------------------
/packages/plugin-router/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "build-plugin-ice-router",
3 | "version": "1.2.1",
4 | "description": "build-plugin-ice-router",
5 | "author": "ice-admin@alibaba-inc.com",
6 | "homepage": "",
7 | "license": "MIT",
8 | "main": "lib/index.js",
9 | "directories": {
10 | "lib": "lib",
11 | "test": "__tests__"
12 | },
13 | "dependencies": {
14 | "fs-extra": "^8.1.0",
15 | "glob": "^7.1.6",
16 | "history": "^4.10.1",
17 | "query-string": "^6.12.1",
18 | "react": "^16.12.0",
19 | "react-dom": "^16.12.0",
20 | "react-router-dom": "^5.1.2"
21 | },
22 | "devDependencies": {
23 | "@alib/build-scripts": "^0.1.13",
24 | "@types/fs-extra": "^8.0.1",
25 | "@types/glob": "^7.1.1",
26 | "@types/history": "^4.7.5",
27 | "@types/node": "^12.12.12",
28 | "@types/react-router-dom": "^5.1.4",
29 | "typescript": "^3.7.2"
30 | },
31 | "files": [
32 | "lib",
33 | "src/types",
34 | "templates"
35 | ],
36 | "publishConfig": {
37 | "registry": "http://registry.npmjs.com/"
38 | },
39 | "scripts": {
40 | "test": "echo \"Error: run tests from root\" && exit 1"
41 | },
42 | "gitHead": "6bbf8de986f2e6d4820c2dc7f92fa87d917b23f7"
43 | }
44 |
--------------------------------------------------------------------------------
/packages/icejs/bin/test.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | const parse = require('yargs-parser');
3 | const { test } = require('@alib/build-scripts');
4 | const log = require('@alib/build-scripts/lib/utils/log');
5 | const getBuiltInPlugins = require('../lib/index');
6 |
7 | module.exports = async () => {
8 | process.env.NODE_ENV = 'test';
9 | const rawArgv = parse(process.argv.slice(3), {
10 | configuration: { 'strip-dashed': true },
11 | });
12 | const jestArgv = {};
13 | // get jest options
14 | Object.keys(rawArgv).forEach(key => {
15 | if (key.indexOf('jest') === 0) {
16 | // transform jest-config to config
17 | const jestKey = key.replace('jest', '');
18 | jestArgv[`${jestKey[0].toLowerCase()}${jestKey.slice(1)}`] = rawArgv[key];
19 | delete rawArgv[key];
20 | }
21 | });
22 |
23 | // filter out objects
24 | const args = rawArgv._.filter(x => rawArgv[x] === undefined);
25 | if (args && args.length > 0) {
26 | jestArgv.regexForTestFiles = args;
27 | }
28 | delete rawArgv._;
29 | try {
30 | await test({
31 | args: { ...rawArgv, jestArgv },
32 | getBuiltInPlugins,
33 | });
34 | } catch (err) {
35 | log.error(err.message);
36 | console.error(err);
37 | process.exit(1);
38 | }
39 | };
40 |
--------------------------------------------------------------------------------
/examples/basic-request/src/pages/Home/index.tsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect } from 'react';
2 | import { useRequest, request } from 'ice';
3 |
4 | // 1. request in outside
5 | request('/user').then(res => console.log('request in outside:', res));
6 |
7 | const Home = () => {
8 | // 2. useRequest hook
9 | const { data, loading, request: fetchRepo } = useRequest({ url: '/repo' });
10 |
11 | useEffect(() => {
12 | fetchRepo();
13 |
14 | // 3. requse.get alias
15 | request.get('/user').then(res => console.log('get:', res));
16 |
17 | // 4. requse.post alias
18 | request.post('/users/123').then(res => console.log('post:', res));
19 |
20 | // 5. requse.delete alias
21 | request.delete('/user/123').then(res => console.log('delete:', res));
22 |
23 | // 6. request method
24 | request({ url: '/user'}).then((res) => {console.log('request:', res);});
25 |
26 | }, [fetchRepo]);
27 |
28 | return (
29 |
30 |
data fetching with icejs
31 |
32 | {
33 | loading ?
34 |
loading...
:
35 | <>
36 |
repo name: {data && data.name}
37 |
repo url: {data && data.url}
38 | >
39 | }
40 |
41 | );
42 | };
43 |
44 | export default Home;
45 |
--------------------------------------------------------------------------------
/examples/basic-service/src/services/todo.ts:
--------------------------------------------------------------------------------
1 | import { createService } from 'ice';
2 |
3 | export interface GetOneParams {
4 | id: string;
5 | }
6 |
7 | export interface AddParams {
8 | title: string;
9 | done?: boolean;
10 | }
11 |
12 | export interface OriginTodo {
13 | id: string;
14 | title: string;
15 | done: boolean;
16 | label?: string;
17 | }
18 |
19 | export interface Todo extends OriginTodo {
20 | label: string;
21 | }
22 |
23 | export type Todos = OriginTodo[];
24 |
25 | function transformTodo(todo: OriginTodo): Todo {
26 | return {
27 | ...todo,
28 | label: todo.done ? '已完成' : '未完成',
29 | };
30 | }
31 |
32 | interface Types {
33 | getOne(params: GetOneParams): Todo;
34 | getAll(): Todos;
35 | add(params: AddParams): Todo;
36 | }
37 |
38 | const getAll = {
39 | options: {
40 | url: '/todo_getAll',
41 | },
42 | };
43 |
44 | const getOne = {
45 | options: {
46 | url: '/todo_getOne',
47 | },
48 | dataHandle: transformTodo,
49 | };
50 |
51 | const add = {
52 | options: {
53 | url: '/todo_add',
54 | method: 'post',
55 | },
56 | dataHandle: transformTodo,
57 | };
58 |
59 | export default createService(
60 | {
61 | getOne,
62 | getAll,
63 | add,
64 | },
65 | {
66 | dataHandler(response) {
67 | return response.data;
68 | }
69 | }
70 | );
71 |
--------------------------------------------------------------------------------
/packages/icejs/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ice.js",
3 | "version": "1.2.1",
4 | "description": "command line interface and builtin plugin for icejs",
5 | "author": "ice-admin@alibaba-inc.com",
6 | "homepage": "",
7 | "license": "MIT",
8 | "files": [
9 | "bin",
10 | "lib"
11 | ],
12 | "bin": {
13 | "icejs": "./bin/ice-cli.js"
14 | },
15 | "main": "lib/index.js",
16 | "publishConfig": {
17 | "registry": "http://registry.npmjs.com/"
18 | },
19 | "scripts": {
20 | "test": "echo \"Error: run tests from root\" && exit 1"
21 | },
22 | "dependencies": {
23 | "@alib/build-scripts": "^0.1.13",
24 | "build-plugin-ice-config": "1.2.1",
25 | "build-plugin-ice-core": "1.2.1",
26 | "build-plugin-ice-helpers": "1.2.1",
27 | "build-plugin-ice-logger": "1.2.1",
28 | "build-plugin-ice-mpa": "1.2.1",
29 | "build-plugin-ice-request": "1.2.1",
30 | "build-plugin-ice-router": "1.2.1",
31 | "build-plugin-ice-ssr": "1.2.1",
32 | "build-plugin-ice-store": "1.2.1",
33 | "build-plugin-react-app": "1.2.1",
34 | "chokidar": "^3.3.1",
35 | "commander": "^5.0.0",
36 | "detect-port": "^1.3.0",
37 | "inquirer": "^7.1.0",
38 | "yargs-parser": "^18.1.2"
39 | },
40 | "engines": {
41 | "node": ">=8.6.0",
42 | "npm": ">=3.0.0"
43 | },
44 | "gitHead": "cf40d079714b437417e77b444b078cf83286f2fc"
45 | }
46 |
--------------------------------------------------------------------------------
/packages/plugin-config/src/index.ts:
--------------------------------------------------------------------------------
1 | import * as path from 'path';
2 | import * as fse from 'fs-extra';
3 | import { IPlugin } from '@alib/build-scripts';
4 |
5 | const plugin: IPlugin = async (api): Promise => {
6 | const { context, getValue, applyMethod } = api;
7 | const { command, rootDir } = context;
8 |
9 | const configFile = `src/config.${getValue('PROJECT_TYPE')}`;
10 |
11 | async function generateConfig() {
12 | const exportName = 'config';
13 | const filePath = path.join(rootDir,configFile);
14 | const distPath = path.join(getValue('ICE_TEMP'), 'config.ts');
15 | if (fse.existsSync(filePath)) {
16 | const srcPath = path.join(__dirname, '..', 'config', 'index.ts');
17 |
18 | await fse.copy(srcPath, distPath);
19 | // add to ice exports
20 | applyMethod('addIceExport', { source: './config', exportName });
21 | } else {
22 | // remove config file
23 | applyMethod('removeIceExport', exportName);
24 | fse.removeSync(distPath);
25 | }
26 | }
27 |
28 | generateConfig();
29 | if (command === 'start') {
30 | // watch folder config file is remove or added
31 | applyMethod('watchFileChange', configFile, async (event: string) => {
32 | if (event === 'unlink' || event === 'add') {
33 | await generateConfig();
34 | }
35 | });
36 | }
37 | };
38 |
39 | export default plugin;
40 |
--------------------------------------------------------------------------------
/packages/plugin-router/src/module.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import defaultRoutes from '$ice/routes';
3 | import { IceRouter } from './runtime/Router';
4 | import formatRoutes, { wrapperPageWithCSR, wrapperPageWithSSR } from './runtime/formatRoutes';
5 |
6 | const module = ({ setRenderRouter, appConfig, modifyRoutes, wrapperRouteComponent, buildConfig, context }) => {
7 | const { router: appConfigRouter = {} } = appConfig;
8 |
9 | // plugin-router 内置确保了 defaultRoutes 最先被添加
10 | modifyRoutes(() => {
11 | return formatRoutes(appConfigRouter.routes || defaultRoutes, '');
12 | });
13 |
14 | const wrapperPageFn = process.env.__IS_SERVER__ ? wrapperPageWithSSR(context, defaultRoutes, appConfig) : wrapperPageWithCSR(appConfig);
15 | wrapperRouteComponent(wrapperPageFn);
16 | if (appConfigRouter.modifyRoutes) {
17 | modifyRoutes(appConfigRouter.modifyRoutes);
18 | }
19 |
20 | const lazy = buildConfig.router && buildConfig.router.lazy;
21 | const renderRouter = (routes) => () => {
22 | let routerProps = {
23 | ...appConfigRouter,
24 | routes,
25 | lazy
26 | };
27 |
28 | if (process.env.__IS_SERVER__) {
29 | const { pathname, staticContext = {} } = context;
30 | routerProps = Object.assign({}, routerProps, { location: pathname, context: staticContext });
31 | }
32 |
33 | return ;
34 | };
35 | setRenderRouter(renderRouter);
36 | };
37 |
38 | export default module;
39 |
--------------------------------------------------------------------------------
/packages/plugin-icestark/README.md:
--------------------------------------------------------------------------------
1 | # plugin-icestark
2 |
3 | > Easy use `rematch` in icejs.
4 |
5 | ## Usage
6 |
7 | ### Framework Application
8 |
9 | Through `appConfig` configuration of your framework application.
10 |
11 | ```js
12 | const appConfig = {
13 | ...
14 | icestark: {
15 | type: 'framework',
16 | getApps: () => {
17 | return [{
18 | path: '/seller',
19 | title: '商家平台',
20 | url: [
21 | '//ice.alicdn.com/icestark/child-seller-react/index.js',
22 | '//ice.alicdn.com/icestark/child-seller-react/index.css',
23 | ],
24 | }];
25 | },
26 | },
27 | };
28 | ```
29 |
30 | **Options:**
31 |
32 | - `type`: config framework to enable Framework application
33 | - `getApps`: get sub-application information, support async function
34 | - `appRouter`
35 | - `ErrorComponent`: error component
36 | - `LoadingComponent`: loading component
37 | - `NotFoundComponent`: 404 not found component
38 | - `shouldAssetsRemove`
39 | - `removeRoutesLayout`: remove global Layout when config `true`
40 | - `AppRoute`: custom AppRoute component
41 | - `Layout`: specify Framework application Layout, use `layouts/index` as default if exisit
42 |
43 | ### Sub-application
44 |
45 | modify `appConfig`:
46 |
47 | ```js
48 | // app.ts
49 | const appConfig = {
50 | ...
51 | icestark: {
52 | type: 'child',
53 | },
54 | };
55 | ```
56 |
57 | **Options:**
58 | - `type`: config `child` to enable Sub-application
59 |
--------------------------------------------------------------------------------
/.github/GIT_COMMIT_SPECIFIC.md:
--------------------------------------------------------------------------------
1 | # GIT COMMIT MESSAGE CHEAT SHEET
2 |
3 | **Proposed format of the commit message**
4 |
5 | ```
6 | :
7 |
8 |
9 | ```
10 |
11 | All lines are wrapped at 100 characters !
12 |
13 | **Allowed ``**
14 |
15 | - feat (A new feature)
16 | - fix (A bug fix)
17 | - docs (Documentation only changes)
18 | - style (Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc))
19 | - perf (A code change that improves performance)
20 | - refactor (A code change that neither fixes a bug nor adds a feature)
21 | - test (Adding missing tests or correcting existing tests)
22 | - build (Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm))
23 | - ci (Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs))
24 | - chore (Other changes that don't modify src or test files)
25 | - revert (Reverts a previous commit)
26 | - release (Relase version)
27 |
28 |
29 | **Breaking changes**
30 |
31 | All breaking changes have to be mentioned in message body, on separated line:
32 |
33 | _Breaks removed $browser.setUrl() method (use $browser.url(newUrl))_
34 | _Breaks ng: repeat option is no longer supported on selects (use ng:options)_
35 |
36 | **Message body**
37 |
38 | - uses the imperative, present tense: “change” not “changed” nor “changes”
39 | - includes motivation for the change and contrasts with previous behavior
40 |
--------------------------------------------------------------------------------
/packages/plugin-request/README.md:
--------------------------------------------------------------------------------
1 | # plugin-ice-request
2 |
3 | use `request` or `useRequest` in icejs.
4 |
5 | ## Install
6 |
7 | ```bash
8 | $ npm i --save build-plugin-ice-request
9 | ```
10 |
11 | Add plugin to `build.json`:
12 |
13 | ```json
14 | {
15 | "plugins": [
16 | "build-plugin-ice-request"
17 | ]
18 | }
19 | ```
20 |
21 | Set runtime options to `src/index.ts`:
22 |
23 | ```js
24 | import { createApp } from 'ice';
25 |
26 | const appConfig = {
27 | request: {
28 | // ref: https://github.com/axios/axios#request-config
29 | ...config,
30 | // ref: https://github.com/axios/axios#interceptors
31 | interceptors: {
32 | request: {
33 | onConfig: (config) => {},
34 | onError: (error) => {}
35 | },
36 | response: {
37 | onConfig: (config) => {},
38 | onError: (error) => {}
39 | },
40 | }
41 | }
42 | };
43 |
44 | createApp(appConfig);
45 | ```
46 |
47 | ## Usage
48 |
49 | ### request
50 |
51 | ```ts
52 | import { request } from 'ice'
53 |
54 | request('/api/repo')
55 | .then(res => console.log(res))
56 | .catch(err => console.log(err))
57 | ```
58 |
59 | ### useRequest
60 |
61 | ```ts
62 | import { useRequest } from 'ice'
63 |
64 | const View = () => {
65 | const { loading, error, data, request } = useRequest({
66 | url: '/api/list',
67 | method: 'GET',
68 | })
69 |
70 | const list = data ? data.list : [];
71 |
72 | useEffect(() => {
73 | request();
74 | }, []);
75 |
76 | return (
77 | // do somethings
78 | )
79 | }
80 | ```
81 | ## License
82 |
83 | MIT
84 |
--------------------------------------------------------------------------------
/examples/basic-spa/mock/index.js:
--------------------------------------------------------------------------------
1 | const projects = [
2 | {
3 | id: 1,
4 | name: 'facebook/react',
5 | description: 'A declarative, efficient, and flexible JavaScript library for building user interfaces',
6 | logo: 'https://avatars3.githubusercontent.com/u/69631',
7 | },
8 | {
9 | id: 2,
10 | name: 'vuejs/vue',
11 | description: 'Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web. ',
12 | logo: 'https://avatars1.githubusercontent.com/u/6128107',
13 | },
14 | {
15 | id: 3,
16 | name: 'angular/angular',
17 | description: 'One framework. Mobile & desktop. ',
18 | logo: 'https://avatars3.githubusercontent.com/u/139426',
19 | },
20 | {
21 | id: 4,
22 | name: 'nuxt/nuxt.js',
23 | description: 'The Vue.js Framework',
24 | logo: 'https://avatars2.githubusercontent.com/u/23360933',
25 | },
26 | {
27 | id: 5,
28 | name: 'zeit/next.js',
29 | description: 'The React Framework',
30 | logo: 'https://avatars0.githubusercontent.com/u/14985020',
31 | },
32 | {
33 | id: 6,
34 | name: 'ice-lab/nice.js',
35 | description: 'A universal framework based on React.js.',
36 | logo: 'https://avatars1.githubusercontent.com/u/1961952',
37 | },
38 | ];
39 |
40 | // mock/index.js
41 | module.exports = {
42 | 'GET /api/repo': {
43 | status: 'SUCCESS',
44 | data: {
45 | group: 'ice.js',
46 | url: 'http://github.com/ice-lab/ice.js'
47 | }
48 | },
49 |
50 | 'GET /api/projects': {
51 | status: 'SUCCESS',
52 | data: projects
53 | }
54 | };
55 |
--------------------------------------------------------------------------------
/packages/plugin-store/README.md:
--------------------------------------------------------------------------------
1 | # plugin-store
2 |
3 | builtin `icestore` in icejs
4 |
5 | ## Usage
6 |
7 | ### Directory structure
8 |
9 | ```markdown
10 | src
11 | ├── models // global models
12 | │ └── user.ts
13 | └── pages
14 | ├── About
15 | │ ├── index.tsx
16 | │ └── model.ts // single model
17 | ├── Dashboard
18 | │ ├── analysis.tsx
19 | │ ├── index.tsx
20 | │ └── models // multi models
21 | │ ├── modelA.ts
22 | │ └── modelB.ts
23 | └── index.tsx
24 | ```
25 |
26 | ### Define a model
27 |
28 | ```ts
29 | // src/models/user.ts
30 | export default {
31 | state: {
32 | user: {}
33 | },
34 |
35 | actions: {
36 | getUserInfo: async () => {}
37 | }
38 | };
39 |
40 | ```
41 |
42 | ### With Component
43 |
44 | ```ts
45 | import { store } from 'ice/Home'
46 |
47 | const View = () => {
48 | const [state, actions] = store.useModel('user')
49 | // do something...
50 | }
51 | ```
52 |
53 | ### Config
54 |
55 | Set global `initialstates` to `src/app.ts`:
56 |
57 | ```ts
58 | import { createApp } from 'ice'
59 |
60 | const appConfig = {
61 | // Set global initialstates
62 | store: {
63 | initialStates: {}
64 | }
65 | }
66 | ```
67 |
68 | Set page `initialstates` to `src/pages/*/index.tsx`:
69 |
70 | ```ts
71 | const HomePage = () => {
72 | return (
73 | <>
74 | HomePage
75 | >
76 | )
77 | }
78 |
79 | HomePage.pageConfig = {
80 | // Set page initialstates
81 | initialstates: {}
82 | }
83 | ```
84 |
85 | [More](https://github.com/ice-lab/icestore)
86 |
--------------------------------------------------------------------------------
/packages/plugin-react-app/src/config/default.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | alias: {},
3 | define: {},
4 | devPublicPath: '/',
5 | filename: '[name].js',
6 | // resolve.extensions
7 | extensions: ['.js', '.jsx', '.json', '.html', '.ts', '.tsx'],
8 | // resolve.modules
9 | modules: ['node_modules'],
10 | devServer: {
11 | disableHostCheck: true,
12 | compress: true,
13 | clientLogLevel: 'none',
14 | logLevel: 'silent',
15 | hot: true,
16 | publicPath: '/',
17 | quiet: false,
18 | watchOptions: {
19 | ignored: /node_modules/,
20 | aggregateTimeout: 600,
21 | },
22 | before(app) {
23 | app.use((req, res, next) => {
24 | // set cros for all served files
25 | res.set('Access-Control-Allow-Origin', '*');
26 | next();
27 | });
28 | },
29 | },
30 | mock: true,
31 | entry: 'src/index.jsx',
32 | externals: {},
33 | hash: false,
34 | injectBabel: 'polyfill',
35 | minify: true,
36 | outputAssetsPath: {
37 | js: 'js',
38 | css: 'css',
39 | },
40 | outputDir: 'build',
41 | proxy: {},
42 | publicPath: '/',
43 | targets: 'last 2 versions, Firefox ESR, > 1%, ie >= 9, iOS >= 8, Android >= 4',
44 | vendor: true,
45 | libraryTarget: '',
46 | library: '',
47 | libraryExport: '',
48 | ignoreHtmlTemplate: false,
49 | sourcemap: false,
50 | terserOptions: {},
51 | cssLoaderOptions: {},
52 | lessLoaderOptions: {},
53 | sassLoaderOptions: {},
54 | postcssrc: false,
55 | compileDependencies: [],
56 | babelPlugins: [],
57 | babelPresets: [],
58 | eslint: false
59 | };
60 |
--------------------------------------------------------------------------------
/packages/plugin-react-app/src/userConfig/proxy.js:
--------------------------------------------------------------------------------
1 | const merge = require('lodash/merge');
2 |
3 | module.exports = (config, proxyConfig) => {
4 | const proxyRules = Object.entries(proxyConfig);
5 | if (proxyRules.length) {
6 | const proxy = proxyRules.map(([match, opts]) => {
7 | // set enable false to disable proxy rule
8 | const { enable, target, ...proxyRule } = opts;
9 | if (enable !== false) {
10 | return merge({
11 | target,
12 | changeOrigin: true,
13 | logLevel: 'warn',
14 | onProxyRes: function onProxyReq(proxyRes, req) {
15 | proxyRes.headers['x-proxy-by'] = 'ice-proxy';
16 | proxyRes.headers['x-proxy-match'] = match;
17 | proxyRes.headers['x-proxy-target'] = target;
18 |
19 | let distTarget = target;
20 | if (target && target.endsWith('/')) {
21 | distTarget = target.replace(/\/$/, '');
22 | }
23 | proxyRes.headers['x-proxy-target-path'] = distTarget + req.url;
24 | },
25 | onError: function onError(err, req, res) {
26 | // proxy server error can't trigger onProxyRes
27 | res.writeHead(500, {
28 | 'x-proxy-by': 'ice-proxy',
29 | 'x-proxy-match': match,
30 | 'x-proxy-target': target,
31 | });
32 | res.end(`proxy server error: ${err.message}`);
33 | },
34 | }, proxyRule, { context: match });
35 | }
36 | return false;
37 | }).filter((v) => v);
38 | config.devServer.proxy(proxy);
39 | }
40 | };
41 |
--------------------------------------------------------------------------------
/packages/plugin-rematch/src/index.ts:
--------------------------------------------------------------------------------
1 | import * as path from 'path';
2 | import generateStore from './generateStore';
3 |
4 | export default async function ({
5 | context,
6 | getValue,
7 | applyMethod,
8 | onHook,
9 | onGetWebpackConfig,
10 | }) {
11 | const { rootDir } = context;
12 | const targetPath = path.join(getValue('ICE_TEMP'), 'store.ts');
13 | const templatePath = path.join(__dirname, './template/store.ts.ejs');
14 | const storesDir = path.join(rootDir, 'src/stores');
15 |
16 | onGetWebpackConfig((config: any) => {
17 | // add alias for module.ts use $ice/helpers
18 | config.resolve.alias.set('$ice/store', targetPath);
19 | });
20 |
21 | handleStoresDirChange(targetPath, templatePath, storesDir, applyMethod);
22 | onHook('before.start.run', async () => {
23 | applyMethod('watchFileChange', /stores\/.*/, (event, filePath) => {
24 | if (event === 'unlink' || event === 'add') {
25 | console.log(`[stores ${event}]`, filePath);
26 | handleStoresDirChange(targetPath, templatePath, storesDir, applyMethod);
27 | }
28 | });
29 | });
30 | }
31 |
32 | async function handleStoresDirChange(targetPath, templatePath, storesDir, applyMethod) {
33 | // 生成 .ice/store.ts
34 | await generateStore(targetPath, templatePath, storesDir);
35 |
36 | // .ice/index.ts: export connect for view
37 | // import { connect } from 'react-redux';
38 | // export { connect }
39 | // remove connect before add in case of dir change
40 | applyMethod('removeIceExport', 'connect');
41 | applyMethod('addIceExport', { source: 'react-redux', specifier: '{ connect }', exportName: 'connect' });
42 | }
43 |
--------------------------------------------------------------------------------
/examples/icestark-layout/src/app.tsx:
--------------------------------------------------------------------------------
1 | import { createApp, IAppConfig } from 'ice';
2 | import * as React from 'react';
3 | import { ConfigProvider } from '@alifd/next';
4 |
5 | const appConfig: IAppConfig = {
6 | app: {
7 | rootId: 'ice-container',
8 | addProvider: ({ children }) => (
9 | {children}
10 | ),
11 | },
12 | logger: {
13 | level: 'warn'
14 | },
15 | router: {
16 | type: 'browser',
17 | },
18 | icestark: {
19 | type: 'framework',
20 | getApps: async () => {
21 | const apps = await new Promise((resolve) => {
22 | setTimeout(() => {
23 | resolve([
24 | {
25 | path: '/seller',
26 | title: '商家平台',
27 | url: [
28 | '//ice.alicdn.com/icestark/child-seller-react/index.js',
29 | '//ice.alicdn.com/icestark/child-seller-react/index.css',
30 | // '//127.0.0.1:3444/js/index.js',
31 | // '//127.0.0.1:3444/css/index.css',
32 | ],
33 | },
34 | {
35 | path: '/waiter',
36 | title: '小二平台',
37 | url: [
38 | '//ice.alicdn.com/icestark/child-waiter-vue/app.js',
39 | '//ice.alicdn.com/icestark/child-waiter-vue/app.css',
40 | // '//localhost:8080/app.js',
41 | // '//localhost:8080/css/app.css',
42 | ],
43 | },
44 | ]);
45 | }, 1000);
46 | });
47 | return apps;
48 | },
49 | removeRoutesLayout: true,
50 | },
51 | };
52 |
53 | createApp(appConfig);
54 |
--------------------------------------------------------------------------------
/packages/icejs/bin/child-process-start.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | const detect = require('detect-port');
3 | const inquirer = require('inquirer');
4 | const parse = require('yargs-parser');
5 | const { start } = require('@alib/build-scripts');
6 | const log = require('@alib/build-scripts/lib/utils/log');
7 | const getBuiltInPlugins = require('../lib/index');
8 |
9 | const rawArgv = parse(process.argv.slice(2), {
10 | configuration: { 'strip-dashed': true },
11 | });
12 |
13 | const DEFAULT_PORT = rawArgv.port || process.env.PORT || 3333;
14 | const defaultPort = parseInt(DEFAULT_PORT, 10);
15 |
16 | (async () => {
17 | let newPort = await detect(defaultPort);
18 | if (newPort !== defaultPort) {
19 | const question = {
20 | type: 'confirm',
21 | name: 'shouldChangePort',
22 | message: `${defaultPort} 端口已被占用,是否使用 ${newPort} 端口启动?`,
23 | default: true,
24 | };
25 | const answer = await inquirer.prompt(question);
26 | if (!answer.shouldChangePort) {
27 | newPort = null;
28 | }
29 | }
30 | if (newPort === null) {
31 | process.exit(1);
32 | }
33 |
34 | process.env.NODE_ENV = 'development';
35 | rawArgv.port = parseInt(newPort, 10);
36 |
37 | // ignore _ in rawArgv
38 | delete rawArgv._;
39 | try {
40 | const devServer = await start({
41 | args: { ...rawArgv },
42 | getBuiltInPlugins,
43 | });
44 |
45 | ['SIGINT', 'SIGTERM'].forEach(function(sig) {
46 | process.on(sig, function() {
47 | devServer.close();
48 | process.exit(0);
49 | });
50 | });
51 | } catch (err) {
52 | log.error(err.message);
53 | console.error(err);
54 | process.exit(1);
55 | }
56 | })();
57 |
--------------------------------------------------------------------------------
/packages/icejs/bin/ice-cli.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | const program = require('commander');
3 | const checkNodeVersion = require('@alib/build-scripts/lib/utils/checkNodeVersion');
4 | const packageInfo = require('../package.json');
5 | const build = require('./build');
6 | const start = require('./start');
7 | const test = require('./test');
8 |
9 | (async () => {
10 | console.log(packageInfo.name, packageInfo.version);
11 | // finish check before run command
12 | checkNodeVersion(packageInfo.engines.node);
13 |
14 | program
15 | .version(packageInfo.version)
16 | .usage(' [options]');
17 |
18 | program
19 | .command('build')
20 | .description('build project')
21 | .allowUnknownOption()
22 | .option('--config ', 'use custom config')
23 | .action(build);
24 |
25 | program
26 | .command('start')
27 | .description('start server')
28 | .allowUnknownOption()
29 | .option('--config ', 'use custom config')
30 | .option('-h, --host ', 'dev server host', '0.0.0.0')
31 | .option('-p, --port ', 'dev server port')
32 | .action(start);
33 |
34 | program
35 | .command('test')
36 | .description('run tests with jest')
37 | .allowUnknownOption() // allow jest config
38 | .option('--config ', 'use custom config')
39 | .action(test);
40 |
41 | program.parse(process.argv);
42 |
43 | const proc = program.runningCommand;
44 |
45 | if (proc) {
46 | proc.on('close', process.exit.bind(process));
47 | proc.on('error', () => {
48 | process.exit(1);
49 | });
50 | }
51 |
52 | const subCmd = program.args[0];
53 | if (!subCmd) {
54 | program.help();
55 | }
56 | })();
57 |
--------------------------------------------------------------------------------
/packages/plugin-react-app/src/utils/getCertificate.js:
--------------------------------------------------------------------------------
1 | const mkcert = require('mkcert');
2 | const fs = require('fs-extra');
3 | const path = require('path');
4 |
5 | const rootDirPath = path.resolve(__dirname, '../ICE_CA');
6 |
7 | function generateCA() {
8 | return new Promise((resolve, reject) => {
9 | mkcert.createCA({
10 | organization: 'ICE Team',
11 | countryCode: 'CN',
12 | state: 'ZJ',
13 | locality: 'HZ',
14 | validityDays: 3650,
15 | }).then((ca) => {
16 | if (!fs.existsSync(rootDirPath)) {
17 | // create ICE_CA folder if not exists
18 | fs.mkdirSync(rootDirPath);
19 | }
20 | const keyPath = path.join(rootDirPath, 'rootCa.key');
21 | const certPath = path.join(rootDirPath, 'rootCa.crt');
22 | fs.writeFileSync(keyPath, ca.key);
23 | fs.writeFileSync(certPath, ca.cert);
24 | resolve({
25 | key: keyPath,
26 | cert: certPath,
27 | });
28 | }).catch((err) => {
29 | reject(err);
30 | });
31 | });
32 | }
33 |
34 | module.exports = async function getCertificate() {
35 | const certPath = path.join(rootDirPath, 'rootCa.crt');
36 | const keyPath = path.join(rootDirPath, 'rootCa.key');
37 | if (!fs.existsSync(certPath) || !fs.existsSync(keyPath)) {
38 | await generateCA();
39 | }
40 | console.log('当前使用的 HTTPS 证书路径(如有需要请手动信任此文件)');
41 | console.log(' ', certPath);
42 | return new Promise((resolve, reject) => {
43 | mkcert.createCert({
44 | domains: ['127.0.0.1', 'localhost'],
45 | validityDays: 365,
46 | caKey: fs.readFileSync(keyPath),
47 | caCert: fs.readFileSync(certPath),
48 | }).then(resolve).catch(reject);
49 | });
50 | };
51 |
--------------------------------------------------------------------------------
/packages/plugin-service/README.md:
--------------------------------------------------------------------------------
1 | # plugin-service
2 |
3 | use `createService` in icejs.
4 |
5 | ## Install
6 |
7 | ```bash
8 | $ npm i --save build-plugin-ice-service
9 | ```
10 |
11 | Add plugin to `build.json`:
12 |
13 | ```json
14 | {
15 | "plugins": [
16 | "build-plugin-ice-service"
17 | ]
18 | }
19 | ```
20 |
21 | ## Usage
22 |
23 | create a service:
24 |
25 | ```ts
26 | // src/services/todos
27 | import { createService } from 'ice';
28 |
29 | export interface GetOneParams {
30 | id: string;
31 | }
32 |
33 | export interface OriginTodo {
34 | id: string;
35 | title: string;
36 | done: boolean;
37 | label?: string;
38 | }
39 |
40 | export interface Todo extends OriginTodo {
41 | label: string;
42 | }
43 |
44 | function transformTodo(todo: OriginTodo): Todo {
45 | return {
46 | ...todo,
47 | label: todo.done ? '已完成' : '未完成',
48 | };
49 | }
50 |
51 | interface Types {
52 | getOne(params: GetOneParams): Todo;
53 | }
54 |
55 | const getOne = {
56 | options: {
57 | url: '/todo',
58 | },
59 | dataHandle: transformTodo,
60 | };
61 |
62 | export default createService(
63 | {
64 | getOne,
65 | },
66 |
67 | // default config
68 | {
69 | options: {
70 | method: 'get',
71 | },
72 | }
73 | );
74 | ```
75 |
76 | use service:
77 |
78 | ```js
79 | import todosService from '@/services/todos';
80 |
81 | export default {
82 | state: {
83 | todos: []
84 | },
85 | reducers: {
86 | addOne(prevState, todo) {
87 | prevState.todos.push(todo);
88 | }
89 | },
90 | effects: (dispatch) => {
91 | async add(id) {
92 | const todo = await todosService.getOne({ id });
93 | this.addOne(todo);
94 | }
95 | }
96 | }
97 | ```
98 |
--------------------------------------------------------------------------------