vue項(xiàng)目打包優(yōu)化的方法實(shí)戰(zhàn)記錄
1.按需加載第三方庫(kù)
例如 ElementUI、lodash 等
a, 裝包
npm install babel-plugin-component -D
b, babel.config.js
module.exports = { "presets": [ "@vue/cli-plugin-babel/preset" ], "plugins": [ [ "component", { "libraryName": "element-ui", "styleLibraryName": "theme-chalk" } ] ] }
c, main.js
import ElementUI from 'element-ui' import 'element-ui/lib/theme-chalk/index.css' Vue.use(ElementUI)
換成
import './plugins/element.js'
element.js
import Vue from 'vue' import { Button, Form, FormItem, Input, Message, Header, Container, Aside, Main, Menu, Submenu, MenuItemGroup, MenuItem, Breadcrumb, BreadcrumbItem, Card, Row, Col, Table, TableColumn, Switch, Tooltip, Pagination, Dialog, MessageBox, Tag, Tree, Select, Option, Cascader, Alert, Tabs, TabPane, Steps, Step, CheckboxGroup, Checkbox, Upload, Timeline, TimelineItem } from 'element-ui' Vue.use(Button) Vue.use(Form) Vue.use(FormItem) Vue.use(Input) Vue.use(Header) Vue.use(Container) Vue.use(Aside) Vue.use(Main) Vue.use(Menu) Vue.use(Submenu) Vue.use(MenuItemGroup) Vue.use(MenuItem) Vue.use(Breadcrumb) Vue.use(BreadcrumbItem) Vue.use(Card) Vue.use(Row) Vue.use(Col) Vue.use(Table) Vue.use(TableColumn) Vue.use(Switch) Vue.use(Tooltip) Vue.use(Pagination) Vue.use(Dialog) Vue.use(Tag) Vue.use(Tree) Vue.use(Select) Vue.use(Option) Vue.use(Cascader) Vue.use(Alert) Vue.use(Tabs) Vue.use(TabPane) Vue.use(Steps) Vue.use(Step) Vue.use(CheckboxGroup) Vue.use(Checkbox) Vue.use(Upload) Vue.use(Timeline) Vue.use(TimelineItem) // 把彈框組件掛著到了 vue 的原型對(duì)象上,這樣每一個(gè)組件都可以直接通過(guò) this 訪問(wèn) Vue.prototype.$message = Message Vue.prototype.$confirm = MessageBox.confirm
效果圖
優(yōu)化 按需加載第三方工具包(例如 lodash)或者使用 CDN 的方式進(jìn)行處理。
按需加載使用的工具方法 (當(dāng)用到的工具方法少時(shí)按需加載打包) 用到的較多通過(guò)cdn
通過(guò)form lodash 搜索 哪處用到
例如此處的 1.
換成
按需導(dǎo)入
效果圖
2.移除console.log
npm i babel-plugin-transform-remove-console -D
babel.config.js
const prodPlugins = [] if (process.env.NODE_ENV === 'production') { prodPlugins.push('transform-remove-console') } module.exports = { presets: ['@vue/cli-plugin-babel/preset'], plugins: [ [ 'component', { libraryName: 'element-ui', styleLibraryName: 'theme-chalk' } ], ...prodPlugins ] }
效果圖
3. Close SourceMap
生產(chǎn)環(huán)境關(guān)閉 功能
vue.config.js
module.exports = { productionSourceMap: false }
效果圖
4. Externals && CDN
通過(guò) externals 排除第三方 JS 和 CSS 文件打包,使用 CDN 加載。
vue.config.js
module.exports = { productionSourceMap: false, chainWebpack: (config) => { config.when(process.env.NODE_ENV === 'production', (config) => { const cdn = { js: [ 'https://cdn.staticfile.org/vue/2.6.11/vue.min.js', 'https://cdn.staticfile.org/vue-router/3.1.3/vue-router.min.js', 'https://cdn.staticfile.org/axios/0.18.0/axios.min.js', 'https://cdn.staticfile.org/echarts/4.1.0/echarts.min.js', 'https://cdn.staticfile.org/nprogress/0.2.0/nprogress.min.js', 'https://cdn.staticfile.org/quill/1.3.4/quill.min.js', 'https://cdn.jsdelivr.net/npm/vue-quill-editor@3.0.4/dist/vue-quill-editor.js' ], css: [ 'https://cdn.staticfile.org/nprogress/0.2.0/nprogress.min.css', 'https://cdn.staticfile.org/quill/1.3.4/quill.core.min.css', 'https://cdn.staticfile.org/quill/1.3.4/quill.snow.min.css', 'https://cdn.staticfile.org/quill/1.3.4/quill.bubble.min.css' ] } config.set('externals', { vue: 'Vue', 'vue-router': 'VueRouter', axios: 'axios', echarts: 'echarts', nprogress: 'NProgress', 'nprogress/nprogress.css': 'NProgress', 'vue-quill-editor': 'VueQuillEditor', 'quill/dist/quill.core.css': 'VueQuillEditor', 'quill/dist/quill.snow.css': 'VueQuillEditor', 'quill/dist/quill.bubble.css': 'VueQuillEditor' }) config.plugin('html').tap((args) => { args[0].isProd = true args[0].cdn = cdn return args }) }) } }
public/index.html
<!DOCTYPE html> <html lang="en"> <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.title %> </title> <% if(htmlWebpackPlugin.options.isProd){ %> <% for(var css of htmlWebpackPlugin.options.cdn.css) { %> <link rel="stylesheet" href="<%=css%>"> <% } %> <% } %> </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 --> <% if(htmlWebpackPlugin.options.isProd){ %> <% for(var js of htmlWebpackPlugin.options.cdn.js) { %> <script src="<%=js%>"></script> <% } %> <% } %> </body> </html>
效果圖
繼續(xù)對(duì) ElementUI 的加載方式進(jìn)行優(yōu)化
vue.config.js
module.exports = { chainWebpack: config => { config.when(process.env.NODE_ENV === 'production', config => { config.set('externals', { './plugins/element.js': 'ELEMENT' }) config.plugin('html').tap(args => { args[0].isProd = true return args }) }) } }
public/index.html
<!DOCTYPE html> <html lang="en"> <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 - ' %>電商后臺(tái)管理系統(tǒng) </title> <% if(htmlWebpackPlugin.options.isProd){ %> <!-- element-ui 的樣式表文件 --> <link rel="stylesheet" /> <!-- element-ui 的 js 文件 --> <script src="https://cdn.staticfile.org/element-ui/2.13.0/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>
效果圖
5.路由懶加載的方式
import Vue from 'vue' import VueRouter from 'vue-router' import Login from '../components/Login.vue' Vue.use(VueRouter) const routes = [ { path: '/', redirect: '/login' }, { path: '/login', component: Login }, { path: '/Home', component: () => import('../components/Home.vue'), redirect: '/welcome', children: [ { path: '/welcome', component: () => import('../components/Welcome.vue') }, { path: '/users', component: () => import('../components/user/Users.vue') }, { path: '/rights', component: () => import('../components/power/Rights.vue') }, { path: '/roles', component: () => import('../components/power/Roles.vue') }, { path: '/categories', component: () => import('../components/goods/Cate.vue') }, { path: '/params', component: () => import('../components/goods/Params.vue') }, { path: '/goods', component: () => import('../components/goods/List.vue') }, { path: '/goods/add', component: () => import('../components/goods/Add.vue') }, { path: '/orders', component: () => import('../components/order/Order.vue') }, { path: '/reports', component: () => import('../components/report/Report.vue') } ] } ] const router = new VueRouter({ routes }) router.beforeEach((to, from, next) => { // to 要訪問(wèn)的路徑 // from 從哪里來(lái)的 // next() 直接放行,next('/login') 表示跳轉(zhuǎn) // 要訪問(wèn) /login 的話那直接放行 if (to.path === '/login') return next() const tokenStr = window.sessionStorage.getItem('token') // token 不存在那就跳轉(zhuǎn)到登錄頁(yè)面 if (!tokenStr) return next('/login') // 否則 token 存在那就放行 next() }) export default router
其他:圖片壓縮、CSS 壓縮和提取、JS 提取...
1.部署到 Nginx
下載 Nginx,雙擊運(yùn)行 nginx.exe,瀏覽器輸入 localhost 能看到界面表示服務(wù)啟動(dòng)成功!
前端 axios 中的 baseURL 指定為 /api,配置 vue.config.js 代理如下
module.exports = { devServer: { proxy: { '/api': { target: 'http://127.0.0.1:8888', changeOrigin: true } } } }
路由模式、基準(zhǔn)地址、404 記得也配置一下
const router = new VueRouter({ mode: 'history', base: '/shop/', routes: [ // ... { path: '*', component: NotFound } ] })
執(zhí)行 npm run build 打包,把 dist 中的內(nèi)容拷貝到 Nginx 的 html 文件夾中
修改 Nginx 配置
http { server { listen 80; location / { # proxy_pass https://www.baidu.com; root html; index index.html index.htm; try_files $uri $uri/ /index.html; } location /api { # 重寫(xiě)地址 # rewrite ^.+api/?(.*)$ /$1 break; # 代理地址 proxy_pass http://127.0.0.1:8888; # 不用管 proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } } }
重啟服務(wù)
nginx -s reload
訪問(wèn) localhost 查看下效果吧
開(kāi)啟 Gzip 壓縮
前端通過(guò) vue.config.js 配置,打包成帶有 gzip 的文件
const CompressionWebpackPlugin = require('compression-webpack-plugin') module.exports = { configureWebpack: config => { if (process.env.NODE_ENV === 'production') { config.plugins = [...config.plugins, new CompressionWebpackPlugin()] } } }
Nginx 中開(kāi)啟 gzip 即可
總結(jié)
到此這篇關(guān)于vue項(xiàng)目打包優(yōu)化的文章就介紹到這了,更多相關(guān)vue項(xiàng)目打包優(yōu)化內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue微信公眾號(hào)網(wǎng)頁(yè)分享的示例代碼
這篇文章主要介紹了Vue微信公眾號(hào)網(wǎng)頁(yè)分享的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05Element框架el-tab點(diǎn)擊標(biāo)簽頁(yè)時(shí)再渲染問(wèn)題的解決
本文主要介紹了Element框架el-tab點(diǎn)擊標(biāo)簽頁(yè)時(shí)再渲染問(wèn)題的解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-04-04vue切換頁(yè)面(路由)時(shí)如何保持滾動(dòng)條回到頂部
這篇文章主要介紹了vue 切換頁(yè)面(路由)時(shí)如何保持滾動(dòng)條回到頂部問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-12-12vue給數(shù)組中對(duì)象排序 sort函數(shù)的用法
這篇文章主要介紹了vue給數(shù)組中對(duì)象排序 sort函數(shù)的用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09在vue使用clipboard.js進(jìn)行一鍵復(fù)制文本的實(shí)現(xiàn)示例
這篇文章主要介紹了在vue使用clipboard.js進(jìn)行一鍵復(fù)制文本的實(shí)現(xiàn)示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-01-01使用Vant如何實(shí)現(xiàn)數(shù)據(jù)分頁(yè),下拉加載
這篇文章主要介紹了使用Vant實(shí)現(xiàn)數(shù)據(jù)分頁(yè)及下拉加載方式。具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06