Vue CLI+Django项目开发版正常,生产打包后运行异常、Vuetify样式缺失
生产环境Vuetify样式丢失问题排查与解决
问题背景
使用Django作为后端、Vue+Vuetify作为前端搭建站点,通过Vue CLI编译.vue文件,部署到生产环境时出现以下异常:
- 执行
vue-cli-service build生成的生产版本应用无法正常渲染,vue-cli-service build --mode development编译的开发版本运行完全正常 - 生产版本运行时JavaScript控制台无任何报错,页面几乎无内容渲染,少量已渲染内容也未加载样式
- axios请求可正常触发,元素审查工具可见DOM节点已正常插入body,仅未渲染展示
相关配置文件
package.json
{ "name": "vueapp", "version": "0.1.0", "private": true, "scripts": { "serve": "vue-cli-service serve", "build": "vue-cli-service build", "build-dev": "vue-cli-service build --mode development", "lint": "vue-cli-service lint" }, "dependencies": { "axios": "^0.21.1", "core-js": "^3.6.5", "vue": "^2.6.11", "vue-router": "^3.2.0", "vuetify": "^2.4.0" }, "devDependencies": { "@mdi/font": "^5.9.55", "@vue/cli-plugin-babel": "~4.5.0", "@vue/cli-plugin-eslint": "~4.5.0", "@vue/cli-plugin-router": "~4.5.0", "@vue/cli-service": "~4.5.0", "babel-eslint": "^10.1.0", "eslint": "^6.7.2", "eslint-plugin-vue": "^6.2.2", "material-design-icons-iconfont": "^6.1.0", "sass": "~1.32.0", "sass-loader": "^10.0.0", "vue-cli-plugin-vuetify": "~2.4.1", "vue-template-compiler": "^2.6.11", "vuetify-loader": "^1.7.0" }, "eslintConfig": { "root": true, "env": { "node": true }, "extends": [ "plugin:vue/essential", "eslint:recommended" ], "parserOptions": { "parser": "babel-eslint" }, "rules": {} }, "browserslist": [ "> 1%", "last 2 versions", "not dead" ] }
vue.config.js
const path = require('path'); module.exports = { publicPath: '/static/app/', outputDir: path.resolve(__dirname, '../static/app/'), filenameHashing: false, runtimeCompiler: true, devServer: { writeToDisk: true, }, transpileDependencies: [ 'vuetify' ], configureWebpack: { resolve: { alias: { '@components': path.resolve(__dirname, 'src/components'), '@shared': path.resolve(__dirname, 'src/shared') }, extensions: ['.js', '.vue', '.json'] } } };
排查记录
2021年9月2日 更新1
执行npm run build仅输出3条资源大小相关警告,无编译错误,完整构建输出如下:
WARNING Compiled with 3 warnings 8:26:39 warning asset size limit: The following asset(s) exceed the recommended size limit (244 KiB). This can impact web performance. Assets: fonts/materialdesignicons-webfont.woff (454 KiB) fonts/materialdesignicons-webfont.woff2 (318 KiB) fonts/materialdesignicons-webfont.ttf (1000 KiB) fonts/materialdesignicons-webfont.eot (1000 KiB) css/chunk-vendors.css (782 KiB) js/chunk-vendors.js (550 KiB) warning entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (244 KiB). This can impact web performance. Entrypoints: app (1.44 MiB) css/chunk-vendors.css js/chunk-vendors.js css/app.css js/app.js warning webpack performance recommendations: You can limit the size of your bundles by using import() or require.ensure to lazy load some parts of your application. File Size Gzipped ..\static\app\js\chunk-vendors.js 550.43 KiB 168.66 KiB ..\static\app\js\app.js 142.10 KiB 28.11 KiB ..\static\app\css\chunk-vendors.css 782.11 KiB 111.41 KiB ..\static\app\css\app.css 0.27 KiB 0.17 KiB Images and other types of assets omitted. DONE Build complete. The ..\static\app directory is ready to be deployed.
2021年9月2日 更新2
测试发现页面中手动引入Vuetify CDN样式即可修复问题:
<link href="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.min.css" rel="stylesheet">
由此判定问题根源为生产构建阶段css和scss未被正常编译,图标资源也未被打包引入。
解决方案
问题本质是Vuetify生产构建时的tree-shaking机制异常,开发模式下默认全量加载样式所以运行正常,生产模式下按需加载逻辑未正确注入样式和图标资源,可按以下步骤修复:
- 检查
src/plugins/vuetify.js配置,显式引入样式和图标依赖:
import Vue from 'vue' import Vuetify from 'vuetify' // 显式引入Vuetify全量样式 import 'vuetify/dist/vuetify.min.css' // 显式引入MDI图标样式 import '@mdi/font/css/materialdesignicons.css' Vue.use(Vuetify) export default new Vuetify({ icons: { iconfont: 'mdi' } })
- 在
vue.config.js中新增css提取配置,强制生产环境正常提取样式文件:
module.exports = { // 原有配置保留,新增以下配置 css: { extract: true, sourceMap: false } }
- 若上述配置仍未解决问题,可关闭Vuetify按需加载,在vuetify配置中添加
treeShake: false即可,打包体积会略有上升,但可彻底避免样式丢失问题。
内容的提问来源于stack exchange,提问作者Mandemon
相关产品推荐
相关产品推荐

