webpack打包后复制dist文件到桌面
由于我们项目目前发布前端代码到线上采用的是半自动部署,需要在本地打包,然后进到目录找到dist文件复制出来转成压缩包,然后再去手动上传部署。这样每次都要进去项目目录里面复制dist文件太麻烦,于是有大佬手动写了个webpack插件,每次打包完成后自动复制dist文件到桌面,以下是整理出来的使用方法。
1、复制文件到桌面功能(也就是所谓的自定义插件)源码:
// CopyDist2DeskTop.js
const fs = require('fs');
const path = require('path');
const os = require('os');
// es5写法
// function CopyDist2DeskTop(options){
// }
// CopyDist2DeskTop.prototype.apply = (compiler) => {
// compiler.plugin("after-emit", (compilation, callback) => {
// });
// }
// 直接采用es6写法,比较美观
// es6写法
class CopyDist2DeskTop {
constructor(options) {
// options 接收调用时传进来的参数,目前只做了接收fileName,如果路径那些也想要采用传参的可自己修改
options = options || {};
this.desktop = path.resolve(os.homedir(), 'Desktop') // 桌面路径
this.projectDist = path.resolve('./', 'dist'); // 被复制的文件路径
this.targetDirName = options.fileName || 'dist'; // 输出的文件名称
this.desktopDist = path.resolve(this.desktop, this.targetDirName); // 含有此名称的桌面文件路径
}
apply(compiler) {
// after-emit 生成资源到 output 目录之后(也就是打包之后)的钩子函数
// 查看webpack的其他钩子函数看这个链接 https://www.webpackjs.com/api/compiler-hooks/#afteremit
// compiler.plugin("afterEmit", () => { // webpack-bundle-analyzer高版本(3.0以上)用这个
compiler.plugin("after-emit", (compilation, callback) => { // webpack-bundle-analyzer低版本(3.0以下)用这个
setTimeout(() => {
// 确保最后执行;this是指CopyDist2DeskTop 这个类,方便其他方法获取它里面的东西
new SaveToDesktop(this);
// 功能完成后调用 webpack 提供的回调,一定要调用此回调,否则无法跳出这个函数(低版本才需要用callback)
callback();
}, 1000)
});
}
}
// 获取打包命令
const myEnv = JSON.parse(process.env.npm_config_argv).original[1]; // --sit --uat --pro
console.log('获取打包命令:', myEnv);
const ENV = {
// 'build:sit': '12.4',
'build': '测试环境',
'build:pro': '生产环境'
}
// 将桌面的存在的 dist 重命名为 dist-时间戳
// 复制 dist 到 桌面
const showLog = {
info: (str, title = 'INFO') => {
console.log('\x1B[44;30m ' + title + ' \x1B[49m \x1B[36m ' + str + ' \033[0m')
},
success: (str, title = 'SUCCESS') => {
console.log('\033[42;30m ' + title + ' \033[40;32m ' + str + ' \033[0m')
},
error: (str, title = 'FAIL') => {
console.log('\x1B[41;30m ' + title + ' \x1B[49m \x1B[31m ' + str + ' \033[0m')
}
}
// const desktop = path.resolve(os.homedir(), 'Desktop')
// const projectDist = path.resolve('./', 'dist');
// const targetDirName = 'App';
// const desktopDist = path.resolve(desktop, targetDirName);
class SaveToDesktop {
constructor(options) {
this.desktop = options.desktop;
this.projectDist = options.projectDist;
this.targetDirName = options.targetDirName;
this.desktopDist = options.desktopDist;
try {
// showLog.info(`正在判断打包 dist 目录和桌面 ${targetDirName} 目录...`);
this.resetDist();
showLog.info(`正在复制 dist 目录到桌面 ${options.targetDirName}...`);
copy(options.projectDist, options.desktopDist);
showLog.success('复制到桌面成功');
showLog.success(`快去发布到:${ENV[myEnv] || ''} 吧~`);
} catch(err) {
showLog.error('保存失败 ' + err.toString());
}
}
resetDist() {
if (!fs.existsSync(this.projectDist)) {
throw new Error('请先打包');
}
if (fs.existsSync(this.desktopDist)) {
const newName = this.targetDirName + '-' + new Date().getTime();
showLog.info(`将桌面存在的 ${this.targetDirName},重命名为:${newName}`);
try {
// 如果桌面存在同名称的文件,则将桌面的该文件重命名拼上时间戳,保证没有时间戳的那个就是最新打包出来的
fs.renameSync(this.desktopDist, path.resolve(this.desktop, newName))
} catch(err) {
throw new Error(`无法重命名目录:可能被占用,请尝试解除占用后重试。操作目录:${this.desktopDist}`);
}
}
}
}
/**
* 复制目录中的所有文件包括子目录
* @param {string} 需要复制的目录、文件
* @param {string} 复制到指定的目录、文件
* @param {function} 每次复制前,都会经过一次filterFn,若返回true,则复制。
*/
function copy(oringe, target,filterFn = ()=> true) {
if (fs.statSync(oringe).isDirectory()) {
// 来源是个文件夹,那目标也整一个文件夹
if (!fs.existsSync(target)) {
fs.mkdirSync(target)
}
fs.readdirSync(oringe).forEach(oringeName => {
const oringeFilePath = path.resolve(oringe, oringeName);
const targetFilePath = path.resolve(target, oringeName);
copy(oringeFilePath, targetFilePath, filterFn);
});
} else if(filterFn(oringe, target)){
fs.copyFileSync(oringe, target);
}
}
module.exports = CopyDist2DeskTop;
2、使用
webpack.prod.conf.js
由于我的项目里build.js引用的就是这个webpack.prod.conf.js文件,所以就把插件放这个文件里
// 使用require方式引入你本地的插件脚本
const CopyDist2DeskTop = require('../plugins/CopyDist2DeskTop')
// 直接在plugins的数组里调用
const webpackConfig = merge(baseWebpackConfig, {
plugins: [
// fileName 是复制到桌面上文件的名称,不传默认叫做dist
new CopyDist2DeskTop({fileName:'App'}), // 调用复制dist文件到桌面插件
]
})
打包后的效果
桌面多了个名叫App的文件,如果多次打包,会将桌面旧的名叫App的文件重命名拼上时间戳,保证没有时间戳的那个就是最新打包出来的
方法二:高版本的webpack-bundle-analyzer可以直接用chainWebpack配置
// import CopyDist2DeskTop from './plugins/CopyDist2DeskTop';
const CopyDist2DeskTop = require('./plugins/CopyDist2DeskTop')
module.exports = {
lintOnSave: true,
publicPath:'./',
productionSourceMap: false,
chainWebpack: (config) => {
// 获取打包命令
const myEnv = JSON.parse(process.env.npm_config_argv).original[1];
if(['build','build:pro'].includes(myEnv)){
// 复制到桌面
config.plugin('copy-dist-2-deskTop').use(CopyDist2DeskTop,[{fileName:'poss'}])
}
},
devServer: {
// 端口配置
port: 8888,
// 反向代理配置
proxy: {
'/api': {
target: 'http://xxxxxxx',
ws: true,
pathRewrite: {
'^/api': '/'
}
}
}
}
}