aixy
v2.2.37
Published
scaffolding base on webpack
Downloads
8
Readme
aixy 是什么?
aixy 是一个小型的的自研的前端多框架、多平台构建工具;目前已支持 angularjs(老旧项目)、Vue1、Vue2、微信小程序/插件、支付宝小程序/插件的构建;目前网页端构建的实现是基于 webpack,小程序端构建的实现基于 gulp;未来如果有更优秀更适合的开源构建工具出现,也是可以继续集成封装在 aixy 内的
demo 地址
以下内容,最好按照这两个 demo 展开,vue2 demo 地址,小程序demo地址
aixy 产生的历史背景
aixy 发展至今的过程我愿称之为 "踩坑血泪史"
因之前的工作中网页端经历了不同时期的项目的不同构建工具,命令也不统一,某些工具还无法接入 npm,导致维护起来特别麻烦,很多新的技术也没法使用,严重影响工作效率,鉴于老系统后来维护居多,移动端又比较轻小,所以我们在后来的新的项目中放弃了之前一直使用的 fis 系列封装的构建工具,转入了使用更易上手、扩展性更好、应用更广泛的 webpack
小程序端选择 gulp, 而不是 webpack,主要是小程序的项目源文件和产出文件是一对一的,gulp 的这种流式操作与小程序更加贴合;
因当时没有现成的完整的解决方案能解决眼前的问题,故将两者统一封装到 aixy ,统一了命令和规范,再配合组件化服务化,接入 npm,基本上我们每次开发,90% 以上的注意力都集中在了需求的实现上,工作效率得了到很大的提升,新人的上手速度也更快;
aixy 的一些简单规范
小程序端的话,aixy 要求页面(pages)和组件(components)目录下的文件默认分为3个同名的 .js、.less、.tpl 文件,网页端的话除开 .less,也可以使用 sass、stylus 等;小程序端的话,样式文件也可以是 .wxss、.acss 这种平台原生的,模板文件的话也可以是 .wxml、.axml 这种平台原生的,原生小程序代码和遵循 aixy 规范的代码在同一个小程序中共存也是可以的,目前已经成功的实践过将别的公司开发的小程序代码接入 aixy
提供的功能
小程序端
- css 预编译(Less)
- Less import 文件路径自动转换
- 多皮肤
- 页面引用的组件的路径自动识别生成(包括分包)
- 非页面/非组件 js 文件引用路径自动生成(包括分包)
- 图片自动转 base64/SVG 嵌入
- 本地以相对路径引入的图片 url 自动拼接图片云服务域名、带 hash
- 多项目共享内容合并策略
- 全局自动注入公共内容至页面模板
- 环境变量注入模板/js
- app.json 与 plugin.json 配置自动生成
- 多平台多环境产出
网页端
- 项目路由按目录自动生成
- 页面 js 的同名 css 自动引入
- Less 引入路径 alias
- 多皮肤构建
- 版本控制
安装
npm install aixy -g
使用
项目运行起来的必要条件:配置文件(override.config.js + .env) + 命令行
1. override.config.js
用于自定义项目和 aixy 的编译配置
小程序端的配置,示例代码如下:
// profile 用于指明当前编译类型,可选类型如下:v1(vue1)、vue(vue2)、microapp(小程序)
exports.profile = 'microapp'
//项目下的多皮肤相关配置
const themeData = require('./components/common/theme')
//当次编译时的皮肤值,取自系统变量
const COLOR = process.env.THEME_COLOR || 'default'
//用户自定义的项目配置,会覆盖 aixy 内部默认的配置,init 函数的参数 Config 是 aixy 内部的默认配置类,init 函数返回的类最终会在 aixy 内部实例化,作为编译的全局配置使用
exports.init = function (Config) {
class ProjectConfig extends Config {
constructor() {
super();
// setConfig 为父类提供的实例方法,通过它,自定义的配置会和 aixy 内部配置合并,得到真正的应用配置
this.setConfig({
//传给 less.js 的参数, modifyVars 配置的变量会覆盖开发者写在项目 .less 文件中的同名变量,这是实现多皮肤的关键
lessOptions: {
modifyVars: themeData[COLOR],
OSS_PATH: JSON.stringify(this.config.imageDomain)
},
enableTheme: false, //多皮肤编译开关,默认关闭,不需要支持多皮肤的项目可忽略此配置
themes: ['red'], //除开默认皮肤,当前项目还需要编译的皮肤种类
themeData, //不同皮肤的 less 变量值配置对象,具体如何配置后面细说
themePrefix:'_T-' //多皮肤公共前缀,默认值为 _T-,一般不建议改动,知道是这个值即可
indexPage: 'pages/mall/mall', //小程序首页路径,默认为 pages/loading/loading
publicPath: '' //项目构建产出目录,不建议用户在这里配置,取值何来,后面细说
imageDomain: '' //图片云服务地址目录,不建议用户在这里配置,取值何来,后面细说
assetsDir: ['images/**/*'], //项目中不需要处理的图片,通常放在小程序根目录下的 images 目录
assertPath: '' //需要上传到图片服务器的图片被提取出来的存放目录,不建议用户在这里配置,取值何来,后面细说
useHash: true, //是否对上传云服务的图片添加 hash,默认开启
hashLen: 8, //图片 hash 长度,默认为 8
ignoreHash: [], //指定不需要带 hash 的图片
//可用在 模板 和 js 文件中的替换常量,健名可以随意,不一定非得是 process.env[pro] 这样
consts: {
'process.env.OSS_PATH': this.config.imageDomain
},
prefix: '@ext' //内容共享目录,每个小程序根目录下的这个目录内部的内容最终都会合并到项目根目录,默认为 @ext,一般不做改动
});
}
}
return ProjectConfig
}
- themeData
多皮肤样式变量的配置文件格式如下:
module.exports = {
red: {
primaryColor: '#fff000',
bgColor: '#fefefe'
},
blue: {
primaryColor: '#8e8e8e',
bgColor: '#cecece'
}
}
- publicPath
项目的产出目录,其默认值为 project/${PLATFORM}/${NODE_ENV}
,是根据用户在 .env 文件中设置的 PLATFORM 和 NODE_ENV 系统变量值自动计算而来,不需要用户手动设置
- imageDomain
项目的图片云服务地址,因开发过程中 NODE_ENV 有 sandbox、production 之分,故而 imageDomain 的值设置在项目根目录下的 @config 目录下的环境配置 js 文件中,NODE_ENV = sandbox 时,对应的配置文件为 @config/config.sandbox.js ,NODE_ENV = production 时,对应的配置文件为 @config/config.js ,less 编译完毕后,less 中的相对路径引用的图片(无?__inline标志的)的前缀都变成了 ${imageDomain}/${enterprise}
,enterprise
取值来自 package.json
- assertPath
less 中以相对路径引用的图片的提取地址,其默认值为:public/${enterprise}
,enterprise
取值来自 package.json ;编译完毕后,在这个目录下你会发现,所有你需要上传到云服务的图片,aixy 都帮你按照原路径提取出来了,你只需要将整个 public/${enterprise}
文件夹扔到云服务器上,在 @config 目录中配置好 imageDomain
就行了
网页端的可用配置,示例代码如下:
//项目下的多皮肤相关配置
var theme = require('./components/common/theme')
var {
version
} = require('./package.json');
//当次编译时的皮肤值,取自系统变量
const COLOR = process.env.THEME_COLOR;
// profile 用于指明当前编译类型,可选类型如下:v1(vue1)、vue(vue2)、microapp(小程序)
exports.profile = 'v1'
exports.init = function(Config) {
class MyConfig extends Config {
constructor() {
super()
// styleLoaderOptions 用于设置对应的 CSS 预编译文件(less)的 loader 的配置,具体如何配置参见各个 css 预编译器的官方 loader
this.config.styleLoaderOptions = {
less: {
lessOptions: {
globalVars: theme['blue']
}
},
sass: {
//参见 sass-loader 官方文档
}
}
// 多皮肤配置,不需要多皮肤的项目,可以删掉此段
if (COLOR && theme[COLOR]) {
this.config.assertPath = `theme_${COLOR}/${version}`
this.config.styleLoaderOptions.less.lessOptions.modifyVars = theme[COLOR]
}
this.setConfig({
importSameNameStyle: true //默认开启同一目录下的同名 less 文件自动 import 到同名 js 文件上,一般不做修改,此特性主要针对旧的 .js、 .tpl、 .less 分开写的项目,vue2 项目可以忽略此配置,直接用 sfc 即可
assertPath:'' // 为内部计算值,默认为 `${platform}/${version}` 这里的 platform 和 version 均来自项目的 package.json,是实现前端版本控制功能的关键
publicPath:'' // 编译产出目录,默认为项目根目录下的 public 目录
entry: './src/boot/boot.js' // webpack 编译的入口文件
root: './src' //项目根目录,存放前端业务代码的目录
templateFile: './index.ejs' //挂载 webpack 入口 chunk 的模板文件,默认使用 ejs
consts: {} //这里配置的值会传给 webpack.definePlugin(conf.consts),可直接在项目 js 文件中使用这里定义的常量,插件会自动替换
})
}
onInit(env) {
// 获取到 aixy 全局配置时候的钩子,此时 webpack 配置文件还未加载
}
onConfig(webpackConf, env){
//webpack 环境关联配置文件已经获取到,用户可在此对 webpack 的配置进行修改,下一步就是执行 compiler = webpack(webpackConfig) 了
}
onDone(stats, env){
// webpack 编译首次成功之后的钩子,stats 参数中可以获取到编译的详细信息,env 表示当前环境为 sandbox/prod
}
onError(stats, env){
// webpack 首次编译失败之后的钩子,stats 参数中可以获取到出错的具体信息,env 表示当前环境为 sandbox/prod
}
}
return MyConfig
}
2. .env
在此文件中以键值对方式配置的变量最终会被添加到 peocess.env 环境变量中,可配置项如下
NODE_ENV=sandbox
PLATFORM=wechat
NODE_ENV 可取值为 sandbox | production 表示当前项目环境是沙箱还是生产
PLATFORM 可取值为 wechat | alipay | tt 表示编译的小程序归属平台
在.env 设置的配置,最终也会被放入 consts 中,这样用户就能在 .js 和 .tpl 文件中以 process.env[pro] 的方式使用它们,同时,consts 还默认提供了 APP_BUILD_TIME(当前构建时间)
、 APP_VERSION(当前小程序版本号)
两个环境变量供开发者使用
3. aixy 命令行
常用命令如下:
- build 生产构建命令,与 dev 命令的区别在于会开启压缩混淆等系列优化能力,网页端不会启动 server,仅做编译工作
- dev 开发构建命令,会启动本地 nodejs server
- pack 打包产出目录文件到 .zip,为小程序端常用功能
- upload 通过微信官方提供的 miniprogram-ci 扩展的上传小程序代码的能力,此功能目前暂未完成测试
- fmt 调用 prettier,自动帮忙做代码格式化工作
- clean 用于删除项目根目录下 node_modules/.cache 内容
常用选项如下:
- --watch 开启小程序端编译监听,网页端不使用此选项
- --theme 开启小程序端多皮肤构建,网页端不需要此选项,网页端多皮肤构建编译一次,构建一种皮肤
- --plugin 开启小程序插件编译,不使用此命令就默认为是编译小程序
- --optimize 开启小程序优化功能(压缩),小程序 build 的时候默认开启
notes
以上只是一个大概的功能和使用介绍,具体如何,建议配合上面提供的两个 demo 以及 demo 的 readme 去看
关于未来
- 虽然目前 aixy 编译微信和支付宝的小程序/插件,都没有问题,未来即使再扩展其它小程序的编译,都是很容易实现的,但是,要做到一份代码同时可以编译到微信、支付宝、百度、抖音,且还能正常运行,目前是还没有完全实现的;作者最近正在找工作,这个事情暂时推后,不过下一个阶段应该就是去研究一下 Taro 的某些实现,虽然我不打算迁过去 Taro(不支持插件),但是我觉得 Taro 的某些思路还是很值得参考的;路过的有想法的朋友可以踊跃贡献思路
- 目前刚好在准备面试,并且我自己是 Vue 技术栈的,索性现在就开始研究 Vue3 了,最近 vue3 的构建功能可能会逐步完善
- 后续会参照 vite-create 开发一个初始化小工具 aixy-create,用于提供各个框架的初始化模板,目前就把原生 vue2 和 小程序的模板先建出来了,后面慢慢会增加 TS 版本
- 近两年在网页端花费的时间比小程序少上很多,所以小程序的编译功能就更加丰富,后面会根据小程序的经验,逆向对网页端的功能进行扩展
- 以上,敬请期待