项目背景
nodejs项目,webpack打包,用axios请求,Promise封装,nunjucks模板引擎;
之前已将nunjucks模板通过webpack打包策略,做成前后端共用;
目前需要将网络请求以及数据处理封装成service模块;
目录划分:
如上图所示:
将公共代码放到service中,整合两端共同的一些网络请求以及数据处理(node首屏,客户端再次请求数据更新等操作)
这里碰到的两个问题:
-
node模块使用module.exports,而webpack我们使用的是import/export,两者共用会报错;
-
我们使用了Promise做了两层封装(service封装、service中的fetch封装:抹平node和客户端的环境差异)
第一个问题,其实webpack也提供了module.exports的方法,所以两端的模块是可以共用的。
而第二个问题,我们使用了Promise,也在webpack全局引入了babel-polyfill,但是会报错:
Uncaught TypeError: Cannot assign to read only property 'exports' of object '#<Object>'
复制代码
导致前面的排查思路一直以为是module.exports出了问题;
解决方法
但最终我们是通过引入es6-promise来解决的:
service/fetch.js:
var axios = require('axios');
var Promise = require('es6-promise').Promise;
module.exports = function(opts, request) {
return new Promise(function(resolve, reject) {
axios(opts).then(function(res) {
res = res.data
if (res.success) {
resolve(res)
} else {
reject({ ___req: opts, ___res: res })
}
}).catch(function(err) {
reject({ ___req: opts, ___res: err.data || err.stack || err })
})
})
}
复制代码
service/wawa.js:
var fetch = require('./fetch');
var Promise = require('es6-promise').Promise;
var getGamelist = function(params, req) {
return new Promise(function(resolve, reject) {
fetch({
url: '/api/appeal/appealJoinOrderPage',
type: 'get',
params: params
}).then(function(res) {
resolve(res.data)
}).catch(function(err) {
reject(err)
})
})
}
module.exports = {
getGamelist
}
复制代码
并且我们也尝试在全局引入es6-promise,仍然报错;
这样我们暂时得出结论,是原生Promise语法,直接与module.exports冲突报错。目前只能通过在当前js中引入es6-promise来规避。
所幸的是,每个js中重复引入的es6-promise,在最终webpack打包的时候会去重,也避免了打包体积变大的问题。
至此,node前后端代码共用的方案通过。并且后面还可以写除了service以外的共用代码,提升了复用性和可维护性。