打包时,为了直观地发现项目中存在的问题,能够在打包时生成报告。生成报告的方式有两种:javascript
vue-cli
的命令选项能够生成打包报告--report
选项能够生成 report.html 以帮助分析包内容vue-cli-service build --report
经过 vue-cli 3.0 工具生成的项目,默认隐藏了全部 webpack 的配置项css
若是有修改 webpack 默认配置的需求,能够在项目根目录中,按需建立 vue.config.js 这个配置文件,从而对项目的打包发布过程作自定义的配置
(具体配置参考:地址)。html
默认状况下,Vue项目的开发模式与发布模式,共用同一个打包的入口文件(即 src/main.js)。为了将项目的开发过程与发布过程分离,咱们能够为两种模式,各自指定打包的入口文件,即:vue
在 vue.config.js 导出的配置对象中,新增 configureWebpack 或 chainWebpack 节点,来自定义 webpack 的打包配置。java
在这里, configureWebpack 和 chainWebpack 的做用相同,惟一的区别就是它们修改 webpack 配置的方式不一样:webpack
二者具体的使用差别,可参考以下网址:地址ios
module.exports = { chainWebpack: config => { config.when(process.env.NODE_ENV === 'production', config => { // entry默认打包入口 config.entry('app').clear().add('./src/main-prod.js') }) config.when(process.env.NODE_ENV === 'development', config => { config.entry('app').clear().add('./src/main-dev.js') }) } }
默认状况下,经过 import 语法导入的第三方依赖包,最终会被打包合并到同一个文件中,从而致使打包成功后,单文件体积过大的问题。web
为了解决上述问题,能够经过 webpack 的 externals
节点,来配置并加载外部的 CDN 资源。凡是声明在externals
中的第三方依赖包,都不会被打包。vue-router
// vue.config.js config.set('externals', { vue: 'Vue', 'vue-router': 'VueRouter', axios: 'axios' })
// vue.config.js module.exports = { chainWebpack: config => { config.when(process.env.NODE_ENV === 'production', config => { // entry默认打包入口 config.entry('app').clear().add('./src/main-prod.js') config.set('externals', { vue: 'Vue', 'vue-router': 'VueRouter', axios: 'axios' }) }) config.when(process.env.NODE_ENV === 'development', config => { config.entry('app').clear().add('./src/main-dev.js') }) } }
须要在 public/index.html 文件的头部,添加 CDN 资源引用:vue-cli
<script src="https://cdn.staticfile.org/vue/2.5.22/vue.min.js"></script> <script src="https://cdn.staticfile.org/vue-router/3.0.1/vue-router.min.js"></script> <script src="https://cdn.staticfile.org/axios/0.18.0/axios.min.js"></script>
虽然在开发阶段,咱们启用了 element-ui 组件的按需加载,尽量的减小了打包的体积,可是那些被按需加载的组件,仍是占用了较大的文件体积。此时,咱们能够将 element-ui 中的组件,也经过 CDN 的形式来加载,这样可以进一步减少打包后的文件体积。
<!-- element-ui 的 css 文件 --> <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css"/> <!-- element-ui 的 js 文件 --> <script src="https://unpkg.com/element-ui/lib/index.js"></script>
不一样的打包环境下,首页内容可能会有所不一样。咱们能够经过插件的方式进行定制,插件配置以下:
module.exports = { chainWebpack: config => { // 发布模式 config.when(process.env.NODE_ENV === 'production', config => { config.entry('app').clear().add('./src/main-prod.js') // 插件名称 html tap修改插件的相关参数 args 是参数项 config.plugin('html').tap(args => { // 添加isProd自定义属性 args[0].isProd = true return args }) }) // 开发模式 config.when(process.env.NODE_ENV === 'development', config => { config.entry('app').clear().add('./src/main-dev.js') config.plugin('html').tap(args => { args[0].isProd = false return args }) }) } }
在 public/index.html 首页中,能够根据 isProd 的值,来决定如何渲染页面结构:
<!– 按需渲染页面的标题 --> <title><%= htmlWebpackPlugin.options.isProd ? '' : 'dev - ' %>电商后台管理系统</title> <!– 按需加载外部的 CDN 资源 --> <% if(htmlWebpackPlugin.options.isProd) { %> <!—经过 externals 加载的外部 CDN 资源--> <% } %>
// public/index.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="<%= BASE_URL %>favicon.ico" /> <title><%= htmlWebpackPlugin.options.isProd ? '':'dev -' %>Emrof记录</title> <!-- 是否加载CDN资源 --> <% if(htmlWebpackPlugin.options.isProd){ %> <!-- element-ui 的 css 文件 --> <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css" /> <!-- 引入组件库 --> <script src="https://cdn.staticfile.org/vue/2.5.22/vue.min.js"></script> <script src="https://cdn.staticfile.org/vue-router/3.0.1/vue-router.min.js"></script> <script src="https://cdn.staticfile.org/axios/0.18.0/axios.min.js"></script> <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/wangeditor@latest/dist/wangEditor.min.js" ></script> <!-- element-ui 的 js 文件 --> <script src="https://unpkg.com/element-ui/lib/index.js"></script> <% } %> </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 --> </body> </html>
当打包构建项目时,JavaScript 包会变得很是大,影响页面加载。若是咱们能把不一样路由对应的组件分割成不一样的代码块,而后当路由被访问的时候才加载对应组件,这样就更加高效了。
具体须要 3 步:
const Foo = () => import(/* webpackChunkName: "group-foo" */ './Foo.vue') const Bar = () => import(/* webpackChunkName: "group-foo" */ './Bar.vue') const Baz = () => import(/* webpackChunkName: "group-boo" */ './Baz.vue')
关于路由懒加载的详细文档,参考以下:地址
使用 gzip 能够减少文件体积,使传输速度更快。
能够经过服务器端使用 Express 作 gzip 压缩。其配置以下:
// 安装相应包 npm install compression -S // 导入包 const compression = require('compression'); // 启用中间件 app.use(compression());
const express = require('express') // const expressJwt = require('express-jwt') const compression = require('compression'); // 建立服务器 const app = express() // gzip 压缩 app.use(compression()); app.listen(8889, () => { console.log('服务器启动成功!'); })