vue-cli3打包成zip压缩文件
目前在我司,采用前后分离的方式开发,这就会面临一个问题。那就是部署到服务器时如何部署?我们之前的方式是:执行打包命令生成文件夹-> 将文件压缩成zip -> 将zip上传至服务器 ->解压缩 -> 重启服务。
在测试阶段每天都要回归bug,所以每天都要重复执行上述操作。有没有更自动化一些的方式来实现呢?
就有了自动化部署,但我在研究自动化部署前,其实我是想在打包的时候自动生成zip文件,然后本地的脚本读取zip并上传至服务器,还有一种思路就是上传脚本可以进行打包压缩zip等。
因为我们还有其他部署方式,所以我采用生成zip包与自动部署2步走的方案。
如何实现?
首先项目框架是vue-cli3,我们也都知道vue-cli内置了我们常用的一些webpack配置,比如css压缩、动态生成html等,但它也提供了扩展的方式。
vue-cli3 的webpack配置都放在了根目录下的vue.config.js中。
生成zip的插件是:filemanager-webpack-plugin
(1) 安装依赖 npm install filemanager-webpack-plugin --dev
(2) 打开vue.config.js进行修改。代码如下:
const FileManagerPlugin = require("filemanager-webpack-plugin"); //引入 const packageName = 'dist'; var path = require('path') module.exports = { productionSourceMap: false, outputDir: packageName, // 包名,我这里将他提取成了一个常量 devServer: { open: true, // 默认打开 port: 8001, // 本地服务端口口 proxy: { // 代理 "/api": { target: '192.168.162.73:8085', //服务器地址 changeOrigin: true, ws: true, pathRewrite: { "^/api": "" } } } }, // webpack配置 configureWebpack: config => { config.resolve = { extensions: ['.js', '.vue', '.json', '.ts'], alias: { '@': path.join(__dirname, 'src') } } // plugins插件是一个数组且webpack本身已经有一些配置,那么我们需要将其追加到数组中 let fileManagerPlugin = new FileManagerPlugin({ onEnd: { delete: [ //首先需要删除项目根目录下的dist.zip `./${packageName}.zip`, ], archive: [ //然后我们选择dist文件夹将之打包成dist.zip并放在根目录 {source: `./${packageName}`, destination: `./${packageName}.zip`}, ] } }) config.plugins.push(fileManagerPlugin) // 追加到webpack plugins数组中。 } };
(3) 执行npm run build ,默认会执行此配置文件。会发现根目录下不仅有dist文件夹,还有dist.zip文件夹。
思考
我们在生成文件前先进行删除本地dist.zip文件,可根据自己情况选择。
它默认会先删除本地的dist.zip文件夹,如果是第一次打包其实没有此文件,它会不会报错呢?你可以尝试一下,事实上是不报错的。
vue-cli3打包优化
vue项目打包是需要做一些性能优化的,这篇文章里我写了关于我知道的要做的优化的部分,仅供参考。
const UglifyJsPlugin = require('uglifyjs-webpack-plugin') const path = require('path') // 开启Gzip需要的依赖 yarn add compression-webpack-plugin -D const CompressionWebpackPlugin = require('compression-webpack-plugin') function resolve(dir) { return path.join(__dirname, dir) } // 标记是否是生产环境 const isPruction = process.env.NODE_ENV === "production" const devNeedCdn = false // 标记本地是否需要cdn引入 // cdn配置 // CDN的本质上是将媒体资源,动静态图片(Flash),HTML,CSS,JS等等内容缓存到距离你更近的IDC, // 从而让用户进行共享资源,实现缩减站点间的响应时间等等需求,而网游加速器的本质则是通过建立高带宽机房, // 架设多节点服务器来为用户进行加速。我们可以将一些大体积的模块,让cdn帮我们提供相应的资源, // 这样就可以缓解我们自己的服务器的压力,同时提供更快更好的资源响应 const cdn = { // 模块名称和作用域名(对应的是window里面的全局变量名) external: { vuex: 'Vuex', 'vue-router': 'VueRouter' }, //cdn的css链接 css: [], //cdn的js连接 这里的资源地址请根据自己的连接 js: [ 'https://cdn.staticfile.org/vuex/3.0.2/vuex.min.js', 'https://cdn.staticfile.org/vue-router/3.0.2/vue-router.min.js' ] } module.exports = { // devServer : { // proxy: 'localhost:8080' // }, productionSourceMap: false, // 上线后不生成map文件 chainWebpack: (config) => { // 配置路径别名 config.resolve.alias .set('@', resolve('src')) .set('components', resolve('src/components')) .set('assets', resolve('src/assets')) .set('api', resolve('src/api')) .set('views', resolve('src/views')) // 上线压缩图片 首先要安装 image-webpack-loader 命令 yarn add image-webpack-loader -D config.module.rule('images') .use('image-webpack-loader') .loader('image-webpack-loader') .options({bypassOnDebug:true}) .end() // 注入cdn config.plugin('html').tap(args => { // console.log(args) // 生产环境或本地需要cdn时,才注入cdn if(isPruction || devNeedCdn) { if (isPruction || devNeedCdn) { args[0].cdn = cdn } } return args }) }, configureWebpack: config => { // 用cdn方式引入,则构建时要忽略相关资源 if (isPruction || devNeedCdn) { config.externals = cdn.externals } if(isPruction) { // 判断是否是生产环境 config.mode = "production"; // 上线关闭console和debugger // 代码压缩 config.optimization.minimizer = [ new UglifyJsPlugin({ uglifyOptions: { compress: { warnings: false, // 如果打包产生错误 可注释掉这里 drop_console: true, drop_debugger: true, pure_funcs: ['console.log'] } } }) ] // 打包文件大小配置 config["performance"] = { "maxEntrypointSize": 10000000, // 此选项根据入口起点的最大体积,控制 webpack 何时生成性能提示 单位是(bytes) "maxAssetSize": 3000000 // 此选项根据单个资源体积,控制 webpack 何时生成性能提示 单位是(bytes) } // gzip压缩 const productionGzipExtensions = ['html', 'js', 'css'] config.plugins.push({ filename:'[path].gz[query]', algorithm: 'gzip', test: new RegExp( // 进行压缩的文件类型 '\\.(' + productionGzipExtensions.join('|') + ')$' ), threshold: 10240, // 定义只有大小大于该值的资源会被处理 minRatio: 0.7, // 只有压缩率小于这个值的资源被处理 deleteOriginalAssets: false // 删除原文件 }) // 公共代码抽离 config.optimization.splitChunks = { cacheGroups: { vendor: { chunks: 'all', test: /node_modules/, name: 'vendor', minChunks: 1, maxInitialRequests: 5, minSize: 0, priority: 100 }, common: { chunks: 'all', test: /[\\/]src[\\/]js[\\/]/, name: 'common', minChunks: 2, maxInitialRequests: 5, minSize: 0, priority: 60 }, styles: { name: 'styles', test: /\.(sa|sc|c)ss$/, chunks: 'all', enforce: true }, runtimeChunk: { name: 'manifest' } } } } else { config.mode = 'development' } } }
cdn配置如果添加了那么html文件也要做相应的修改,这里是修改后的html文件
<!DOCTYPE html> <html lang=""> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <link rel="icon" href="https://www.atool.online/article/<%= BASE_URL %>favicon.ico" rel="external nofollow" > <!-- 使用CDN的CSS文件 --> <% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.css) { %> <link href="https://www.atool.online/article/<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="external nofollow" rel="stylesheet" /> <% } %> <title><%= htmlWebpackPlugin.options.title %></title> </head> <body> <noscript> <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> </noscript> <div id="app"></div> <!-- built files will be auto injected --> <!-- 使用CDN的JS文件 --> <% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.js) { %> <script src="https://www.atool.online/article/<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script> <% } %> </body> </html>
以上为个人经验,希望能给大家一个参考,也希望大家多多支持阿兔在线工具。