@quilted/rollup 0.1.18 → 0.2.0
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/CHANGELOG.md +25 -0
- package/build/esm/app.mjs +442 -233
- package/build/esm/constants.mjs +5 -5
- package/build/esm/features/assets.mjs +93 -81
- package/build/esm/features/async.mjs +186 -0
- package/build/esm/features/css.mjs +26 -39
- package/build/esm/features/env.mjs +47 -44
- package/build/esm/features/esnext.mjs +57 -0
- package/build/esm/features/graphql/transform.mjs +60 -56
- package/build/esm/features/graphql.mjs +65 -47
- package/build/esm/features/request-router.mjs +6 -4
- package/build/esm/features/source-code.mjs +54 -28
- package/build/esm/features/system-js.mjs +13 -18
- package/build/esm/features/typescript.mjs +13 -10
- package/build/esm/features/workers.mjs +173 -0
- package/build/esm/index.mjs +3 -2
- package/build/esm/module.mjs +69 -62
- package/build/esm/package.mjs +275 -84
- package/build/esm/server.mjs +118 -0
- package/build/esm/shared/browserslist.mjs +141 -16
- package/build/esm/shared/magic-module.mjs +9 -7
- package/build/esm/shared/package-json.mjs +7 -1
- package/build/esm/shared/path.mjs +7 -0
- package/build/esm/shared/rollup.mjs +89 -25
- package/build/esm/shared/strings.mjs +7 -6
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/typescript/app.d.ts +126 -27
- package/build/typescript/app.d.ts.map +1 -1
- package/build/typescript/features/assets.d.ts +1 -2
- package/build/typescript/features/assets.d.ts.map +1 -1
- package/build/typescript/features/async.d.ts +10 -0
- package/build/typescript/features/async.d.ts.map +1 -0
- package/build/typescript/features/css.d.ts +2 -1
- package/build/typescript/features/css.d.ts.map +1 -1
- package/build/typescript/features/env.d.ts +1 -0
- package/build/typescript/features/env.d.ts.map +1 -1
- package/build/typescript/features/esnext.d.ts +9 -0
- package/build/typescript/features/esnext.d.ts.map +1 -0
- package/build/typescript/features/graphql.d.ts +2 -2
- package/build/typescript/features/graphql.d.ts.map +1 -1
- package/build/typescript/features/source-code.d.ts +9 -3
- package/build/typescript/features/source-code.d.ts.map +1 -1
- package/build/typescript/features/workers.d.ts +52 -0
- package/build/typescript/features/workers.d.ts.map +1 -0
- package/build/typescript/index.d.ts +3 -2
- package/build/typescript/index.d.ts.map +1 -1
- package/build/typescript/module.d.ts +24 -6
- package/build/typescript/module.d.ts.map +1 -1
- package/build/typescript/package.d.ts +196 -4
- package/build/typescript/package.d.ts.map +1 -1
- package/build/typescript/server.d.ts +98 -0
- package/build/typescript/server.d.ts.map +1 -0
- package/build/typescript/shared/browserslist.d.ts +20 -3
- package/build/typescript/shared/browserslist.d.ts.map +1 -1
- package/build/typescript/shared/path.d.ts +2 -0
- package/build/typescript/shared/path.d.ts.map +1 -0
- package/build/typescript/shared/rollup.d.ts +27 -1
- package/build/typescript/shared/rollup.d.ts.map +1 -1
- package/configuration/rollup.config.js +40 -0
- package/package.json +61 -8
- package/source/app.ts +472 -109
- package/source/features/assets.ts +5 -7
- package/source/features/async.ts +249 -0
- package/source/features/css.ts +4 -2
- package/source/features/env.ts +6 -0
- package/source/features/esnext.ts +70 -0
- package/source/features/graphql.ts +4 -2
- package/source/features/source-code.ts +26 -8
- package/source/features/workers.ts +292 -0
- package/source/index.ts +4 -0
- package/source/module.ts +45 -19
- package/source/package.ts +394 -36
- package/source/server.ts +245 -0
- package/source/shared/browserslist.ts +208 -18
- package/source/shared/path.ts +5 -0
- package/source/shared/rollup.ts +102 -4
- package/tsconfig.json +6 -2
- package/build/cjs/app.cjs +0 -456
- package/build/cjs/constants.cjs +0 -13
- package/build/cjs/features/assets.cjs +0 -240
- package/build/cjs/features/css.cjs +0 -71
- package/build/cjs/features/env.cjs +0 -135
- package/build/cjs/features/graphql/transform.cjs +0 -186
- package/build/cjs/features/graphql.cjs +0 -86
- package/build/cjs/features/request-router.cjs +0 -31
- package/build/cjs/features/source-code.cjs +0 -54
- package/build/cjs/features/system-js.cjs +0 -36
- package/build/cjs/features/typescript.cjs +0 -56
- package/build/cjs/index.cjs +0 -13
- package/build/cjs/module.cjs +0 -121
- package/build/cjs/package.cjs +0 -170
- package/build/cjs/shared/browserslist.cjs +0 -25
- package/build/cjs/shared/magic-module.cjs +0 -32
- package/build/cjs/shared/package-json.cjs +0 -31
- package/build/cjs/shared/rollup.cjs +0 -72
- package/build/cjs/shared/strings.cjs +0 -16
- package/build/esnext/app.esnext +0 -429
- package/build/esnext/constants.esnext +0 -7
- package/build/esnext/features/assets.esnext +0 -215
- package/build/esnext/features/css.esnext +0 -69
- package/build/esnext/features/env.esnext +0 -112
- package/build/esnext/features/graphql/transform.esnext +0 -181
- package/build/esnext/features/graphql.esnext +0 -84
- package/build/esnext/features/request-router.esnext +0 -29
- package/build/esnext/features/source-code.esnext +0 -51
- package/build/esnext/features/system-js.esnext +0 -33
- package/build/esnext/features/typescript.esnext +0 -34
- package/build/esnext/index.esnext +0 -3
- package/build/esnext/module.esnext +0 -100
- package/build/esnext/package.esnext +0 -148
- package/build/esnext/shared/browserslist.esnext +0 -23
- package/build/esnext/shared/magic-module.esnext +0 -30
- package/build/esnext/shared/package-json.esnext +0 -10
- package/build/esnext/shared/rollup.esnext +0 -49
- package/build/esnext/shared/strings.esnext +0 -14
- package/build/typescript/env.d.ts +0 -55
- package/build/typescript/env.d.ts.map +0 -1
- package/build/typescript/graphql/transform.d.ts +0 -17
- package/build/typescript/graphql/transform.d.ts.map +0 -1
- package/build/typescript/graphql.d.ts +0 -6
- package/build/typescript/graphql.d.ts.map +0 -1
- package/build/typescript/request-router.d.ts +0 -15
- package/build/typescript/request-router.d.ts.map +0 -1
- package/build/typescript/shared/source-code.d.ts +0 -5
- package/build/typescript/shared/source-code.d.ts.map +0 -1
- package/quilt.project.ts +0 -5
package/source/app.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as path from 'path';
|
|
2
2
|
import * as fs from 'fs/promises';
|
|
3
3
|
import {glob} from 'glob';
|
|
4
|
-
import {
|
|
4
|
+
import {createRequire} from 'module';
|
|
5
5
|
|
|
6
6
|
import type {Plugin, RollupOptions, GetManualChunk} from 'rollup';
|
|
7
7
|
import type {AssetsBuildManifest} from '@quilted/assets';
|
|
@@ -12,17 +12,27 @@ import {
|
|
|
12
12
|
MAGIC_MODULE_BROWSER_ASSETS,
|
|
13
13
|
MAGIC_MODULE_REQUEST_ROUTER,
|
|
14
14
|
} from './constants.ts';
|
|
15
|
-
import type
|
|
15
|
+
import {resolveEnvOption, type MagicModuleEnvOptions} from './features/env.ts';
|
|
16
16
|
|
|
17
17
|
import {multiline} from './shared/strings.ts';
|
|
18
|
-
import {
|
|
18
|
+
import {
|
|
19
|
+
getNodePlugins,
|
|
20
|
+
removeBuildFiles,
|
|
21
|
+
type RollupNodePluginOptions,
|
|
22
|
+
} from './shared/rollup.ts';
|
|
19
23
|
import {createMagicModulePlugin} from './shared/magic-module.ts';
|
|
20
24
|
import {
|
|
21
|
-
|
|
22
|
-
|
|
25
|
+
targetsSupportModules,
|
|
26
|
+
getBrowserGroups,
|
|
27
|
+
getBrowserGroupTargetDetails,
|
|
28
|
+
getBrowserGroupRegularExpressions,
|
|
29
|
+
rollupGenerateOptionsForBrowsers,
|
|
30
|
+
type BrowserGroupTargetSelection,
|
|
23
31
|
} from './shared/browserslist.ts';
|
|
32
|
+
import {loadPackageJSON, type PackageJSON} from './shared/package-json.ts';
|
|
33
|
+
import {resolveRoot} from './shared/path.ts';
|
|
24
34
|
|
|
25
|
-
export interface
|
|
35
|
+
export interface AppBaseOptions {
|
|
26
36
|
/**
|
|
27
37
|
* The root directory containing the source code for your application.
|
|
28
38
|
*/
|
|
@@ -52,13 +62,33 @@ export interface AppOptions {
|
|
|
52
62
|
|
|
53
63
|
/**
|
|
54
64
|
* Customizes the behavior of environment variables for your application. You
|
|
55
|
-
* can further customize the environment variables provided
|
|
56
|
-
*
|
|
65
|
+
* can further customize the environment variables provided to browser assets
|
|
66
|
+
* by passing the `browser.env`, and those passed during server-side rendering
|
|
67
|
+
* by passing `server.env`.
|
|
57
68
|
*/
|
|
58
|
-
env?: MagicModuleEnvOptions;
|
|
69
|
+
env?: MagicModuleEnvOptions | MagicModuleEnvOptions['mode'];
|
|
59
70
|
}
|
|
60
71
|
|
|
61
|
-
export interface
|
|
72
|
+
export interface AppOptions extends AppBaseOptions {
|
|
73
|
+
/**
|
|
74
|
+
* Customizes the browser build of your application.
|
|
75
|
+
*/
|
|
76
|
+
browser?: Omit<AppBrowserOptions, keyof AppBaseOptions> &
|
|
77
|
+
Pick<AppBrowserOptions, 'env'>;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Customizes the assets created for your application.
|
|
81
|
+
*/
|
|
82
|
+
assets?: AppBrowserOptions['assets'];
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Customizes the server build of your application.
|
|
86
|
+
*/
|
|
87
|
+
server?: Omit<AppServerOptions, keyof AppBaseOptions> &
|
|
88
|
+
Pick<AppServerOptions, 'env'>;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export interface AppBrowserOptions extends AppBaseOptions {
|
|
62
92
|
/**
|
|
63
93
|
* The entry module for this browser. This should be an absolute path, or relative
|
|
64
94
|
* path from the root directory containing your project. This entry should be the
|
|
@@ -99,15 +129,150 @@ export interface AppBrowserModuleOptions {
|
|
|
99
129
|
|
|
100
130
|
export interface AppBrowserAssetsOptions {
|
|
101
131
|
/**
|
|
102
|
-
* Whether to minify assets created
|
|
132
|
+
* Whether to minify assets created for you application.
|
|
103
133
|
*
|
|
104
134
|
* @default true
|
|
105
135
|
*/
|
|
106
136
|
minify?: boolean;
|
|
107
137
|
|
|
108
138
|
baseURL?: string;
|
|
109
|
-
targets?:
|
|
139
|
+
targets?: BrowserGroupTargetSelection;
|
|
110
140
|
priority?: number;
|
|
141
|
+
clean?: boolean;
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Controls how assets like images are inlined into your bundles JavaScript.
|
|
145
|
+
*/
|
|
146
|
+
inline?:
|
|
147
|
+
| boolean
|
|
148
|
+
| {
|
|
149
|
+
/**
|
|
150
|
+
* The maximum size in bytes that an asset should be in order to
|
|
151
|
+
* be inlined into the bundle. Defaults to `4096`.
|
|
152
|
+
*/
|
|
153
|
+
limit?: number;
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export interface AppServerOptions extends AppBaseOptions {
|
|
158
|
+
/**
|
|
159
|
+
* The entry module for this app’s server. By default, this module must export
|
|
160
|
+
* a `RequestRouter` object as its default export, which will be wrapped in
|
|
161
|
+
* the specific server runtime you configure. If you set the format to `'custom'`,
|
|
162
|
+
* this entry can be any content — it will be bundled as-is.
|
|
163
|
+
*
|
|
164
|
+
* If not provided, this will default to a file named `server`, `service`,
|
|
165
|
+
* or `backend` in your app’s root directory.
|
|
166
|
+
*/
|
|
167
|
+
entry?: string;
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Whether this server code uses the `request-router` library to
|
|
171
|
+
* define itself in a generic way, which can be adapted to a variety
|
|
172
|
+
* of environments. By default, this is `'request-router'`, and when `'request-router'`,
|
|
173
|
+
* the `entry` you specified must export an `RequestRouter` object as
|
|
174
|
+
* its default export. When set to `false`, the app server will be built
|
|
175
|
+
* as a basic server-side JavaScript project, without the special
|
|
176
|
+
* `request-router` adaptor.
|
|
177
|
+
*
|
|
178
|
+
* @default 'request-router'
|
|
179
|
+
*/
|
|
180
|
+
format?: 'request-router' | 'custom';
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Customizes the assets created for your application.
|
|
184
|
+
*/
|
|
185
|
+
assets?: Pick<AppBrowserAssetsOptions, 'baseURL' | 'inline'>;
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Customizes the output files created for your server.
|
|
189
|
+
*/
|
|
190
|
+
output?: AppServerOutputOptions;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
export interface AppServerOutputOptions
|
|
194
|
+
extends Pick<RollupNodePluginOptions, 'bundle'> {
|
|
195
|
+
/**
|
|
196
|
+
* Whether to minify assets created for this server.
|
|
197
|
+
*
|
|
198
|
+
* @default false
|
|
199
|
+
*/
|
|
200
|
+
minify?: boolean;
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Whether to add a hash to the output files for your server. You can set
|
|
204
|
+
* this to `true`, which includes a hash for all files, `false`, which never
|
|
205
|
+
* includes a hash, or `'async-only'`, which only includes a hash for files
|
|
206
|
+
* that are loaded asynchronously (that is, your entry file will not have a
|
|
207
|
+
* hash, but any files it loads will).
|
|
208
|
+
*
|
|
209
|
+
* @default 'async-only'
|
|
210
|
+
*/
|
|
211
|
+
hash?: boolean | 'async-only';
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* What module format to use for the server output.
|
|
215
|
+
*
|
|
216
|
+
* @default 'esmodules'
|
|
217
|
+
*/
|
|
218
|
+
format?: 'esmodules' | 'esm' | 'es' | 'commonjs' | 'cjs';
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
const require = createRequire(import.meta.url);
|
|
222
|
+
|
|
223
|
+
export async function quiltApp({
|
|
224
|
+
root: rootPath = process.cwd(),
|
|
225
|
+
app,
|
|
226
|
+
env,
|
|
227
|
+
graphql,
|
|
228
|
+
assets,
|
|
229
|
+
browser: browserOptions,
|
|
230
|
+
server: serverOptions,
|
|
231
|
+
}: AppOptions = {}) {
|
|
232
|
+
const root = resolveRoot(rootPath);
|
|
233
|
+
|
|
234
|
+
const browserGroups = await getBrowserGroups({root});
|
|
235
|
+
const browserGroupEntries = Object.entries(browserGroups);
|
|
236
|
+
const hasMultipleBrowserGroups = browserGroupEntries.length > 1;
|
|
237
|
+
|
|
238
|
+
const optionPromises: Promise<RollupOptions>[] = [];
|
|
239
|
+
|
|
240
|
+
browserGroupEntries.forEach(([name, browsers], index) => {
|
|
241
|
+
optionPromises.push(
|
|
242
|
+
quiltAppBrowser({
|
|
243
|
+
root,
|
|
244
|
+
app,
|
|
245
|
+
graphql,
|
|
246
|
+
...browserOptions,
|
|
247
|
+
env: {
|
|
248
|
+
...resolveEnvOption(env),
|
|
249
|
+
...resolveEnvOption(browserOptions?.env),
|
|
250
|
+
},
|
|
251
|
+
assets: {
|
|
252
|
+
...assets,
|
|
253
|
+
...browserOptions?.assets,
|
|
254
|
+
// Only clean on the first build, otherwise each subsequent build removes
|
|
255
|
+
// assets from the previous ones.
|
|
256
|
+
clean: index === 0,
|
|
257
|
+
priority: index,
|
|
258
|
+
targets: hasMultipleBrowserGroups ? {name, browsers} : browsers,
|
|
259
|
+
},
|
|
260
|
+
}),
|
|
261
|
+
);
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
optionPromises.push(
|
|
265
|
+
quiltAppServer({
|
|
266
|
+
root,
|
|
267
|
+
app,
|
|
268
|
+
graphql,
|
|
269
|
+
...serverOptions,
|
|
270
|
+
env: {...resolveEnvOption(env), ...resolveEnvOption(serverOptions?.env)},
|
|
271
|
+
assets: {...assets, ...serverOptions?.assets},
|
|
272
|
+
}),
|
|
273
|
+
);
|
|
274
|
+
|
|
275
|
+
return Promise.all(optionPromises);
|
|
111
276
|
}
|
|
112
277
|
|
|
113
278
|
export async function quiltAppBrowser({
|
|
@@ -119,14 +284,16 @@ export async function quiltAppBrowser({
|
|
|
119
284
|
module,
|
|
120
285
|
graphql = true,
|
|
121
286
|
}: AppBrowserOptions = {}) {
|
|
122
|
-
const root =
|
|
123
|
-
const mode =
|
|
124
|
-
(typeof env === 'object' ? env?.mode : undefined) ?? 'production';
|
|
287
|
+
const root = resolveRoot(rootPath);
|
|
288
|
+
const mode = (typeof env === 'object' ? env?.mode : env) ?? 'production';
|
|
125
289
|
const minify = assets?.minify ?? mode === 'production';
|
|
126
290
|
const baseURL = assets?.baseURL ?? '/assets/';
|
|
291
|
+
const assetsInline = assets?.inline ?? true;
|
|
127
292
|
|
|
128
|
-
const
|
|
129
|
-
|
|
293
|
+
const browserGroup = await getBrowserGroupTargetDetails(assets?.targets, {
|
|
294
|
+
root,
|
|
295
|
+
});
|
|
296
|
+
const targetFilenamePart = browserGroup.name ? `.${browserGroup.name}` : '';
|
|
130
297
|
|
|
131
298
|
const [
|
|
132
299
|
{visualizer},
|
|
@@ -135,8 +302,12 @@ export async function quiltAppBrowser({
|
|
|
135
302
|
{createTSConfigAliasPlugin},
|
|
136
303
|
{css},
|
|
137
304
|
{assetManifest, rawAssets, staticAssets},
|
|
305
|
+
{asyncModules},
|
|
138
306
|
{systemJS},
|
|
307
|
+
{workers},
|
|
308
|
+
{esnext},
|
|
139
309
|
nodePlugins,
|
|
310
|
+
packageJSON,
|
|
140
311
|
] = await Promise.all([
|
|
141
312
|
import('rollup-plugin-visualizer'),
|
|
142
313
|
import('./features/env.ts'),
|
|
@@ -144,37 +315,84 @@ export async function quiltAppBrowser({
|
|
|
144
315
|
import('./features/typescript.ts'),
|
|
145
316
|
import('./features/css.ts'),
|
|
146
317
|
import('./features/assets.ts'),
|
|
318
|
+
import('./features/async.ts'),
|
|
147
319
|
import('./features/system-js.ts'),
|
|
148
|
-
|
|
320
|
+
import('./features/workers.ts'),
|
|
321
|
+
import('./features/esnext.ts'),
|
|
322
|
+
getNodePlugins({bundle: true}),
|
|
323
|
+
loadPackageJSON(root),
|
|
149
324
|
]);
|
|
150
325
|
|
|
151
326
|
const plugins: Plugin[] = [
|
|
152
327
|
...nodePlugins,
|
|
153
328
|
systemJS({minify}),
|
|
154
329
|
replaceProcessEnv({mode}),
|
|
155
|
-
magicModuleEnv({...env, mode}),
|
|
156
|
-
sourceCode({
|
|
330
|
+
magicModuleEnv({...resolveEnvOption(env), mode}),
|
|
331
|
+
sourceCode({
|
|
332
|
+
mode,
|
|
333
|
+
targets: browserGroup.browsers,
|
|
334
|
+
babel: {
|
|
335
|
+
useBuiltIns: 'entry',
|
|
336
|
+
options(options) {
|
|
337
|
+
return {
|
|
338
|
+
...options,
|
|
339
|
+
plugins: [
|
|
340
|
+
...(options?.plugins ?? []),
|
|
341
|
+
require.resolve('@quilted/babel/async'),
|
|
342
|
+
require.resolve('@quilted/babel/workers'),
|
|
343
|
+
],
|
|
344
|
+
};
|
|
345
|
+
},
|
|
346
|
+
},
|
|
347
|
+
}),
|
|
348
|
+
esnext({
|
|
349
|
+
mode,
|
|
350
|
+
targets: browserGroup.browsers,
|
|
351
|
+
}),
|
|
157
352
|
css({minify, emit: true}),
|
|
158
353
|
rawAssets(),
|
|
159
|
-
staticAssets({
|
|
160
|
-
|
|
161
|
-
|
|
354
|
+
staticAssets({
|
|
355
|
+
baseURL,
|
|
356
|
+
emit: true,
|
|
357
|
+
inlineLimit: assetsInline
|
|
358
|
+
? typeof assetsInline === 'boolean'
|
|
359
|
+
? undefined
|
|
360
|
+
: assetsInline?.limit
|
|
361
|
+
: Number.POSITIVE_INFINITY,
|
|
362
|
+
}),
|
|
363
|
+
asyncModules({
|
|
364
|
+
baseURL,
|
|
365
|
+
preload: true,
|
|
366
|
+
moduleID: ({imported}) => path.relative(root, imported),
|
|
367
|
+
}),
|
|
368
|
+
workers({
|
|
369
|
+
baseURL,
|
|
370
|
+
outputOptions: {
|
|
371
|
+
format: 'iife',
|
|
372
|
+
inlineDynamicImports: true,
|
|
373
|
+
dir: path.resolve(root, `build/assets`),
|
|
374
|
+
entryFileNames: `[name]${targetFilenamePart}.[hash].js`,
|
|
375
|
+
assetFileNames: `[name]${targetFilenamePart}.[hash].[ext]`,
|
|
376
|
+
chunkFileNames: `[name]${targetFilenamePart}.[hash].js`,
|
|
377
|
+
},
|
|
162
378
|
}),
|
|
163
379
|
];
|
|
164
380
|
|
|
381
|
+
if (assets?.clean ?? true) {
|
|
382
|
+
plugins.push(
|
|
383
|
+
removeBuildFiles(['build/assets', 'build/manifests', 'build/reports'], {
|
|
384
|
+
root,
|
|
385
|
+
}),
|
|
386
|
+
);
|
|
387
|
+
}
|
|
388
|
+
|
|
165
389
|
const tsconfigAliases = await createTSConfigAliasPlugin();
|
|
166
390
|
|
|
167
391
|
if (tsconfigAliases) {
|
|
168
392
|
plugins.push(tsconfigAliases);
|
|
169
393
|
}
|
|
170
394
|
|
|
171
|
-
const appEntry =
|
|
172
|
-
app ??
|
|
173
|
-
(await glob('{App,app,input}.{ts,tsx,mjs,js,jsx}', {
|
|
174
|
-
cwd: root,
|
|
175
|
-
nodir: true,
|
|
176
|
-
absolute: true,
|
|
177
|
-
}).then((files) => files[0]));
|
|
395
|
+
const appEntry = await resolveAppEntry(app, {root, packageJSON});
|
|
178
396
|
|
|
179
397
|
if (appEntry) {
|
|
180
398
|
plugins.push(magicModuleAppComponent({entry: appEntry}));
|
|
@@ -198,16 +416,15 @@ export async function quiltAppBrowser({
|
|
|
198
416
|
plugins.push(minify());
|
|
199
417
|
}
|
|
200
418
|
|
|
201
|
-
const cacheKey =
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
419
|
+
const cacheKey = new URLSearchParams();
|
|
420
|
+
if (browserGroup.name) {
|
|
421
|
+
cacheKey.set('browserGroup', browserGroup.name);
|
|
422
|
+
}
|
|
205
423
|
|
|
206
424
|
plugins.push(
|
|
207
425
|
assetManifest({
|
|
208
|
-
id,
|
|
209
|
-
cacheKey,
|
|
210
426
|
baseURL,
|
|
427
|
+
cacheKey,
|
|
211
428
|
file: path.resolve(`build/manifests/assets${targetFilenamePart}.json`),
|
|
212
429
|
priority: assets?.priority,
|
|
213
430
|
}),
|
|
@@ -221,14 +438,15 @@ export async function quiltAppBrowser({
|
|
|
221
438
|
}),
|
|
222
439
|
);
|
|
223
440
|
|
|
224
|
-
const finalEntry =
|
|
225
|
-
entry
|
|
226
|
-
(await glob('{browser,client}.{ts,tsx,mjs,js,jsx}', {
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
441
|
+
const finalEntry = entry
|
|
442
|
+
? path.resolve(root, entry)
|
|
443
|
+
: (await glob('{browser,client,web}.{ts,tsx,mjs,js,jsx}', {
|
|
444
|
+
cwd: root,
|
|
445
|
+
nodir: true,
|
|
446
|
+
absolute: true,
|
|
447
|
+
}).then((files) => files[0])) ?? MAGIC_MODULE_ENTRY;
|
|
448
|
+
|
|
449
|
+
const isESM = await targetsSupportModules(browserGroup.browsers);
|
|
232
450
|
|
|
233
451
|
return {
|
|
234
452
|
input: finalEntry,
|
|
@@ -246,68 +464,104 @@ export async function quiltAppBrowser({
|
|
|
246
464
|
defaultWarn(warning);
|
|
247
465
|
},
|
|
248
466
|
output: {
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
dir: path.resolve(`build/assets`),
|
|
467
|
+
format: isESM ? 'esm' : 'systemjs',
|
|
468
|
+
dir: path.resolve(root, `build/assets`),
|
|
252
469
|
entryFileNames: `app${targetFilenamePart}.[hash].js`,
|
|
253
470
|
assetFileNames: `[name]${targetFilenamePart}.[hash].[ext]`,
|
|
254
471
|
chunkFileNames: `[name]${targetFilenamePart}.[hash].js`,
|
|
255
472
|
manualChunks: createManualChunksSorter(),
|
|
473
|
+
generatedCode: await rollupGenerateOptionsForBrowsers(
|
|
474
|
+
browserGroup.browsers,
|
|
475
|
+
),
|
|
256
476
|
},
|
|
257
477
|
} satisfies RollupOptions;
|
|
258
478
|
}
|
|
259
479
|
|
|
260
|
-
export interface AppServerOptions extends AppOptions {
|
|
261
|
-
/**
|
|
262
|
-
* The entry module for the server of this app. This module must export a
|
|
263
|
-
* `RequestRouter` object as its default export, which will be wrapped in
|
|
264
|
-
* the specific server runtime you configure.
|
|
265
|
-
*/
|
|
266
|
-
entry?: string;
|
|
267
|
-
|
|
268
|
-
/**
|
|
269
|
-
* Whether to minify the JavaScript outputs for your server.
|
|
270
|
-
*
|
|
271
|
-
* @default false
|
|
272
|
-
*/
|
|
273
|
-
minify?: boolean;
|
|
274
|
-
}
|
|
275
|
-
|
|
276
480
|
export async function quiltAppServer({
|
|
481
|
+
root: rootPath = process.cwd(),
|
|
277
482
|
app,
|
|
278
483
|
env,
|
|
279
484
|
entry,
|
|
485
|
+
format = 'request-router',
|
|
280
486
|
graphql = true,
|
|
281
|
-
|
|
487
|
+
assets,
|
|
488
|
+
output,
|
|
282
489
|
}: AppServerOptions = {}) {
|
|
283
|
-
const root =
|
|
284
|
-
const mode =
|
|
285
|
-
|
|
490
|
+
const root = resolveRoot(rootPath);
|
|
491
|
+
const mode = (typeof env === 'object' ? env?.mode : env) ?? 'production';
|
|
492
|
+
|
|
493
|
+
const baseURL = assets?.baseURL ?? '/assets/';
|
|
494
|
+
const assetsInline = assets?.inline ?? true;
|
|
495
|
+
|
|
496
|
+
const bundle = output?.bundle;
|
|
497
|
+
const minify = output?.minify ?? false;
|
|
498
|
+
const hash = output?.hash ?? 'async-only';
|
|
499
|
+
const outputFormat = output?.format ?? 'esmodules';
|
|
286
500
|
|
|
287
501
|
const [
|
|
288
502
|
{visualizer},
|
|
503
|
+
{magicModuleEnv, replaceProcessEnv},
|
|
289
504
|
{sourceCode},
|
|
290
505
|
{createTSConfigAliasPlugin},
|
|
291
506
|
{css},
|
|
292
507
|
{rawAssets, staticAssets},
|
|
293
|
-
{
|
|
508
|
+
{asyncModules},
|
|
509
|
+
{esnext},
|
|
294
510
|
nodePlugins,
|
|
511
|
+
packageJSON,
|
|
295
512
|
] = await Promise.all([
|
|
296
513
|
import('rollup-plugin-visualizer'),
|
|
514
|
+
import('./features/env.ts'),
|
|
297
515
|
import('./features/source-code.ts'),
|
|
298
516
|
import('./features/typescript.ts'),
|
|
299
517
|
import('./features/css.ts'),
|
|
300
518
|
import('./features/assets.ts'),
|
|
301
|
-
import('./features/
|
|
302
|
-
|
|
519
|
+
import('./features/async.ts'),
|
|
520
|
+
import('./features/esnext.ts'),
|
|
521
|
+
getNodePlugins({bundle}),
|
|
522
|
+
loadPackageJSON(root),
|
|
303
523
|
]);
|
|
304
524
|
|
|
305
525
|
const plugins: Plugin[] = [
|
|
306
526
|
...nodePlugins,
|
|
307
|
-
|
|
527
|
+
replaceProcessEnv({mode}),
|
|
528
|
+
magicModuleEnv({...resolveEnvOption(env), mode}),
|
|
529
|
+
sourceCode({
|
|
530
|
+
mode,
|
|
531
|
+
targets: ['current node'],
|
|
532
|
+
babel: {
|
|
533
|
+
options(options) {
|
|
534
|
+
return {
|
|
535
|
+
...options,
|
|
536
|
+
plugins: [
|
|
537
|
+
...(options?.plugins ?? []),
|
|
538
|
+
require.resolve('@quilted/babel/async'),
|
|
539
|
+
[require.resolve('@quilted/babel/workers'), {noop: true}],
|
|
540
|
+
],
|
|
541
|
+
};
|
|
542
|
+
},
|
|
543
|
+
},
|
|
544
|
+
}),
|
|
545
|
+
esnext({
|
|
546
|
+
mode,
|
|
547
|
+
targets: ['current node'],
|
|
548
|
+
}),
|
|
308
549
|
css({emit: false, minify}),
|
|
309
550
|
rawAssets(),
|
|
310
|
-
staticAssets({
|
|
551
|
+
staticAssets({
|
|
552
|
+
emit: false,
|
|
553
|
+
baseURL,
|
|
554
|
+
inlineLimit: assetsInline
|
|
555
|
+
? typeof assetsInline === 'boolean'
|
|
556
|
+
? undefined
|
|
557
|
+
: assetsInline?.limit
|
|
558
|
+
: Number.POSITIVE_INFINITY,
|
|
559
|
+
}),
|
|
560
|
+
asyncModules({
|
|
561
|
+
baseURL,
|
|
562
|
+
preload: false,
|
|
563
|
+
moduleID: ({imported}) => path.relative(root, imported),
|
|
564
|
+
}),
|
|
311
565
|
removeBuildFiles(['build/server'], {root}),
|
|
312
566
|
];
|
|
313
567
|
|
|
@@ -317,35 +571,32 @@ export async function quiltAppServer({
|
|
|
317
571
|
plugins.push(tsconfigAliases);
|
|
318
572
|
}
|
|
319
573
|
|
|
320
|
-
|
|
321
|
-
const {magicModuleEnv, replaceProcessEnv} = await import(
|
|
322
|
-
'./features/env.ts'
|
|
323
|
-
);
|
|
324
|
-
|
|
325
|
-
if (typeof env === 'boolean') {
|
|
326
|
-
plugins.push(replaceProcessEnv({mode}));
|
|
327
|
-
plugins.push(magicModuleEnv({mode}));
|
|
328
|
-
} else {
|
|
329
|
-
plugins.push(replaceProcessEnv({mode}));
|
|
330
|
-
plugins.push(magicModuleEnv({mode}));
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
const appEntry =
|
|
335
|
-
app ??
|
|
336
|
-
(await glob('{App,app,input}.{ts,tsx,mjs,js,jsx}', {
|
|
337
|
-
cwd: root,
|
|
338
|
-
nodir: true,
|
|
339
|
-
absolute: true,
|
|
340
|
-
}).then((files) => files[0]));
|
|
574
|
+
const appEntry = await resolveAppEntry(app, {root, packageJSON});
|
|
341
575
|
|
|
342
576
|
if (appEntry) {
|
|
343
577
|
plugins.push(magicModuleAppComponent({entry: appEntry}));
|
|
344
578
|
}
|
|
345
579
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
580
|
+
const serverEntry = entry
|
|
581
|
+
? path.resolve(root, entry)
|
|
582
|
+
: await glob('{server,service,backend}.{ts,tsx,mjs,js,jsx}', {
|
|
583
|
+
cwd: root,
|
|
584
|
+
nodir: true,
|
|
585
|
+
absolute: true,
|
|
586
|
+
}).then((files) => files[0]);
|
|
587
|
+
|
|
588
|
+
const finalEntry =
|
|
589
|
+
format === 'request-router'
|
|
590
|
+
? MAGIC_MODULE_ENTRY
|
|
591
|
+
: serverEntry ?? MAGIC_MODULE_ENTRY;
|
|
592
|
+
|
|
593
|
+
plugins.push(
|
|
594
|
+
magicModuleAppServerEntry({
|
|
595
|
+
assets: {baseURL},
|
|
596
|
+
}),
|
|
597
|
+
magicModuleAppRequestRouter({entry: serverEntry}),
|
|
598
|
+
magicModuleAppAssetManifests(),
|
|
599
|
+
);
|
|
349
600
|
|
|
350
601
|
if (graphql) {
|
|
351
602
|
const {graphql} = await import('./features/graphql.ts');
|
|
@@ -366,15 +617,6 @@ export async function quiltAppServer({
|
|
|
366
617
|
}),
|
|
367
618
|
);
|
|
368
619
|
|
|
369
|
-
const finalEntry =
|
|
370
|
-
entry ??
|
|
371
|
-
(await glob('{server,service,backend}.{ts,tsx,mjs,js,jsx}', {
|
|
372
|
-
cwd: root,
|
|
373
|
-
nodir: true,
|
|
374
|
-
absolute: true,
|
|
375
|
-
}).then((files) => files[0])) ??
|
|
376
|
-
MAGIC_MODULE_ENTRY;
|
|
377
|
-
|
|
378
620
|
return {
|
|
379
621
|
input: finalEntry,
|
|
380
622
|
plugins,
|
|
@@ -391,10 +633,15 @@ export async function quiltAppServer({
|
|
|
391
633
|
defaultWarn(warning);
|
|
392
634
|
},
|
|
393
635
|
output: {
|
|
394
|
-
|
|
395
|
-
|
|
636
|
+
format:
|
|
637
|
+
outputFormat === 'commonjs' || outputFormat === 'cjs' ? 'cjs' : 'esm',
|
|
396
638
|
dir: path.resolve(`build/server`),
|
|
397
|
-
entryFileNames: '
|
|
639
|
+
entryFileNames: `server${hash === true ? `.[hash]` : ''}.js`,
|
|
640
|
+
chunkFileNames: `[name]${
|
|
641
|
+
hash === true || hash === 'async-only' ? `.[hash]` : ''
|
|
642
|
+
}.js`,
|
|
643
|
+
assetFileNames: `[name]${hash === true ? `.[hash]` : ''}.[ext]`,
|
|
644
|
+
generatedCode: 'es2015',
|
|
398
645
|
},
|
|
399
646
|
} satisfies RollupOptions;
|
|
400
647
|
}
|
|
@@ -479,6 +726,75 @@ export function magicModuleAppBrowserEntry({
|
|
|
479
726
|
});
|
|
480
727
|
}
|
|
481
728
|
|
|
729
|
+
export function magicModuleAppServerEntry({
|
|
730
|
+
host,
|
|
731
|
+
port,
|
|
732
|
+
assets,
|
|
733
|
+
format = 'module',
|
|
734
|
+
}: {
|
|
735
|
+
host?: string;
|
|
736
|
+
port?: number;
|
|
737
|
+
assets?: boolean | {baseURL: string};
|
|
738
|
+
format?: 'module' | 'commonjs';
|
|
739
|
+
} = {}) {
|
|
740
|
+
const baseURL = typeof assets === 'object' ? assets.baseURL : '/assets/';
|
|
741
|
+
|
|
742
|
+
return createMagicModulePlugin({
|
|
743
|
+
name: '@quilted/request-router/app-server',
|
|
744
|
+
module: MAGIC_MODULE_ENTRY,
|
|
745
|
+
sideEffects: true,
|
|
746
|
+
async source() {
|
|
747
|
+
const serveAssets = Boolean(assets);
|
|
748
|
+
|
|
749
|
+
return multiline`
|
|
750
|
+
${serveAssets ? `import * as path from 'path';` : ''}
|
|
751
|
+
${
|
|
752
|
+
serveAssets && format === 'module'
|
|
753
|
+
? `import {fileURLToPath} from 'url';`
|
|
754
|
+
: ''
|
|
755
|
+
}
|
|
756
|
+
import {createServer} from 'http';
|
|
757
|
+
|
|
758
|
+
import requestRouter from ${JSON.stringify(
|
|
759
|
+
MAGIC_MODULE_REQUEST_ROUTER,
|
|
760
|
+
)};
|
|
761
|
+
|
|
762
|
+
import {createHttpRequestListener${
|
|
763
|
+
serveAssets ? ', serveStatic' : ''
|
|
764
|
+
}} from '@quilted/quilt/request-router/node';
|
|
765
|
+
|
|
766
|
+
const port = ${port ?? 'Number.parseInt(process.env.PORT, 10)'};
|
|
767
|
+
const host = ${host ? JSON.stringify(host) : 'process.env.HOST'};
|
|
768
|
+
|
|
769
|
+
${
|
|
770
|
+
serveAssets
|
|
771
|
+
? `const dirname = ${
|
|
772
|
+
format === 'module'
|
|
773
|
+
? 'path.dirname(fileURLToPath(import.meta.url))'
|
|
774
|
+
: '__dirname'
|
|
775
|
+
};\nconst serve = serveStatic(path.resolve(dirname, '../assets'), {
|
|
776
|
+
baseUrl: ${JSON.stringify(baseURL)},
|
|
777
|
+
});`
|
|
778
|
+
: ''
|
|
779
|
+
}
|
|
780
|
+
const listener = createHttpRequestListener(requestRouter);
|
|
781
|
+
|
|
782
|
+
createServer(async (request, response) => {
|
|
783
|
+
${
|
|
784
|
+
serveAssets
|
|
785
|
+
? `if (request.url.startsWith(${JSON.stringify(
|
|
786
|
+
baseURL,
|
|
787
|
+
)})) return serve(request, response);`
|
|
788
|
+
: ''
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
await listener(request, response);
|
|
792
|
+
}).listen(port, host);
|
|
793
|
+
`;
|
|
794
|
+
},
|
|
795
|
+
});
|
|
796
|
+
}
|
|
797
|
+
|
|
482
798
|
export function magicModuleAppAssetManifests() {
|
|
483
799
|
return createMagicModulePlugin({
|
|
484
800
|
name: '@quilted/magic-module/asset-manifests',
|
|
@@ -504,6 +820,8 @@ export function magicModuleAppAssetManifests() {
|
|
|
504
820
|
(manifestA.priority ?? 0) - (manifestB.priority ?? 0),
|
|
505
821
|
);
|
|
506
822
|
|
|
823
|
+
const browserGroupRegexes = await getBrowserGroupRegularExpressions();
|
|
824
|
+
|
|
507
825
|
return multiline`
|
|
508
826
|
import {BrowserAssetsFromManifests} from '@quilted/quilt/server';
|
|
509
827
|
|
|
@@ -513,12 +831,31 @@ export function magicModuleAppAssetManifests() {
|
|
|
513
831
|
JSON.stringify(manifests),
|
|
514
832
|
)});
|
|
515
833
|
|
|
834
|
+
const browserGroupTests = [
|
|
835
|
+
${Object.entries(browserGroupRegexes)
|
|
836
|
+
.map(
|
|
837
|
+
([name, test]) =>
|
|
838
|
+
`[${JSON.stringify(name)}, new RegExp(${JSON.stringify(
|
|
839
|
+
test.source,
|
|
840
|
+
)})]`,
|
|
841
|
+
)
|
|
842
|
+
.join(', ')}
|
|
843
|
+
];
|
|
844
|
+
|
|
516
845
|
// The default manifest is the last one, since it has the widest browser support.
|
|
517
846
|
const defaultManifest = manifests.at(-1);
|
|
518
847
|
|
|
519
848
|
super(manifests, {
|
|
520
849
|
defaultManifest,
|
|
521
850
|
cacheKey(request) {
|
|
851
|
+
const userAgent = request.headers.get('User-Agent');
|
|
852
|
+
|
|
853
|
+
if (userAgent) {
|
|
854
|
+
for (const [name, test] of browserGroupTests) {
|
|
855
|
+
if (test.test(userAgent)) return {browserGroup: name};
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
|
|
522
859
|
return {};
|
|
523
860
|
},
|
|
524
861
|
});
|
|
@@ -548,7 +885,6 @@ const FRAMEWORK_TEST_STRINGS: (string | RegExp)[] = [
|
|
|
548
885
|
];
|
|
549
886
|
|
|
550
887
|
const POLYFILL_TEST_STRINGS = [
|
|
551
|
-
'/node_modules/@quilted/polyfills/',
|
|
552
888
|
'/node_modules/core-js/',
|
|
553
889
|
'/node_modules/whatwg-fetch/',
|
|
554
890
|
'/node_modules/regenerator-runtime/',
|
|
@@ -628,3 +964,30 @@ function createManualChunksSorter(): GetManualChunk {
|
|
|
628
964
|
return `${bundleBaseName}-${relativeId.split(path.sep)[0]?.split('.')[0]}`;
|
|
629
965
|
};
|
|
630
966
|
}
|
|
967
|
+
|
|
968
|
+
async function resolveAppEntry(
|
|
969
|
+
entry: string | undefined,
|
|
970
|
+
{root, packageJSON}: {root: string; packageJSON: PackageJSON},
|
|
971
|
+
) {
|
|
972
|
+
if (entry) {
|
|
973
|
+
return path.resolve(root, entry);
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
if (typeof packageJSON.main === 'string') {
|
|
977
|
+
return path.resolve(root, packageJSON.main);
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
const rootEntry = (packageJSON.exports as any)?.['.'];
|
|
981
|
+
|
|
982
|
+
if (typeof rootEntry === 'string') {
|
|
983
|
+
return path.resolve(root, rootEntry);
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
const globbed = await glob('{App,app,index}.{ts,tsx,mjs,js,jsx}', {
|
|
987
|
+
cwd: root,
|
|
988
|
+
nodir: true,
|
|
989
|
+
absolute: true,
|
|
990
|
+
});
|
|
991
|
+
|
|
992
|
+
return globbed[0];
|
|
993
|
+
}
|