@next-core/brick-container 2.75.34 → 2.76.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/serve/serve.js CHANGED
@@ -24,138 +24,135 @@ module.exports = function serve(runtimeFlags) {
24
24
 
25
25
  serveLocal(env, app);
26
26
 
27
- let cachedIndexHtml;
27
+ const serveIndexHtmlFactory = (standaloneConfig) => (_req, res) => {
28
+ const indexHtml = path.join(distDir, "index.html");
29
+ let content = fs.readFileSync(indexHtml, "utf8");
28
30
 
29
- const standaloneAppRoot = env.standaloneAppRoot;
30
-
31
- const serveIndexHtml = (_req, res) => {
32
- if (!cachedIndexHtml) {
33
- const indexHtml = path.join(distDir, "index.html");
34
- let content = fs.readFileSync(indexHtml, "utf8");
35
-
36
- if (env.liveReload) {
37
- content = appendLiveReloadScript(content, env);
38
- }
31
+ if (env.liveReload) {
32
+ content = appendLiveReloadScript(content, env);
33
+ }
39
34
 
40
- content = content
41
- .replace(
42
- new RegExp(
43
- escapeRegExp("<!--# echo var='base_href' default='/' -->"),
44
- "g"
45
- ),
46
- env.baseHref
47
- )
48
- .replace(
49
- new RegExp(
50
- escapeRegExp("<!--# echo var='app_root' default='' -->"),
51
- "g"
52
- ),
53
- standaloneAppRoot
54
- )
55
- .replace(
56
- new RegExp(
57
- escapeRegExp("<!--# echo var='core_root' default='' -->"),
58
- "g"
59
- ),
60
- `${env.publicCdn ?? ""}${
61
- env.standaloneMicroApps ? `${standaloneAppRoot}-/core/` : ""
62
- }`
63
- )
64
- .replace(
65
- new RegExp(
66
- escapeRegExp("<!--# echo var='mock_date' default='' -->"),
67
- "g"
68
- ),
69
- env.mockDate ?? ""
70
- )
71
- .replace(
72
- new RegExp(
73
- escapeRegExp("<!--# echo var='public_cdn' default='' -->"),
74
- "g"
75
- ),
76
- env.publicCdn ?? ""
77
- );
35
+ // Replace nginx ssi placeholders.
36
+ content = content
37
+ .replace(
38
+ new RegExp(
39
+ escapeRegExp("<!--# echo var='base_href' default='/' -->"),
40
+ "g"
41
+ ),
42
+ env.baseHref
43
+ )
44
+ .replace(
45
+ new RegExp(
46
+ escapeRegExp("<!--# echo var='app_root' default='' -->"),
47
+ "g"
48
+ ),
49
+ standaloneConfig ? standaloneConfig.appRoot : ""
50
+ )
51
+ .replace(
52
+ new RegExp(
53
+ escapeRegExp("<!--# echo var='core_root' default='' -->"),
54
+ "g"
55
+ ),
56
+ `${env.publicCdn ?? ""}${
57
+ standaloneConfig ? `${standaloneConfig.appRoot}-/core/` : ""
58
+ }`
59
+ )
60
+ .replace(
61
+ new RegExp(
62
+ escapeRegExp("<!--# echo var='mock_date' default='' -->"),
63
+ "g"
64
+ ),
65
+ env.mockDate ?? ""
66
+ )
67
+ .replace(
68
+ new RegExp(
69
+ escapeRegExp("<!--# echo var='public_cdn' default='' -->"),
70
+ "g"
71
+ ),
72
+ env.publicCdn ?? ""
73
+ );
78
74
 
79
- if (env.standaloneMicroApps) {
80
- content = content.replace(
81
- "</head>",
75
+ if (standaloneConfig) {
76
+ content = content.replace(
77
+ "</head>",
78
+ [
79
+ "<script>",
80
+ "((w)=>{",
82
81
  [
83
- "<script>",
84
- "((w)=>{",
85
- [
86
- "w.STANDALONE_MICRO_APPS=!0",
87
- `var a=w.APP_ROOT=${JSON.stringify(standaloneAppRoot)}`,
88
- `var d=a+"-/"`,
89
- 'var p=w.PUBLIC_ROOT=(w.PUBLIC_CDN||"")+d',
90
- 'w.CORE_ROOT=p+"core/"',
91
- `w.BOOTSTRAP_FILE=d+"bootstrap.${env.bootstrapHash}.json"`,
92
- ]
93
- .filter(Boolean)
94
- .join(";"),
95
- "})(window)",
96
- "</script></head>",
97
- ].join("")
98
- );
99
- }
100
-
101
- cachedIndexHtml = content;
82
+ "w.STANDALONE_MICRO_APPS=!0",
83
+ `var a=w.APP_ROOT=${JSON.stringify(standaloneConfig.appRoot)}`,
84
+ `var d=a+"-/"`,
85
+ 'var p=w.PUBLIC_ROOT=(w.PUBLIC_CDN||"")+d',
86
+ 'w.CORE_ROOT=p+"core/"',
87
+ `w.BOOTSTRAP_FILE=d+"bootstrap.${standaloneConfig.bootstrapHash}.json"`,
88
+ ]
89
+ .filter(Boolean)
90
+ .join(";"),
91
+ "})(window)",
92
+ "</script></head>",
93
+ ].join("")
94
+ );
102
95
  }
103
96
 
104
- // Replace nginx ssi placeholders.
105
- res.send(cachedIndexHtml);
97
+ res.send(content);
106
98
  };
107
99
 
108
- if (env.standaloneMicroApps && !env.useRemote) {
109
- // Return a fake `conf.yaml` for standalone micro-apps.
110
- app.get(`${standaloneAppRoot}conf.yaml`, (req, res) => {
111
- res.setHeader("content-type", "text/plain");
112
- res.send(
113
- yaml.safeDump({
114
- sys_settings: {
115
- feature_flags: {
116
- "development-mode": true,
100
+ if (!env.useRemote) {
101
+ let fakeAuthHandled = false;
102
+ for (const standaloneConfig of env.standaloneAppsConfig) {
103
+ // Return a fake `conf.yaml` for standalone micro-apps.
104
+ app.get(`${standaloneConfig.appRoot}conf.yaml`, (req, res) => {
105
+ res.setHeader("content-type", "text/plain");
106
+ res.send(
107
+ yaml.safeDump({
108
+ sys_settings: {
109
+ feature_flags: {
110
+ "development-mode": true,
111
+ },
117
112
  },
118
- },
119
- })
120
- );
121
- });
122
-
123
- // Return a fake page of `/auth/*` for fully standalone micro-apps.
124
- if (env.standaloneAppDir) {
125
- app.get(`${env.baseHref}auth/login`, (req, res) => {
126
- res.send("Developing Login");
113
+ })
114
+ );
127
115
  });
116
+
117
+ // Return a fake page of `/auth/*` for fully standalone micro-apps.
118
+ if (!fakeAuthHandled && standaloneConfig.appDir) {
119
+ fakeAuthHandled = true;
120
+ app.get(`${env.baseHref}auth/login`, (req, res) => {
121
+ res.send("Developing Login");
122
+ });
123
+ }
128
124
  }
129
125
  }
130
126
 
131
- const serveRoot = env.standaloneMicroApps
132
- ? `${env.baseHref}${env.standaloneAppDir}`
133
- : env.baseHref;
134
-
135
127
  if (env.useLocalContainer) {
136
128
  const browseHappyHtml = "browse-happy.html";
137
- if (env.asCdn) {
138
- app.get(serveRoot, (req, res) => {
139
- res.sendStatus(404);
140
- });
141
- app.get(`${env.baseHref}${browseHappyHtml}`, (req, res) => {
142
- res.sendStatus(404);
143
- });
144
- } else {
145
- // Serve index.html.
146
- app.get(serveRoot, serveIndexHtml);
129
+ for (const standaloneConfig of env.allAppsConfig) {
130
+ const serveRoot = `${env.baseHref}${
131
+ standaloneConfig ? standaloneConfig.appDir : ""
132
+ }`;
133
+ if (env.asCdn) {
134
+ app.get(serveRoot, (req, res) => {
135
+ res.sendStatus(404);
136
+ });
137
+ app.get(`${env.baseHref}${browseHappyHtml}`, (req, res) => {
138
+ res.sendStatus(404);
139
+ });
140
+ } else {
141
+ // Serve index.html.
142
+ app.get(serveRoot, serveIndexHtmlFactory(standaloneConfig));
147
143
 
148
- // Serve browse-happy.html.
149
- app.get(`${env.baseHref}${browseHappyHtml}`, (req, res) => {
150
- res.sendFile(path.join(distDir, browseHappyHtml));
151
- });
152
- }
144
+ // Serve browse-happy.html.
145
+ app.get(`${env.baseHref}${browseHappyHtml}`, (req, res) => {
146
+ res.sendFile(path.join(distDir, browseHappyHtml));
147
+ });
148
+ }
153
149
 
154
- // Serve static files.
155
- const staticRoot = env.standaloneMicroApps
156
- ? `${standaloneAppRoot || serveRoot}-/core/`
157
- : serveRoot;
158
- app.use(staticRoot, express.static(distDir));
150
+ // Serve static files.
151
+ const staticRoot = standaloneConfig
152
+ ? `${standaloneConfig.appRoot || serveRoot}-/core/`
153
+ : serveRoot;
154
+ app.use(staticRoot, express.static(distDir));
155
+ }
159
156
  }
160
157
 
161
158
  // Using proxies.
@@ -216,18 +213,21 @@ module.exports = function serve(runtimeFlags) {
216
213
  }
217
214
 
218
215
  if (env.useLocalContainer && !env.asCdn) {
219
- app.use(serveRoot, serveIndexHtml);
220
-
221
- if (env.standaloneAppDir) {
222
- // Return a fake 404 page for path other than current app.
223
- app.use(env.baseHref, (req, res) => {
224
- res.send(
225
- `<basic-bricks.page-not-found>${env.baseHref.replace(/\/$/, "")}${
226
- req.path
227
- } is not found</basic-bricks.page-not-found>`
228
- );
229
- });
216
+ for (const standaloneConfig of env.allAppsConfig) {
217
+ const serveRoot = `${env.baseHref}${
218
+ standaloneConfig ? standaloneConfig.appDir : ""
219
+ }`;
220
+ app.use(serveRoot, serveIndexHtmlFactory(standaloneConfig));
230
221
  }
222
+
223
+ // Return a fake 404 page for not-existed apps.
224
+ app.use(env.baseHref, (req, res) => {
225
+ res.send(
226
+ `<basic-bricks.page-not-found>${env.baseHref.replace(/\/$/, "")}${
227
+ req.path
228
+ } is not found</basic-bricks.page-not-found>`
229
+ );
230
+ });
231
231
  }
232
232
 
233
233
  if (env.https) {
@@ -1,5 +1,4 @@
1
1
  const path = require("path");
2
- const fs = require("fs-extra");
3
2
  const bodyParser = require("body-parser");
4
3
  const { escapeRegExp } = require("lodash");
5
4
  const {
@@ -28,137 +27,127 @@ module.exports = (env, app) => {
28
27
  mocked,
29
28
  mockedMicroAppsDir,
30
29
  mockedMicroApps,
31
- standaloneMicroApps,
32
- standaloneAppRoot,
30
+ allAppsConfig,
33
31
  asCdn,
34
32
  } = env;
35
33
  let username;
36
34
 
37
- const publicRoot = standaloneMicroApps ? `${standaloneAppRoot}-/` : baseHref;
35
+ for (const standaloneConfig of allAppsConfig) {
36
+ const publicRoot = standaloneConfig
37
+ ? `${standaloneConfig.appRoot}-/`
38
+ : baseHref;
38
39
 
39
- // 开发时默认拦截 bootstrap 请求。
40
- // 如果设定 `REMOTE=true`,则透传远端请求。
41
- if (useRemote) {
42
- // 设定透传远端请求时,可以指定特定的 brick packages, micro apps, template packages 使用本地文件。
43
- localEditorPackages.forEach((pkgId) => {
44
- // 直接返回本地构件库编辑器相关文件。
45
- app.get(`${publicRoot}bricks/${pkgId}/dist/editors/*`, (req, res) => {
46
- tryServeFiles(
47
- [
48
- path.join(brickPackagesDir, pkgId, "dist-editors", req.params[0]),
49
- path.join(brickPackagesDir, pkgId, "dist/editors", req.params[0]),
50
- path.join(
51
- alternativeBrickPackagesDir,
52
- pkgId,
53
- "dist-editors",
54
- req.params[0]
55
- ),
56
- path.join(
57
- alternativeBrickPackagesDir,
58
- pkgId,
59
- "dist/editors",
60
- req.params[0]
61
- ),
62
- ],
63
- req,
64
- res
65
- );
66
- });
67
- });
68
-
69
- localBrickPackages.forEach((pkgId) => {
70
- // 直接返回本地构件库相关文件(但排除编辑器相关文件)。
71
- app.get(
72
- new RegExp(
73
- `^${escapeRegExp(
74
- `${publicRoot}bricks/${pkgId}/`
75
- )}(?!dist\\/editors\\/)(.+)`
76
- ),
77
- (req, res) => {
40
+ // 开发时默认拦截 bootstrap 请求。
41
+ // 如果设定 `REMOTE=true`,则透传远端请求。
42
+ if (useRemote) {
43
+ // 设定透传远端请求时,可以指定特定的 brick packages, micro apps, template packages 使用本地文件。
44
+ localEditorPackages.forEach((pkgId) => {
45
+ // 直接返回本地构件库编辑器相关文件。
46
+ app.get(`${publicRoot}bricks/${pkgId}/dist/editors/*`, (req, res) => {
78
47
  tryServeFiles(
79
48
  [
80
- path.join(brickPackagesDir, pkgId, req.params[0]),
81
- path.join(alternativeBrickPackagesDir, pkgId, req.params[0]),
49
+ path.join(brickPackagesDir, pkgId, "dist-editors", req.params[0]),
50
+ path.join(brickPackagesDir, pkgId, "dist/editors", req.params[0]),
51
+ path.join(
52
+ alternativeBrickPackagesDir,
53
+ pkgId,
54
+ "dist-editors",
55
+ req.params[0]
56
+ ),
57
+ path.join(
58
+ alternativeBrickPackagesDir,
59
+ pkgId,
60
+ "dist/editors",
61
+ req.params[0]
62
+ ),
82
63
  ],
83
64
  req,
84
65
  res
85
66
  );
86
- }
87
- );
88
- });
89
-
90
- standaloneMicroApps ||
91
- localMicroApps.forEach((appId) => {
92
- // 直接返回本地小产品相关文件。
93
- app.get(`${baseHref}micro-apps/${appId}/*`, (req, res) => {
94
- const filePath = path.join(microAppsDir, appId, req.params[0]);
95
- tryServeFiles(filePath, req, res);
96
67
  });
97
68
  });
98
- localTemplates.forEach((pkgId) => {
99
- // 直接返回本地模板相关文件。
100
- app.get(`${publicRoot}templates/${pkgId}/*`, (req, res) => {
101
- const filePath = path.join(templatePackagesDir, pkgId, req.params[0]);
102
- tryServeFiles(filePath, req, res);
69
+
70
+ localBrickPackages.forEach((pkgId) => {
71
+ // 直接返回本地构件库相关文件(但排除编辑器相关文件)。
72
+ app.get(
73
+ new RegExp(
74
+ `^${escapeRegExp(
75
+ `${publicRoot}bricks/${pkgId}/`
76
+ )}(?!dist\\/editors\\/)(.+)`
77
+ ),
78
+ (req, res) => {
79
+ tryServeFiles(
80
+ [
81
+ path.join(brickPackagesDir, pkgId, req.params[0]),
82
+ path.join(alternativeBrickPackagesDir, pkgId, req.params[0]),
83
+ ],
84
+ req,
85
+ res
86
+ );
87
+ }
88
+ );
103
89
  });
104
- });
105
- standaloneMicroApps ||
106
- mockedMicroApps.forEach((appId) => {
107
- // 直接返回本地小产品相关文件。
108
- app.get(`${baseHref}micro-apps/${appId}/*`, (req, res) => {
109
- const filePath = path.join(mockedMicroAppsDir, appId, req.params[0]);
90
+
91
+ standaloneConfig ||
92
+ localMicroApps.forEach((appId) => {
93
+ // 直接返回本地小产品相关文件。
94
+ app.get(`${baseHref}micro-apps/${appId}/*`, (req, res) => {
95
+ const filePath = path.join(microAppsDir, appId, req.params[0]);
96
+ tryServeFiles(filePath, req, res);
97
+ });
98
+ });
99
+ localTemplates.forEach((pkgId) => {
100
+ // 直接返回本地模板相关文件。
101
+ app.get(`${publicRoot}templates/${pkgId}/*`, (req, res) => {
102
+ const filePath = path.join(templatePackagesDir, pkgId, req.params[0]);
110
103
  tryServeFiles(filePath, req, res);
111
104
  });
112
- asCdn ||
105
+ });
106
+
107
+ standaloneConfig ||
108
+ mockedMicroApps.forEach((appId) => {
109
+ // 直接返回本地小产品相关文件。
110
+ app.get(`${baseHref}micro-apps/${appId}/*`, (req, res) => {
111
+ const filePath = path.join(
112
+ mockedMicroAppsDir,
113
+ appId,
114
+ req.params[0]
115
+ );
116
+ tryServeFiles(filePath, req, res);
117
+ });
118
+ asCdn ||
119
+ app.get(
120
+ `${baseHref}api/auth(/v2)?/bootstrap/${appId}`,
121
+ (req, res) => {
122
+ res.json({
123
+ code: 0,
124
+ data: getSingleStoryboard(env, appId, true),
125
+ });
126
+ }
127
+ );
128
+ });
129
+ // API to fulfil the active storyboard.
130
+ asCdn ||
131
+ standaloneConfig ||
132
+ localMicroApps.concat(mockedMicroApps).forEach((appId) => {
113
133
  app.get(
114
134
  `${baseHref}api/auth(/v2)?/bootstrap/${appId}`,
115
135
  (req, res) => {
116
136
  res.json({
117
137
  code: 0,
118
- data: getSingleStoryboard(env, appId, true),
138
+ data: getSingleStoryboard(
139
+ env,
140
+ appId,
141
+ mockedMicroApps.includes(appId)
142
+ ),
119
143
  });
120
144
  }
121
145
  );
122
- });
123
- // API to fulfil the active storyboard.
124
- asCdn ||
125
- standaloneMicroApps ||
126
- localMicroApps.concat(mockedMicroApps).forEach((appId) => {
127
- app.get(`${baseHref}api/auth(/v2)?/bootstrap/${appId}`, (req, res) => {
128
- res.json({
129
- code: 0,
130
- data: getSingleStoryboard(
131
- env,
132
- appId,
133
- mockedMicroApps.includes(appId)
134
- ),
135
- });
136
146
  });
137
- });
138
- } else {
139
- if (standaloneMicroApps) {
140
- app.get(`${publicRoot}bootstrap.hash.json`, (req, res) => {
141
- res.json({
142
- navbar: getNavbar(env),
143
- storyboards: (mocked
144
- ? getStoryboardsByMicroApps(env, true, {
145
- brief: req.query.brief === "true",
146
- })
147
- : []
148
- ).concat(
149
- getStoryboardsByMicroApps(env, false, {
150
- brief: req.query.brief === "true",
151
- })
152
- ),
153
- brickPackages: getBrickPackages(env),
154
- templatePackages: getTemplatePackages(env),
155
- });
156
- });
157
147
  } else {
158
- app.get(`${baseHref}api/auth(/v2)?/bootstrap`, (req, res) => {
159
- res.json({
160
- code: 0,
161
- data: {
148
+ if (standaloneConfig) {
149
+ app.get(`${publicRoot}bootstrap.hash.json`, (req, res) => {
150
+ res.json({
162
151
  navbar: getNavbar(env),
163
152
  storyboards: (mocked
164
153
  ? getStoryboardsByMicroApps(env, true, {
@@ -172,52 +161,73 @@ module.exports = (env, app) => {
172
161
  ),
173
162
  brickPackages: getBrickPackages(env),
174
163
  templatePackages: getTemplatePackages(env),
175
- settings: getSettings(env),
176
- },
164
+ });
165
+ });
166
+ } else {
167
+ app.get(`${baseHref}api/auth(/v2)?/bootstrap`, (req, res) => {
168
+ res.json({
169
+ code: 0,
170
+ data: {
171
+ navbar: getNavbar(env),
172
+ storyboards: (mocked
173
+ ? getStoryboardsByMicroApps(env, true, {
174
+ brief: req.query.brief === "true",
175
+ })
176
+ : []
177
+ ).concat(
178
+ getStoryboardsByMicroApps(env, false, {
179
+ brief: req.query.brief === "true",
180
+ })
181
+ ),
182
+ brickPackages: getBrickPackages(env),
183
+ templatePackages: getTemplatePackages(env),
184
+ settings: getSettings(env),
185
+ },
186
+ });
177
187
  });
178
- });
179
188
 
180
- app.get(`${baseHref}api/auth(/v2)?/bootstrap/:appId`, (req, res) => {
181
- res.json({
182
- code: 0,
183
- data: getSingleStoryboard(
184
- env,
185
- req.params.appId,
186
- mockedMicroApps.includes(req.params.appId)
187
- ),
189
+ app.get(`${baseHref}api/auth(/v2)?/bootstrap/:appId`, (req, res) => {
190
+ res.json({
191
+ code: 0,
192
+ data: getSingleStoryboard(
193
+ env,
194
+ req.params.appId,
195
+ mockedMicroApps.includes(req.params.appId)
196
+ ),
197
+ });
188
198
  });
189
- });
190
- }
199
+ }
191
200
 
192
- // 直接返回构件库 js 文件。
193
- app.get(`${publicRoot}bricks/*`, (req, res) => {
194
- tryServeFiles(
195
- [
196
- path.join(brickPackagesDir, req.params[0]),
197
- path.join(alternativeBrickPackagesDir, req.params[0]),
198
- ],
199
- req,
200
- res
201
- );
202
- });
201
+ // 直接返回构件库 js 文件。
202
+ app.get(`${publicRoot}bricks/*`, (req, res) => {
203
+ tryServeFiles(
204
+ [
205
+ path.join(brickPackagesDir, req.params[0]),
206
+ path.join(alternativeBrickPackagesDir, req.params[0]),
207
+ ],
208
+ req,
209
+ res
210
+ );
211
+ });
203
212
 
204
- // 直接返回小产品相关文件。
205
- app.get(`${publicRoot}micro-apps/*`, (req, res) => {
206
- tryServeFiles(
207
- [
208
- ...(mocked ? [path.join(mockedMicroAppsDir, req.params[0])] : []),
209
- path.join(microAppsDir, req.params[0]),
210
- ],
211
- req,
212
- res
213
- );
214
- });
213
+ // 直接返回小产品相关文件。
214
+ app.get(`${publicRoot}micro-apps/*`, (req, res) => {
215
+ tryServeFiles(
216
+ [
217
+ ...(mocked ? [path.join(mockedMicroAppsDir, req.params[0])] : []),
218
+ path.join(microAppsDir, req.params[0]),
219
+ ],
220
+ req,
221
+ res
222
+ );
223
+ });
215
224
 
216
- // 直接返回模板库 js 文件。
217
- app.get(`${publicRoot}templates/*`, (req, res) => {
218
- const filePath = path.join(templatePackagesDir, req.params[0]);
219
- tryServeFiles(filePath, req, res);
220
- });
225
+ // 直接返回模板库 js 文件。
226
+ app.get(`${publicRoot}templates/*`, (req, res) => {
227
+ const filePath = path.join(templatePackagesDir, req.params[0]);
228
+ tryServeFiles(filePath, req, res);
229
+ });
230
+ }
221
231
  }
222
232
 
223
233
  if (useOffline) {
package/serve/utils.js CHANGED
@@ -24,7 +24,8 @@ function getNamesOfMicroApps(env, mocked) {
24
24
  .filter((dirent) => dirent.isDirectory() || dirent.isSymbolicLink())
25
25
  .map((dirent) => dirent.name);
26
26
  // Ignore `auth` for fully standalone micro-apps.
27
- return mocked && env.standaloneAppDir
27
+ return mocked &&
28
+ env.standaloneAppsConfig.some((standaloneConfig) => standaloneConfig.appDir)
28
29
  ? apps.filter((name) => name !== "auth")
29
30
  : apps;
30
31
  }