• Stars
    star
    183
  • Rank 210,154 (Top 5 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 6 years ago
  • Updated over 3 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Enhanced Wechat App Development Toolkit (微信小程序增强开发工具)。不同于 wepy 或者 mpvue,是一个轻量级小程序开发框架。支持原生小程序所有功能,无需学习,极易上手。支持转换为百度/字节跳动/QQ/支付宝小程序。

EWA (微信小程序增强开发工具)

Enhanced Wechat App Development Toolkit (微信小程序增强开发工具)

为什么开发这个工具?

厌倦了不停的对比 tarowepy 或者 mpvue 的特性,间歇性的踩雷,构建和运行速度慢以及 code once, run everywhere 的幻想。只想给小程序开发插上效率的翅膀 ~

功能特性

  1. Async/Await 支持
  2. Javascript ES2020 语法
  3. 原生小程序所有功能,无需学习,极易上手
  4. 微信接口 Promise 化
  5. 支持安装 NPM 包
  6. 支持 SCSS(或 LESS) 以及 小于 16k 的 background-image
  7. 支持 source map, 方便调试
  8. 添加新页面或新组件无需重启编译
  9. 允许自定义编译流程
  10. 自动兼容旧版本手机中的显示样式
  11. 支持 WXSS 和 SCSS(或 LESS) 混用
  12. 代码混淆及高度压缩,节省包大小
  13. Typescript 支持
  14. 支持转换成 百度 / 字节跳动 / QQ / 支付宝小程序
  15. 多种小程序开发插件,为小程序开发减负,解放生产力

更多特性正在赶来 ... 敬请期待

安装

需要 node 版本 >= 10.13

npm i -g ewa-cli 或者 yarn global add ewa-cli

如何使用

创建新项目

ewa new your_project_name

集成到现有小程序项目,仅支持小程序原生开发项目转换

注意:使用此方法,请务必对项目代码做好备份!!!

cd your_project_dir && ewa init

启动

运行 npm start 即可启动实时编译

运行 npm run build 即可编译线上版本(相比实时编译而言,去除了 source map 并增加了代码压缩混淆等,体积更小)

上述命令运行成功后,可以看到本地多了个 dist 目录,这个目录里就是生成的小程序相关代码。

使用微信开发者工具选择 dist 目录打开,即可预览项目

目录结构

├── .ewa                         特殊占位目录,用于检查是否为 ewa 项目
├── dist                         小程序运行代码目录(该目录由ewa的start 或者 build指令自动编译生成,请不要直接修改该目录下的文件)
├── node_modules                 外部依赖库
├── src                          代码编写的目录(该目录为使用ewa后的开发目录)
│   ├── components               小程序组件目录
│   ├── pages                    小程序页面目录
│   │   ├── index
│   │   │   ├── index.js
│   │   │   ├── index.wxml
│   │   │   └── index.wxss
│   │   └── logs
│   │       ├── logs.js
│   │       ├── logs.json
│   │       ├── logs.wxml
│   │       └── logs.wxss
│   ├── templates                小程序模版目录
│   ├── utils
│   │   └── util.js
│   ├── app.js                   小程序入口文件
│   ├── app.json                 小程序全局配置文件
│   ├── app.wxss                 小程序全局样式文件
│   └── project.config.json      微信开发者工具小程序项目配置文件
├── ewa.config.js                ewa 配置文件
├── .gitignore
├── .eslintrc.js                 eslint 配置
└── package.json

命令行说明

概览

ewa <cmd> [args]

命令:
  ewa new <projectName>       创建新的微信小程序项目           [别名: create]
  ewa init                    在现有的小程序项目中初始化 EWA
  ewa start                   启动 EWA 小程序项目实时编译         [别名: dev]
  ewa build                   编译小程序静态文件
  ewa clean                   清理小程序静态文件
  ewa upgrade                 升级 EWA 工具
  ewa generate <type> <name>  快速生成模版                          [别名: g]

选项:
  -v, --version  当前版本号                                               [布尔]
  -h, --help     获取使用帮助                                             [布尔]

实时编译

ewa start

启动 EWA 小程序项目实时编译

选项:
  -v, --version  当前版本号                                               [布尔]
  -h, --help     获取使用帮助                                             [布尔]
  -t, --type     构建目标 `weapp` 或 `swan` 或 `alipay` 或 `tt` 或 `qq`
            [字符串] [可选值: "weapp", "swan", "alipay", "tt", "qq"] [默认值: "weapp"]

构建

ewa build

编译小程序静态文件

选项:
  -v, --version  当前版本号                                               [布尔]
  -h, --help     获取使用帮助                                             [布尔]
  -t, --type     构建目标 `weapp` 或 `swan` 或 `alipay` 或 `tt` 或 `qq`
            [字符串] [可选值: "weapp", "swan", "alipay", "tt", "qq"] [默认值: "weapp"]

快速生成样板文件

ewa generate <type> <name>

快速生成模版

位置:
  type  类型 `page` 或 `component` 或 `template`
                       [字符串] [必需] [可选值: "page", "component", "template"]
  name  名称                                                     [字符串] [必需]

选项:
  -v, --version     当前版本号                                            [布尔]
  -h, --help        获取使用帮助                                          [布尔]
  -d, --target-dir  目标文件夹,默认为 src,也可以指定为 src 中的某个子目录
                                                                        [字符串]
  -i, --index       生成的文件名称为 [name]/index,默认为 [name]/[name]   [布尔]

清理 dist 目录

ewa clean

清理小程序静态文件

选项:
  -v, --version  当前版本号                                               [布尔]
  -h, --help     获取使用帮助                                             [布尔]
  -t, --type     构建目标 `weapp` 或 `swan` 或 `alipay` 或 `tt` 或 `qq`
      [字符串] [可选值: "weapp", "swan", "alipay", "tt", "qq"] [默认值: "weapp"]

多端支持和环境变量

多端支持

目前 EWA 支持 微信 / 百度 / 字节跳动 / QQ / 支付宝 5个平台的小程序。

只需要基于微信小程序开发,可以通过命令行工具自动构建为不同平台的小程序,具体参见上方的命令行说明。

多端构建的 dist 目录分别为:

微信: dist
百度: dist-swan
字节跳动: dist-tt
QQ: dist-qq
支付宝: dist-alipay

环境变量

EWA 会提供 process.env.EWA_ENVprocess.env.NODE_ENV 来辅助开发同学判断多端和不同的开发环境

可以在 .js 或 .ts 文件中直接使用,可选值见下方说明:

process.env.EWA_ENV: 多端支持的环境变量
可选值为 "weapp"、"swan"、"alipay"、"tt"、"qq", 默认是 "weapp"

process.env.NODE_ENV: 开发环境变量
可选值为 "development" 和 "production", 分别对应 ewa start 和 ewa build 命令

功能插件

微信接口 Promise 化

// 引入
const { api } = require('ewa');

// 例:
Page({
  async onLoad() {
    let { data } = await api.request({ url: 'http://your_api_endpoint' });
  }
})

插件: enableState

用途

PageComponent 中引入 this.setState(data, callback) 方法, 并根据 data 数据自动 diff 出变更, 减少单次 data 提交的数据量,避免超过小程序 1mb 的限制

常见问题

  1. 由于小程序本身的 bug, 当增量更新数组元素的时候, wxml 中无法正确获取到数组元素的 length

使用示例

// 在 app.js 中引入插件,并初始化
const { enableState } = require('ewa');

// 参数支持:
//   opts: 参数对象
//     debug: 是否开启 debug 模式,支持3种参数: true, 'page', 'component', 默认为 false
//     component: 是否开启 component 支持, 默认为 true
//     page: 是否开启 page 支持, 默认为 true
//     overwriteArrayOnDeleted: 是否在数组发生删除操作是覆盖整个数组 true 或者 false, 默认为 true
//     autoSync: 是否在 调用 setData 时自动同步 state, 默认为 true; 如果关闭此操作,在同一个页面或组件中混用 setState 或 setData 的时候,可能会导致BUG, 也可以手动调用 this.syncState() 来手动同步
enableState({
  debug: true,
  component: true,
  page: true,
  overwriteArrayOnDeleted: true,
  autoSync: true
});

// 上述插件会引入 this.setState 方法,在 Page 和 Component 中均可调用
// setState 方法会自动 diff 并仅提交数据变更
// 例:
Page({
  data: { a: 1, b: 1, c: { d: 1, e: 1 } }
  async onLoad() {
    // 自动 diff 变化
    // 相当于 this.setData({ b: 2, 'c.d': 2 });
    this.setState({ a: 1, b: 2, c: { d: 2, e: 1 } });

    // this.setState 支持使用 promise 来代替回调函数,如
    this.setState({ info: { name: 'My Page Title' } }).then(() => {
      // 数据已更新到视图, 这里写完成视图更新后的逻辑
    });

    // 同理,这里可以使用 await 来简化
    await this.setState({ info: { name: 'My Page Title' } });
    // 数据已更新到视图, 这里写完成视图更新后的逻辑
  }
})

插件: createStore

用途

支持设置全局响应式对象, 能够监听对象属性并自动更新到 data 中

使用示例

// 1. 创建 store: 对任意纯对象调用 createStore 使其响应式化(以 app.js 中 globalData 为例)
//    app.js 中引入
const { createStore } = require('ewa');

App({
  ...
  globalData: createStore (
    // 全局响应式对象
    {
      a: 'old1',
      b: {
        c: 'old2'
      }
    },

    // 可以自定义注入到 Page 或 Component 中的方法和属性,也可以不设置
    // 如果设置了自定义的方法和变量
    // 那么实际在 Page 或 Component 中引用的时候需要相应的替换成 自定义的名称,示例如下:
    {
      $set: 'yourCustomSet',
      $on: 'yourCustomOn',
      $emit: 'yourCustomEmit',
      $off: 'yourCustomOff',
      $once: 'yourCustomOnce',
      $watch: 'yourCustomWatch'
    }
  )
})

// 2. 改变 globalData 以及全局状态更新(支持嵌套属性和数组下标修改)

// pageA.js
Page({
  data: {
    a: '',
    b: {
      c: ''
    }
  }
})

onLoad() {
  App().globalData.a = 'new1'
  console.log(this.data.a === 'new1')  // true

  App().globalData.b.c = 'new2'
  console.log(this.data.b.c === 'new2') // true
}


// 3. 注入全局方法 使用示例:
this.$on('test', (val) => { console.log(val) })

// 发射数据变化
this.$emit('test', 'value');

// 使用方法同 this.$on 只会触发一次
this.$once('test', (val) => {});

// 解绑当前实例通过 this.$on(...) 注册的事件
this.$off('test');

// 以上方法适用于
// 1. 页面与页面
// 2. 页面与组件
// 3. 组件与组件

// 注: 所有页面或组件销毁时会自动解绑所有的事件(无需手动调用 `this.$off(...)`)
// `this.$set('coinName', '金币')` 更新所有页面和组件 data 中 'coinName' 的值为 '金币'(支持嵌套属性和数组下标修改)

// $watch 监听页面或组件 data 中属性 支持监听属性路径形式如 'a[1].b'

// 使用示例:
Page({
  data: {
     prop: '',
     obj: {
       key: ''
     }
   },
   $watch: {
     // 方式一
     'prop': function(newVal, oldVal) {
     },
     // 方式二
     'obj': {
       handler: function(newVal, oldVal) {
       },
       deep: Boolean, // 深度遍历
       immediate: Boolean // 立即触发
     }
   }
});

配置

ewa 通过 ewa.config.js 来支持个性化配置。如下所示:

// ewa.config.js

module.exports = {
  // 公用代码库 (node_modules 打包生成的文件)名称,默认为 vendors.js
  commonModuleName: 'vendors.js',

  // 通用模块匹配模式,默认为 /[\\/](node_modules|utils|vendor)[\\/].+\.js/
  // 如需添加多个文件夹,可自定义正则,如 /[\\/](node_modules|utils|custom_dirname)[\\/].+\.js/
  commonModulePattern: /[\\/](node_modules|utils|vendor)[\\/].+\.js/,

  // 是否简化路径,作用于 page 和 component,如 index/index.wxml=> index.wxml,默认为 false
  simplifyPath: false,

  // 文件夹快捷引用
  aliasDirs: [
    'apis',
    'assets',
    'constants',
    'utils'
  ],

  // 需要拷贝的文件类型
  copyFileTypes: [
    'png',
    'jpeg',
    'jpg',
    'gif',
    'svg',
    'ico'
  ],

  // webpack loader 规则
  rules: [],

  // webpack 插件
  plugins: [],

  // 开发环境下是否自动清理无用文件,默认为 true
  autoCleanUnusedFiles: true,

  // css 解析器,sass 或者 less,默认为 sass
  cssParser: 'sass',

  // 是否开启 hashed module id
  hashedModuleIds: true,

  // 是否开启缓存,默认为 true
  cache: true,

  // 自定义环境变量, 默认为 ['NODE_ENV', 'EWA_ENV']
  customEnvironments: [],

  // 嫌不够灵活?直接修改 webpack 配置
  webpack: function(config) {
    return config;
  }
};

更新日志

本项目遵从 Angular Style Commit Message Conventions,更新日志请查阅 Release

常见问题 & Tips

  1. 可以使用 @ 来代替 源代码根目录 来引入代码或样式,如 const utils = require('@/utils/util')
  2. WXSS 中可以直接编写 SCSS 样式代码
  3. WXSS 或 SCSS 中引用绝对路径需要在路径前加 ~ 符号,如:@import "~@/assets/styles/common.scss";,具体原因参见: sass-loader
  4. ewa build 后如果无法正常运行小程序,可检查下是否关闭了微信开发者工具中的 ES6 转 ES5增强编译 选项。原因是:ewa 打包时会将 ES6 转换为 ES5 并混淆压缩,此功能和微信开发者工具自带的 ES6 转 ES5增强编译 功能有部分重复,多次转换会导致代码无法运行,所以只要关闭即可。
  5. 其他问题欢迎直接在 Github 上提交 issue,也可以添加下方微信反馈(请注明来意 ^_^)

lyfeyaj

More Repositories

1

awesome-resources

Awesome resources for coding and learning: open source projects, websites, books e.g.
HTML
1,665
star
2

swipe

Swipe is the most accurate touch slider. Support both React and Angular.
JavaScript
961
star
3

sublime-text-imfix

Fix Sublime Text 3 Input method problem (CJK words) under Ubuntu
C
936
star
4

smart_sms

The easiest way to integrate SMS service in China
Ruby
91
star
5

qn-webpack

Qiniu webpack plugin (七牛 Webpack 插件)
JavaScript
40
star
6

pretty_doc

Pretty document empowered by markdown language
CSS
9
star
7

ovt

Javascript Object Validation Tool
JavaScript
8
star
8

atom-transpose

Transpose your text. Behave transpose action like Sublime Text 2/3.
CoffeeScript
7
star
9

magico

Magic object accessor for javascript!
JavaScript
6
star
10

dotfiles

My dotfiles
Shell
5
star
11

stoc

String to object compiler for Javascript
JavaScript
4
star
12

rsqoot

A Ruby Wrapper For Sqoot API V2
Ruby
4
star
13

iconcutter

Painless way to resize your icon for all platforms: wechat, weibo, ios, android, and so on
Ruby
4
star
14

railscasts-subscriber

RailsCasts Subscriber with a little hack
Ruby
3
star
15

servant

A Life Servant
JavaScript
2
star
16

system-detective

A detective for your server to find out evils
Ruby
2
star
17

xpick

Extremely powerful pick functionality
JavaScript
2
star
18

ovt-plugin-xss

Ovt plugin for js-xss
JavaScript
2
star
19

lyfeyaj

My Zone ~ 关于技术 & 产品 & 设计的一些思考
2
star
20

jaql

Automatically exported from code.google.com/p/jaql
Java
1
star
21

reminder

Reminder
Ruby
1
star
22

ovt-plugin-lodash

Ovt plugin for lodash
JavaScript
1
star
23

mass-mailer

Mass Mailer
1
star
24

ovt-plugin-baiji

Ovt plugin for baiji
JavaScript
1
star
25

basepack

Front end engineering base toolchain on top of webpack
1
star
26

OpenNash

OpenLDAP Portal System(公司内网LDAP管理,用于企业内部LDAP应用管理,统一入口+员工权限分配)
1
star
27

blog

lyfeyaj's blog
JavaScript
1
star
28

ovt-plugin-validator

Ovt plugin for validator.js
JavaScript
1
star
29

dot-atom

My Atom config and plugins
JavaScript
1
star