VUE 打包封装
最近公司好多项目用到了VUE,大家有遇到VUE打包生产,打包测试要修改后端服务器地址的痛点,因为vue脚手架,产生的项目并不完整(3.0可能有所不同),自己算去年就已经是VUE的使用人员,之前对webpack有所研究,结合项目和网上资料,自己实践过VUE项目打包改造。总结如下,希望对大家有所帮助
前提:大家都应该已经有自己的项目了,并且可以打包了,只是打包不方便,
1.对打包的理解
为什么 npm run build 会执行打包?
由于之前是小白,也没有时间研究webpack,所以我全文搜索了一下 build,最后发现最有关联可能的就是build.js和package.json
,此外之前对element admin 的打包 npm run build:prod 产生过兴趣,为啥它不一样,咋整的,所有我又搜索了 build:prod,发现确实在 package.json中,package.json就是模块的描述文件,那么答案就显而易见,
而且很多vue项目居然是用npm start 来启动的,为啥这么6,下一节给出解释
2.element admin打包给我的提示
我们先来看element admin 的package.json,为啥它可以npm run build:prod而不是npm run build,
"scripts": {
"dev": "cross-env BABEL_ENV=development webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
为啥你可以这么写,不用build
"build:prod": "cross-env NODE_ENV=production env_config=prod node build/build.js",
"build:sit": "cross-env NODE_ENV=production env_config=sit node build/build.js",
"lint": "eslint --ext .js,.vue src",
"test": "npm run lint",
"precommit": "lint-staged",
"svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml"
},
你可以写,那么我自己一定也可以这么写,而且我要和你不一样,我要npm run build--prod
"scripts": {
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
npm start 可以运行的原因在此
"start": "npm run dev",
"unit": "jest --config test/unit/jest.conf.js --coverage",
"e2e": "node test/e2e/runner.js",
"test": "npm run unit && npm run e2e",
"lint": "eslint --ext .js,.vue src test/unit test/e2e/specs",
"build": "node build/build.js",
"build:report": "npm_config_report=true node build/build.js",
我模仿添加的打包新命令 npm run build--test
"build--test": "cross-env NODE_ENV=testing env_config=test node build/build.js",
"build--prod": "cross-env NODE_ENV=production env_config=prod node build/build.js"
},
然后赶紧迫不及待的运行一下npm run build--prod,然而并不仅仅是这样,报错
PS D:\git\eyun-front> npm run build--test
npm WARN invalid config proxy="=https://10.0.60.80:8080"
npm WARN invalid config Must be a full url with 'http://'
npm WARN invalid config proxy="=https://10.0.60.80:8080"
npm WARN invalid config Must be a full url with 'http://'
> javalsj-vue@1.0.0 build--test D:\git\eyun-front
> cross-env NODE_ENV=testing env_config=test node build/build.js
'cross-env' 不是内部或外部命令,也不是可运行的程序
或批处理文件。
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! javalsj-vue@1.0.0 build--test: `cross-env NODE_ENV=testing env_config=test node build/build.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the javalsj-vue@1.0.0 build--test script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! C:\Users\qsnp236\AppData\Roaming\npm-cache\_logs\2020-05-15T06_46_11_145Z-debug.log
还好这个报错挺明显 ,就是缺少内部命令,百度一下呗 npm install --save-dev cross-env
PS D:\git\eyun-front> npm install --save-dev cross-env
npm WARN invalid config proxy="=https://10.0.60.80:8080"
npm WARN invalid config Must be a full url with 'http://'
npm WARN invalid config proxy="=https://10.0.60.80:8080"
npm WARN invalid config Must be a full url with 'http://'
npm WARN acorn-jsx@5.0.1 requires a peer of acorn@^6.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN ajv-keywords@3.2.0 requires a peer of ajv@^6.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.7 (node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.7: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
3,还是得先研究一下打包
"build--prod": "cross-env NODE_ENV=production env_config=prod node build/build.js"
cross-env 这个迷你的包(cross-env)能够提供一个设置环境变量的scripts,让你能够以unix方式设置环境变量,然后在windows上也能兼容运行。
NODE_ENV=production env_config=prod 参数
node build/build.js node命令来执行
4 build.js 做了什么
以element admin 为例,看它做了啥,只看主要部分
1.引入生产打包配置文件
const baseWebpackConfig = require('./webpack.base.conf')
2.引入生产参数
const env = require('../config/' + process.env.env_config + '.env') 这个结合3中的解释(NODE_ENV=production env_config=prod 参数),
其实不一定要这么改
我的写法是这样
// const env = require('../config/prod.env')
console.log('################打包'+process.env.NODE_ENV+'############')
const env = process.env.NODE_ENV === 'testing'
? require('../config/test.env')
: require('../config/prod.env')
const env = require('../config/prod.env')
即得到这个
const env =
module.exports = {
NODE_ENV: '"production"',
ENV_CONFIG: '"prod"',
BASE_API: '"http://####:8910/"'
}
3.组装webpack配置信息
const webpackConfig = merge(baseWebpackConfig, {
new webpack.DefinePlugin({
'process.env': env
}),
new HtmlWebpackPlugin({
5.如何动态获取服务Ip和port
调用后台服务我们用的是 axios, element admin 也是如此,它搞了一个src\utils\request.js,你可能通常做的是直接在main.js中,引入axios,然后指定路劲(也是可以的)
element admin是如下做的,这样的好处是可以定义一些 token,超时的限制,错误的统一处理等
onst service = axios.create({
baseURL: process.env.BASE_API, // api 的 base_url
timeout: 25000 // request timeout
})
好的,这研究结束了,我们的项目怎么改造呢,可以参考他
6我们自己项目改造
1.build\webpack.prod.conf.js
中添加
const env = process.env.NODE_ENV === 'testing'
? require('../config/test.env')
: require('../config/prod.env')
这一点有点不太同意 element admin的做法,一个参数其实也能搞定,
2.仿照element admin创建单独的 axios 封装,我命名为http.js
存放路径随意,只要能引入main.js
内容如下
-------------------------------------------------------------------
import Axios from 'axios'
// 设置后端api路径
if (process.env.NODE_ENV == 'development') {
Axios.defaults.baseURL = 'http:///api';}
else if (process.env.NODE_ENV == 'testing') {
Axios.defaults.baseURL = 'http://www/api';
}
else if (process.env.NODE_ENV == 'production') {
Axios.defaults.baseURL = 'https:/api';
}
Axios.defaults.timeout = 30000;
// Axios.defaults.headers['Access-Control-Allow-Origin'] = '*'
// Axios.defaults.headers['Access-Control-Allow-Methods'] = 'POST'
// Axios.defaults.headers['Access-Control-Allow-Headers'] = 'x-requested-with,content-type'
// 设置请求头
Axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8'
Axios.interceptors.request.use(config => {
// config.headers['Accept-Key'] = Store.getters.key
return config
}, error => {
Promise.reject(error)
})
// 设置拦截 出现错误时提示 错误信息
Axios.interceptors.response.use(response => response, error => {
return Promise.reject(error)
})
export default Axios
---------------------------------------------------------------------------------
3.然后在main.js中引入
import HttpRequest from '@/utils/http'
这个路径自己调试,
4.绑定全局参数 main.js中
Vue.prototype.$axios = HttpRequest
5.开始你的表演
7.思考
element admin 不一定是标准,条条道路通罗马,这肯定不是唯一的路径,其他的方式应该也可以
主要思路就是,通过不同的自定义打包命令,在构造axios的时候,动态的选择你的后端服务地址,至于为什么能这么打包,请参考 webpack : https://www.webpackjs.com/
学习笔记 ,仅供参考,