这几篇文章是一个系列的。之前的文章在这里:

1,第一节:搭建基础的webpack项目:https://blog.csdn.net/weixin_42349568/article/details/124370794?spm=1001.2014.3001.5502

2,第二节:在项目中引入eslint+prittier+husky:https://blog.csdn.net/weixin_42349568/article/details/124372963?spm=1001.2014.3001.5502

本文是第三节,配置化打包前端项目。项目代码每一节都在各自代码分支里。具体地址见文末。

一,交互式打包

1,为什么需要用户交互

当我们打包前端项目的时候,有时需要用户做一些判断,配置打包的一些参数,于是就可以使用下面的方法,进行处理。

例如分环境打包,我们之前是在package.json文件中的script中写:

"scripts": {"dev": "cross-env envMode=dev webpack serve --config ./config/webpack.dev.conf.js  --color --hot","testing": "cross-env envMode=testing webpack --config ./config/webpack.prod.conf.js  --color","build": "cross-env envMode=prod webpack --config ./config/webpack.prod.conf.js  --color","analyzer": "cross-env envMode=prod analyMode=true webpack --config ./config/webpack.prod.conf.js  --color --progress"},

当我们执行npm run testing的时候,就会打出测试包,而执行npm run build的时候,就会打出生产包。这还只是两个环境,如果有多个环境,多种配置。打包者就需要查看这个文件,了解项目结构才能打出合适的包。

这就有些麻烦,我们需要一个脚本来提供用户交互,让他选择他需要的配置。

2,安装相关依赖

npm i shelljs inquirer chalk@4.1.2 compressing -D
shelljs:可以让我们在终端中命令行的方式执行命令。
inquirer:交互式库,可以让用户在终端进行交互
chalk:字体样式的js库,配置显示在终端上的文本颜色
compressing:压缩文件的js库

3,书写打包脚本

在项目根目录下新建script文件夹,里面新建build.js文件。

//...script/build.js
const shell = require('shelljs');
const inquirer = require('inquirer');
const chalk = require('chalk');
const pkg = require('../package.json');
const compressing = require('compressing');const env = new Map([['测试环境', 'testing'],['生产环境', 'prod']
]);
const bundleType = new Map([['直接打生产包', 'bulid'],['运行打包文件大小分析工具', 'analyzer']
]);const build = async () => {const version = pkg.version;const res = await inquirer.prompt([{type: 'list',name: 'env',message: '请选择你要部署的环境?',choices: ['生产环境', '测试环境']}]);const envName = env.get(res.env);console.log(chalk.green(`您要打包的是 ******* (${version})【${res.env}】*******`));//若是打生产包,则还要判断是直接打生产包还是要运行打包分析工具let res2;let analyzer;if (envName === 'prod') {res2 = await inquirer.prompt([{type: 'list',name: 'bundleType',message: '请选择你要打的生产包的形式?',choices: ['直接打生产包', '运行打包文件大小分析工具']}]);analyzer = bundleType.get(res2.bundleType) === 'analyzer';} else {analyzer = false;}//二次确认const res3 = await inquirer.prompt([{type: 'confirm',name: 'secondCheck',message: '确定以上信息无误?',default: true}]);if (!res3.secondCheck) {return;}console.log(chalk.blue(`cross-env envMode=${envName} analyMode=${analyzer} ./node_modules/.bin/webpack --config ./config/webpack.prod.conf.js  --color`));// exec括号内不能换行,不然环境变量会读取不到await shell.exec(`cross-env envMode=${envName} analyMode=${analyzer} ./node_modules/.bin/webpack --config ./config/webpack.prod.conf.js  --color`);console.log(chalk.green(`编译完成!`));//生产环境生成压缩包if (envName == 'prod') {compressing.zip.compressDir('dist', `${pkg.name}.zip`).then(() => {console.log(chalk.green(`生成压缩包${pkg.name}.zip成功!`));}).catch(err => {console.error(err);});}
};
build();

4,修改package.json中script的配置

  "scripts": {"dev": "cross-env envMode=dev webpack serve --config ./config/webpack.dev.conf.js  --color --hot","build": "node ./script/build.js",},

5,运行打生产包的效果

二,自动化部署

1,为什么要自动化部署

平时开发的时候,经常需要写一部分代码,就需要部署到测试,特别是在联调和测试的时候,这种操作尤其的频繁,为了简化工作。可以把这部分工作用脚本来代替。

2,安装依赖

npm i node-ssh -D

3,在script文件夹下新建shell.js文件

const { NodeSSH } = require('node-ssh');
const path = require('path');
const log = console.log;
const { local, remote, clientConfig } = (() => {return {local: path.resolve(__dirname, '../dist'), //本地 待发布目标remote: '/www/wwwroot/myvue', //服务器 发布地址clientConfig: {port: 22, // ssh 端口host: 'xxx.xx.xx.xxx', // ssh 地址username: 'root', // ssh 用户password: 'xxxxxxxx' // 密码}};
})();async function init() {//实例化node服务器连接协议const client = new NodeSSH();//连接服务器, connect获取连接信息let connect = await client.connect(clientConfig);//判断是否连接成功let isConnected = client.isConnected();if (isConnected) {log('----------------------连接成功----------------------');// 删除对应目录下的所有文件await client.execCommand('rm -rf *', { cwd: remote });log('----------------------删除文件成功----------------------');const status = await client.putDirectory(local, remote, {recursive: true,concurrency: 10,tick: function (localPath, remotePath, error) {console.log('tick is>>>>>>>>>', localPath, remotePath, error);}});//成功为truestatus? console.warn('=================部署成功=================='): console.warn('============部署失败====================');process.exit(0);} else {log('连接失败');}
}
init();

4,修改package.json

  "scripts": {"dev": "cross-env envMode=dev webpack serve --config ./config/webpack.dev.conf.js  --color --hot","build": "node ./script/build.js","lint": "eslint --ext .js --ext .jsx --ext .vue src/","deploy": " node  ./script/shell.js"},

运行npm run bulid先打包出来dist文件。然后npm run deploy执行自动化部署。

5,打包整合自动化部署

我们更希望把自动化部署也整合到第一节的交互式打包中去,这样用户只要运行一个npm run build就行,然后交互是选择需要的操作。

接下来的任务交给脚本执行

并且实际生产过程中,会分测试环境部署和生产环境的部署,这同样需要支持。

于是可以在build.js中加入:

  //询问是否需要打包const isPushRes = await inquirer.prompt([{type: 'confirm',name: 'isPush',message: '是否需要部署到服务器?',default: true}]);if (isPushRes.isPush) {// 开始执行部署的命令await shell.exec(`cross-env envMode=${envName} node ./script/shell.js`);console.log(chalk.green(`部署完成!`));}

然后,shell.js分环境连接服务器:

const env = process.env.envMode;
const { local, remote, clientConfig } = (() => {if (env === 'testing') {return {local: path.resolve(__dirname, '../dist'), //本地 待发布目标remote: '/www/wwwroot/myvue', //服务器 发布地址clientConfig: {port: 22, // ssh 端口host: 'xxx.xx.xx.xx', // ssh 地址username: 'root', // ssh 用户password: '******' // 密码}};} else if (env === 'prod') {return {local: path.resolve(__dirname, '../dist'), //本地 待发布目标remote: '/www/wwwroot/myvue', //服务器 发布地址clientConfig: {port: 22, // ssh 端口host: 'xxx.xxx.xx.xxx', // ssh 地址username: 'root', // ssh 用户password: '****' // 密码}};}
})();

三,最终的代码

1,/script/build.js

const shell = require('shelljs');
const inquirer = require('inquirer');
const chalk = require('chalk');
const pkg = require('../package.json');
const compressing = require('compressing');const env = new Map([['测试环境', 'testing'],['生产环境', 'prod']
]);
const bundleType = new Map([['直接打生产包', 'bulid'],['运行打包文件大小分析工具', 'analyzer']
]);const build = async () => {const version = pkg.version;const res = await inquirer.prompt([{type: 'list',name: 'env',message: '请选择你要部署的环境?',choices: ['生产环境', '测试环境']}]);const envName = env.get(res.env);console.log(chalk.green(`您要打包的是 ******* (${version})【${res.env}】*******`));//若是打生产包,则还要判断是直接打生产包还是要运行打包分析工具let res2;let analyzer;if (envName === 'prod') {res2 = await inquirer.prompt([{type: 'list',name: 'bundleType',message: '请选择你要打的生产包的形式?',choices: ['直接打生产包', '运行打包文件大小分析工具']}]);analyzer = bundleType.get(res2.bundleType) === 'analyzer';} else {analyzer = false;}//询问是否需要打包const isPushRes = await inquirer.prompt([{type: 'confirm',name: 'isPush',message: '是否需要部署到服务器?',default: true}]);//二次确认const res3 = await inquirer.prompt([{type: 'confirm',name: 'secondCheck',message: '确定以上信息无误?',default: true}]);if (!res3.secondCheck) {return;}console.log(chalk.blue(`cross-env envMode=${envName} analyMode=${analyzer} ./node_modules/.bin/webpack --config ./config/webpack.prod.conf.js  --color`));// exec括号内不能换行,不然环境变量会读取不到await shell.exec(`cross-env envMode=${envName} analyMode=${analyzer} ./node_modules/.bin/webpack --config ./config/webpack.prod.conf.js  --color`);console.log(chalk.green(`编译完成!`));if (isPushRes.isPush) {// 开始执行部署的命令await shell.exec(`cross-env envMode=${envName} node ./script/shell.js`);console.log(chalk.green(`部署完成!`));}//生产环境生成压缩包if (envName == 'prod') {compressing.zip.compressDir('dist', `${pkg.name}.zip`).then(() => {console.log(chalk.green(`生成压缩包${pkg.name}.zip成功!`));}).catch(err => {console.error(err);});}
};
build();

2,/script/shell.js

const { NodeSSH } = require('node-ssh');
const path = require('path');
const log = console.log;
const env = process.env.envMode;
const { local, remote, clientConfig } = (() => {if (env === 'testing') {return {local: path.resolve(__dirname, '../dist'), //本地 待发布目标remote: '/www/wwwroot/myvue', //服务器 发布地址clientConfig: {port: 22, // ssh 端口host: 'xxx.xx.xx.xx', // ssh 地址username: 'root', // ssh 用户password: '******' // 密码}};} else if (env === 'prod') {return {local: path.resolve(__dirname, '../dist'), //本地 待发布目标remote: '/www/wwwroot/myvue', //服务器 发布地址clientConfig: {port: 22, // ssh 端口host: 'xxx.xxx.xx.xxx', // ssh 地址username: 'root', // ssh 用户password: '****' // 密码}};}
})();async function init() {//实例化node服务器连接协议const client = new NodeSSH();//连接服务器, connect获取连接信息let connect = await client.connect(clientConfig);//判断是否连接成功let isConnected = client.isConnected();if (isConnected) {log('----------------------连接成功----------------------');// 删除对应目录下的所有文件await client.execCommand('rm -rf *', { cwd: remote });log('----------------------删除文件成功----------------------');const status = await client.putDirectory(local, remote, {recursive: true,concurrency: 10,tick: function (localPath, remotePath, error) {console.log('tick is>>>>>>>>>', localPath, remotePath, error);}});//成功为truestatus? console.warn('=================部署成功=================='): console.warn('============部署失败====================');process.exit(0);} else {log('连接失败');}
}init();

3,实现的效果:

4,最终的项目地址(放置在shelljs分支)

https://gitee.com/ling-xu/webapck5

前端项目架构模板-(三)交互式打包及自动化部署前端项目相关推荐

  1. Vue3+TypeScript从入门到进阶(八)——项目打包和自动化部署——附沿途学习案例及项目实战代码

    文章目录 一.简介 二.Vue2和Vue3区别 三.Vue知识点学习 四.TypeScript知识点 五.项目实战 六.项目打包和自动化部署 一. 项目部署和DevOps 1.1. 传统的开发模式 1 ...

  2. 项目打包和自动化部署

    项目打包和自动化部署 一. 项目部署和DevOps 1.1. 传统的开发模式 在传统的开发模式中,开发的整个过程是按部就班就行: 但是这种模式存在很大的弊端: 工作的不协调:开发人员在开发阶段,测试和 ...

  3. Jenkins自动化部署前端Vue项目

    Jenkins自动化部署前端Vue项目 前言 安装NodeJs 下载NodeJs 安装NodeJs npm配置 Jenkins配置NodeJs 安装NodeJs插件 配置NodeJs 新建及配置任务 ...

  4. (三)jenkins+bonobo git server+windows系统自动化部署springboot项目(远程windows自动化部署)

    前提 jenkins安装,参考:(一)jenkins+bonobo git server+windows系统自动化部署springboot项目(jenkins安装) 自动化部署,参考:(二)jenki ...

  5. cloudmaker一个云架构的画图工具也支持自动化部署,界面清爽功能好用

    最近发现一个云架构画图工具,也支持自动化部署,界面非常清爽,功能也比较完善,分享一下给大家玩一玩. cloudmaker创建于2017年,英国伦敦,创始人是Nick Smith和Alex Metaxa ...

  6. 纯java的方式实现自定义自动化部署java项目

    纯java的方式实现自定义自动化部署java项目 前言 使用第三方的服务或插件实现部署所存在的问题 自动化部署java项目 java项目部署方式 流程 代码实现 打包 使用 java 执行 cmd 进 ...

  7. (二)jenkins+bonobo git server+windows系统自动化部署springboot项目(自动化部署)

    前提:jenkins安装 参考:(一)jenkins+bonobo git server+windows系统自动化部署springboot项目(jenkins安装) 1插件下载 主要是检查如下插件是否 ...

  8. Jenkins结合Gitee(码云)自动化部署Springboot项目(比较详细)

    Jenkins结合码云自动化部署Springboot项目 一.准备工作(有的话,可以忽略) 1. 安装wget 2. 安装jdk 3. 安装maven 4. 安装git 二.开始部署 (jenkins ...

  9. Jenkins自动化部署Vue项目

    Jenkins自动化部署Vue项目 jenkins介绍 Jenkins是开源的,使用Java编写的持续集成的工具,在Centos上可以通过yum命令行直接安装.Jenkins只是一个平台,真正运作的都 ...

  10. 前端项目中的CI/CD实践(自动化部署)

    前言 前置知识 Linux Docker Nginx Github 可以干嘛 作为一套面向开发和运维团队的解决方案,CI/CD 主要解决集成新代码和向用户频繁交付应用的问题. 更直接地说,就是可以解放 ...

最新文章

  1. 笨办法学 Python · 续 第五部分:文本解析
  2. WP8.1学习系列(第十二章)——全景控件Panorama开发指南
  3. 【转】Silverlight 3 Beta 新特性解析(7)- Child Window和Shader Effect篇
  4. C++改变基类成员在派生类中的访问属性
  5. Win32 串口编程(一)
  6. 搜推广遇上用户画像:Lookalike相似人群拓展算法
  7. 最详细的 SAP ABAP Web Service 创建和消费步骤讲解
  8. 厉害了,Servlet3的异步处理机制
  9. 38 FI配置-财务会计-固定资产-组织结构-指定帐户确定
  10. 迪士尼正式收购21世纪福克斯!网友:原来米老鼠才是灭霸…
  11. Apache Spark源码走读之22 -- 浅谈mllib中线性回归的算法实现
  12. 黑马程序员传智播客 python生成器 学习笔记
  13. 开源软件,自由软件,免费软件三者的区别
  14. php第三方微信app支付接口开发,PHP开发APP微信支付接口
  15. OC中内存管理(转)
  16. HTML作业-商城网页
  17. Vue后台管理系统项目——实现登录功能
  18. 【开关电源】降压变换器(BUCK)的断续模式建模
  19. js对abc进行排序
  20. 时序分析(14) GMM (Generalized Method of Moments) with GARCH

热门文章

  1. MOSE:针对配置管理服务器的后渗透工具
  2. 西门子S7系列中间人攻击:流量劫持和转发(一)
  3. Eclipse 中Access restriction: The type ‘XXX’ is not API
  4. 安全清理大部分的C盘内存(一般10GB以上)
  5. win7计算机自动关机设置在哪里设置方法,win7怎么设置自动关机【详细步骤】
  6. c语言0x00如何不截断_数组越界及其避免方法,C语言数组越界详解
  7. MySQL InnoDB中,乐观锁、悲观锁、共享锁、排它锁、行锁、表锁、死锁概念的理解
  8. 跟小丸子学基础口语16-20
  9. SQL Server系统表sysobjects介绍
  10. Prim POJ 2031 Building a Space Station