AKFun 是一个基于 Webpack 与 Rollup 的多场景前端打包工具,支持 Vue、React、React+TS 技术栈,致力于提供"零配置、开箱即用"的前端工程能力,让开发者专注于业务开发。
- 零配置: 内置默认配置(前端工程最佳实践),开箱可用
- 多技术体系支持: 支持 Vue、React、React+TS 的调试与构建
- 多种构建类型: 本地开发(含热更新/代理)、生产构建、库构建(UMD/ESM)、Node 模块构建
- 灵活可配: 支持入口、别名、代理、公共样式注入、ESLint/StyleLint、Babel/Loader/Plugin 扩展等配置
- 样式与规范: 集成 Autoprefixer、Sass、PostCSS、ESLint、StyleLint
- 参数替换: 支持基于 params-replace-loader 的环境变量批量替换
- 模板支持: 提供完整的 Vue/React 项目模板
- 内置缓存机制: 内置缓存机制,提升二次构建速度
yarn global add akfun
# 或
npm i -g akfunyarn add akfun --dev
# 或
npm i akfun --save-dev-
创建项目(可指定模板与目录)
akfun init -t=vue # 指定目录 akfun init -t=vue --dir=myTest1 -
安装依赖
cd myTest1 npm install # 或 yarn install
-
开始开发
akfun dev
-
安装依赖(见上方安装说明)
-
初始化配置文件
akfun config init
-
在 package.json 添加脚本
{ "scripts": { "dev": "akfun dev", "build": "akfun build", "build2lib": "akfun build2lib", "build2esm": "akfun build2esm" } } -
运行命令
npm run dev npm run build
| 命令 | 说明 |
|---|---|
akfun init |
交互式创建项目,支持 -t(模板类型)、--dir(目录名)参数 |
akfun config init |
在当前项目生成 akfun.config.js 配置文件 |
akfun dev |
启动本地开发服务器(含热更新、接口代理、可选 HTTPS、可选 ESLint/StyleLint) |
akfun build |
生产环境构建(压缩优化、可选分析) |
akfun build2lib |
构建 UMD 格式的库产物 |
akfun build2esm |
构建 ESM 格式的库产物 |
akfun build2node |
构建 Node 模块 |
AKFun 默认提供完整配置,开箱即用。如需自定义配置,执行 akfun config init 生成 akfun.config.js 文件,然后按需修改。
配置文件采用 CommonJS 格式,导出一个配置对象:
module.exports = {
// 配置项...
}控制 ESLint 和 StyleLint 的启用与自动修复:
module.exports = {
settings: {
enableESLint: true, // 是否开启 ESLint,默认开启
enableESLintFix: false, // 是否 ESLint 自动修正代码格式
enableStyleLint: true, // 是否开启 StyleLint,默认开启
enableStyleLintFix: false // 是否 StyleLint 自动修正代码格式
}
}配置构建入口文件,支持多入口。优先级:dev/build/build2lib.entry > webpack.entry
提示: 建议以 key/value(object
{ <key>: string | [string] })配置 entry。详情参考 Webpack 文档
module.exports = {
webpack: {
entry: {
index: './src/index.js'
}
},
// 各场景可单独配置入口
dev: { entry: {} },
build: { entry: {} },
build2lib: { entry: {} },
build2esm: {
input: resolve('src/main.js'),
fileName: 'index'
}
}配置模块解析的文件扩展名:
module.exports = {
webpack: {
resolve: {
extensions: ['.js', '.jsx', '.vue', '.json']
}
}
}配置模块路径别名,简化导入路径:
module.exports = {
webpack: {
resolve: {
alias: {
'@': resolve('src'),
'components': resolve('src/components')
}
}
}
}module.exports = {
webpack: {
template: '', // 自定义页面模板路径
sassResources: [ // 为每个 .scss 文件注入公共 SASS(变量、mixin、function 等)
resolve('src/assets/css/mixin.scss'),
resolve('src/assets/css/variables.scss')
]
}
}控制是否忽略 node_modules 中的依赖,减少打包体积:
module.exports = {
webpack: {
ignoreNodeModules: true, // 是否忽略 node_modules 中的依赖文件
allowList: [ // 配置需要注入 bundle 的依赖包(ignoreNodeModules 为 true 时生效)
'lodash',
'axios'
]
}
}module.exports = {
webpack: {
createDeclaration: true, // 是否生成 TypeScript 声明文件
projectDir: ['./src'] // 可配置多个目录,用于提升工程执行效率
}
}基于 params-replace-loader 实现环境变量批量替换:
module.exports = {
envParams: {
common: { // 通用参数
'#version#': '20200810.1'
},
local: { // 本地开发环境
'#dataApiBase#': 'http://localhost:1024', // 数据接口根地址
'#assetsPublicPath#': 'http://localhost:1024', // 静态资源根地址
'#routeBasePath#': '/' // 路由根地址
}
}
}配置开发服务器的端口、代理、资源路径等:
关于 proxyTable 的配置方法,参考 Webpack DevServer Proxy 文档
module.exports = {
dev: {
NODE_ENV: 'development', // development 模式,不会启动 UglifyJsPlugin
port: 80, // 启动 server 服务的端口
autoOpenBrowser: true, // 是否自动打开页面
assetsPublicPath: '/', // 设置静态资源的引用路径(根域名+路径)
assetsSubDirectory: '', // 资源引用二级路径
hostname: 'localhost', // 自动打开的页面主机
proxyTable: { // 接口代理配置
'/apiTest': {
target: 'http://api-test.com.cn', // 不支持跨域的接口根地址
ws: true, // 启用 WebSocket
changeOrigin: true // 改变请求头中的 origin
}
},
cssSourceMap: false, // CSS Source Map
https: false // 是否启用 HTTPS(见下方 HTTPS 配置说明)
}
}启用本地 HTTPS 开发服务:
使用
https://localhost/index.html访问当前项目
module.exports = {
dev: {
https: true // 默认不开启
}
}注意事项: akfun 使用自签名证书开启 HTTPS 服务,浏览器会提示安全性问题。需要进行如下设置:
- Chrome: 浏览器打开
chrome://flags/#allow-insecure-localhost后将其设置为Enabled - 其他浏览器: 类似设置允许本地不安全的 localhost 连接
配置生产构建的输出路径、资源路径、压缩优化等:
module.exports = {
build: {
NODE_ENV: 'production', // production 模式,会启动 UglifyJsPlugin
assetsRoot: resolve('./dist'), // 打包后的文件绝对路径(物理路径)
assetsPublicPath: '/', // 设置静态资源的引用路径(根域名+路径)
assetsSubDirectory: '', // 资源引用二级路径
productionSourceMap: false, // 是否生成 Source Map
productionGzip: false, // 是否开启 Gzip 压缩
productionGzipExtensions: ['js', 'css', 'json'], // Gzip 识别的文件后缀
bundleAnalyzerReport: false // 是否开启打包分析功能
}
}构建 UMD 格式的库,适用于通过 <script> 标签或 CommonJS/AMD 方式引入:
module.exports = {
build2lib: {
NODE_ENV: 'production', // production 模式
libraryName: 'MyLibrary', // 构建第三方功能包时最后导出的引用变量名
assetsRoot: resolve('dist'), // 编译完成的文件存放路径
assetsPublicPath: '/', // 设置静态资源的引用路径
assetsSubDirectory: '', // 资源引用二级路径
productionSourceMap: false, // 是否生成 Source Map
productionGzip: false, // 是否开启 Gzip 压缩
productionGzipExtensions: ['js', 'css', 'json'], // Gzip 识别的文件后缀
bundleAnalyzerReport: false // 是否开启打包分析功能
}
}构建 ESM 格式的库,适用于现代模块系统:
module.exports = {
build2esm: {
input: resolve('src/main.js'), // 入口文件
fileName: 'index', // 输出的文件名称
svgDir: 'src/icons/**' // 用于设置当前项目的 icon 所在目录,避免被 @rollup/plugin-image 编译成 base64 格式
}
}构建 Node 模块,通常用于构建 node cli 工具:
module.exports = {
build2node: {
input: resolve('src/main.js'), // 入口文件
fileName: 'index', // 输出的文件名称
outDir: 'src' // 输出目录
}
}扩展 Webpack 的 Loader、Plugin 和 Babel 插件:
module.exports = {
webpack: {
moduleRules: [], // 用于添加自定义 loaders
plugins: [], // 用于添加自定义 plugins
babelPlugins: [ // 用于添加自定义 Babel plugins
[
'component',
{
libraryName: 'element-ui',
styleLibraryName: 'theme-chalk'
}
]
]
}
}示例: 以上自定义 babelPlugins 用于实现 element-ui 组件按需引入
函数形式: 也支持以函数形式动态调整内置 Babel Plugins:
module.exports = {
webpack: {
babelPlugins: (curBabelPlugins) => {
curBabelPlugins.push(/* your plugin */)
return curBabelPlugins
}
}
}自定义 CSS 和 PostCSS 的处理配置:
module.exports = {
webpack: {
cssLoaderOption: {
import: false // 启用/禁用 @import 解析
},
postCssLoaderOption: { // 自定义 postcss-loader 的配置
postcssOptions: {
plugins: [
require('postcss-pxtorem')({ // 用于将 px 自动转化为 rem
rootValue: 16, // 1rem 等于 16px
propList: ['*'] // 所有属性都转换
})
]
}
}
}
}-
自动扫描入口: 当
entry仅配置一个且对应文件不存在时,会自动从src/pages扫描以.ts/.tsx/.js/.jsx结尾的文件作为入口,匹配同名 HTML 作为模板(对应正则/\.[tj]sx?$/) -
模板使用范围: 仅
dev和build使用页面模板;build2lib不向页面注入打包产物 -
模板优先级:
- 优先使用
./src/index.html - 不存在时使用内置默认模板
- 多页面时,若
pages下存在同名 HTML,将其作为页面模板
- 优先使用