字节笔记本

2026年2月22日

Vue CLI 4 配置完全指南:从入门到生产优化

本文介绍 vue-cli4-config,一个 Vue CLI 4 配置参考项目,由 staven630 开发维护。该项目在 GitHub 上已获得 2.7k+ stars,提供了完整的 vue.config.js 配置示例,涵盖 25+ 种优化技巧和最佳实践,帮助开发者快速搭建生产级 Vue 项目。

项目简介

vue-cli4-config 是一个开源的 Vue CLI 4 配置参考项目,旨在为开发者提供一套完整的 webpack 配置方案。项目包含了从开发环境到生产环境的全方位配置,包括代码分割、资源压缩、CDN 加速、多页面打包等高级功能。

核心特性

  • 多环境配置:支持 development、production 等多环境变量配置
  • 代码分割优化:使用 splitChunks 实现 vendor 代码分离
  • 资源压缩:集成 Gzip/Brotli 压缩,减小打包体积
  • CDN 加速:支持 Vue、Element UI 等库的外部 CDN 引用
  • 图片优化:自动压缩图片资源,支持雪碧图生成
  • SVG 处理:支持 SVG 图标组件化和字体转换
  • 多页面打包:支持多入口页面配置
  • 预渲染支持:集成 prerender-spa-plugin 实现静态预渲染
  • 样式规范:集成 Stylelint 进行 SCSS/CSS 代码检查
  • IE 兼容:通过 core-js 和 regenerator-runtime 支持旧版浏览器

技术栈

  • Vue 2.6.10 - 前端框架
  • Vue CLI 4 - 项目脚手架
  • Webpack 4 - 模块打包工具
  • Element UI 2.10.1 - UI 组件库
  • Vue Router 3.0.6 - 路由管理
  • Vuex 3.1.1 - 状态管理
  • SCSS - CSS 预处理器
  • Stylelint - CSS/SCSS 代码规范检查

安装指南

前置要求

  • Node.js >= 12
  • npm >= 6 或 yarn >= 1.22

克隆项目

bash
# 克隆仓库
git clone https://github.com/staven630/vue-cli4-config.git

# 进入项目目录
cd vue-cli4-config

# 安装依赖
npm install

环境变量配置

项目支持多环境配置,创建以下文件:

bash
# .env - 默认环境
VUE_APP_PUBLIC_PATH=/
VUE_APP_BASE_API=https://api.example.com

# .env.development - 开发环境
NODE_ENV=development
VUE_APP_PUBLIC_PATH=/

# .env.production - 生产环境
NODE_ENV=production
VUE_APP_PUBLIC_PATH=https://cdn.example.com/

注意:环境变量必须以 VUE_APP_ 开头才能在客户端代码中访问。

快速开始

bash
# 启动开发服务器
npm run serve

# 构建生产环境
npm run build

# 运行代码检查
npm run lint

核心配置详解

1. 路径别名配置

javascript
// vue.config.js
chainWebpack: config => {
  config.resolve.alias
    .set("@", resolve("src"))
    .set("@components", resolve("src/components"))
    .set("@views", resolve("src/views"))
    .set("@assets", resolve("src/assets"))
    .set("@utils", resolve("src/utils"));
}

2. CDN 外部化配置

javascript
// 生产环境使用 CDN
config.externals = {
  vue: "Vue",
  "element-ui": "ELEMENT",
  "vue-router": "VueRouter",
  vuex: "Vuex",
  axios: "axios"
};

// HTML 中注入 CDN 链接
const cdn = {
  css: ["//unpkg.com/element-ui@2.10.1/lib/theme-chalk/index.css"],
  js: [
    "//unpkg.com/vue@2.6.10/dist/vue.min.js",
    "//unpkg.com/vue-router@3.0.6/dist/vue-router.min.js",
    "//unpkg.com/vuex@3.1.1/dist/vuex.min.js",
    "//unpkg.com/axios@0.19.0/dist/axios.min.js",
    "//unpkg.com/element-ui@2.10.1/lib/index.js"
  ]
};

config.plugin("html").tap(args => {
  args[0].cdn = cdn;
  return args;
});

3. 图片压缩配置

javascript
// 生产环境启用图片压缩
if (IS_PROD) {
  config.module
    .rule("images")
    .test(/\.(png|jpe?g|gif|svg)(\?.*)?$/)
    .use("image-webpack-loader")
    .loader("image-webpack-loader")
    .options({
      mozjpeg: { progressive: true, quality: 65 },
      optipng: { enabled: false },
      pngquant: { quality: [0.65, 0.90], speed: 4 },
      gifsicle: { interlaced: false }
    });
}

4. SVG 雪碧图配置

javascript
// 自动生成雪碧图
const SpritesmithPlugin = require("webpack-spritesmith");

plugins.push(
  new SpritesmithPlugin({
    src: {
      cwd: path.resolve(__dirname, './src/assets/icons/'),
      glob: '**/*.png'
    },
    target: {
      image: path.resolve(__dirname, './src/assets/images/sprites.png'),
      css: [
        [path.resolve(__dirname, './src/assets/scss/sprites.scss'), {
          format: 'function_based_template'
        }]
      ]
    },
    apiOptions: {
      cssImageRef: '../images/sprites.png'
    }
  })
);

5. 全局 SCSS 变量注入

javascript
css: {
  loaderOptions: {
    scss: {
      prependData: `
        @import "@scss/variables.scss";
        @import "@scss/mixins.scss";
        $src: "${process.env.VUE_APP_BASE_API}";
      `
    }
  }
}

6. 代理配置(开发环境)

javascript
devServer: {
  proxy: {
    "/api": {
      target: "https://www.easy-mock.com/mock/...",
      secure: false,
      changeOrigin: true,
      pathRewrite: {
        "^/api": "/"
      }
    }
  }
}

7. Moment.js 语言包优化

javascript
// 只保留中文语言包
config.plugin("ignore").use(
  new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, /zh-cn$/)
);

生产环境优化

代码分割策略

javascript
configureWebpack: config => {
  config.optimization = {
    splitChunks: {
      chunks: 'all',
      cacheGroups: {
        vendor: {
          name: 'chunk-vendors',
          test: /[\\/]node_modules[\\/]/,
          priority: 10,
          chunks: 'initial'
        },
        common: {
          name: 'chunk-common',
          minChunks: 2,
          priority: 5,
          chunks: 'initial',
          reuseExistingChunk: true
        }
      }
    }
  };
}

移除 console.log

bash
# 安装 babel 插件
npm install babel-plugin-transform-remove-console --save-dev
javascript
// babel.config.js
const plugins = [];
if (process.env.NODE_ENV === 'production') {
  plugins.push('transform-remove-console');
}
module.exports = {
  presets: ['@vue/cli-plugin-babel/preset'],
  plugins
};

打包分析

javascript
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin;

// 生产环境启用打包分析
if (IS_PROD) {
  config.plugin("webpack-report").use(BundleAnalyzerPlugin, [
    { analyzerMode: "static" }
  ]);
}

多页面配置

javascript
// pages.config.js
module.exports = {
  index: {
    template: 'public/index.html',
    filename: 'index.html',
    title: '首页'
  },
  admin: {
    template: 'public/admin.html',
    filename: 'admin.html',
    title: '管理后台'
  }
};
javascript
// vue.config.js
const glob = require('glob');
const pagesInfo = require('./pages.config');
const pages = {};

glob.sync('./src/pages/**/main.js').forEach(entry => {
  let chunk = entry.match(/\.\/src\/pages\/(.*)\/main\.js/)[1];
  const curr = pagesInfo[chunk];
  if (curr) {
    pages[chunk] = {
      entry,
      ...curr,
      chunk: ["chunk-vendors", "chunk-common", chunk]
    };
  }
});

module.exports = {
  pages
};

注意事项

  1. 环境变量命名:客户端可访问的环境变量必须以 VUE_APP_ 开头
  2. CDN 版本匹配:确保 CDN 版本与 package.json 中的版本一致
  3. 雪碧图更新:添加新图标后需要重启开发服务器
  4. HMR 问题:如遇到热更新失效,检查 config.resolve.symlinks(true)
  5. 代理配置:生产环境需要使用 Nginx 或服务器端配置代理

项目链接

分享: