今天有時間分享一些平時自己開發上的一些構建配置,我們以Vue-CLI-2.x來構建開發環境。 好,我們先來看一下我們要做哪些工作。
現附上原始碼地址,github.com/749264345/V…
1.Vue,Vuex,vue-router,axios通過CDN引入;優化打包後檔案過大的問題
2.開發環境區分開發,測試,生產;提高開發效率
3.打包區分測試與生產
4.實現專案打包後自動部署到遠端伺服器
5.模組化構建vuex狀態管理
6.打包後自動清除console.log()
7.專案預設基於Element-ui,對相關元件二次封裝
8.模組化構建axios請求響應攔截器
一寸光陰一寸金,寸金難買寸光陰~ 廢話不多說,直接擼起袖子就是幹~~
1.Vue,Vuex,vue-router,axios通過CDN引入
在過去我們都習慣使用npm或者cnpm安裝依賴,因為這種操作非常方便,但是有利必有弊,有些小夥伴在將專案打包後會發現打包後的js檔案非常龐大,有些甚至達到了幾兆,所以最終導致應用開啟時首屏載入非常慢,因此我們可以使用傳統的引入方式,也就是CDN引入。 Vue,Vuex,vue-router,axios,這些均為靜態資源,我們從它們官網下載適合的版本後放入專案根目錄【static】資料夾,然後修改幾個地方: 首先,index.html
<!--相容ie-->
<script src="./static/libs/polyfill.min.js"></script>
<script src="./static/libs/eventsource.js"></script>
<!--vue-->
<script src="./static/libs/vue.js"></script>
<script src="./static/libs/vue-router.min.js"></script>
<script src="./static/libs/element-ui/element-ui.js"></script>
<script src="./static/libs/axios.js"></script>
<script src="./static/libs/vuex.js"></script>
複製程式碼
然後修改,build/webpack.base.conf.js
module.exports = {
externals: {
'vue': 'Vue',
'vuex': 'Vuex',
'vue-router': 'VueRouter',
'axios': 'axios'
},
...
}
複製程式碼
到這裡基本配置已經完成,最後一步需要在main.js中刪除原先對這些模組的import操作即可。這樣後再打包專案,你會發現頁面非常絲滑,幾乎秒開。
2.開發環境區分開發,測試,生產;提高開發效率
在除錯介面,或者debug的時候我們經常會切換環境,而且在打包的時候又要改成生產的介面,這樣沒有效率,所以我們可以做如下配置。 在config/dev.env.js檔案中,
const TARGET = process.env.npm_lifecycle_event;
//開發環境
if (TARGET === 'dev') {
var data = {
NODE_ENV: '"dev"',
API: '"http://www.dev.com"'
}
}
//測試環境
if (TARGET === 'test') {
var data = {
NODE_ENV: '"test"',
API: '"http://www.test.com"'
}
}
//生產環境
if (TARGET === 'prod') {
var data = {
NODE_ENV: '"prod"',
API: '"http://www.prod.com"'
}
}
複製程式碼
我們從process.env.npm_lifecycle_event中獲得當前node執行的環境來區分專案執行的環境,這樣我們可以用來區分介面環境,因此我們新增相關指令。 在根目錄package.json檔案中,
"scripts": {
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
"test": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
"prod": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js"
},
複製程式碼
新增三條指令,分別為dev,test,prod對應config/dev.env.js檔案中新增的三個環境。 到這裡我們完成了開發環境的區分。
3.打包區分測試與生產
原理和上面一致, 在config/prod.env.js檔案中,
const TARGET = process.env.npm_lifecycle_event;
//測試環境
if (TARGET === 'build:test') {
module.exports = {
NODE_ENV: '"build:test"',
NODE_NAME: '"測試"',
API: '"http://www.test.com"'
}
}
//生產環境
if (TARGET === 'build:prod') {
module.exports = {
NODE_ENV: '"build:prod"',
NODE_NAME: '"生產"',
API: '"http://www.prod.com"'
}
}
複製程式碼
同時在根目錄package.json檔案中,
"scripts": {
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
"test": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
"prod": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
"build:test": "node build/build.js",
"build:prod": "node build/build.js"
},
複製程式碼
我們看到新增了最後2條指令,這裡我麼就可以直接打測試包,與生產包。 而不需要每次在專案中修改程式碼。
4.實現專案打包後自動部署到遠端伺服器
首先安裝
npm install scp2 --save-dev
複製程式碼
然後修改專案build/build.js 新增如下程式碼,
var scpClient = require('scp2');
var serverConf = require('../config/prod.env');
const spinner2 = ora('正在釋出到' + serverConf.NODE_NAME + '伺服器...');
spinner2.start();
scpClient.scp('dist/', serverConf.server,
function (err) {
spinner2.stop();
if (err) {
console.log(chalk.red('釋出失敗.\n'));
throw err;
} else {
var date = new Date();
var year = date.getFullYear();
var month = date.getMonth() + 1;
var day = date.getDate();
var hour = date.getHours();
var minute = date.getMinutes();
var second = date.getSeconds();
console.log(chalk.green(
'Success! 成功釋出到' + serverConf.NODE_NAME + '伺服器! \n' +
year + '年' + month + '月' + day + '日 ' + hour + ':' + minute + ':' + second
));
}
}
);
複製程式碼
另外,我們新增了釋出後顯示當期時間的功能,方便我們檢視。 我們遠端伺服器的配置資訊放在在config/prod.env.js檔案中,如下,
//測試環境
if (TARGET === 'build:test') {
module.exports = {
NODE_ENV: '"build:test"',
NODE_NAME: '"測試"',
API: '"http://192.168.1.123:8080"',
server: {
host: '192.168.1.123',
port: 3122,
username: 'root',
password: '2019111',
path: '/usr/local/nginx/html/test'
}
}
}
複製程式碼
到這裡我們完成了,自動部署的功能,命令列輸入
npm run build:test
複製程式碼
稍等片刻,
OK,完美~
5.模組化構建vuex狀態管理
由於篇幅,以及對於vuex的配置有很多,這裡不再做闡述。
6.打包後自動清除console.log()
開啟build/webpack.prod.conf.js新增一個外掛,
plugins:[
new UglifyJsPlugin({
uglifyOptions: {
compress: {
warnings: false,
drop_console: true,
pure_funcs: ['console.log']
}
},
sourceMap: config.build.productionSourceMap,
parallel: true
}),
]
複製程式碼
這樣,專案打包後的console.log()將不會出現在控制檯,很乾淨。
7.專案預設基於Element-ui,對相關元件二次封裝
這裡我們以element-ui分頁元件為例, 我們新建一個vue檔案,
<template>
<el-pagination background style="text-align:right;margin-top:10px;" popper-class="pagination"
layout="total, prev, pager, next,sizes, jumper"
:total="total"
:page-sizes="[10, 20, 30, 40,50]"
:page-size="size"
:current-page="current"
@size-change="sizeChange"
@current-change="currentChange"></el-pagination>
</template>
<script>
export default {
data() {
return {
pageSize: this.size,
pageCurrent: this.current
}
},
props: {
total: {
type: Number,
default: 0
},
current: {
type: Number,
default: 1
},
size: {
type: Number,
default: 10
}
},
methods: {
currentChange(current) {
this.pageCurrent = current;
this.emit();
},
sizeChange(size) {
this.pageSize = size;
this.pageCurrent = 1;
this.emit();
},
emit() {
this.$emit('pageChange', {
pageSize: this.pageSize,
pageCurrent: this.pageCurrent
})
}
}
}
</script>
複製程式碼
我們通過emit()方法將元件內的狀態傳送給父元件,父元件通過事件訂閱來監聽,我們來看父元件,
<script>
<template>
<!-- 分頁 -->
<Pagination v-on:pageChange="pageChange" :total="total" :current="pageCurrent" :size="pageSize"></Pagination>
</template>
//引入元件
import Pagination from "../components/Pagination";
export default {
components: {
Pagination
},
data() {
return {
//分頁資料
total: 0,
pageSize: 10,
pageCurrent: 1
};
},
methods: {
//分頁發生改變
pageChange(res) {
this.pageSize = res.pageSize;
this.pageCurrent = res.pageCurrent;
}
}
};
</script>
複製程式碼
我們使用pageChange()來監聽,這樣不論是程式碼篇幅還是邏輯都變得更清晰。
8.模組化構建axios請求響應攔截器
我們新建一個檔案,interceptors.js
// 介面請求攔截器
axios.interceptors.request.use((config) => {
//每次請求發起前為當前介面建立,取消請求的例項
const CancelToken = axios.CancelToken;
const source = CancelToken.source();
Vue.prototype.$requestCancel = function () {
source.cancel('canceled');
};
config.cancelToken = source.token;
// 介面新增頭資訊
config.headers.Authorization = localStorage.getItem('token');
return config;
},
(err) => {
return Promise.reject(err);
}
);
// 介面響應攔截器
axios.interceptors.response.use((response) => {
if (response.data.code == 200) {
localStorage.setItem('token', response.headers.authorization);
} else {
Vue.prototype.$message.error(response.data.msg);
}
return response;
},
(error) => {
return Promise.reject(error.response.data);
}
);
複製程式碼
我們通過攔截器實現token資訊的統一獲取和請求攜帶,統一提示錯誤資訊,並且記錄當前請求,並且在路由跳轉時取消上一張頁面的請求,提高當前頁面的有效展現。
由於篇幅問題,具體其他配置請移步我的github~ 原始碼地址,github.com/749264345/V… 如有更優的配置方案請求在下方留言~