@modern-js/plugin-bff 1.0.0 → 1.1.2-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +37 -0
- package/README.md +1 -4
- package/dist/js/modern/cli.js +7 -5
- package/dist/js/modern/constants.js +1 -1
- package/dist/js/modern/loader.js +2 -1
- package/dist/js/modern/server.js +67 -12
- package/dist/js/node/cli.js +18 -13
- package/dist/js/node/constants.js +3 -3
- package/dist/js/node/loader.js +2 -1
- package/dist/js/node/server.js +72 -11
- package/dist/types/cli.d.ts +1 -1
- package/dist/types/constants.d.ts +1 -1
- package/package.json +30 -26
- package/src/cli.ts +11 -5
- package/src/constants.ts +1 -1
- package/src/loader.ts +5 -1
- package/src/server.ts +56 -10
- package/tests/.eslintrc.js +6 -0
- package/tests/__snapshots__/cli.test.ts.snap +8 -35
- package/tests/cli.test.ts +37 -6
- package/tests/compiler.ts +1 -1
- package/tests/loader.test.ts +11 -7
- package/tests/server.test.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,42 @@
|
|
|
1
1
|
# @modern-js/plugin-bff
|
|
2
2
|
|
|
3
|
+
## 1.1.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 0fa83663: support more .env files
|
|
8
|
+
- Updated dependencies [6f7fe574]
|
|
9
|
+
- Updated dependencies [b011e0c5]
|
|
10
|
+
- Updated dependencies [0fa83663]
|
|
11
|
+
- Updated dependencies [f594fbc8]
|
|
12
|
+
- Updated dependencies [395beb1e]
|
|
13
|
+
- @modern-js/core@1.1.2
|
|
14
|
+
- @modern-js/babel-preset-lib@1.1.1
|
|
15
|
+
- @modern-js/server-utils@1.1.1
|
|
16
|
+
- @modern-js/bff-utils@1.1.1
|
|
17
|
+
- @modern-js/create-request@1.1.1
|
|
18
|
+
- @modern-js/server-plugin@1.1.1
|
|
19
|
+
- @modern-js/babel-chain@1.1.1
|
|
20
|
+
- @modern-js/babel-compiler@1.1.2
|
|
21
|
+
- @modern-js/utils@1.1.2
|
|
22
|
+
|
|
23
|
+
## 1.1.0
|
|
24
|
+
|
|
25
|
+
### Minor Changes
|
|
26
|
+
|
|
27
|
+
- 96119db2: Relese v1.1.0### Patch Changes
|
|
28
|
+
|
|
29
|
+
- Updated dependencies [96119db2]
|
|
30
|
+
- @modern-js/babel-preset-lib@1.1.0
|
|
31
|
+
- @modern-js/core@1.1.0
|
|
32
|
+
- @modern-js/bff-utils@1.1.0
|
|
33
|
+
- @modern-js/create-request@1.1.0
|
|
34
|
+
- @modern-js/server-plugin@1.1.0
|
|
35
|
+
- @modern-js/server-utils@1.1.0
|
|
36
|
+
- @modern-js/babel-chain@1.1.0
|
|
37
|
+
- @modern-js/babel-compiler@1.1.0
|
|
38
|
+
- @modern-js/utils@1.1.0
|
|
39
|
+
|
|
3
40
|
## 1.0.0
|
|
4
41
|
|
|
5
42
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -17,10 +17,7 @@
|
|
|
17
17
|
|
|
18
18
|
> The doc site ([modernjs.dev](https://modernjs.dev)) and articles are only available in Chinese for now, we are planning to add English versions soon.
|
|
19
19
|
|
|
20
|
-
-
|
|
21
|
-
- [迈入现代 Web 开发](https://zhuanlan.zhihu.com/p/386607009)
|
|
22
|
-
- [现代 Web 开发者问卷调查报告](https://zhuanlan.zhihu.com/p/403206195)
|
|
23
|
-
- [字节跳动是如何落地微前端的](https://mp.weixin.qq.com/s/L9wbfNG5fTXF5bx7dcgj4Q)
|
|
20
|
+
- [Modern.js: Hello, World!](https://zhuanlan.zhihu.com/p/426707646)
|
|
24
21
|
|
|
25
22
|
## Getting Started
|
|
26
23
|
|
package/dist/js/modern/cli.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import fs from 'fs-extra';
|
|
1
3
|
import { createPlugin, useAppContext, useResolvedConfigContext } from '@modern-js/core';
|
|
2
4
|
import { compiler } from '@modern-js/babel-compiler';
|
|
3
|
-
import { PLUGIN_SCHEMAS,
|
|
5
|
+
import { PLUGIN_SCHEMAS, normalizeOutputPath, API_DIR } from '@modern-js/utils';
|
|
4
6
|
import { resolveBabelConfig } from '@modern-js/server-utils';
|
|
5
|
-
import { API_DIR } from "./constants";
|
|
6
7
|
const DEFAULT_API_PREFIX = '/api';
|
|
7
8
|
const TS_CONFIG_FILENAME = 'tsconfig.json';
|
|
8
9
|
const FILE_EXTENSIONS = ['.js', '.ts', '.mjs', '.ejs'];
|
|
@@ -33,13 +34,14 @@ export default createPlugin(() => ({
|
|
|
33
34
|
const prefix = (bff === null || bff === void 0 ? void 0 : bff.prefix) || DEFAULT_API_PREFIX;
|
|
34
35
|
const rootDir = path.resolve(appDirectory, API_DIR);
|
|
35
36
|
chain.resolve.alias.set('@api', rootDir);
|
|
36
|
-
const apiRegexp = new RegExp(`${appDirectory}
|
|
37
|
-
chain.module.rule('loaders').oneOf('bff-client').before('fallback').test(apiRegexp).use('custom-loader').loader(
|
|
37
|
+
const apiRegexp = new RegExp(normalizeOutputPath(`${appDirectory}${path.sep}api${path.sep}.*(.[tj]s)$`));
|
|
38
|
+
chain.module.rule('loaders').oneOf('bff-client').before('fallback').test(apiRegexp).use('custom-loader').loader(require.resolve("./loader").replace(/\\/g, '/')).options({
|
|
38
39
|
prefix,
|
|
39
40
|
apiDir: rootDir,
|
|
40
41
|
port,
|
|
41
42
|
fetcher,
|
|
42
|
-
target: _config.name
|
|
43
|
+
target: _config.name,
|
|
44
|
+
requestCreator: bff === null || bff === void 0 ? void 0 : bff.requestCreator
|
|
43
45
|
});
|
|
44
46
|
}
|
|
45
47
|
},
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const
|
|
1
|
+
export const API_APP_NAME = '_app';
|
|
2
2
|
export const BUILD_FILES = ['**/*.[tj]sx?', '!**/*.test.jsx?', '!**/*.test.tsx?', '!**/*.spec.jsx?', '!**/*.spec.tsx?', '!__tests__/*.tsx?', '!__tests__/*.jsx?'];
|
package/dist/js/modern/loader.js
CHANGED
|
@@ -9,7 +9,7 @@ async function loader(source) {
|
|
|
9
9
|
|
|
10
10
|
const draftOptions = getOptions(this);
|
|
11
11
|
const options = {
|
|
12
|
-
prefix: draftOptions.prefix,
|
|
12
|
+
prefix: Array.isArray(draftOptions.prefix) ? draftOptions.prefix[0] : draftOptions.prefix,
|
|
13
13
|
apiDir: draftOptions.apiDir,
|
|
14
14
|
target: draftOptions.target,
|
|
15
15
|
port: Number(draftOptions.port),
|
|
@@ -26,6 +26,7 @@ async function loader(source) {
|
|
|
26
26
|
options.requestCreator = draftOptions.requestCreator;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
options.requireResolve = require.resolve;
|
|
29
30
|
const result = await generateClient(options);
|
|
30
31
|
|
|
31
32
|
if (result.isOk) {
|
package/dist/js/modern/server.js
CHANGED
|
@@ -1,18 +1,73 @@
|
|
|
1
|
-
import
|
|
1
|
+
import path from 'path';
|
|
2
2
|
import { createPlugin } from '@modern-js/server-plugin';
|
|
3
3
|
import { injectAPIHandlerInfos } from '@modern-js/bff-utils';
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
4
|
+
import { useAppContext } from '@modern-js/core';
|
|
5
|
+
import { API_DIR, isProd, requireExistModule } from '@modern-js/utils';
|
|
6
|
+
import { API_APP_NAME } from "./constants";
|
|
7
|
+
|
|
8
|
+
class Storage {
|
|
9
|
+
constructor() {
|
|
10
|
+
this.middlewares = [];
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
reset() {
|
|
14
|
+
this.middlewares = [];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const createTransformAPI = storage => ({
|
|
20
|
+
addMiddleware(fn) {
|
|
21
|
+
storage.middlewares.push(fn);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
export default createPlugin(() => {
|
|
27
|
+
const {
|
|
28
|
+
appDirectory,
|
|
29
|
+
distDirectory
|
|
30
|
+
} = useAppContext();
|
|
31
|
+
const root = isProd() ? distDirectory : appDirectory;
|
|
32
|
+
const apiPath = path.resolve(root || process.cwd(), API_DIR);
|
|
33
|
+
const apiAppPath = path.resolve(apiPath, API_APP_NAME);
|
|
34
|
+
const storage = new Storage();
|
|
35
|
+
const transformAPI = createTransformAPI(storage);
|
|
36
|
+
const apiMod = requireExistModule(apiAppPath);
|
|
37
|
+
|
|
38
|
+
if (apiMod) {
|
|
39
|
+
apiMod(transformAPI);
|
|
14
40
|
}
|
|
15
41
|
|
|
16
|
-
|
|
42
|
+
return {
|
|
43
|
+
reset() {
|
|
44
|
+
storage.reset();
|
|
45
|
+
const newApiModule = requireExistModule(apiAppPath);
|
|
46
|
+
|
|
47
|
+
if (newApiModule) {
|
|
48
|
+
newApiModule(transformAPI);
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
gather({
|
|
53
|
+
addAPIMiddleware
|
|
54
|
+
}) {
|
|
55
|
+
storage.middlewares.forEach(mid => {
|
|
56
|
+
addAPIMiddleware(mid);
|
|
57
|
+
});
|
|
58
|
+
},
|
|
59
|
+
|
|
60
|
+
prepareApiServer(props, next) {
|
|
61
|
+
const {
|
|
62
|
+
pwd,
|
|
63
|
+
prefix
|
|
64
|
+
} = props;
|
|
65
|
+
const apiDir = path.resolve(pwd, API_DIR);
|
|
66
|
+
injectAPIHandlerInfos(apiDir, prefix);
|
|
67
|
+
return next(props);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
};
|
|
71
|
+
}, {
|
|
17
72
|
name: '@modern-js/plugin-bff'
|
|
18
73
|
});
|
package/dist/js/node/cli.js
CHANGED
|
@@ -5,6 +5,10 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
|
|
8
|
+
var _path = _interopRequireDefault(require("path"));
|
|
9
|
+
|
|
10
|
+
var _fsExtra = _interopRequireDefault(require("fs-extra"));
|
|
11
|
+
|
|
8
12
|
var _core = require("@modern-js/core");
|
|
9
13
|
|
|
10
14
|
var _babelCompiler = require("@modern-js/babel-compiler");
|
|
@@ -13,7 +17,7 @@ var _utils = require("@modern-js/utils");
|
|
|
13
17
|
|
|
14
18
|
var _serverUtils = require("@modern-js/server-utils");
|
|
15
19
|
|
|
16
|
-
|
|
20
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
17
21
|
|
|
18
22
|
const DEFAULT_API_PREFIX = '/api';
|
|
19
23
|
const TS_CONFIG_FILENAME = 'tsconfig.json';
|
|
@@ -45,21 +49,22 @@ var _default = (0, _core.createPlugin)(() => ({
|
|
|
45
49
|
} = bff || {};
|
|
46
50
|
const prefix = (bff === null || bff === void 0 ? void 0 : bff.prefix) || DEFAULT_API_PREFIX;
|
|
47
51
|
|
|
48
|
-
const rootDir =
|
|
52
|
+
const rootDir = _path.default.resolve(appDirectory, _utils.API_DIR);
|
|
49
53
|
|
|
50
54
|
chain.resolve.alias.set('@api', rootDir);
|
|
51
|
-
const apiRegexp = new RegExp(`${appDirectory}
|
|
52
|
-
chain.module.rule('loaders').oneOf('bff-client').before('fallback').test(apiRegexp).use('custom-loader').loader(
|
|
55
|
+
const apiRegexp = new RegExp((0, _utils.normalizeOutputPath)(`${appDirectory}${_path.default.sep}api${_path.default.sep}.*(.[tj]s)$`));
|
|
56
|
+
chain.module.rule('loaders').oneOf('bff-client').before('fallback').test(apiRegexp).use('custom-loader').loader(require.resolve("./loader").replace(/\\/g, '/')).options({
|
|
53
57
|
prefix,
|
|
54
58
|
apiDir: rootDir,
|
|
55
59
|
port,
|
|
56
60
|
fetcher,
|
|
57
|
-
target: _config.name
|
|
61
|
+
target: _config.name,
|
|
62
|
+
requestCreator: bff === null || bff === void 0 ? void 0 : bff.requestCreator
|
|
58
63
|
});
|
|
59
64
|
}
|
|
60
65
|
},
|
|
61
66
|
source: {
|
|
62
|
-
moduleScopes: [`./${
|
|
67
|
+
moduleScopes: [`./${_utils.API_DIR}`]
|
|
63
68
|
}
|
|
64
69
|
};
|
|
65
70
|
},
|
|
@@ -103,13 +108,13 @@ var _default = (0, _core.createPlugin)(() => ({
|
|
|
103
108
|
|
|
104
109
|
const modernConfig = (0, _core.useResolvedConfigContext)();
|
|
105
110
|
|
|
106
|
-
const rootDir =
|
|
111
|
+
const rootDir = _path.default.resolve(appDirectory, _utils.API_DIR);
|
|
107
112
|
|
|
108
|
-
const distDir =
|
|
113
|
+
const distDir = _path.default.resolve(distDirectory, _utils.API_DIR);
|
|
109
114
|
|
|
110
|
-
const sourceAbsDir =
|
|
115
|
+
const sourceAbsDir = _path.default.resolve(appDirectory, _utils.API_DIR);
|
|
111
116
|
|
|
112
|
-
const tsconfigPath =
|
|
117
|
+
const tsconfigPath = _path.default.resolve(appDirectory, TS_CONFIG_FILENAME);
|
|
113
118
|
|
|
114
119
|
const babelConfig = (0, _serverUtils.resolveBabelConfig)(appDirectory, modernConfig, {
|
|
115
120
|
tsconfigPath,
|
|
@@ -124,9 +129,9 @@ var _default = (0, _core.createPlugin)(() => ({
|
|
|
124
129
|
ignore: [`**/__tests__/**`, '**/typings/**', '*.d.ts']
|
|
125
130
|
}, babelConfig);
|
|
126
131
|
|
|
127
|
-
if (await
|
|
128
|
-
await
|
|
129
|
-
filter: src => !['.ts', '.js'].includes(
|
|
132
|
+
if (await _fsExtra.default.pathExists(rootDir)) {
|
|
133
|
+
await _fsExtra.default.copy(rootDir, distDir, {
|
|
134
|
+
filter: src => !['.ts', '.js'].includes(_path.default.extname(src)) && src !== tsconfigPath
|
|
130
135
|
});
|
|
131
136
|
}
|
|
132
137
|
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.BUILD_FILES = exports.
|
|
7
|
-
const
|
|
8
|
-
exports.
|
|
6
|
+
exports.BUILD_FILES = exports.API_APP_NAME = void 0;
|
|
7
|
+
const API_APP_NAME = '_app';
|
|
8
|
+
exports.API_APP_NAME = API_APP_NAME;
|
|
9
9
|
const BUILD_FILES = ['**/*.[tj]sx?', '!**/*.test.jsx?', '!**/*.test.tsx?', '!**/*.spec.jsx?', '!**/*.spec.tsx?', '!__tests__/*.tsx?', '!__tests__/*.jsx?'];
|
|
10
10
|
exports.BUILD_FILES = BUILD_FILES;
|
package/dist/js/node/loader.js
CHANGED
|
@@ -17,7 +17,7 @@ async function loader(source) {
|
|
|
17
17
|
|
|
18
18
|
const draftOptions = (0, _loaderUtils.getOptions)(this);
|
|
19
19
|
const options = {
|
|
20
|
-
prefix: draftOptions.prefix,
|
|
20
|
+
prefix: Array.isArray(draftOptions.prefix) ? draftOptions.prefix[0] : draftOptions.prefix,
|
|
21
21
|
apiDir: draftOptions.apiDir,
|
|
22
22
|
target: draftOptions.target,
|
|
23
23
|
port: Number(draftOptions.port),
|
|
@@ -34,6 +34,7 @@ async function loader(source) {
|
|
|
34
34
|
options.requestCreator = draftOptions.requestCreator;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
options.requireResolve = require.resolve;
|
|
37
38
|
const result = await (0, _bffUtils.generateClient)(options);
|
|
38
39
|
|
|
39
40
|
if (result.isOk) {
|
package/dist/js/node/server.js
CHANGED
|
@@ -5,28 +5,89 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
|
|
8
|
-
var
|
|
8
|
+
var _path = _interopRequireDefault(require("path"));
|
|
9
9
|
|
|
10
10
|
var _serverPlugin = require("@modern-js/server-plugin");
|
|
11
11
|
|
|
12
12
|
var _bffUtils = require("@modern-js/bff-utils");
|
|
13
13
|
|
|
14
|
+
var _core = require("@modern-js/core");
|
|
15
|
+
|
|
16
|
+
var _utils = require("@modern-js/utils");
|
|
17
|
+
|
|
14
18
|
var _constants = require("./constants");
|
|
15
19
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
21
|
+
|
|
22
|
+
class Storage {
|
|
23
|
+
constructor() {
|
|
24
|
+
this.middlewares = [];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
reset() {
|
|
28
|
+
this.middlewares = [];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const createTransformAPI = storage => ({
|
|
34
|
+
addMiddleware(fn) {
|
|
35
|
+
storage.middlewares.push(fn);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
var _default = (0, _serverPlugin.createPlugin)(() => {
|
|
41
|
+
const {
|
|
42
|
+
appDirectory,
|
|
43
|
+
distDirectory
|
|
44
|
+
} = (0, _core.useAppContext)();
|
|
45
|
+
const root = (0, _utils.isProd)() ? distDirectory : appDirectory;
|
|
22
46
|
|
|
23
|
-
|
|
47
|
+
const apiPath = _path.default.resolve(root || process.cwd(), _utils.API_DIR);
|
|
24
48
|
|
|
25
|
-
|
|
26
|
-
|
|
49
|
+
const apiAppPath = _path.default.resolve(apiPath, _constants.API_APP_NAME);
|
|
50
|
+
|
|
51
|
+
const storage = new Storage();
|
|
52
|
+
const transformAPI = createTransformAPI(storage);
|
|
53
|
+
const apiMod = (0, _utils.requireExistModule)(apiAppPath);
|
|
54
|
+
|
|
55
|
+
if (apiMod) {
|
|
56
|
+
apiMod(transformAPI);
|
|
27
57
|
}
|
|
28
58
|
|
|
29
|
-
|
|
59
|
+
return {
|
|
60
|
+
reset() {
|
|
61
|
+
storage.reset();
|
|
62
|
+
const newApiModule = (0, _utils.requireExistModule)(apiAppPath);
|
|
63
|
+
|
|
64
|
+
if (newApiModule) {
|
|
65
|
+
newApiModule(transformAPI);
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
gather({
|
|
70
|
+
addAPIMiddleware
|
|
71
|
+
}) {
|
|
72
|
+
storage.middlewares.forEach(mid => {
|
|
73
|
+
addAPIMiddleware(mid);
|
|
74
|
+
});
|
|
75
|
+
},
|
|
76
|
+
|
|
77
|
+
prepareApiServer(props, next) {
|
|
78
|
+
const {
|
|
79
|
+
pwd,
|
|
80
|
+
prefix
|
|
81
|
+
} = props;
|
|
82
|
+
|
|
83
|
+
const apiDir = _path.default.resolve(pwd, _utils.API_DIR);
|
|
84
|
+
|
|
85
|
+
(0, _bffUtils.injectAPIHandlerInfos)(apiDir, prefix);
|
|
86
|
+
return next(props);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
};
|
|
90
|
+
}, {
|
|
30
91
|
name: '@modern-js/plugin-bff'
|
|
31
92
|
});
|
|
32
93
|
|
package/dist/types/cli.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const
|
|
1
|
+
export declare const API_APP_NAME = "_app";
|
|
2
2
|
export declare const BUILD_FILES: string[];
|
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"modern",
|
|
12
12
|
"modern.js"
|
|
13
13
|
],
|
|
14
|
-
"version": "1.
|
|
14
|
+
"version": "1.1.2-beta.0",
|
|
15
15
|
"jsnext:source": "./src/index.ts",
|
|
16
16
|
"types": "./dist/types/index.d.ts",
|
|
17
17
|
"main": "./dist/js/node/index.js",
|
|
@@ -41,26 +41,37 @@
|
|
|
41
41
|
]
|
|
42
42
|
}
|
|
43
43
|
},
|
|
44
|
+
"scripts": {
|
|
45
|
+
"prepare": "pnpm build",
|
|
46
|
+
"prepublishOnly": "pnpm build -- --platform",
|
|
47
|
+
"new": "modern new",
|
|
48
|
+
"build": "modern build",
|
|
49
|
+
"dev": "modern build --watch",
|
|
50
|
+
"test": "modern test"
|
|
51
|
+
},
|
|
44
52
|
"dependencies": {
|
|
45
53
|
"@babel/core": "^7.15.5",
|
|
46
54
|
"@babel/runtime": "^7",
|
|
47
|
-
"@modern-js/babel-chain": "
|
|
48
|
-
"@modern-js/babel-compiler": "
|
|
49
|
-
"@modern-js/babel-preset-lib": "
|
|
50
|
-
"@modern-js/
|
|
51
|
-
"@modern-js/utils": "
|
|
55
|
+
"@modern-js/babel-chain": "workspace:^1.1.1",
|
|
56
|
+
"@modern-js/babel-compiler": "workspace:^1.1.2",
|
|
57
|
+
"@modern-js/babel-preset-lib": "workspace:^1.1.1",
|
|
58
|
+
"@modern-js/create-request": "workspace:^1.1.1",
|
|
59
|
+
"@modern-js/server-utils": "workspace:^1.1.1",
|
|
60
|
+
"@modern-js/utils": "workspace:^1.1.2",
|
|
61
|
+
"fs-extra": "^10.0.0",
|
|
52
62
|
"loader-utils": "^2.0.0"
|
|
53
63
|
},
|
|
54
64
|
"devDependencies": {
|
|
55
|
-
"@modern-js/
|
|
56
|
-
"@modern-js/
|
|
57
|
-
"@modern-js/
|
|
58
|
-
"@modern-js/plugin-
|
|
59
|
-
"@modern-js/plugin-
|
|
60
|
-
"@modern-js/
|
|
61
|
-
"@modern-js/
|
|
62
|
-
"@modern-js/types": "
|
|
65
|
+
"@modern-js/bff-utils": "workspace:^1.1.1",
|
|
66
|
+
"@modern-js/core": "workspace:^1.1.2",
|
|
67
|
+
"@modern-js/module-tools": "^1.1.1",
|
|
68
|
+
"@modern-js/plugin-analyze": "workspace:^1.1.1",
|
|
69
|
+
"@modern-js/plugin-testing": "^1.1.1",
|
|
70
|
+
"@modern-js/runtime": "workspace:^1.1.1",
|
|
71
|
+
"@modern-js/server-plugin": "workspace:^1.1.1",
|
|
72
|
+
"@modern-js/types": "workspace:^1.1.2",
|
|
63
73
|
"@types/babel__core": "^7.1.15",
|
|
74
|
+
"@types/fs-extra": "^9.0.13",
|
|
64
75
|
"@types/jest": "^26",
|
|
65
76
|
"@types/loader-utils": "^2.0.3",
|
|
66
77
|
"@types/node": "^14",
|
|
@@ -68,13 +79,12 @@
|
|
|
68
79
|
"ts-jest": "^27.0.5",
|
|
69
80
|
"typescript": "^4",
|
|
70
81
|
"webpack": "^5.54.0",
|
|
71
|
-
"webpack-chain": "^6.5.1"
|
|
72
|
-
"@modern-js/module-tools": "^1.0.0"
|
|
82
|
+
"webpack-chain": "^6.5.1"
|
|
73
83
|
},
|
|
74
84
|
"peerDependencies": {
|
|
75
|
-
"@modern-js/
|
|
76
|
-
"@modern-js/
|
|
77
|
-
"@modern-js/
|
|
85
|
+
"@modern-js/bff-utils": "workspace:^1.1.1",
|
|
86
|
+
"@modern-js/core": "workspace:^1.1.2",
|
|
87
|
+
"@modern-js/server-plugin": "workspace:^1.1.1"
|
|
78
88
|
},
|
|
79
89
|
"modernConfig": {
|
|
80
90
|
"output": {
|
|
@@ -85,11 +95,5 @@
|
|
|
85
95
|
"publishConfig": {
|
|
86
96
|
"registry": "https://registry.npmjs.org/",
|
|
87
97
|
"access": "public"
|
|
88
|
-
},
|
|
89
|
-
"scripts": {
|
|
90
|
-
"new": "modern new",
|
|
91
|
-
"build": "modern build",
|
|
92
|
-
"dev": "modern build --watch",
|
|
93
|
-
"test": "modern test"
|
|
94
98
|
}
|
|
95
|
-
}
|
|
99
|
+
}
|
package/src/cli.ts
CHANGED
|
@@ -1,22 +1,23 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import fs from 'fs-extra';
|
|
1
3
|
import {
|
|
2
4
|
createPlugin,
|
|
3
5
|
useAppContext,
|
|
4
6
|
useResolvedConfigContext,
|
|
5
7
|
} from '@modern-js/core';
|
|
6
8
|
import { compiler } from '@modern-js/babel-compiler';
|
|
7
|
-
import { PLUGIN_SCHEMAS,
|
|
9
|
+
import { PLUGIN_SCHEMAS, normalizeOutputPath, API_DIR } from '@modern-js/utils';
|
|
8
10
|
import { resolveBabelConfig } from '@modern-js/server-utils';
|
|
9
11
|
|
|
10
12
|
import type { Configuration } from 'webpack';
|
|
11
13
|
import type Chain from 'webpack-chain';
|
|
12
14
|
import type { ServerRoute } from '@modern-js/types';
|
|
13
|
-
import { API_DIR } from './constants';
|
|
14
15
|
|
|
15
16
|
declare module '@modern-js/core' {
|
|
16
17
|
interface UserConfig {
|
|
17
18
|
bff: {
|
|
18
19
|
prefix?: string;
|
|
19
|
-
|
|
20
|
+
requestCreator?: string;
|
|
20
21
|
fetcher?: string;
|
|
21
22
|
proxy: Record<string, any>;
|
|
22
23
|
};
|
|
@@ -49,20 +50,25 @@ export default createPlugin(
|
|
|
49
50
|
|
|
50
51
|
chain.resolve.alias.set('@api', rootDir);
|
|
51
52
|
|
|
52
|
-
const apiRegexp = new RegExp(
|
|
53
|
+
const apiRegexp = new RegExp(
|
|
54
|
+
normalizeOutputPath(
|
|
55
|
+
`${appDirectory}${path.sep}api${path.sep}.*(.[tj]s)$`,
|
|
56
|
+
),
|
|
57
|
+
);
|
|
53
58
|
chain.module
|
|
54
59
|
.rule('loaders')
|
|
55
60
|
.oneOf('bff-client')
|
|
56
61
|
.before('fallback')
|
|
57
62
|
.test(apiRegexp)
|
|
58
63
|
.use('custom-loader')
|
|
59
|
-
.loader(
|
|
64
|
+
.loader(require.resolve('./loader').replace(/\\/g, '/'))
|
|
60
65
|
.options({
|
|
61
66
|
prefix,
|
|
62
67
|
apiDir: rootDir,
|
|
63
68
|
port,
|
|
64
69
|
fetcher,
|
|
65
70
|
target: _config.name,
|
|
71
|
+
requestCreator: bff?.requestCreator,
|
|
66
72
|
});
|
|
67
73
|
},
|
|
68
74
|
},
|
package/src/constants.ts
CHANGED
package/src/loader.ts
CHANGED
|
@@ -20,7 +20,9 @@ async function loader(this: LoaderContext<APILoaderOptions>, source: string) {
|
|
|
20
20
|
const draftOptions = getOptions(this as any);
|
|
21
21
|
|
|
22
22
|
const options: GenClientOptions = {
|
|
23
|
-
prefix: draftOptions.prefix
|
|
23
|
+
prefix: (Array.isArray(draftOptions.prefix)
|
|
24
|
+
? draftOptions.prefix[0]
|
|
25
|
+
: draftOptions.prefix) as string,
|
|
24
26
|
apiDir: draftOptions.apiDir as string,
|
|
25
27
|
target: draftOptions.target as string,
|
|
26
28
|
port: Number(draftOptions.port),
|
|
@@ -37,6 +39,8 @@ async function loader(this: LoaderContext<APILoaderOptions>, source: string) {
|
|
|
37
39
|
options.requestCreator = draftOptions.requestCreator as string;
|
|
38
40
|
}
|
|
39
41
|
|
|
42
|
+
options.requireResolve = require.resolve;
|
|
43
|
+
|
|
40
44
|
const result = await generateClient(options);
|
|
41
45
|
|
|
42
46
|
if (result.isOk) {
|
package/src/server.ts
CHANGED
|
@@ -1,18 +1,64 @@
|
|
|
1
|
-
import
|
|
1
|
+
import path from 'path';
|
|
2
2
|
import { createPlugin } from '@modern-js/server-plugin';
|
|
3
3
|
import { injectAPIHandlerInfos } from '@modern-js/bff-utils';
|
|
4
|
-
import {
|
|
4
|
+
import { useAppContext } from '@modern-js/core';
|
|
5
|
+
import { API_DIR, isProd, requireExistModule } from '@modern-js/utils';
|
|
6
|
+
import { API_APP_NAME } from './constants';
|
|
7
|
+
|
|
8
|
+
type SF = (args: any) => void;
|
|
9
|
+
class Storage {
|
|
10
|
+
public middlewares: SF[] = [];
|
|
11
|
+
|
|
12
|
+
reset() {
|
|
13
|
+
this.middlewares = [];
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const createTransformAPI = (storage: Storage) => ({
|
|
18
|
+
addMiddleware(fn: SF) {
|
|
19
|
+
storage.middlewares.push(fn);
|
|
20
|
+
},
|
|
21
|
+
});
|
|
5
22
|
|
|
6
23
|
export default createPlugin(
|
|
7
|
-
() =>
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
24
|
+
() => {
|
|
25
|
+
const { appDirectory, distDirectory } = useAppContext();
|
|
26
|
+
|
|
27
|
+
const root = isProd() ? distDirectory : appDirectory;
|
|
28
|
+
|
|
29
|
+
const apiPath = path.resolve(root || process.cwd(), API_DIR);
|
|
30
|
+
const apiAppPath = path.resolve(apiPath, API_APP_NAME);
|
|
31
|
+
|
|
32
|
+
const storage = new Storage();
|
|
33
|
+
const transformAPI = createTransformAPI(storage);
|
|
34
|
+
|
|
35
|
+
const apiMod = requireExistModule(apiAppPath);
|
|
36
|
+
if (apiMod) {
|
|
37
|
+
apiMod(transformAPI);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return {
|
|
41
|
+
reset() {
|
|
42
|
+
storage.reset();
|
|
43
|
+
const newApiModule = requireExistModule(apiAppPath);
|
|
44
|
+
if (newApiModule) {
|
|
45
|
+
newApiModule(transformAPI);
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
gather({ addAPIMiddleware }) {
|
|
49
|
+
storage.middlewares.forEach(mid => {
|
|
50
|
+
addAPIMiddleware(mid);
|
|
51
|
+
});
|
|
52
|
+
},
|
|
53
|
+
prepareApiServer(props, next) {
|
|
54
|
+
const { pwd, prefix } = props;
|
|
55
|
+
const apiDir = path.resolve(pwd, API_DIR);
|
|
11
56
|
|
|
12
|
-
|
|
57
|
+
injectAPIHandlerInfos(apiDir, prefix);
|
|
13
58
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
59
|
+
return next(props);
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
},
|
|
17
63
|
{ name: '@modern-js/plugin-bff' },
|
|
18
64
|
) as any;
|
|
@@ -15,39 +15,6 @@ Array [
|
|
|
15
15
|
]
|
|
16
16
|
`;
|
|
17
17
|
|
|
18
|
-
exports[`bff cli plugin config webpack chain 1`] = `
|
|
19
|
-
Object {
|
|
20
|
-
"module": Object {
|
|
21
|
-
"rules": Array [
|
|
22
|
-
Object {
|
|
23
|
-
"oneOf": Array [
|
|
24
|
-
Object {
|
|
25
|
-
"test": /\\.\\\\/fixtures\\\\/function\\\\/api\\\\/\\.\\*\\(\\.\\[tj\\]s\\)\\$/,
|
|
26
|
-
"use": Array [
|
|
27
|
-
Object {
|
|
28
|
-
"loader": "/packages/cli/plugin-bff/src/loader.ts",
|
|
29
|
-
"options": Object {
|
|
30
|
-
"apiDir": "/packages/cli/plugin-bff/fixtures/function/api",
|
|
31
|
-
"fetcher": undefined,
|
|
32
|
-
"port": 3000,
|
|
33
|
-
"prefix": "/api",
|
|
34
|
-
"target": undefined,
|
|
35
|
-
},
|
|
36
|
-
},
|
|
37
|
-
],
|
|
38
|
-
},
|
|
39
|
-
],
|
|
40
|
-
},
|
|
41
|
-
],
|
|
42
|
-
},
|
|
43
|
-
"resolve": Object {
|
|
44
|
-
"alias": Object {
|
|
45
|
-
"@api": "/packages/cli/plugin-bff/fixtures/function/api",
|
|
46
|
-
},
|
|
47
|
-
},
|
|
48
|
-
}
|
|
49
|
-
`;
|
|
50
|
-
|
|
51
18
|
exports[`bff cli plugin schema 1`] = `
|
|
52
19
|
Array [
|
|
53
20
|
Array [
|
|
@@ -58,12 +25,18 @@ Array [
|
|
|
58
25
|
"type": "string",
|
|
59
26
|
},
|
|
60
27
|
"prefix": Object {
|
|
61
|
-
"
|
|
28
|
+
"items": Object {
|
|
29
|
+
"type": "string",
|
|
30
|
+
},
|
|
31
|
+
"type": Array [
|
|
32
|
+
"string",
|
|
33
|
+
"array",
|
|
34
|
+
],
|
|
62
35
|
},
|
|
63
36
|
"proxy": Object {
|
|
64
37
|
"type": "object",
|
|
65
38
|
},
|
|
66
|
-
"
|
|
39
|
+
"requestCreator": Object {
|
|
67
40
|
"type": "string",
|
|
68
41
|
},
|
|
69
42
|
},
|
package/tests/cli.test.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import
|
|
1
|
+
import path from 'path';
|
|
2
2
|
import { manager, AppContext } from '@modern-js/core';
|
|
3
3
|
import { modifyServerRoutes } from '@modern-js/plugin-analyze';
|
|
4
4
|
import Chain from 'webpack-chain';
|
|
5
5
|
import plugin from '../src/cli';
|
|
6
6
|
|
|
7
|
-
const root = path.resolve(__dirname, '../../../../');
|
|
7
|
+
const root = path.normalize(path.resolve(__dirname, '../../../../'));
|
|
8
8
|
expect.addSnapshotSerializer({
|
|
9
9
|
test: val =>
|
|
10
10
|
typeof val === 'string' &&
|
|
11
|
-
(val.includes('modern
|
|
11
|
+
(val.includes('modern.js') ||
|
|
12
12
|
val.includes('node_modules') ||
|
|
13
13
|
val.includes(root)),
|
|
14
14
|
print: val =>
|
|
@@ -17,8 +17,8 @@ expect.addSnapshotSerializer({
|
|
|
17
17
|
? // eslint-disable-next-line no-nested-ternary
|
|
18
18
|
val.includes('node_modules')
|
|
19
19
|
? `"${val.replace(/.+node_modules/, '')}"`
|
|
20
|
-
: val.includes('modern
|
|
21
|
-
? `"${val.replace(/.+modern
|
|
20
|
+
: val.includes('modern.js')
|
|
21
|
+
? `"${val.replace(/.+modern\.js/, '')}"`
|
|
22
22
|
: `"${val.replace(root, '')}"`
|
|
23
23
|
: (val as string),
|
|
24
24
|
});
|
|
@@ -53,7 +53,38 @@ describe('bff cli plugin', () => {
|
|
|
53
53
|
});
|
|
54
54
|
manager.run(() => tools.webpack({}, { chain }));
|
|
55
55
|
|
|
56
|
-
expect(chain.toConfig()).
|
|
56
|
+
expect(chain.toConfig()).toMatchObject({
|
|
57
|
+
module: {
|
|
58
|
+
rules: [
|
|
59
|
+
{
|
|
60
|
+
oneOf: [
|
|
61
|
+
{
|
|
62
|
+
test: /.\/fixtures\/function\/api\/\.*(\.[tj]s)$/,
|
|
63
|
+
use: [
|
|
64
|
+
{
|
|
65
|
+
loader: require
|
|
66
|
+
.resolve('../src/loader.ts')
|
|
67
|
+
.replace(/\\/g, '/'),
|
|
68
|
+
options: {
|
|
69
|
+
apiDir: path.resolve('./fixtures/function/api'),
|
|
70
|
+
fetcher: undefined,
|
|
71
|
+
port: 3000,
|
|
72
|
+
prefix: '/api',
|
|
73
|
+
target: undefined,
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
],
|
|
77
|
+
},
|
|
78
|
+
],
|
|
79
|
+
},
|
|
80
|
+
],
|
|
81
|
+
},
|
|
82
|
+
resolve: {
|
|
83
|
+
alias: {
|
|
84
|
+
'@api': path.resolve('./fixtures/function/api'),
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
});
|
|
57
88
|
});
|
|
58
89
|
|
|
59
90
|
it('server routes', async () => {
|
package/tests/compiler.ts
CHANGED
package/tests/loader.test.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import path from 'path';
|
|
2
2
|
import { compiler } from './compiler';
|
|
3
3
|
|
|
4
4
|
const apiDir = path.resolve(__dirname, './fixtures/function/api');
|
|
@@ -10,7 +10,7 @@ const root = path.resolve(__dirname, '../../../../');
|
|
|
10
10
|
expect.addSnapshotSerializer({
|
|
11
11
|
test: val =>
|
|
12
12
|
typeof val === 'string' &&
|
|
13
|
-
(val.includes('modern
|
|
13
|
+
(val.includes('modern.js') ||
|
|
14
14
|
val.includes('node_modules') ||
|
|
15
15
|
val.includes(root)),
|
|
16
16
|
print: val =>
|
|
@@ -18,9 +18,9 @@ expect.addSnapshotSerializer({
|
|
|
18
18
|
typeof val === 'string'
|
|
19
19
|
? // eslint-disable-next-line no-nested-ternary
|
|
20
20
|
val.includes('node_modules')
|
|
21
|
-
? `"${val.replace(
|
|
22
|
-
: val.includes('modern
|
|
23
|
-
? `"${val.replace(
|
|
21
|
+
? `"${val.replace(/'.+node_modules/, `'`)}"`
|
|
22
|
+
: val.includes('modern.js')
|
|
23
|
+
? `"${val.replace(/'.+modern\.js/, `'`)}"`
|
|
24
24
|
: `"${val.replace(root, '')}"`
|
|
25
25
|
: (val as string),
|
|
26
26
|
});
|
|
@@ -80,7 +80,9 @@ describe('bff loader', () => {
|
|
|
80
80
|
prefix: '',
|
|
81
81
|
port: 80,
|
|
82
82
|
target: 'client',
|
|
83
|
-
fetcher: path
|
|
83
|
+
fetcher: path
|
|
84
|
+
.resolve(__dirname, './fixtures/test-fetcher')
|
|
85
|
+
.replace(/\\/g, '/'),
|
|
84
86
|
});
|
|
85
87
|
const output = stats?.toJson({ source: true }).modules?.[0]?.source;
|
|
86
88
|
|
|
@@ -93,7 +95,9 @@ describe('bff loader', () => {
|
|
|
93
95
|
prefix: '',
|
|
94
96
|
port: 80,
|
|
95
97
|
target: 'client',
|
|
96
|
-
requestCreator: path
|
|
98
|
+
requestCreator: path
|
|
99
|
+
.resolve(__dirname, './fixtures/test-requestCreator')
|
|
100
|
+
.replace(/\\/g, '/'),
|
|
97
101
|
});
|
|
98
102
|
const output = stats?.toJson({ source: true }).modules?.[0]?.source;
|
|
99
103
|
|
package/tests/server.test.ts
CHANGED