来源: uni-app踩坑+小改造最近团队内部一直在试点用uni-app去做一些小需求,但主要是先在H5上做试点,之后再按计划编 – 掘金
背景
最近团队内部一直在试点用uni-app
去做一些小需求,但主要是先在H5上做试点,之后再按计划编译成小程序去发布。这回分享几个遇到的小问题和解决方案。
下面说到的问题主要在用uni-app
开发H5
平台时才会遇到,非H5
平台可忽略。
跨域的问题
首先,在本地开发时,不同于直接用小程序IDE进行开发,在开发H5
平台时,需要使用浏览器进行调试,而浏览器会有跨域的问题。比如直接通过本地IP地址去访问开发中的页面,同时这个页面会调一些现有的接口时,就面临着跨域的问题。
官方的解决方案
uni-app
官方介绍了一些解决跨域问题的方法,比如服务端开启CORS,给浏览器安装跨域插件等,详见uni-app的H5版使用注意事项。但里面并没有提到(应该是很久未更新文档导致)的是,如果不想这么麻烦去解决,还有个更方便的办法,也就是用webpack-dev-server去代理即可解决。
更方便的解决方案
根据官方文档的描述,devServer
配置被要求在manifest.json
去配置,并且由于这个配置文件是json
格式的,所以只能对简单类型进行配置。但对于proxy
这项配置来说也是足够了的。直接如下方式配置即可解决:
// manifest.json
{
"h5": {
"devServer": {
"proxy": {
"/prefix/api/user/list": {
"target": "https://api-remote.xxxx.com",
"pathRewrite": {
"^/prefix": ""
}
}
}
}
}
}
另一种解决方案
直接创建一个vue.config.js文件,并在里面配置devServer,直接上代码
// vue.config.js
module.exports = {
devServer: {
proxy: {
'/prefix/api/user/list': {
target: 'https://api-remote.xxxx.com',
pathRewrite: {
'^/prefix': ''
}
}
},
}
}
这种办法的好处显而易见,用js
而非json
去配置会更加的灵活,需要注意的是以上两种方案不能同时使用,第一种会覆盖第二种方案。
Mock的问题
这可能也不是什么大问题,毕竟现在有很多像Easy Mock这样的在线Mock平台。但有时我们可能嫌麻烦,不想离开代码编辑窗口去注册,编写在线Mock数据,更想一切都用代码解决,那么同样可以用上面的第二种方案来搞定
解决方案
借助mocker-api
和mockjs
这两个工具,直接配置devServer
的before
选项即可,代码如下:
// vue.config.js
const webpackApiMocker = require('mocker-api')
module.exports = {
devServer: {
before (app) {
webpackApiMocker(app, path.resolve('./mock/index.js'))
}
}
}
// mock/index.js
const Mock = require('mockjs')
const Random = Mock.Random
const mock = Mock.mock
const proxy = {
'GET /api/user/list': mock({
'array|3': [
{
id: 1,
username: 'kenny',
sex: 'male'
}
]
}),
'POST /api/login/account': (req, res) => {
return res.json({
status: 'ok',
data: {
id: Random.id(),
userName: Random.cname(),
city: Random.city()
}
})
}
}
module.exports = proxy
publicPath的问题
到了测试阶段,我们需要将代码部署到CDN上提测,不同的环境对应不同的CDN域名,官方通过manifest.json
的方式配置publicPath显然非常的不灵活,我们希望publicPath
是动态的,与环境,仓库,工程名甚至开发分支有关,而且不需要开发人员去关心。
解决方案
要解决这个问题就需要对脚手架做一些小改造了。
- 首先,我们将
publicPath
这项配置拿出来单独放在一个配置文件中,比如project-config.js
,并放在工程根目录下
const projectName = 'xxx' // 当前工程名,此处自由发挥即可
const isDev = isDev() // 是否为本地开发环境,此处自由发挥即可
const CDN_HOST = process.env.CDN_HOST // build时指定的CDN域名
const APP_ENV = process.env.APP_ENV // build时指定的自定义环境
module.exports = {
publicPath: isDev
? '/'
: `//${CDN_HOST}/static/${projectName}/${APP_ENV}/`,
}
- 其次,我们fork了一版官方的uni-app源码,并对
@dcloudio/vue-cli-plugin-uni/index.js
做了点改动
// @dcloudio/vue-cli-plugin-uni/index.js#L30
// 获取本地的project-config配置
module.exports = (api, options) => {
const projectConfig = require(api.resolve('project-config'))
Object.assign(options, {
outputDir: process.env.UNI_OUTPUT_TMP_DIR || process.env.UNI_OUTPUT_DIR,
assetsDir
}, vueConfig, {
// 重新对publicPath进行覆盖
publicPath: process.env.NODE_ENV === 'production' ? projectConfig.publicPath : '/'
})
}
这样会使manifest.json
中的配置失效,也就是如果使用HBuilder
开发的话会受到点影响。
链接:https://juejin.cn/post/6844904063855755271
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。