@maka/meteor-sdk 0.2.12 → 0.2.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +39 -6
- package/package.json +2 -2
- package/packages/webapp/webapp_server.js +22 -1
- package/src/bundle.js +14 -0
- package/tools/isobuild/bundler.js +38 -5
- package/tools/static-assets/server/boot.js +10 -1
package/README.md
CHANGED
|
@@ -70,13 +70,44 @@ output), the same output `meteor build` produces.
|
|
|
70
70
|
```js
|
|
71
71
|
await sdk.bundle(project, {
|
|
72
72
|
outputPath: "/path/to/output",
|
|
73
|
-
minifyMode: "production", //
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
73
|
+
minifyMode: "production", // DEFAULT IS "development" -- pass
|
|
74
|
+
// "production" explicitly for deploys.
|
|
75
|
+
// Real minification can take minutes and
|
|
76
|
+
// multiple GB of RAM on a cold build.
|
|
77
|
+
buildMode: "production", // default; also "development"/"test"
|
|
78
|
+
serverArch: undefined, // default: the build host's arch
|
|
79
|
+
webArchs: undefined, // default: the project's platform list
|
|
80
|
+
programs: "all", // "all" (default) | "server" | "client"
|
|
77
81
|
});
|
|
78
82
|
```
|
|
79
83
|
|
|
84
|
+
#### Split server/client bundles (`programs`)
|
|
85
|
+
|
|
86
|
+
`programs: "server"` writes a bundle with no client programs whose
|
|
87
|
+
`programs/server/config.json` still records the *intended*
|
|
88
|
+
`clientArchs`. It boots normally and serves pages with 404 until the
|
|
89
|
+
client programs exist -- webapp logs a note per reload and starts
|
|
90
|
+
serving the moment they appear (process restart, or `SIGHUP`, which
|
|
91
|
+
autoupdate already wires to a client-program reload plus a hot-code
|
|
92
|
+
push to connected browsers).
|
|
93
|
+
|
|
94
|
+
`programs: "client"` writes a standalone client artifact: a `star.json`
|
|
95
|
+
listing only the web programs plus `programs/<arch>/` trees that are
|
|
96
|
+
byte-identical to a full bundle's -- so they are drop-in *siblings* for
|
|
97
|
+
a server bundle. Copy `programs/<arch>` into the server bundle's
|
|
98
|
+
`programs/` directory (never untar the client artifact wholesale over a
|
|
99
|
+
server bundle: its root `star.json` would clobber the server's), or
|
|
100
|
+
point the server at an external location with
|
|
101
|
+
`METEOR_CLIENT_BUNDLE_DIR=/path/to/client-artifact/programs` (honored
|
|
102
|
+
by both webapp's static serving and dynamic `import()`).
|
|
103
|
+
|
|
104
|
+
Swap discipline for live servers: activate a new client release with an
|
|
105
|
+
**atomic symlink flip**, never by copying into the live directory -- a
|
|
106
|
+
half-written `program.json` observed by a reload is a fatal error by
|
|
107
|
+
design. Client-only deploys are for client-safe changes; anything
|
|
108
|
+
touching methods, publications or schemas ships server-first or as a
|
|
109
|
+
full bundle.
|
|
110
|
+
|
|
80
111
|
### `createAppRunner(project, options)`
|
|
81
112
|
|
|
82
113
|
Runs an app the way `meteor run` does, with a stoppable handle instead of
|
|
@@ -281,8 +312,10 @@ why) if you ever need to diagnose unexpected rebuilds.
|
|
|
281
312
|
springboarding/multi-release-per-process.** Out of scope for this SDK.
|
|
282
313
|
- **`createAppRunner()`/`testRun()` don't manage a Mongo process** -- bring
|
|
283
314
|
your own `mongoUrl`.
|
|
284
|
-
- **`bundle()`
|
|
285
|
-
`"
|
|
315
|
+
- **`bundle()` defaults to `minifyMode: "development"`** (fast, no real
|
|
316
|
+
minification) -- deploys must pass `"production"` explicitly, and that
|
|
317
|
+
mode is legitimately slow on a cold build. (Earlier revisions of this
|
|
318
|
+
README claimed production was the default; the code never agreed.)
|
|
286
319
|
- A rare, environment-specific gap, out of scope for this package to
|
|
287
320
|
fix: a from-scratch install can hit an npm/Windows spawn issue when a
|
|
288
321
|
dependency needs a native rebuild for the first time.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@maka/meteor-sdk",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.13",
|
|
4
4
|
"description": "Programmatic Node API over the Meteor build tool (bundle/run/create/etc.) -- for driving Meteor's build system from plain Node code instead of shelling out to a meteor CLI (there isn't one anymore; see README.md). \"dependencies\" is generated by scripts/write-tool-package-json.js from scripts/dev-bundle-tool-package.js at the monorepo root -- do not hand-edit that field, edit that file and re-run the script instead.",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"exports": {
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"scripts": {
|
|
26
26
|
"prepack": "node scripts/prepack.js",
|
|
27
27
|
"build": "node scripts/prepack.js",
|
|
28
|
-
"test": "node --test --test-force-exit --test-concurrency=1 test/exports-map.test.js test/ddp.test.js test/test-run.test.js test/errors.test.js test/load-project.test.js test/bundle.test.js test/create.test.js test/close.test.js test/fiber-stubs.test.js test/esm-passthrough.test.js"
|
|
28
|
+
"test": "node --test --test-force-exit --test-concurrency=1 test/exports-map.test.js test/ddp.test.js test/test-run.test.js test/errors.test.js test/load-project.test.js test/bundle.test.js test/bundle-split.test.js test/create.test.js test/close.test.js test/fiber-stubs.test.js test/esm-passthrough.test.js"
|
|
29
29
|
},
|
|
30
30
|
"repository": {
|
|
31
31
|
"type": "git",
|
|
@@ -903,6 +903,18 @@ async function runWebAppServer() {
|
|
|
903
903
|
clientArchs.forEach(arch => {
|
|
904
904
|
generateClientProgram(arch, staticFilesByArch);
|
|
905
905
|
});
|
|
906
|
+
// A configured arch with no program on disk is legal (split
|
|
907
|
+
// server/client deploy: the client artifact hasn't landed yet)
|
|
908
|
+
// but silent was wrong -- say so once per reload so an operator
|
|
909
|
+
// can tell "not deployed yet" from "deployed to the wrong path".
|
|
910
|
+
clientArchs
|
|
911
|
+
.filter(arch => !(arch in staticFilesByArch))
|
|
912
|
+
.forEach(arch => {
|
|
913
|
+
Log.info(
|
|
914
|
+
'webapp: no client program for ' + arch + ' yet; ' +
|
|
915
|
+
'serving begins when it appears (restart or SIGHUP).'
|
|
916
|
+
);
|
|
917
|
+
});
|
|
906
918
|
WebAppInternals.staticFilesByArch = staticFilesByArch;
|
|
907
919
|
} catch (e) {
|
|
908
920
|
Log.error('Error reloading the client program: ' + e.stack);
|
|
@@ -940,8 +952,17 @@ async function runWebAppServer() {
|
|
|
940
952
|
arch,
|
|
941
953
|
staticFilesByArch = WebAppInternals.staticFilesByArch
|
|
942
954
|
) {
|
|
955
|
+
// METEOR_CLIENT_BUNDLE_DIR relocates the client programs for split
|
|
956
|
+
// server/client deploys (a directory holding <arch>/ program dirs);
|
|
957
|
+
// default is the classic sibling layout. Keep in sync with boot.js's
|
|
958
|
+
// dynamic-import root, which honors the same variable -- and note
|
|
959
|
+
// the ENOENT return below is a FEATURE the split relies on: a
|
|
960
|
+
// server-only bundle boots with clientArchs recorded as intent and
|
|
961
|
+
// starts serving the moment the client artifact lands (restart, or
|
|
962
|
+
// SIGHUP via autoupdate's enqueueVersionsRefresh).
|
|
943
963
|
const clientDir = pathJoin(
|
|
944
|
-
|
|
964
|
+
process.env.METEOR_CLIENT_BUNDLE_DIR ||
|
|
965
|
+
pathDirname(__meteor_bootstrap__.serverDir),
|
|
945
966
|
arch
|
|
946
967
|
);
|
|
947
968
|
|
package/src/bundle.js
CHANGED
|
@@ -25,6 +25,19 @@ async function bundle(project, options) {
|
|
|
25
25
|
throw new MeteorSdkError("bundle() requires options.outputPath");
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
+
// Validate BEFORE the expensive build, same spirit as the outputPath
|
|
29
|
+
// check above. 'server' writes a bundle without client programs whose
|
|
30
|
+
// config.json still records the intended clientArchs; 'client' writes
|
|
31
|
+
// a standalone client-only star (no server program, no main.js) whose
|
|
32
|
+
// programs/<arch> trees are drop-in siblings for a server bundle.
|
|
33
|
+
const programs = options.programs || "all";
|
|
34
|
+
if (!["all", "server", "client"].includes(programs)) {
|
|
35
|
+
throw new MeteorSdkError(
|
|
36
|
+
"bundle() options.programs must be 'all', 'server' or 'client' " +
|
|
37
|
+
"(got " + JSON.stringify(options.programs) + ")"
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
28
41
|
const bundler = require("../tools/isobuild/bundler.js");
|
|
29
42
|
|
|
30
43
|
const result = await bundler.bundle({
|
|
@@ -35,6 +48,7 @@ async function bundle(project, options) {
|
|
|
35
48
|
buildMode: options.buildMode || "production",
|
|
36
49
|
serverArch: options.serverArch,
|
|
37
50
|
webArchs: options.webArchs,
|
|
51
|
+
programs,
|
|
38
52
|
},
|
|
39
53
|
});
|
|
40
54
|
|
|
@@ -3300,6 +3300,12 @@ Find out more about Meteor at meteor.com.
|
|
|
3300
3300
|
* of debugOnly, prodOnly and testOnly packages, default 'production'
|
|
3301
3301
|
* - webArchs: array of 'web.*' options to build (defaults to
|
|
3302
3302
|
* projectContext.platformList.getWebArchs())
|
|
3303
|
+
* - programs: 'all' (default), 'server' or 'client'. 'server' writes a
|
|
3304
|
+
* bundle without client programs whose config.json still records the
|
|
3305
|
+
* intended clientArchs (webapp serves them when the client artifact
|
|
3306
|
+
* arrives at the sibling path); 'client' writes a standalone
|
|
3307
|
+
* client-only star -- programs/<arch> trees byte-identical to a full
|
|
3308
|
+
* bundle's, no server program, no main.js.
|
|
3303
3309
|
* - warnings: a MessageSet of linting messages or null if linting
|
|
3304
3310
|
* wasn't performed at all (either disabled or lack of linters).
|
|
3305
3311
|
*
|
|
@@ -3364,6 +3370,16 @@ async function bundle({
|
|
|
3364
3370
|
}
|
|
3365
3371
|
const minifyMode = buildOptions.minifyMode || 'development';
|
|
3366
3372
|
const buildMode = buildOptions.buildMode || 'production';
|
|
3373
|
+
// Which programs to build and write: 'all' (default), 'server' (skip
|
|
3374
|
+
// the client targets but still record the INTENDED clientArchs in
|
|
3375
|
+
// programs/server/config.json, so webapp serves them once the client
|
|
3376
|
+
// artifact arrives -- missing-at-boot is already tolerated, see
|
|
3377
|
+
// webapp_server.js generateClientProgram's ENOENT path), or 'client'
|
|
3378
|
+
// (skip the server target; writeSiteArchive already gates main.js,
|
|
3379
|
+
// README and config.json on targets.server, so the client-only
|
|
3380
|
+
// artifact falls out honest: a star.json listing only web archs plus
|
|
3381
|
+
// programs/<arch>/ trees byte-identical to a full bundle's).
|
|
3382
|
+
const programs = buildOptions.programs || 'all';
|
|
3367
3383
|
|
|
3368
3384
|
var releaseName =
|
|
3369
3385
|
release.current.isCheckout() ? "none" : release.current.name;
|
|
@@ -3389,6 +3405,11 @@ async function bundle({
|
|
|
3389
3405
|
throw new Error('Unrecognized build mode: ' + buildMode);
|
|
3390
3406
|
}
|
|
3391
3407
|
|
|
3408
|
+
if (! ['all', 'server', 'client'].includes(programs)) {
|
|
3409
|
+
throw new Error('Unrecognized programs selection: ' + programs +
|
|
3410
|
+
" (expected 'all', 'server' or 'client')");
|
|
3411
|
+
}
|
|
3412
|
+
|
|
3392
3413
|
var messages = await buildmessage.capture({
|
|
3393
3414
|
title: "building the application"
|
|
3394
3415
|
}, async function () {
|
|
@@ -3520,13 +3541,25 @@ async function bundle({
|
|
|
3520
3541
|
previousBuilders[arch] = written.builder;
|
|
3521
3542
|
}
|
|
3522
3543
|
|
|
3523
|
-
// Client
|
|
3524
|
-
|
|
3525
|
-
|
|
3544
|
+
// Client. Skipped entirely for a server-only build -- but note
|
|
3545
|
+
// webArchs itself is NOT emptied: makeServerTarget below still
|
|
3546
|
+
// receives the full list, so programs/server/config.json records
|
|
3547
|
+
// the INTENDED clientArchs and the server will serve those programs
|
|
3548
|
+
// the moment the separately-deployed client artifact appears at the
|
|
3549
|
+
// sibling path (webapp tolerates missing-at-boot; ENOENT skip in
|
|
3550
|
+
// generateClientProgram).
|
|
3551
|
+
if (programs !== 'server') {
|
|
3552
|
+
for (const arch of webArchs) {
|
|
3553
|
+
targets[arch] = await makeClientTarget(app, arch, {minifiers});
|
|
3554
|
+
}
|
|
3526
3555
|
}
|
|
3527
3556
|
|
|
3528
|
-
// Server
|
|
3529
|
-
|
|
3557
|
+
// Server. Skipped for a client-only build: writeSiteArchive already
|
|
3558
|
+
// gates main.js/README/config.json on targets.server, so the
|
|
3559
|
+
// resulting artifact is an honest client-only star -- programs list
|
|
3560
|
+
// holds only web archs, and the program dirs are byte-identical to
|
|
3561
|
+
// a full bundle's (drop-in compatible as siblings).
|
|
3562
|
+
if (! hasCachedBundle && programs !== 'client') {
|
|
3530
3563
|
targets.server = await makeServerTarget(app, webArchs);
|
|
3531
3564
|
}
|
|
3532
3565
|
|
|
@@ -207,9 +207,18 @@ var specialArgPaths = {
|
|
|
207
207
|
var clientArchs = configJson.clientArchs ||
|
|
208
208
|
Object.keys(configJson.clientPaths);
|
|
209
209
|
|
|
210
|
+
// METEOR_CLIENT_BUNDLE_DIR relocates the CLIENT programs (split
|
|
211
|
+
// server/client deploys -- a directory containing <arch>/ program
|
|
212
|
+
// dirs). Must agree with webapp_server.js's generateClientProgram,
|
|
213
|
+
// which honors the same variable: dynamic-import fetches modules
|
|
214
|
+
// from disk independently of webapp's static file map, so missing
|
|
215
|
+
// this one silently breaks import() while pages still serve.
|
|
216
|
+
var clientProgramsDir =
|
|
217
|
+
process.env.METEOR_CLIENT_BUNDLE_DIR || programsDir;
|
|
218
|
+
|
|
210
219
|
clientArchs.forEach(function (arch) {
|
|
211
220
|
dynamicImportInfo[arch] = {
|
|
212
|
-
dynamicRoot: path.join(
|
|
221
|
+
dynamicRoot: path.join(clientProgramsDir, arch, "dynamic")
|
|
213
222
|
};
|
|
214
223
|
});
|
|
215
224
|
|