skyl
安装
特点
- 快速刷新(Fast Refresh)
- 约定式路由(支持动态路由、路由懒加载)
- Mock 数据(支持文件上传)
- 包按需引入(支持swc)
- 模块联邦
- 微前端(qiankun)
- 自动装卸的 redux 模版
- 自动装卸的国际化模版
- 移动端
- 编译 apk、ipa
- 支持切换 swc | tsc 构建
快速开始
# 安装脚手架工具
npm i skyl -g
创建一个新项目
skyl create demo-project # 项目名 demo-project
? 请输入开发者名称? skyl
? 您想创建一个什么类型的项目呢? 移动端 H5应用(mobile)
? 请选择需要开启的开发辅助功能 (Press <space> to select, <a> to toggle all, <i> to invert selection, and <ente? 请选择需要开启的开发辅助功能 css代码规范, javascript代码规范
fetching plugin-runtime: ^1.0.30
fetching stylelint-config-neko: ^1.0.0
fetching eslint-config-neko: ^1.0.1
# 创建完成
cd ./demo-project
npm install
npm start
开始开发
cd 项目名称
# 安装依赖
npm i
# 启动项目
npm start
# 编译项目 (编译前跳过 lint: skyl build site no-verify)
npm run build
项目结构
./
├── config 脚手架自定义配置
├── mock 自定义mock脚本
├── src 源码
├── components 组件目录
├── locales 国际化配置
├── models redux 模块化配置
├── pages 页面路由组件
├── router 自定义路由配置
├── services 数据请求脚本
├── styles 公共样式表
├── mixins less:全局mixins(不需要引入)
├── variables less:全局变量(不需要引入)
├── index.global.less 全局样式表(不需要引入)
├── reset.less 重置样式表(不需要引入)
├── utils 工具脚本
└── index.ts 初始化时会执行的脚本
├── typings 全局类型定义
├── .gitignore git过滤项
├── .prettierignore prettier过滤项
├── .stylelintrc.yaml stylelint配置项
├── .eslintrc.yaml eslint配置项
├── .prettierrc.yaml prettier配置项
├── package.json 包依赖配置
├── README.md 项目说明文档
└── tsconfig.json typescript配置项
配置
// config/index.ts
import type { PartialConfigType } from 'plugin-runtime';
import { packageJson } from 'plugin-runtime/build/common';
const config: PartialConfigType<'swc'> = {
/** 编译器 */
compiler: 'swc',
/** swc 配置项,仅当编译器为 swc 时有效 */
swcrc: {},
/**
* 自定义entry
* 当你需要添加一些polyfill函数时可在这里添加
* 比如兼容es10的object.fromentries:
* @example
* ```
* const config = {
* entry: {
* polyfillObjectFromentries: 'polyfill-object.fromentries'
* }
* }
* ```
**/
entry: {},
/** 压缩配置 */
minifier: {
type: 'terser',
},
/** 环境变量, 可通过 process.env 获取 */
env: {},
/** mini-idc 数据持久化配置, 为 false 时关闭持久化 */
miniIdc: {
/** 持久化数据使用的key, 当key为 'none' 时, 关闭持久化 */
programName: 'programName',
/** 持久化数据是否加密 */
encrypt: false,
/** 自定义RSA加密密钥 */
// encryptKey: ''
},
/** 路径别名映射 */
alias: {},
/** 设计图尺寸 默认: 1680 */
designSize: 1680,
/** 自定义降级组件 */
fallbackCompPath: null,
/** less 全局变量 */
modifyVars: {},
/** antd 主题配置 */
antdThemeVariables: {
compact: false,
dark: false,
};
/** 类名前缀 */
prefixCls: 'skl',
/** 是否需要左侧菜单栏 仅 type: back-stage 时有效 */
layoutHasSider: false,
/** 自定义 webpack module rules */
moduleRules: [],
/** node_modules中, 需要开启 cssModules 的模块 */
cssModules: [],
/** 开发服务器代理 */
proxy: {},
/** 网站徽标 */
favicon: 'public/favicon.ico',
/** 自定义缓存目录,为 false 时,不使用缓存 */
cacheDirectory: false,
/** 开发服务器设置 */
devServer: {
port: 3000,
};
/** 自定义插入 html 的 js 和 css */
assetHtml: [
{
// 自动加入 public 文件夹下 满足 *.entry.js 的文件
glob: './public/*.entry.js',
},
{
// antd 原始类名 兜底
glob: './public/*.entry.css',
typeOfAsset: 'css',
},
],
/** 路由模式 默认 browser */
routerMode: 'hash',
/** webpack 插件 */
plugins: [],
/** 通过Web字体加载加载的字体 */
webFontLoader: [],
/** 编译输出路径 */
output: path.join(__dirname, `./dist/`),
/** 模块联邦 */
moduleFederation: [
{
name: 'pkg_name',
// 接入远程 'shared_library' 模块
remotes: [
{
name: 'shared_library',
host: '[window.__MicroAppEntry__.shared_library]',
// 声明从 shared_library 这个远程模块加载的依赖
library: ['react', 'react-dom'],
},
],
// 将本项目的 Button 组件共享出去,其他项目接入 'pkg_name' 模块,可通过 import Button from 'pkg_name/Button'; 使用
exposes: [
{
name: 'Button',
path: './components/button/index.tsx',
},
],
},
],
// swc 的按需导入配置如下,tsc按需导入参考 ts-import-plugin
importOnDemand: {
antd: ['[source]/es/[name:-]', '[source]/es/[name:-]/style'],
lodash: '[source]/[name]',
'skyline-ui': '[source]/es/[name:-]',
'skyline-business': '[source]/es/[name:-]',
'@ant-design/icons': {
transform: ({ name, source }) => {
if (name === 'createFromIconfontCN') {
return `${source}/es/components/IconFont`;
}
return `${source}/es/icons/${name}`;
},
},
},
};
export default config;
自定义模块解析规则
// config/index.ts
export default {
moduleRules: [
{
test: /\.md$/,
type: 'assets',
exclude: [/node_modules/],
},
],
};
模块按需引入配置
// config/index.ts
export default {
// 模块按需引入配置 例如:
importOnDemand: [
{
libraryName: '@antv/x6-react-components',
libraryDirectory: 'es',
style: true,
transformToDefaultImport: false,
},
],
};
开发环境请求代理配置
// config/index.ts
export default {
proxy: [
{
context: ['/api/'],
target: 'http://***.***.***.***:****/',
changeOrigin: true,
pathRewrite: { '^/api/': '/' },
secure: false,
},
],
};
自定义 ts-loader 配置
在项目根目录下创建一个 tsloader.config.ts
// tsloader.config.ts
export default = {};
国际化配置
通过在 src/locales 目录下创建一个 ts 或 js 文件来描述
// src/locales/zh-CN.ts
import type { LocalesConfType } from 'plugin-runtime';
const zhCN: LocalesConfType = {
namespace: 'zh_CN',
title: '简体中文',
translation: {
'route-home': '主页',
},
};
export default zhCN;
如何使用?
import React from 'react';
import { useLocale } from 'plugin-runtime';
const Test: React.FC = () => {
const { getLanguage } = useLocale();
return <div>{getLanguage('unknown')}</div>;
};
export default Test;
redux model
只需在 src/models 目录下新建 符合规则的 js 文件即可
如何使用?
-
创建一个角色 model
import { loginByUserName } from '@/services/user'; const model: ModelType<UserModelType> = { // model名称,view层用于提取state的key,需要保证唯一 namespace: 'user', // 初始state状态 state: {}, effects: { // 用户名登录 --> 请求远程数据 *fetchLoginByUserName({ payload }, { call, put, select }) { // 在 effects 中读取state?使用 select 获取 const resp = yield call(() => loginByUserName(payload.data)); yield put({ type: 'user/saveUserInfo', payload: resp.result, }); }, }, reducers: { // 通过 user/saveUserInfo 调用 saveUserInfo(state, action) { return { ...state, info: action.payload }; }, logout() { return {}; }, }, }; export default model;
-
在页面或组件中使用
import React from 'react';
import { useDispatch, useSelector, shallowEqual } from 'plugin-runtime';
const Test: React.FC = () => {
const userInfo = useSelector((state) => state.user.info, shallowEqual);
const dispatch = useDispatch();
return (
<div onClick={() => dispatch({ type: 'user/logout' })}>
登录
{userInfo}
</div>
);
};
export default Test;
编译 app
需安装 flutter 环境
skyl buildApp
? 请输入软件包名称? com.myoucai.bid ## 默认值
? 请选择需要打包的类型 打包为apk (release)
❯◉ 打包为apk (release) # 方向上下键选择条目,按空格键选中,回车键确认
◯ 打包为apk (debug)
◯ 打包为ipa (release)[未签名,需要 OSX 及 Xcode]
◯ 打包为ipa (debug)[未签名,需要 OSX 及 Xcode]
# ...
Running Gradle task 'assembleRelease'... 27.7s
✓ Built build/app/outputs/flutter-apk/app-release.apk (15.8MB).
Done