{"id":15020092,"url":"https://github.com/lyfeyaj/ewa","last_synced_at":"2025-04-09T09:04:04.836Z","repository":{"id":49257445,"uuid":"138582241","full_name":"lyfeyaj/ewa","owner":"lyfeyaj","description":"Enhanced Wechat App Development Toolkit (微信小程序增强开发工具)。不同于 wepy 或者 mpvue，是一个轻量级小程序开发框架。支持原生小程序所有功能，无需学习，极易上手。支持转换为百度/字节跳动/QQ/支付宝小程序。","archived":false,"fork":false,"pushed_at":"2021-07-06T12:49:11.000Z","size":2175,"stargazers_count":181,"open_issues_count":0,"forks_count":26,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-04-02T08:11:34.611Z","etag":null,"topics":["ewa","mpvue","promise","wechat-app","wechat-mini-program","wepy","wxss-scss"],"latest_commit_sha":null,"homepage":"https://ewa.js.org","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lyfeyaj.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-06-25T10:53:05.000Z","updated_at":"2025-01-20T07:07:18.000Z","dependencies_parsed_at":"2022-09-04T15:04:46.587Z","dependency_job_id":null,"html_url":"https://github.com/lyfeyaj/ewa","commit_stats":null,"previous_names":[],"tags_count":111,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lyfeyaj%2Fewa","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lyfeyaj%2Fewa/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lyfeyaj%2Fewa/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lyfeyaj%2Fewa/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lyfeyaj","download_url":"https://codeload.github.com/lyfeyaj/ewa/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248008628,"owners_count":21032556,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ewa","mpvue","promise","wechat-app","wechat-mini-program","wepy","wxss-scss"],"created_at":"2024-09-24T19:54:34.765Z","updated_at":"2025-04-09T09:04:04.817Z","avatar_url":"https://github.com/lyfeyaj.png","language":"JavaScript","readme":"EWA (微信小程序增强开发工具)\n=========================\n\nEnhanced Wechat App Development Toolkit (微信小程序增强开发工具)\n\n## 为什么开发这个工具？\n\n厌倦了不停的对比 [taro](https://github.com/NervJS/taro)、[wepy](https://github.com/Tencent/wepy) 或者 [mpvue](https://github.com/Meituan-Dianping/mpvue) 的特性，间歇性的踩雷，构建和运行速度慢以及 `code once, run everywhere` 的幻想。只想给小程序开发插上效率的翅膀 ~\n\n## 功能特性\n\n1. Async/Await 支持\n2. Javascript ES2020 语法\n3. 原生小程序所有功能，无需学习，极易上手\n4. 微信接口 Promise 化\n5. 支持安装 NPM 包\n6. 支持 SCSS(或 LESS) 以及 小于 16k 的 background-image\n7. 支持 source map, 方便调试\n8. 添加新页面或新组件无需重启编译\n9. 允许自定义编译流程\n10. 自动兼容旧版本手机中的显示样式\n11. 支持 WXSS 和 SCSS(或 LESS) 混用\n12. 代码混淆及高度压缩，节省包大小\n13. Typescript 支持\n14. 支持转换成 百度 / 字节跳动 / QQ / 支付宝小程序\n15. 多种小程序开发插件，为小程序开发减负，解放生产力\n\n[更多特性正在赶来 ... 敬请期待](./TODOS.md)\n\n## 安装\n\n***需要 node 版本 \u003e= 10.13***\n\n```bash\nnpm i -g ewa-cli 或者 yarn global add ewa-cli\n```\n\n## 如何使用\n\n### 创建新项目\n\n```bash\newa new your_project_name\n```\n\n### 集成到现有小程序项目，仅支持小程序原生开发项目转换\n\n***注意：使用此方法，请务必对项目代码做好备份！！！***\n\n```bash\ncd your_project_dir \u0026\u0026 ewa init\n```\n\n### 启动\n\n运行 `npm start` 即可启动实时编译\n\n运行 `npm run build` 即可编译线上版本（相比实时编译而言，去除了 source map 并增加了代码压缩混淆等，体积更小）\n\n上述命令运行成功后，可以看到本地多了个 `dist` 目录，这个目录里就是生成的小程序相关代码。\n\n使用[微信开发者工具](https://mp.weixin.qq.com/debug/wxadoc/dev/devtools/devtools.html)选择 `dist` 目录打开，即可预览项目\n\n### 目录结构\n\n```\n├── .ewa                         特殊占位目录，用于检查是否为 ewa 项目\n├── dist                         小程序运行代码目录（该目录由ewa的start 或者 build指令自动编译生成，请不要直接修改该目录下的文件）\n├── node_modules                 外部依赖库\n├── src                          代码编写的目录（该目录为使用ewa后的开发目录）\n│   ├── components               小程序组件目录\n│   ├── pages                    小程序页面目录\n│   │   ├── index\n│   │   │   ├── index.js\n│   │   │   ├── index.wxml\n│   │   │   └── index.wxss\n│   │   └── logs\n│   │       ├── logs.js\n│   │       ├── logs.json\n│   │       ├── logs.wxml\n│   │       └── logs.wxss\n│   ├── templates                小程序模版目录\n│   ├── utils\n│   │   └── util.js\n│   ├── app.js                   小程序入口文件\n│   ├── app.json                 小程序全局配置文件\n│   ├── app.wxss                 小程序全局样式文件\n│   └── project.config.json      微信开发者工具小程序项目配置文件\n├── ewa.config.js                ewa 配置文件\n├── .gitignore\n├── .eslintrc.js                 eslint 配置\n└── package.json\n```\n\n### 命令行说明\n\n#### 概览\n\n```\newa \u003ccmd\u003e [args]\n\n命令：\n  ewa new \u003cprojectName\u003e       创建新的微信小程序项目           [别名: create]\n  ewa init                    在现有的小程序项目中初始化 EWA\n  ewa start                   启动 EWA 小程序项目实时编译         [别名: dev]\n  ewa build                   编译小程序静态文件\n  ewa clean                   清理小程序静态文件\n  ewa upgrade                 升级 EWA 工具\n  ewa generate \u003ctype\u003e \u003cname\u003e  快速生成模版                          [别名: g]\n\n选项：\n  -v, --version  当前版本号                                               [布尔]\n  -h, --help     获取使用帮助                                             [布尔]\n```\n\n#### 实时编译\n\n```\newa start\n\n启动 EWA 小程序项目实时编译\n\n选项：\n  -v, --version  当前版本号                                               [布尔]\n  -h, --help     获取使用帮助                                             [布尔]\n  -t, --type     构建目标 `weapp` 或 `swan` 或 `alipay` 或 `tt` 或 `qq`\n            [字符串] [可选值: \"weapp\", \"swan\", \"alipay\", \"tt\", \"qq\"] [默认值: \"weapp\"]\n```\n\n#### 构建\n\n```\newa build\n\n编译小程序静态文件\n\n选项：\n  -v, --version  当前版本号                                               [布尔]\n  -h, --help     获取使用帮助                                             [布尔]\n  -t, --type     构建目标 `weapp` 或 `swan` 或 `alipay` 或 `tt` 或 `qq`\n            [字符串] [可选值: \"weapp\", \"swan\", \"alipay\", \"tt\", \"qq\"] [默认值: \"weapp\"]\n```\n\n#### 快速生成样板文件\n\n```\newa generate \u003ctype\u003e \u003cname\u003e\n\n快速生成模版\n\n位置：\n  type  类型 `page` 或 `component` 或 `template`\n                       [字符串] [必需] [可选值: \"page\", \"component\", \"template\"]\n  name  名称                                                     [字符串] [必需]\n\n选项：\n  -v, --version     当前版本号                                            [布尔]\n  -h, --help        获取使用帮助                                          [布尔]\n  -d, --target-dir  目标文件夹，默认为 src，也可以指定为 src 中的某个子目录\n                                                                        [字符串]\n  -i, --index       生成的文件名称为 [name]/index，默认为 [name]/[name]   [布尔]\n```\n\n#### 清理 dist 目录\n\n```\newa clean\n\n清理小程序静态文件\n\n选项：\n  -v, --version  当前版本号                                               [布尔]\n  -h, --help     获取使用帮助                                             [布尔]\n  -t, --type     构建目标 `weapp` 或 `swan` 或 `alipay` 或 `tt` 或 `qq`\n      [字符串] [可选值: \"weapp\", \"swan\", \"alipay\", \"tt\", \"qq\"] [默认值: \"weapp\"]\n```\n\n## 多端支持和环境变量\n\n### 多端支持\n\n目前 EWA 支持 **微信** / **百度** / **字节跳动** / **QQ** / **支付宝** 5个平台的小程序。\n\n只需要基于`微信小程序`开发，可以通过命令行工具自动构建为不同平台的小程序，具体参见上方的命令行说明。\n\n多端构建的 dist 目录分别为:\n\n```\n微信: dist\n百度: dist-swan\n字节跳动: dist-tt\nQQ: dist-qq\n支付宝: dist-alipay\n```\n\n### 环境变量\n\nEWA 会提供 `process.env.EWA_ENV` 和 `process.env.NODE_ENV` 来辅助开发同学判断多端和不同的开发环境\n\n可以在 .js 或 .ts 文件中直接使用，可选值见下方说明：\n\n```\nprocess.env.EWA_ENV: 多端支持的环境变量\n可选值为 \"weapp\"、\"swan\"、\"alipay\"、\"tt\"、\"qq\", 默认是 \"weapp\"\n\nprocess.env.NODE_ENV: 开发环境变量\n可选值为 \"development\" 和 \"production\", 分别对应 ewa start 和 ewa build 命令\n```\n\n## 功能插件\n\n### 微信接口 Promise 化\n\n```javascript\n// 引入\nconst { api } = require('ewa');\n\n// 例：\nPage({\n  async onLoad() {\n    let { data } = await api.request({ url: 'http://your_api_endpoint' });\n  }\n})\n```\n\n### 插件: `enableState`\n\n#### 用途\n\n在 `Page` 和 `Component` 中引入 `this.setState(data, callback)` 方法, 并根据 data 数据自动 diff 出变更, 减少单次 data 提交的数据量，避免超过小程序 1mb 的限制\n\n#### 常见问题\n\n1. 由于小程序本身的 bug, 当增量更新数组元素的时候, wxml 中无法正确获取到数组元素的 length\n\n#### 使用示例\n\n```javascript\n// 在 app.js 中引入插件，并初始化\nconst { enableState } = require('ewa');\n\n// 参数支持：\n//   opts: 参数对象\n//     debug: 是否开启 debug 模式，支持3种参数： true, 'page', 'component', 默认为 false\n//     component: 是否开启 component 支持, 默认为 true\n//     page: 是否开启 page 支持, 默认为 true\n//     overwriteArrayOnDeleted: 是否在数组发生删除操作是覆盖整个数组 true 或者 false, 默认为 true\n//     autoSync: 是否在 调用 setData 时自动同步 state, 默认为 true; 如果关闭此操作，在同一个页面或组件中混用 setState 或 setData 的时候，可能会导致BUG, 也可以手动调用 this.syncState() 来手动同步\nenableState({\n  debug: true,\n  component: true,\n  page: true,\n  overwriteArrayOnDeleted: true,\n  autoSync: true\n});\n\n// 上述插件会引入 this.setState 方法，在 Page 和 Component 中均可调用\n// setState 方法会自动 diff 并仅提交数据变更\n// 例：\nPage({\n  data: { a: 1, b: 1, c: { d: 1, e: 1 } }\n  async onLoad() {\n    // 自动 diff 变化\n    // 相当于 this.setData({ b: 2, 'c.d': 2 });\n    this.setState({ a: 1, b: 2, c: { d: 2, e: 1 } });\n\n    // this.setState 支持使用 promise 来代替回调函数，如\n    this.setState({ info: { name: 'My Page Title' } }).then(() =\u003e {\n      // 数据已更新到视图, 这里写完成视图更新后的逻辑\n    });\n\n    // 同理，这里可以使用 await 来简化\n    await this.setState({ info: { name: 'My Page Title' } });\n    // 数据已更新到视图, 这里写完成视图更新后的逻辑\n  }\n})\n```\n\n### 插件: `createStore`\n\n#### 用途\n\n支持设置全局响应式对象, 能够监听对象属性并自动更新到 data 中\n\n#### 使用示例\n\n```javascript\n// 1. 创建 store: 对任意纯对象调用 createStore 使其响应式化（以 app.js 中 globalData 为例）\n//    app.js 中引入\nconst { createStore } = require('ewa');\n\nApp({\n  ...\n  globalData: createStore (\n    // 全局响应式对象\n    {\n      a: 'old1',\n      b: {\n        c: 'old2'\n      }\n    },\n\n    // 可以自定义注入到 Page 或 Component 中的方法和属性，也可以不设置\n    // 如果设置了自定义的方法和变量\n    // 那么实际在 Page 或 Component 中引用的时候需要相应的替换成 自定义的名称，示例如下：\n    {\n      $set: 'yourCustomSet',\n      $on: 'yourCustomOn',\n      $emit: 'yourCustomEmit',\n      $off: 'yourCustomOff',\n      $once: 'yourCustomOnce',\n      $watch: 'yourCustomWatch'\n    }\n  )\n})\n\n// 2. 改变 globalData 以及全局状态更新（支持嵌套属性和数组下标修改）\n\n// pageA.js\nPage({\n  data: {\n    a: '',\n    b: {\n      c: ''\n    }\n  }\n})\n\nonLoad() {\n  App().globalData.a = 'new1'\n  console.log(this.data.a === 'new1')  // true\n\n  App().globalData.b.c = 'new2'\n  console.log(this.data.b.c === 'new2') // true\n}\n\n\n// 3. 注入全局方法 使用示例:\nthis.$on('test', (val) =\u003e { console.log(val) })\n\n// 发射数据变化\nthis.$emit('test', 'value');\n\n// 使用方法同 this.$on 只会触发一次\nthis.$once('test', (val) =\u003e {});\n\n// 解绑当前实例通过 this.$on(...) 注册的事件\nthis.$off('test');\n\n// 以上方法适用于\n// 1. 页面与页面\n// 2. 页面与组件\n// 3. 组件与组件\n\n// 注: 所有页面或组件销毁时会自动解绑所有的事件(无需手动调用 `this.$off(...)`)\n// `this.$set('coinName', '金币')` 更新所有页面和组件 data 中 'coinName' 的值为 '金币'（支持嵌套属性和数组下标修改）\n\n// $watch 监听页面或组件 data 中属性 支持监听属性路径形式如 'a[1].b'\n\n// 使用示例：\nPage({\n  data: {\n     prop: '',\n     obj: {\n       key: ''\n     }\n   },\n   $watch: {\n     // 方式一\n     'prop': function(newVal, oldVal) {\n     },\n     // 方式二\n     'obj': {\n       handler: function(newVal, oldVal) {\n       },\n       deep: Boolean, // 深度遍历\n       immediate: Boolean // 立即触发\n     }\n   }\n});\n```\n\n## 配置\n\newa 通过 `ewa.config.js` 来支持个性化配置。如下所示：\n\n``` javascript\n// ewa.config.js\n\nmodule.exports = {\n  // 公用代码库 (node_modules 打包生成的文件)名称，默认为 vendors.js\n  commonModuleName: 'vendors.js',\n\n  // 通用模块匹配模式，默认为 /[\\\\/](node_modules|utils|vendor)[\\\\/].+\\.js/\n  // 如需添加多个文件夹，可自定义正则，如 /[\\\\/](node_modules|utils|custom_dirname)[\\\\/].+\\.js/\n  commonModulePattern: /[\\\\/](node_modules|utils|vendor)[\\\\/].+\\.js/,\n\n  // 是否简化路径，作用于 page 和 component，如 index/index.wxml=\u003e index.wxml，默认为 false\n  simplifyPath: false,\n\n  // 文件夹快捷引用\n  aliasDirs: [\n    'apis',\n    'assets',\n    'constants',\n    'utils'\n  ],\n\n  // 需要拷贝的文件类型\n  copyFileTypes: [\n    'png',\n    'jpeg',\n    'jpg',\n    'gif',\n    'svg',\n    'ico'\n  ],\n\n  // webpack loader 规则\n  rules: [],\n\n  // webpack 插件\n  plugins: [],\n\n  // 开发环境下是否自动清理无用文件，默认为 true\n  autoCleanUnusedFiles: true,\n\n  // css 解析器，sass 或者 less，默认为 sass\n  cssParser: 'sass',\n\n  // 是否开启 hashed module id\n  hashedModuleIds: true,\n\n  // 是否开启缓存，默认为 true\n  cache: true,\n\n  // 自定义环境变量, 默认为 ['NODE_ENV', 'EWA_ENV']\n  customEnvironments: [],\n\n  // 嫌不够灵活？直接修改 webpack 配置\n  webpack: function(config) {\n    return config;\n  }\n};\n```\n\n\n## 更新日志\n\n本项目遵从 [Angular Style Commit Message Conventions](https://gist.github.com/stephenparish/9941e89d80e2bc58a153)，更新日志请查阅 [Release](https://github.com/lyfeyaj/ewa/releases)。\n\n## 常见问题 \u0026 Tips\n\n1. 可以使用 `@` 来代替 **源代码根目录** 来引入代码或样式，如 `const utils = require('@/utils/util')`\n2. WXSS 中可以直接编写 SCSS 样式代码\n3. WXSS 或 SCSS 中引用绝对路径需要在路径前加 `~` 符号，如：`@import \"~@/assets/styles/common.scss\";`，具体原因参见: [sass-loader](https://github.com/webpack-contrib/sass-loader#imports)\n4. `ewa build` 后如果无法正常运行小程序，可检查下是否关闭了微信开发者工具中的 `ES6 转 ES5` 和 `增强编译` 选项。原因是：ewa 打包时会将 ES6 转换为 ES5 并混淆压缩，此功能和微信开发者工具自带的 `ES6 转 ES5` 和 `增强编译` 功能有部分重复，多次转换会导致代码无法运行，所以只要关闭即可。\n5. 其他问题欢迎直接在 Github 上提交 issue，也可以添加下方微信反馈(请注明来意 ^_^)\n\n![lyfeyaj](https://raw.githubusercontent.com/lyfeyaj/ewa/master/docs/_media/wechat-qrcode.jpg)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flyfeyaj%2Fewa","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flyfeyaj%2Fewa","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flyfeyaj%2Fewa/lists"}