UNPKG

8.83 kBJavaScriptView Raw
1var through2 = require("through2");
2var GulpFile = require("vinyl");
3var { readFileSync } = require("fs");
4var { concat } = require("lodash");
5var glob = require("glob");
6var { generateIndexHtmlContent } = require("./html");
7
8var {
9 generatePreloadFile,
10 findAllImportModules,
11 findAllUi5StandardModules,
12 findAllUi5ViewModules,
13 fetchAllResource,
14 resolveUI5Module,
15 findAllLibraries,
16 readURLFromCache,
17 readBinary,
18 persistCache
19} = require("./ui5");
20
21var path = require("path");
22
23var { bundleModule } = require("./thirdparty");
24
25var defaultResourceRoot = "https://openui5.hana.ondemand.com/resources/";
26
27module.exports = function ({
28 sourceDir,
29 preload = false,
30 outputFilePath,
31 thirdpartyLibPath = ".",
32 ui5ResourceRoot = defaultResourceRoot,
33 ui5ThemeRoot = {},
34 projectNameSpace: projectNameSpace = "",
35 additionalModules = [],
36 additionalResources = [],
37 theme,
38 title,
39 production = false,
40 withLoadingSpinner = false,
41 bootScript,
42 bootScriptPath,
43 offline = false,
44 library = false
45}) {
46 if (!ui5ResourceRoot.endsWith("/")) {
47 ui5ResourceRoot = `${ui5ResourceRoot}/`;
48 }
49 var namepath = projectNameSpace.replace(/\./g, "/");
50
51 var targetJSPath = thirdpartyLibPath;
52
53 if (targetJSPath.endsWith("/") || targetJSPath.startsWith("/")) {
54 throw new Error(
55 `Not accept path :${thirdpartyLibPath}, please give thirdpartyLibPath like lib |_thirdparty | other/lib`
56 );
57 }
58
59 return through2.obj(async function (file, encoding, cb) {
60 try {
61
62 var libs = [];
63
64 var thirdpartyLibs = [];
65
66 /**
67 * distinct dependencies for this project
68 */
69 var distinctDeps = new Set(additionalModules);
70
71 // preload js module
72 var preloadPromise = new Promise((resolve, reject) => {
73 glob(`${sourceDir}/**/*.?(js|jsx|ts|tsx|mjs)`, async (err, files) => {
74 try {
75
76 if (err) {
77 reject(err);
78 return;
79 }
80
81 var allDeps = files.map(f => {
82
83 var mName = f.replace(sourceDir, namepath);
84 var source = readFileSync(f, { encoding: "utf-8" });
85
86 return concat(
87 findAllImportModules(source, mName),
88 findAllUi5StandardModules(source, mName)
89 );
90
91 });
92
93 concat(...allDeps).forEach(d => {
94 d = path.normalize(d).replace(path.normalize(sourceDir), namepath).replace(/\\/g, "/");
95 if (d.startsWith("sap")) {
96 distinctDeps.add(d);
97 } else if (!d.startsWith(namepath) && !d.startsWith("./") && !d.startsWith("../")) {
98 thirdpartyLibs.push(d);
99 }
100 });
101
102 resolve();
103
104 } catch (e) {
105
106 reject(e);
107
108 }
109 });
110 });
111
112 // preload xml view
113 var preloadProjectPromise = new Promise((resolve, reject) => {
114 glob(`${sourceDir}/**/*.+(view|fragment).xml`, async (err, files) => {
115 if (err) {
116 reject(err);
117 } else {
118 var allDeps = await Promise.all(files.map(f => {
119 var mName = f.replace(sourceDir, namepath);
120 var source = readFileSync(f, { encoding: "utf-8" });
121 return findAllUi5ViewModules(source, mName);
122 }));
123 concat(...allDeps).forEach(d => {
124 if (d.startsWith("sap")) {
125 distinctDeps.add(d);
126 }
127 });
128 resolve();
129 }
130 });
131 });
132
133 // await analyze project modules
134 await Promise.all([preloadPromise, preloadProjectPromise]);
135
136 var thirdPartyDepsObject = {};
137 var thirdPartyDepsCode = {};
138
139 if (thirdpartyLibs) {
140 try {
141 await Promise.all(
142 thirdpartyLibs.map(async packageDepName => {
143 // removing non-alphanumeric chars
144 thirdPartyDepsObject[packageDepName] = `${thirdpartyLibPath}/${packageDepName}`;
145 // use original dep name to resolve dep
146 const code = await bundleModule(packageDepName, production);
147 thirdPartyDepsCode[`${packageDepName}`] = code;
148 this.push(
149 new GulpFile({
150 path: `${targetJSPath}/${packageDepName}.js`,
151 contents: Buffer.from(code)
152 })
153 );
154 })
155 );
156 } catch (error) {
157 cb(error);
158 }
159 }
160
161 if (preload) {
162
163 // generate preload file
164 var modules = await resolveUI5Module(Array.from(distinctDeps), ui5ResourceRoot);
165
166 libs = await findAllLibraries(Object.keys(modules));
167
168 additionalResources = additionalResources.concat(libs.map(l => `${l}/messagebundle_zh_CN.properties`));
169 additionalResources = additionalResources.concat(libs.map(l => `${l}/messagebundle_en.properties`));
170 additionalResources = additionalResources.concat(libs.map(l => `${l}/messagebundle.properties`));
171 additionalResources = additionalResources.concat(libs.map(l => `${l}/messagebundle_en_US.properties`));
172 additionalResources = additionalResources.concat(libs.map(l => `${l}/messagebundle_en_UK.properties`));
173
174 var resources = await fetchAllResource(additionalResources, ui5ResourceRoot);
175
176 modules = Object.assign(modules, thirdPartyDepsCode);
177
178 this.push(
179 new GulpFile({
180 path: "preload.js",
181 contents: Buffer.from(
182 generatePreloadFile(
183 modules,
184 resources
185 )
186 )
187 })
188 );
189
190 } else {
191 libs = findAllLibraries(distinctDeps);
192 }
193
194 var cssLinks = [];
195
196 if (offline) {
197 var uiCoreContent = await readURLFromCache(`${ui5ResourceRoot}sap-ui-core.js`);
198 var corePreloadContent = await readURLFromCache(`${ui5ResourceRoot}sap/ui/core/library-preload.js`);
199
200 var offlineFiles = [
201 `sap/ui/core/themes/${theme}/fonts/72-Regular.woff2`,
202 `sap/ui/core/themes/${theme}/fonts/72-Regular.woff`,
203 `sap/ui/core/themes/${theme}/fonts/72-Regular-full.woff2`,
204 `sap/ui/core/themes/${theme}/fonts/72-Regular-full.woff`,
205 `sap/ui/core/themes/${theme}/fonts/72-Bold.woff2`,
206 `sap/ui/core/themes/${theme}/fonts/72-Bold.woff`,
207 `sap/ui/core/themes/${theme}/fonts/72-Bold-full.woff2`,
208 `sap/ui/core/themes/${theme}/fonts/72-Bold-full.woff`,
209 "sap/ui/core/themes/base/fonts/SAP-icons.woff2",
210 "sap/ui/core/themes/base/fonts/SAP-icons.woff",
211 "sap/ui/core/themes/base/fonts/SAP-icons.ttf",
212 "sap/ui/core/cldr/zh_CN.json",
213 "sap-ui-version.json"
214 ];
215
216 var files = await Promise.all(
217 concat(
218 libs.map(async l => ({
219 target: `resources/${l}/themes/${theme}/library.css`,
220 content: Buffer.from(await readURLFromCache(`${ui5ResourceRoot}${l}/themes/${theme}/library.css`))
221 })),
222 libs.map(async l => ({
223 target: `resources/${l}/themes/${theme}/library-parameters.json`,
224 content: Buffer.from(await readURLFromCache(`${ui5ResourceRoot}${l}/themes/${theme}/library-parameters.json`))
225 })),
226 offlineFiles.map(async fontPath => ({ target: `resources/${fontPath}`, content: await readBinary(`${ui5ResourceRoot}${fontPath}`) }))
227 )
228 );
229
230
231 this.push(
232 new GulpFile({
233 path: "resources/sap-ui-core.js",
234 contents: Buffer.from(uiCoreContent)
235 })
236 );
237 this.push(
238 new GulpFile({
239 path: "resources/sap/ui/core/library-preload.js",
240 contents: Buffer.from(corePreloadContent)
241 })
242 );
243 files.forEach(f => {
244 this.push(
245 new GulpFile({
246 path: f.target,
247 contents: f.content
248 })
249 );
250 });
251 }
252
253 if (!library) {
254
255 var indexHtml = generateIndexHtmlContent({
256 resourceRoot: ui5ResourceRoot,
257 projectNameSpace: projectNameSpace,
258 theme: theme,
259 title: title,
260 ui5ThemeRoot,
261 bootScript,
262 bootScriptPath,
263 preload,
264 offline,
265 withLoadingSpinner,
266 inlineCssLink: cssLinks,
267 resourceRoots: {
268 [projectNameSpace]: ".",
269 ...thirdPartyDepsObject
270 }
271 });
272
273 this.push(
274 new GulpFile({
275 path: outputFilePath || "index.html",
276 contents: Buffer.from(indexHtml)
277 })
278 );
279
280 }
281
282
283 persistCache.Persist();
284
285 cb();
286
287 } catch (err) {
288
289 cb(err);
290
291 }
292 });
293
294};
295
296module.exports.componentPreload = require("./component_preload");