网站首页 > 技术文章 正文
webpack是前端开发中很火的模块打包工具,只需要通过简单的配置,便可以完成模块的加载和打包。
当前,前端技术日新月异,公司的团队技术栈和业务场景不同,都会建立自己的前端工程体系。一个好的工程体系能够保证团队的研发流程规范,提高团队的研发效率,能够减少人员流动带来的项目交接和维护成本。2-3个项目还可维护,那20-30个项目?
在 easywebpack 工程体系的最初设计中,考虑前端工程的复杂性和扩展性问题,各种插件都是可插拔设计,可以灵活组装使用,也可以脱离 easywebpack 体系单独使用,从而保证能够基于 easywebpack 体系定制出符合自己的团队的工程体系方案。
easywebpack-cli
easywebpack-cli 主要包括 Command, Action, Config, Ask 四部分,默认集成了常用的功能服务,你可以很方便的集成已有功能和服务,同时通过覆写基类方法自定义实现相关功能。easywebpack-cli 命令注册是通过 commander 插件实现的,默认支持的命令有如下命令。
下面以实现 Egg + React 集成 CLI 为例,具备 easywebpack-cli 所有能力之外,同时根据 Egg + React 的框架形态进行定制,最终实现 res-cli 自定义 CLI 命令行工具。
Initialize
首先初始化一个 npm 代码库,可以通过 easy init 初始化一个简单的 npm package 代码仓库 res-cli, 然后添加 bin/cli.js , lib/command.js , lib/action.js , lib/config.js , lib/ask.js 等文件。同时在 package.json 中配置添加 bin 命令行入口配置接口初始化一个非常的简单的 res 命令行。
// ${root}/package.json { "bin": { "res": "bin/cli.js" } } // ${root}/bin/cli.js #!/usr/bin/env node const Command = require('../lib/command'); new Command().run();
接下来就是根据 easywebpack-cli 提供的 Command, Action, Config, Ask 实现自己的 CLI 定制部分。
Command
// ${root}/lib/command.js 'use strict'; const path = require('path'); const EasyCLI = require('@easy-team/easywebpack-cli'); // 自定义 Action, 见下面 Action 实现 const Action = require('./action'); module.exports = class ResCommand extends EasyCLI.Command { constructor() { super(); // 命令行库名称,日志输出显示 this.cli.name = 'res-cli'; // 命令行命令 this.cli.cmd = 'res'; // 当前 cli 库的根目录 this.context = path.resolve(__dirname, '..'); // 需要合并的 webpack.config.js 配置文件路径 this.program.filename = path.resolve(this.baseDir, 'config/res.config.js'); // 命令具体逻辑实现 this.action = new Action(this); // 提供给 res init 骨架初始化的配置 this.boilerplate = require('./ask'); } // 定义 res tsc 实现方法即可 tsc() { this.program .command('tsc') .option('-p, --project [filename]', 'tsconfig.json file path', this.baseDir) .description('typescript compile') .action(options => { this.action.tsc(options); }); } command() { // 注册自定义命令 res tsc this.register('tsc'); super.command(); } };
Action
命令行命令逻辑自定义实现
// ${root}/lib/action.js 'use strict'; const EasyCLI = require('@easy-team/easywebpack-cli'); const Command = require('egg-bin'); const ScriptCommand = require('egg-scripts'); // 自定义 Config 实现,见下发 Config 实现 const Config = require('./config'); module.exports = class ResAction extends EasyCLI.Action { // 提供 Cli 内置 Webpack 配置合并钩子, 需要集成到 cli 内部的 webpack 配置,通过复写该方法实现。 initCustomizeConfig(options) { return Config.getResConfig(options); } // 覆写 dev 命令 dev() { const cmd = ['dev', '--framework', '@easy-team/res']; if (EasyCLI.utils.isEggTypeScriptProject(this.baseDir)) { cmd.push('-r'); cmd.push('egg-ts-helper/register'); } new Command(cmd).start(); } // 覆写 debug 命令 debug() { const cmd = ['debug', '--framework', '@easy-team/res']; if (EasyCLI.utils.isEggTypeScriptProject(this.baseDir)) { cmd.push('-r'); cmd.push('egg-ts-helper/register'); } new Command(cmd).start(); } // 覆写 start 命令 start() { new ScriptCommand(['start', '--framework', '@easy-team/res']).start(); } }
Config
res-cli 内置 Webpack 配置和合并项目自定义 Wepback 处理
// ${root}/lib/config.js 'use strict'; const path = require('path'); const fs = require('fs'); const merge = require('webpack-merge'); const easywebpack = require('@easy-team/easywebpack-react'); // 获取项目自定义 webpack 配置 exports.getResWebpackFileConfig = baseDir => { const filepath = path.resolve(baseDir, 'config/res.config.js'); if (fs.existsSync(filepath)) { return require(filepath); } return {}; }; // 获取 cli 内部默认集成的 webpack 配置 exports.getResConfig = (options = {}) => { const { baseDir = process.cwd(), env } = options; const baseConfig = { baseDir, framework: 'react', // 基于 easywebpack-react 扩展 webpack + react 配置方法 configured: true, // 表示项目自定义 webpack 配置在这里已经进行 merge 合并了,无需再次合并 output: { path: path.join(baseDir, 'app/public') }, module: { rules: [ { ts: true // res 默认开启 easywebpack 的 typescript 支持 }, { scss: true // res 默认开启 easywebpack 的 sass 支持 }, { stylus: true // res 默认开启 easywebpack 的 stylus 支持 }, { less: true // res 默认开启 easywebpack 的 less 支持 } ] } }; const resConfig = exports.getResWebpackFileConfig(baseDir); return merge(baseConfig, resConfig, options); }; // 提供 webpack 最终配置的钩子方法,主要提供给项目自定义需要。 exports.getWebpackConfig = (options = {}) => { const config = exports.getResConfig(options); return easywebpack.getWebpackConfig(config); };
Ask
easy init 骨架初始化交互式配置实现
- name:命令行显示文本说明
- value:唯一的标识
- pkgName: 下载代码模板的 npm 模块名称
- choices: 自定义选择,目前支持 name,description,npm(yarn/npm/cnpm安装模式), style (scss/sass/less/stylus样式)自定义配置。
// ${root}/ask.js 'use strict'; const chalk = require('chalk'); exports.boilerplateChoice = [ { name: `Create ${chalk.green('React')} ${chalk.yellow('Server Side Render')} Web Application for Res`, value: 'res-react-asset-boilerplate', pkgName: 'res-react-asset-boilerplate', choices: ['name', 'description', 'npm'] }, { name: `Create ${chalk.green('React')} ${chalk.yellow('Client Side Render')} Web Application for Res`, value: 'res-react-spa-boilerplate', pkgName: 'res-react-spa-boilerplate', choices: ['name', 'description', 'npm'] }, { name: `Create ${chalk.green('React')} ${chalk.yellow('Nunjucks HTML Render')} Web Application for Res`, value: 'res-react-html-boilerplate', pkgName: 'res-react-html-boilerplate', choices: ['name', 'description', 'npm'] }, { name: `Create ${chalk.green('React')} ${chalk.yellow('Nunjucks Asset Render')} Web Application for Res`, value: 'res-react-asset-boilerplate', pkgName: 'res-react-asset-boilerplate', choices: ['name', 'description', 'npm'] }, { name: `Create ${chalk.green('React')} ${chalk.yellow('TypeScript')} Awesome Web Application for Res`, value: 'res-awesome', pkgName: 'res-awesome', choices: ['name', 'description', 'npm'] }, ];
项目结构
运行效果
验证 cli 可以通过 npm link 或者 npm publish 安装的方式验证 res 命令
- res --help
- res init
- res dev
- res build --size
实际案例
- Egg + React Node Framework Command Line Tool https://github.com/easy-team/res-cli
- Egg + Vue Node Framework Command Line Tool https://github.com/easy-team/ves-cli
相关方案
easywebpack · 语雀?www.yuque.com
https://github.com/easy-team?github.com
喜欢小编的可以点个赞关注小编哦,小编每天都会给大家分享文章。
我自己是一名从事了多年的前端老程序员,小编为大家准备了新出的前端编程学习资料,免费分享给大家!
如果你也想学习前端,那么帮忙转发一下然后再关注小编后私信【1】可以得到我整理的这些前端资料了(私信方法:点击我头像进我主页有个上面有个私信按钮)
猜你喜欢
- 2024-10-09 苹果iPhone 15 Pro系列手机静音拨片将改为Action按钮
- 2024-10-09 22个必须学习的Linux安全命令 简述linux的安全口令规则
- 2024-10-09 盘点|22个基本的Linux安全命令 linux教程安全性
- 2024-10-09 0207-使用Oozie API接口向Kerberos环境的CDH集群提交Shell作业
- 2024-10-09 什么是CSRF攻击? 简述csrf攻击的基本原理
- 2024-10-09 DELMIA软件物流仿真:操作对象显示与隐藏功能介绍与使用方法
- 2024-10-09 机器人机械臂ROS通讯机制发布订阅多线程
你 发表评论:
欢迎- 最近发表
-
- 在 Spring Boot 项目中使用 activiti
- 开箱即用-activiti流程引擎(active 流程引擎)
- 在springBoot项目中整合使用activiti
- activiti中的网关是干什么的?(activiti包含网关)
- SpringBoot集成工作流Activiti(完整源码和配套文档)
- Activiti工作流介绍及使用(activiti工作流会签)
- SpringBoot集成工作流Activiti(实际项目演示)
- activiti工作流引擎(activiti工作流引擎怎么用)
- 工作流Activiti初体验及在数据库中生成的表
- Activiti工作流浅析(activiti6.0工作流引擎深度解析)
- 标签列表
-
- oraclesql优化 (66)
- 类的加载机制 (75)
- feignclient (62)
- 一致性hash算法 (71)
- dockfile (66)
- 锁机制 (57)
- javaresponse (60)
- 查看hive版本 (59)
- phpworkerman (57)
- spark算子 (58)
- vue双向绑定的原理 (68)
- springbootget请求 (58)
- docker网络三种模式 (67)
- spring控制反转 (71)
- data:image/jpeg (69)
- base64 (69)
- java分页 (64)
- kibanadocker (60)
- qabstracttablemodel (62)
- java生成pdf文件 (69)
- deletelater (62)
- com.aspose.words (58)
- android.mk (62)
- qopengl (73)
- epoch_millis (61)
本文暂时没有评论,来添加一个吧(●'◡'●)