1 | const Watcher = require("./utils/watcher");
|
2 | const Manifest = require("./manifest");
|
3 | const Queue = require("p-queue").default;
|
4 | const path = require("path");
|
5 | const fs = require("fs");
|
6 | const del = require("del");
|
7 | const debug = require("debug")("core");
|
8 | const mkdirp = require("mkdirp");
|
9 | const slash = require("./utils/fixPathSlashes");
|
10 | const pkg = require("../package");
|
11 | const FileHash = require("./utils/fileHash");
|
12 | const setupEnvVariables = require("./utils/setupEnvVars");
|
13 | const getBuildInfo = require("./utils/getBuildInfo");
|
14 |
|
15 | function builder(sourcePath, cwd) {
|
16 | const buildStartTime = Date.now();
|
17 |
|
18 |
|
19 | process.env.ISBUILDER = "true";
|
20 | process.env.NODE_ENV = "production";
|
21 |
|
22 | console.log(`\x1b[2m⚡️ Zero ${pkg.version ? `v${pkg.version}` : ""}\x1b[0m`);
|
23 | var bundleInfoMap = {};
|
24 | setupEnvVariables(sourcePath, cwd);
|
25 |
|
26 |
|
27 | mkdirp.sync(process.env.BUILDPATH);
|
28 |
|
29 | var fileWatch = new Watcher(sourcePath, false);
|
30 | var manifest = new Manifest(sourcePath, fileWatch);
|
31 |
|
32 | return new Promise((resolve, reject) => {
|
33 | manifest.on(
|
34 | "change",
|
35 | async ({ manifest, forbiddenFiles, filesUpdated, dependencies }) => {
|
36 |
|
37 | var fileHashes = {};
|
38 | for (var file in manifest.fileToPages) {
|
39 | fileHashes[file] = [
|
40 | await FileHash(file),
|
41 | manifest.fileToPages[file].map(entryFile => {
|
42 | var pageData = manifest.pages.find(page => {
|
43 | return page.entryFile === entryFile;
|
44 | });
|
45 | return pageData.id;
|
46 | })
|
47 | ];
|
48 | }
|
49 |
|
50 | var pastFileHashes = false;
|
51 | var pastBuildInfoMap = false;
|
52 | var fileHashPath = path.join(
|
53 | process.env.BUILDPATH,
|
54 | "zero-builds",
|
55 | "_config",
|
56 | "hashes.json"
|
57 | );
|
58 |
|
59 | var buildInfoMapPath = path.join(
|
60 | process.env.BUILDPATH,
|
61 | "zero-builds",
|
62 | "build-info.json"
|
63 | );
|
64 |
|
65 | try {
|
66 | if (fs.existsSync(fileHashPath) && fs.existsSync(buildInfoMapPath)) {
|
67 | pastBuildInfoMap = require(buildInfoMapPath);
|
68 | pastFileHashes = require(fileHashPath);
|
69 |
|
70 |
|
71 | }
|
72 | } catch (e) {}
|
73 |
|
74 |
|
75 | var queue = new Queue({
|
76 | concurrency: parseInt(process.env.BUILDCONCURRENCY) || 2
|
77 | });
|
78 |
|
79 |
|
80 | var filterPages = false;
|
81 | if (pastFileHashes) {
|
82 | filterPages = {};
|
83 | Object.keys(fileHashes).forEach(file => {
|
84 | if (
|
85 | !pastFileHashes[file] ||
|
86 | fileHashes[file][0] !== pastFileHashes[file][0]
|
87 | ) {
|
88 |
|
89 | manifest.fileToPages[file].forEach(page => {
|
90 | filterPages[page] = true;
|
91 | });
|
92 | }
|
93 | });
|
94 |
|
95 |
|
96 |
|
97 | for (var file in pastFileHashes) {
|
98 | if (!fileHashes[file]) {
|
99 | for (var index in pastFileHashes[file][1]) {
|
100 | try {
|
101 | var pageId = pastFileHashes[file][1][index];
|
102 | debug("deleting", file, pastFileHashes[file][1], pageId);
|
103 | await del(
|
104 | [
|
105 | slash(
|
106 | path.join(
|
107 | process.env.BUILDPATH,
|
108 | "zero-builds",
|
109 | pageId,
|
110 | "/**"
|
111 | )
|
112 | )
|
113 | ],
|
114 | {
|
115 | force: true
|
116 | }
|
117 | );
|
118 | } catch (e) {}
|
119 | }
|
120 | }
|
121 | }
|
122 | }
|
123 |
|
124 | for (var i in manifest.pages) {
|
125 | queue.add(
|
126 | async function(index) {
|
127 | var pageData = manifest.pages[index];
|
128 | var pageId = pageData.id;
|
129 | if (
|
130 | filterPages &&
|
131 | !filterPages[pageData.entryFile] &&
|
132 | pastBuildInfoMap[pageId]
|
133 | ) {
|
134 | console.log(
|
135 | `\x1b[2m[${~~index + 1}/${manifest.pages.length}] Skipping`,
|
136 | pageData.path || "/",
|
137 | `\x1b[0m`
|
138 | );
|
139 | bundleInfoMap[pageId] = pastBuildInfoMap[pageId];
|
140 | return;
|
141 | }
|
142 |
|
143 | console.log(
|
144 | `[${~~index + 1}/${manifest.pages.length}] Building`,
|
145 | pageData.path || "/"
|
146 | );
|
147 | var { info } = await getBuildInfo(pageData);
|
148 | bundleInfoMap[pageId] = { info };
|
149 | }.bind(this, i)
|
150 | );
|
151 | }
|
152 |
|
153 | await queue.onIdle();
|
154 | debug("bundleInfo", bundleInfoMap);
|
155 | mkdirp.sync(path.join(process.env.BUILDPATH, "zero-builds"));
|
156 | fs.writeFileSync(
|
157 | path.join(process.env.BUILDPATH, "zero-builds", "build-info.json"),
|
158 | JSON.stringify(bundleInfoMap),
|
159 | "utf8"
|
160 | );
|
161 |
|
162 |
|
163 | mkdirp.sync(path.join(process.env.BUILDPATH, "zero-builds", "_config"));
|
164 |
|
165 | fs.writeFileSync(
|
166 | path.join(
|
167 | process.env.BUILDPATH,
|
168 | "zero-builds",
|
169 | "_config",
|
170 | "package.json"
|
171 | ),
|
172 | fs.readFileSync(path.join(process.env.PROJECTPATH, "package.json"))
|
173 | );
|
174 |
|
175 |
|
176 | fs.writeFileSync(
|
177 | path.join(
|
178 | process.env.BUILDPATH,
|
179 | "zero-builds",
|
180 | "_config",
|
181 | ".babelrc"
|
182 | ),
|
183 | fs.readFileSync(path.join(process.env.PROJECTPATH, ".babelrc"))
|
184 | );
|
185 |
|
186 |
|
187 | fs.writeFileSync(fileHashPath, JSON.stringify(fileHashes));
|
188 |
|
189 | console.log(
|
190 | `\x1b[2mBuilt in ${((Date.now() - buildStartTime) / 1000).toFixed(
|
191 | 1
|
192 | )} seconds.\x1b[0m`
|
193 | );
|
194 |
|
195 | // resolve with manifest
|
196 | resolve({ manifest, forbiddenFiles, dependencies });
|
197 | }
|
198 | );
|
199 | });
|
200 | }
|
201 |
|
202 | module.exports = builder;
|
203 |
|
\ | No newline at end of file |