akfun
Version:
前端脚手架:支持Vue技术栈和react技术栈
489 lines (380 loc) • 13.6 kB
Markdown
# AKFun 前端脚手架
AKFun 是一个基于 Webpack 与 Rollup 的多场景前端打包工具,支持 Vue、React、React+TS 技术栈,致力于提供"零配置、开箱即用"的前端工程能力,让开发者专注于业务开发。
## 在线使用手册
[https://wibetter.github.io/akfun/](https://wibetter.github.io/akfun/)
国内访问地址: [https://akfun-docs.netlify.app/](https://akfun-docs.netlify.app/)。
## 目录
- [主要特性](#主要特性)
- [安装](#安装)
- [快速开始](#快速开始)
- [命令说明](#命令说明)
- [配置指南](#配置指南)
- [配置文件说明](#配置文件说明)
- [基础配置](#基础配置)
- [开发配置](#开发配置)
- [构建配置](#构建配置)
- [高级配置](#高级配置)
- [其他说明](#其他说明)
## 主要特性
- **零配置**: 内置默认配置(前端工程最佳实践),开箱可用
- **多技术体系支持**: 支持 Vue、React、React+TS 的调试与构建
- **多种构建类型**: 本地开发(含热更新/代理)、生产构建、库构建(UMD/ESM)、Node 模块构建
- **灵活可配**: 支持入口、别名、代理、公共样式注入、ESLint/StyleLint、Babel/Loader/Plugin 扩展等配置
- **样式与规范**: 集成 Autoprefixer、Sass、PostCSS、ESLint、StyleLint
- **参数替换**: 支持基于 [params-replace-loader](https://www.npmjs.com/package/params-replace-loader) 的环境变量批量替换
- **模板支持**: 提供完整的 Vue/React 项目模板
- **内置缓存机制**: 内置缓存机制,提升二次构建速度
## 安装
### 全局安装
```bash
yarn global add akfun
# 或
npm i -g akfun
```
### 项目内安装
```bash
yarn add akfun --dev
# 或
npm i akfun --save-dev
```
## 快速开始
### 方式一:创建新项目
1. **创建项目**(可指定模板与目录)
```bash
akfun init -t=vue
# 指定目录
akfun init -t=vue --dir=myTest1
```
2. **安装依赖**
```bash
cd myTest1
npm install
# 或
yarn install
```
3. **开始开发**
```bash
akfun dev
```
### 方式二:在现有项目中使用
1. **安装依赖**(见上方安装说明)
2. **初始化配置文件**
```bash
akfun config init
```
3. **在 package.json 添加脚本**
```json
{
"scripts": {
"dev": "akfun dev",
"build": "akfun build",
"build2lib": "akfun build2lib",
"build2esm": "akfun build2esm"
}
}
```
4. **运行命令**
```bash
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 格式,导出一个配置对象:
```javascript
module.exports = {
// 配置项...
}
```
### 基础配置
#### 1. 代码规范检查
控制 ESLint 和 StyleLint 的启用与自动修复:
```javascript
module.exports = {
settings: {
enableESLint: true, // 是否开启 ESLint,默认开启
enableESLintFix: false, // 是否 ESLint 自动修正代码格式
enableStyleLint: true, // 是否开启 StyleLint,默认开启
enableStyleLintFix: false // 是否 StyleLint 自动修正代码格式
}
}
```
#### 2. 构建入口
配置构建入口文件,支持多入口。优先级:`dev/build/build2lib.entry` > `webpack.entry`
> **提示**: 建议以 key/value(object `{ <key>: string | [string] }`)配置 entry。详情参考 [Webpack 文档](https://www.webpackjs.com/configuration/entry-context/#entry)
```javascript
module.exports = {
webpack: {
entry: {
index: './src/index.js'
}
},
// 各场景可单独配置入口
dev: { entry: {} },
build: { entry: {} },
build2lib: { entry: {} },
build2esm: {
input: resolve('src/main.js'),
fileName: 'index'
}
}
```
#### 3. 文件解析配置
配置模块解析的文件扩展名:
> 详情参考 [Webpack resolve.extensions 文档](https://www.webpackjs.com/configuration/resolve/#resolve-extensions)
```javascript
module.exports = {
webpack: {
resolve: {
extensions: ['.js', '.jsx', '.vue', '.json']
}
}
}
```
#### 4. 路径别名配置
配置模块路径别名,简化导入路径:
> 详情参考 [Webpack resolve.alias 文档](https://www.webpackjs.com/configuration/resolve/#resolve-alias)
```javascript
module.exports = {
webpack: {
resolve: {
alias: {
'@': resolve('src'),
'components': resolve('src/components')
}
}
}
}
```
#### 5. 页面模板与样式资源
```javascript
module.exports = {
webpack: {
template: '', // 自定义页面模板路径
sassResources: [ // 为每个 .scss 文件注入公共 SASS(变量、mixin、function 等)
resolve('src/assets/css/mixin.scss'),
resolve('src/assets/css/variables.scss')
]
}
}
```
#### 6. 依赖打包策略
控制是否忽略 `node_modules` 中的依赖,减少打包体积:
```javascript
module.exports = {
webpack: {
ignoreNodeModules: true, // 是否忽略 node_modules 中的依赖文件
allowList: [ // 配置需要注入 bundle 的依赖包(ignoreNodeModules 为 true 时生效)
'lodash',
'axios'
]
}
}
```
#### 7. TypeScript 配置
```javascript
module.exports = {
webpack: {
createDeclaration: true, // 是否生成 TypeScript 声明文件
projectDir: ['./src'] // 可配置多个目录,用于提升工程执行效率
}
}
```
#### 8. 环境变量替换
基于 [params-replace-loader](https://www.npmjs.com/package/params-replace-loader) 实现环境变量批量替换:
> 详情参考 [params-replace-loader 使用文档](https://www.npmjs.com/package/params-replace-loader)
```javascript
module.exports = {
envParams: {
common: { // 通用参数
'#version#': '20200810.1'
},
local: { // 本地开发环境
'#dataApiBase#': 'http://localhost:1024', // 数据接口根地址
'#assetsPublicPath#': 'http://localhost:1024', // 静态资源根地址
'#routeBasePath#': '/' // 路由根地址
}
}
}
```
### 开发配置
#### 开发服务器配置
配置开发服务器的端口、代理、资源路径等:
> 关于 proxyTable 的配置方法,参考 [Webpack DevServer Proxy 文档](https://www.webpackjs.com/configuration/dev-server/#devserver-proxy)
```javascript
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 开发服务:
> 使用 `https://localhost/index.html` 访问当前项目
```javascript
module.exports = {
dev: {
https: true // 默认不开启
}
}
```
**注意事项**: akfun 使用自签名证书开启 HTTPS 服务,浏览器会提示安全性问题。需要进行如下设置:
- **Chrome**: 浏览器打开 `chrome://flags/#allow-insecure-localhost` 后将其设置为 `Enabled`
- **其他浏览器**: 类似设置允许本地不安全的 localhost 连接
### 构建配置
#### 生产环境构建
配置生产构建的输出路径、资源路径、压缩优化等:
```javascript
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)
构建 UMD 格式的库,适用于通过 `<script>` 标签或 CommonJS/AMD 方式引入:
```javascript
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)
构建 ESM 格式的库,适用于现代模块系统:
```javascript
module.exports = {
build2esm: {
input: resolve('src/main.js'), // 入口文件
fileName: 'index', // 输出的文件名称
svgDir: 'src/icons/**' // 用于设置当前项目的 icon 所在目录,避免被 @rollup/plugin-image 编译成 base64 格式
}
}
```
#### 构建 Node 模块
构建 Node 模块,通常用于构建 node cli 工具:
```javascript
module.exports = {
build2node: {
input: resolve('src/main.js'), // 入口文件
fileName: 'index', // 输出的文件名称
outDir: 'src' // 输出目录
}
}
```
### 高级配置
#### 自定义 Loader / Plugin / Babel Plugins
扩展 Webpack 的 Loader、Plugin 和 Babel 插件:
```javascript
module.exports = {
webpack: {
moduleRules: [], // 用于添加自定义 loaders
plugins: [], // 用于添加自定义 plugins
babelPlugins: [ // 用于添加自定义 Babel plugins
[
'component',
{
libraryName: 'element-ui',
styleLibraryName: 'theme-chalk'
}
]
]
}
}
```
**示例**: 以上自定义 `babelPlugins` 用于实现 [element-ui 组件按需引入](https://element.eleme.cn/#/zh-CN/component/quickstart#an-xu-yin-ru)
**函数形式**: 也支持以函数形式动态调整内置 Babel Plugins:
```javascript
module.exports = {
webpack: {
babelPlugins: (curBabelPlugins) => {
curBabelPlugins.push(/* your plugin */)
return curBabelPlugins
}
}
}
```
#### 自定义 CSS Loader / PostCSS Loader
自定义 CSS 和 PostCSS 的处理配置:
```javascript
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` 不向页面注入打包产物
- **模板优先级**:
1. 优先使用 `./src/index.html`
2. 不存在时使用内置默认模板
3. 多页面时,若 `pages` 下存在同名 HTML,将其作为页面模板
## 相关链接
- [Webpack 官方文档](https://webpack.js.org/)
- [Rollup 官方文档](https://rollupjs.org/)
- [params-replace-loader](https://www.npmjs.com/package/params-replace-loader)