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