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 { bundleModule } = require("./thirdparty");
|
21 |
|
22 | var defaultResourceRoot = "https://openui5.hana.ondemand.com/resources/";
|
23 |
|
24 | module.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 |
|
61 |
|
62 | var distinctDeps = new Set(additionalModules);
|
63 |
|
64 |
|
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 |
|
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 |
|
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 |
|
123 | thirdPartyDepsObject[packageDepName] = `${thirdpartyLibPath}/${packageDepName}`;
|
124 |
|
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 |
|
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 |
|
265 | module.exports.componentPreload = require("./component_preload");
|