UNPKG

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