SaaS工程编译

webpack配置

  • 将工程打包到一个文件中

工程中使用app-module-path设置src为根路径,所以在打包时需要对src做替换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
const path = require('path');
module.exports = {
entry: './index.js',
target: 'node',
output: {
filename: 'bundle.js',
path: __dirname
},
// devtool: 'inline-source-map',
externals: _externals(),
resolve:{
alias: {
config: path.resolve(__dirname, 'config.js'),
'src': path.resolve(__dirname, './src'),
}
}
};
function _externals() {
let manifest = require('./package.json');
let dependencies = manifest.dependencies;
let externals = {};
for (let p in dependencies) {
externals[p] = 'commonjs ' + p;
}
return externals;
}

动态引用转为静态引用脚本

工程通过读取目标来实现动态引用,只在执行时触发,导致两个问题:

  1. 动态路径无法被webpack打包
  2. 转成静态引用后出现循环调用问题

生成静态引用脚本

生成对应目录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const dir = dirname(__dirname)+'/src/routes';
let requireString=`'use strict';
`
fs.readdirSync(dir).filter(function (file) {
return (file.indexOf('.') !== 0) && (file !== 'index.js') && (file.slice(-3) === '.js');
})
.forEach(function (file) {
requireString += `require('./${basename(file)}');\n`
});
fs.writeFileSync(dir+'/index.js',requireString)

循环调用

工程service文件夹内部有相互调用,但直接引用index.js文件,转成静态引用后出现循环调用导致报错

通过Proxy来处理循环引用,原理是在init时只给个proxy对象,在正真调用时返回require对应的文件

1
2
3
4
5
6
7
8
9
10
11
12
module.exports = new Proxy({}, {
get: (target, value) => {
// 有些地方在init时就要获取具体的service (like, {foo} = service),所以需要多返回一层Proxy
return new Proxy({
service: value
}, {
get: (target, value) => {
return requireObj[target.service][value]
}
});
}
})

.env文件处理

增加另外的启动文件run.js,加.env加到环境变量中

1
2
3
4
5
6
7
8
'use strict';
require('dotenv').config({path:__dirname+'/.env'})
process.env.APP_HOME = __dirname;
process.env.pkg = 1;
require('./bundle.js');

pkg编译

run.js设为编译入口,再引入.env和grpc.proto,node_modules也会打包编译进去

1
2
3
4
5
6
// package.json
"bin": "run.js",
"pkg":{
"assets": [".env","grpc.proto"]
}

最后生成saas的执行文件