vue单页项目优化

vue-cli 打包时抽离项目相关配置文件

当使用vue-cli进行开发时时常需要动态配置一些设置,比如接口的请求地址(axios.defaults.baseURL)
这些设置可能需要在项目编译后再进行设置的,(方便运维部署人员自己配置接口IP)
所以在vue-cli里我们需要对这些配置文件进行抽离,不让webpack把配置文件也进行编译。

// public/js/index.js
window.global = {
  api: "https://www.baidu.com",
  url: "http://10.10.10.210",
  axios_outtime:1500
};

在 public/index.html 文件中引入
在项目中使用时,直接使用window.global去调用这个配置文件的内容。
<script src="/js/config.js"></script>

vue-cli 开启 Gzip 压缩

  1. 安装压缩插件 cnpm i compression-webpack-plugin@6.1.1 --save-dev

注意,这里不能直接下载,需要下载低版本的。直接下载就是最新版的了,vue脚手架暂时不支持最新版的,所以就会报错

  1. vue.config.js使用
    // 引入gzip压缩插件
    const CompressionPlugin = require('compression-webpack-plugin');
    // 暴露配置项,会被合并到webpack中去
    module.exports = {
        chainWebpack(config) {
            // ......
        },
        configureWebpack: config => {
            // 开发环境不配置  生产环境才去配置
            if (process.env.NODE_ENV !== 'production') return
            return {
                plugins: [
                    //此插件不能使用太高的版本,否则报错:TypeError: Cannot read property 'tapPromise' of undefined
                    new CompressionPlugin({
                        // filename: "[path][base].gz", // 这种方式是默认的,多个文件压缩就有多个.gz文件,建议使用下方的写法
                        filename: '[path].gz[query]', //  使得多个.gz文件合并成一个文件,这种方式压缩后的文件少,建议使用
                        algorithm: 'gzip', // 官方默认压缩算法也是gzip
                        // 使用正则给匹配到的文件做压缩,这里是给html、css、js以及字体(.ttf和.woff和.eot)做压缩
                        test: /\.js$|\.css$|\.html$|\.ttf$|\.eot$|\.woff$/,
                        threshold: 10240, //以字节为单位压缩超过此大小的文件,使用默认值10240吧
                        minRatio: 0.8, // 最小压缩比率,官方默认0.8
                        // 是否删除原有静态资源文件,即只保留压缩后的.gz文件,建议这个置为false,还保留源文件。以防:
                        // 假如出现访问.gz文件访问不到的时候,还可以访问源文件双重保障
                        deleteOriginalAssets: false
                    })
                ]
            }
        },
    };

  1. 这里配置完以后,暂时还不能使用,还需要后端做一下配置,这里后端以nginx为例
    server {
        listen       80;
        server_name  localhost;
        location / {
            try_files $uri $uri/ /index.html;
            root C:/nginx-1.18.0/html/gzip/dist;
            index  index.html index.htm;
        }
        location /api/ {
            proxy_pass http://localhost:6666/;
        }
        
        # 主要是下方的gizp配置
        gzip on; # 开启gzip压缩
        gzip_min_length 4k; # 小于4k的文件不会被压缩,大于4k的文件才会去压缩
        gzip_buffers 16 8k; # 处理请求压缩的缓冲区数量和大小,比如8k为单位申请16倍内存空间;使用默认即可,不用修改
        gzip_http_version 1.1; # 早期版本http不支持,指定默认兼容,不用修改
        gzip_comp_level 2; # gzip 压缩级别,1-9,理论上数字越大压缩的越好,也越占用CPU时间。实际上超过2的再压缩,只能压缩一点点了,但是cpu确是有点浪费。因为2就够用了
                 # 压缩的文件类型 MIME类型,                                   # css             # xml             # 识别php     # 图片
        gzip_types text/plain application/x-javascript application/javascript text/javascript text/css application/xml application/x-httpd-php image/jpeg image/gif image/png application/vnd.ms-fontobject font/x-woff font/ttf;
                 # text                   # 早期js                 # js        # js的另一种写法                                                                                 # .eot字体                   # woff字体  # ttf字体
        gzip_vary on; # 是否在http header中添加Vary: Accept-Encoding,一般情况下建议开启       
    }

图片压缩配置

  1. 安装 cnpm i image-webpack-loader@7.0.1 --save-dev

使用 cnpm 安装,如果使用npm 可能有些安装会报错;

chainWebpack: (config) => {
    // 图片压缩;
    config.module
      .rule("images")
      .test(/\.(png|jpe?g|gif|svg)(\?.*)?$/)
      .use("image-webpack-loader")
      .loader("image-webpack-loader")
      .options({ bypassOnDebug: false });
  },

cdn 配置

在生产环境中 将常见的依赖通过 cdn 引入;


// 生产环境不打包这些包
const externals = {
  vue: "Vue",
  "vue-router": "VueRouter",
  vuex: "Vuex",
  axios: "axios",
};
// CDN 外链,会插入到 index.html 中
const cdn = {
  // 开发环境
  dev: {
    css: [],
    js: [],
  },
  // 生产环境
  build: {
    css: ["https://cdn.jsdelivr.net/npm/ant-design-vue@1.7.8/dist/antd.min.css",],
    js: [
      "https://cdn.jsdelivr.net/npm/vue@2.6.11/dist/vue.min.js",
      "https://cdn.jsdelivr.net/npm/vue-router@3.2.0/dist/vue-router.min.js",
      "https://cdn.jsdelivr.net/npm/axios@0.21.1/dist/axios.min.js",
      "https://cdn.jsdelivr.net/npm/vuex@3.4.0/dist/vuex.min.js",
      "https://cdn.jsdelivr.net/npm/moment@2.29.1/moment.min.js", // 必须先引入moment,否则报错“TypeError: Cannot read property 'default' of undefined”
      "https://cdn.jsdelivr.net/npm/moment@2.29.1/locale/zh-cn.js", // 需同步引入语言包,否则日期选择控件等将默认显示为英文
      "https://cdn.jsdelivr.net/npm/ant-design-vue@1.7.6/dist/antd.min.js",
    ],
  },
};

module.exports = {
    chainWebpack: (config) => {

        // 添加 CDN 参数到 htmlWebpackPlugin 配置中
        config.plugin("html").tap((args) => {
        if (process.env["NODE_ENV"] == "production") {
            args[0].cdn = cdn.build;
            args[0].title = "评价系统"; //设置 index.html 页面的title;
        } else {
            args[0].cdn = cdn.dev;
            args[0].title = "评价系统"; //设置 index.html 页面的title;
        }
        return args;
        });
    },

    configureWebpack:(config)=>{

        // 只在生产环境使用 cdn
        if (process.env["NODE_ENV"] == "production") {
        // 忽略 vue 和 vuex,vueRouter 等模块
            config.externals = externals;
        }
    }
    // public/index.html 文件中 index.html 引入
    <% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.css) { %>
      <link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="preload" as="style" />
      <link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="stylesheet" />
    <% } %>
      <!-- 使用 CDN 加速的 JS 文件,配置在 vue.config.js 下 -->
    <% for (var i in htmlWebpackPlugin.options.cdn&&htmlWebpackPlugin.options.cdn.js) { %>
      <script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script>
    <% } %>
}

删除 Prefetch 优化配置

/*
 * <link rel="prefetch"> 是一种 resource hint,用来告诉浏览器在页面加载完成后,利用空闲时间提前获取用户未来可能会访问的内容。
 * 删除 Prefetch  或者 修改 Prefetch
 * 
 */
chainWebpack: (config) => {
    // 移除 prefetch 插件
    config.plugins.delete("prefetch");
}

devServer开发代理服务器配置


module.exports = {
  productionSourceMap: false,
  // https://cli.vuejs.org/zh/config/?#publicpath
  publicPath: "/",
  // 当运行 vue-cli-service build 时生成的生产环境构建文件的目录。注意目标目录的内容在构建之前会被清除 (构建时传入 --no-clean 可关闭该行为)。
  outputDir: process.env.VUE_APP_outputDir,
  // 是否使用包含运行时编译器的 Vue 构建版本。设置为 true 后你就可以在 Vue 组件中使用 template 选项了,但是这会让你的应用额外增加 10kb 左右。
  runtimeCompiler: true,
  devServer: {
    open: true, // 是否打开浏览器;
    hotOnly: true, // 是否热更新;
    proxy: {
      "/api": {
        // 路径中有 /api 的请求都会走这个代理 , 可以自己定义一个,下面移除即可
        target: "http://10.10.10.211",
        secure: false,
        changeOrigin: true, // 开启代理,在本地创建一个虚拟服务端
        ws: true, // 是否启用  websockets;
        pathRewrite: {
          // 去掉 路径中的  /api  的这一截
          "^/api": "",
        },
      },
    },
  },
}

// .env 文件
VUE_APP_API = "/api"

// axios.js
let HTTP = axios.create({
  baseURL:process.env.VUE_APP_API,
  timeout: 15000,
  headers: {
    "Content-Type": "application/json;charset=UTF-8",
  },
});

vue.config.js 全部的完整配置代码

const externals = {
  vue: "Vue",
  "vue-router": "VueRouter",
  vuex: "Vuex",
  axios: "axios",
};
// CDN 外链,会插入到 index.html 中
const cdn = {
  // 开发环境
  dev: {
    css: [],
    js: [],
  },
  // 生产环境
  build: {
    css: ["https://cdn.jsdelivr.net/npm/ant-design-vue@1.7.6/dist/antd.min.css"],
    js: [
      "https://cdn.jsdelivr.net/npm/vue@2.6.11/dist/vue.min.js",
      "https://cdn.jsdelivr.net/npm/vue-router@3.2.0/dist/vue-router.min.js",
      "https://cdn.jsdelivr.net/npm/axios@0.21.1/dist/axios.min.js",
      "https://cdn.jsdelivr.net/npm/vuex@3.4.0/dist/vuex.min.js",
       "https://cdn.jsdelivr.net/npm/moment@2.29.1/moment.min.js", // 必须先引入moment,否则报错“TypeError: Cannot read property 'default' of undefined”
      "https://cdn.jsdelivr.net/npm/moment@2.29.1/locale/zh-cn.js", // 需同步引入语言包,否则日期选择控件等将默认显示为英文
      "https://cdn.jsdelivr.net/npm/ant-design-vue@1.7.6/dist/antd.min.js",
    ],
  },
};

const CompressionPlugin = require("compression-webpack-plugin");
module.exports = {
  productionSourceMap: false,
  publicPath: "/", //
  outputDir: process.env.VUE_APP_outputDir,
  runtimeCompiler: true, //是否使用包含运行时编译器的 Vue 构建版本。设置为 true 后你就可以在 Vue 组件中使用 template 选项了,但是这会让你的应用额外增加 10kb 左右。
  devServer: {
    open: true, // 是否打开浏览器;
    hotOnly: true, // 是否热更新;
    proxy: {
      "/api": {
        // 路径中有 /api 的请求都会走这个代理 , 可以自己定义一个,下面移除即可
        target: urlList[1],
        secure: false,
        changeOrigin: true, // 开启代理,在本地创建一个虚拟服务端
        ws: true, // 是否启用  websockets;
        pathRewrite: {
          // 去掉 路径中的  /api  的这一截
          "^/api": "",
        },
      },
    },
  },

  chainWebpack: (config) => {
    // 图片压缩;
    config.module
      .rule("images")
      .test(/\.(png|jpe?g|gif|svg)(\?.*)?$/)
      .use("image-webpack-loader")
      .loader("image-webpack-loader")
      .options({ bypassOnDebug: false });
    /*
     * <link rel="prefetch"> 是一种 resource hint,用来告诉浏览器在页面加载完成后,利用空闲时间提前获取用户未来可能会访问的内容。
     * 删除 Prefetch  或者 修改 Prefetch
     * */
    // 移除 prefetch 插件
    config.plugins.delete("prefetch");

    // 添加 CDN 参数到 htmlWebpackPlugin 配置中
    config.plugin("html").tap((args) => {
      if (process.env["NODE_ENV"] == "production") {
        args[0].cdn = cdn.build;
        args[0].title = "评价系统";
      } else {
        args[0].cdn = cdn.dev;
        args[0].title = "评价系统";
      }
      return args;
    });
  },

  configureWebpack: (config) => {
    // gzip压缩配置
    config.plugins.push(
      new CompressionPlugin({
        algorithm: "gzip", // 使用gzip压缩
        test: /\.js$|\.html$|\.css$/, // 匹配文件名
        filename: "[path][base].gz", // 压缩后的文件名(保持原文件名,后缀加.gz)
        minRatio: 1, // 压缩率小于1才会压缩
        threshold: 10240, // 对超过10k的数据压缩
        deleteOriginalAssets: false, // 是否删除未压缩的源文件,谨慎设置,如果希望提供非gzip的资源,可不设置或者设置为false(比如删除打包后的gz后还可以加载到原始资源文件)
      })
    );
    // 只在生产环境使用 cdn
    if (process.env["NODE_ENV"] == "production") {
      // 不打包 vue 和 vuex,vueRouter 等模块
      config.externals = externals;
    }
  },
};

去除 console.log()


1. 安装 npm i babel-plugin-transform-remove-console --save-dev
2. babel.config.js 中配置下面代码

const plugins = ["@vue/babel-plugin-transform-vue-jsx"];
// 去除 环境中 移除console
if (process.env.NODE_ENV === "production") {
  plugins.push("transform-remove-console");
}

module.exports = {
  plugins: plugins,
  presets: ["@vue/cli-plugin-babel/preset"],
};
posted @ 2022-06-27 09:08  kgwei  阅读(128)  评论(0编辑  收藏  举报