@quilted/rollup 0.1.19 → 0.2.1
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 +27 -0
- package/build/esm/app.mjs +450 -222
- 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 +29 -20
- 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 +132 -29
- 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/system-js.d.ts +4 -1
- package/build/typescript/features/system-js.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 +62 -9
- package/source/app.ts +475 -99
- 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 +27 -9
- package/source/features/system-js.ts +25 -2
- 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 -441
- 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 -414
- 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`.
|
|
68
|
+
*/
|
|
69
|
+
env?: MagicModuleEnvOptions | MagicModuleEnvOptions['mode'];
|
|
70
|
+
}
|
|
71
|
+
|
|
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.
|
|
57
86
|
*/
|
|
58
|
-
|
|
87
|
+
server?: Omit<AppServerOptions, keyof AppBaseOptions> &
|
|
88
|
+
Pick<AppServerOptions, 'env'>;
|
|
59
89
|
}
|
|
60
90
|
|
|
61
|
-
export interface AppBrowserOptions extends
|
|
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,15 +284,16 @@ export async function quiltAppBrowser({
|
|
|
119
284
|
module,
|
|
120
285
|
graphql = true,
|
|
121
286
|
}: AppBrowserOptions = {}) {
|
|
122
|
-
const root =
|
|
123
|
-
|
|
124
|
-
const mode =
|
|
125
|
-
(typeof env === 'object' ? env?.mode : undefined) ?? 'production';
|
|
287
|
+
const root = resolveRoot(rootPath);
|
|
288
|
+
const mode = (typeof env === 'object' ? env?.mode : env) ?? 'production';
|
|
126
289
|
const minify = assets?.minify ?? mode === 'production';
|
|
127
290
|
const baseURL = assets?.baseURL ?? '/assets/';
|
|
291
|
+
const assetsInline = assets?.inline ?? true;
|
|
128
292
|
|
|
129
|
-
const
|
|
130
|
-
|
|
293
|
+
const browserGroup = await getBrowserGroupTargetDetails(assets?.targets, {
|
|
294
|
+
root,
|
|
295
|
+
});
|
|
296
|
+
const targetFilenamePart = browserGroup.name ? `.${browserGroup.name}` : '';
|
|
131
297
|
|
|
132
298
|
const [
|
|
133
299
|
{visualizer},
|
|
@@ -136,8 +302,12 @@ export async function quiltAppBrowser({
|
|
|
136
302
|
{createTSConfigAliasPlugin},
|
|
137
303
|
{css},
|
|
138
304
|
{assetManifest, rawAssets, staticAssets},
|
|
305
|
+
{asyncModules},
|
|
139
306
|
{systemJS},
|
|
307
|
+
{workers},
|
|
308
|
+
{esnext},
|
|
140
309
|
nodePlugins,
|
|
310
|
+
packageJSON,
|
|
141
311
|
] = await Promise.all([
|
|
142
312
|
import('rollup-plugin-visualizer'),
|
|
143
313
|
import('./features/env.ts'),
|
|
@@ -145,37 +315,84 @@ export async function quiltAppBrowser({
|
|
|
145
315
|
import('./features/typescript.ts'),
|
|
146
316
|
import('./features/css.ts'),
|
|
147
317
|
import('./features/assets.ts'),
|
|
318
|
+
import('./features/async.ts'),
|
|
148
319
|
import('./features/system-js.ts'),
|
|
149
|
-
|
|
320
|
+
import('./features/workers.ts'),
|
|
321
|
+
import('./features/esnext.ts'),
|
|
322
|
+
getNodePlugins({bundle: true}),
|
|
323
|
+
loadPackageJSON(root),
|
|
150
324
|
]);
|
|
151
325
|
|
|
152
326
|
const plugins: Plugin[] = [
|
|
153
327
|
...nodePlugins,
|
|
154
328
|
systemJS({minify}),
|
|
155
329
|
replaceProcessEnv({mode}),
|
|
156
|
-
magicModuleEnv({...env, mode}),
|
|
157
|
-
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
|
+
}),
|
|
158
352
|
css({minify, emit: true}),
|
|
159
353
|
rawAssets(),
|
|
160
|
-
staticAssets({
|
|
161
|
-
|
|
162
|
-
|
|
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
|
+
},
|
|
163
378
|
}),
|
|
164
379
|
];
|
|
165
380
|
|
|
381
|
+
if (assets?.clean ?? true) {
|
|
382
|
+
plugins.push(
|
|
383
|
+
removeBuildFiles(['build/assets', 'build/manifests', 'build/reports'], {
|
|
384
|
+
root,
|
|
385
|
+
}),
|
|
386
|
+
);
|
|
387
|
+
}
|
|
388
|
+
|
|
166
389
|
const tsconfigAliases = await createTSConfigAliasPlugin();
|
|
167
390
|
|
|
168
391
|
if (tsconfigAliases) {
|
|
169
392
|
plugins.push(tsconfigAliases);
|
|
170
393
|
}
|
|
171
394
|
|
|
172
|
-
const appEntry =
|
|
173
|
-
app ??
|
|
174
|
-
(await glob('{App,app,input}.{ts,tsx,mjs,js,jsx}', {
|
|
175
|
-
cwd: root,
|
|
176
|
-
nodir: true,
|
|
177
|
-
absolute: true,
|
|
178
|
-
}).then((files) => files[0]));
|
|
395
|
+
const appEntry = await resolveAppEntry(app, {root, packageJSON});
|
|
179
396
|
|
|
180
397
|
if (appEntry) {
|
|
181
398
|
plugins.push(magicModuleAppComponent({entry: appEntry}));
|
|
@@ -199,16 +416,15 @@ export async function quiltAppBrowser({
|
|
|
199
416
|
plugins.push(minify());
|
|
200
417
|
}
|
|
201
418
|
|
|
202
|
-
const cacheKey =
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
419
|
+
const cacheKey = new URLSearchParams();
|
|
420
|
+
if (browserGroup.name) {
|
|
421
|
+
cacheKey.set('browserGroup', browserGroup.name);
|
|
422
|
+
}
|
|
206
423
|
|
|
207
424
|
plugins.push(
|
|
208
425
|
assetManifest({
|
|
209
|
-
id,
|
|
210
|
-
cacheKey,
|
|
211
426
|
baseURL,
|
|
427
|
+
cacheKey,
|
|
212
428
|
file: path.resolve(`build/manifests/assets${targetFilenamePart}.json`),
|
|
213
429
|
priority: assets?.priority,
|
|
214
430
|
}),
|
|
@@ -222,17 +438,21 @@ export async function quiltAppBrowser({
|
|
|
222
438
|
}),
|
|
223
439
|
);
|
|
224
440
|
|
|
225
|
-
const finalEntry =
|
|
226
|
-
entry
|
|
227
|
-
(await glob('{browser,client}.{ts,tsx,mjs,js,jsx}', {
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
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);
|
|
233
450
|
|
|
234
451
|
return {
|
|
235
|
-
|
|
452
|
+
// If we are using the "magic entry", give it an explicit name of `browser`.
|
|
453
|
+
// Otherwise, Rollup will use the file name as the output name.
|
|
454
|
+
input:
|
|
455
|
+
finalEntry === MAGIC_MODULE_ENTRY ? {browser: finalEntry} : finalEntry,
|
|
236
456
|
plugins,
|
|
237
457
|
onwarn(warning, defaultWarn) {
|
|
238
458
|
// Removes annoying warnings for React-focused libraries that
|
|
@@ -247,43 +467,39 @@ export async function quiltAppBrowser({
|
|
|
247
467
|
defaultWarn(warning);
|
|
248
468
|
},
|
|
249
469
|
output: {
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
entryFileNames: `app${targetFilenamePart}.[hash].js`,
|
|
470
|
+
format: isESM ? 'esm' : 'systemjs',
|
|
471
|
+
dir: path.resolve(root, `build/assets`),
|
|
472
|
+
entryFileNames: `[name]${targetFilenamePart}.[hash].js`,
|
|
254
473
|
assetFileNames: `[name]${targetFilenamePart}.[hash].[ext]`,
|
|
255
474
|
chunkFileNames: `[name]${targetFilenamePart}.[hash].js`,
|
|
256
475
|
manualChunks: createManualChunksSorter(),
|
|
476
|
+
generatedCode: await rollupGenerateOptionsForBrowsers(
|
|
477
|
+
browserGroup.browsers,
|
|
478
|
+
),
|
|
257
479
|
},
|
|
258
480
|
} satisfies RollupOptions;
|
|
259
481
|
}
|
|
260
482
|
|
|
261
|
-
export interface AppServerOptions extends AppOptions {
|
|
262
|
-
/**
|
|
263
|
-
* The entry module for the server of this app. This module must export a
|
|
264
|
-
* `RequestRouter` object as its default export, which will be wrapped in
|
|
265
|
-
* the specific server runtime you configure.
|
|
266
|
-
*/
|
|
267
|
-
entry?: string;
|
|
268
|
-
|
|
269
|
-
/**
|
|
270
|
-
* Whether to minify the JavaScript outputs for your server.
|
|
271
|
-
*
|
|
272
|
-
* @default false
|
|
273
|
-
*/
|
|
274
|
-
minify?: boolean;
|
|
275
|
-
}
|
|
276
|
-
|
|
277
483
|
export async function quiltAppServer({
|
|
484
|
+
root: rootPath = process.cwd(),
|
|
278
485
|
app,
|
|
279
486
|
env,
|
|
280
487
|
entry,
|
|
488
|
+
format = 'request-router',
|
|
281
489
|
graphql = true,
|
|
282
|
-
|
|
490
|
+
assets,
|
|
491
|
+
output,
|
|
283
492
|
}: AppServerOptions = {}) {
|
|
284
|
-
const root =
|
|
285
|
-
const mode =
|
|
286
|
-
|
|
493
|
+
const root = resolveRoot(rootPath);
|
|
494
|
+
const mode = (typeof env === 'object' ? env?.mode : env) ?? 'production';
|
|
495
|
+
|
|
496
|
+
const baseURL = assets?.baseURL ?? '/assets/';
|
|
497
|
+
const assetsInline = assets?.inline ?? true;
|
|
498
|
+
|
|
499
|
+
const bundle = output?.bundle;
|
|
500
|
+
const minify = output?.minify ?? false;
|
|
501
|
+
const hash = output?.hash ?? 'async-only';
|
|
502
|
+
const outputFormat = output?.format ?? 'esmodules';
|
|
287
503
|
|
|
288
504
|
const [
|
|
289
505
|
{visualizer},
|
|
@@ -292,8 +508,10 @@ export async function quiltAppServer({
|
|
|
292
508
|
{createTSConfigAliasPlugin},
|
|
293
509
|
{css},
|
|
294
510
|
{rawAssets, staticAssets},
|
|
295
|
-
{
|
|
511
|
+
{asyncModules},
|
|
512
|
+
{esnext},
|
|
296
513
|
nodePlugins,
|
|
514
|
+
packageJSON,
|
|
297
515
|
] = await Promise.all([
|
|
298
516
|
import('rollup-plugin-visualizer'),
|
|
299
517
|
import('./features/env.ts'),
|
|
@@ -301,18 +519,52 @@ export async function quiltAppServer({
|
|
|
301
519
|
import('./features/typescript.ts'),
|
|
302
520
|
import('./features/css.ts'),
|
|
303
521
|
import('./features/assets.ts'),
|
|
304
|
-
import('./features/
|
|
305
|
-
|
|
522
|
+
import('./features/async.ts'),
|
|
523
|
+
import('./features/esnext.ts'),
|
|
524
|
+
getNodePlugins({bundle}),
|
|
525
|
+
loadPackageJSON(root),
|
|
306
526
|
]);
|
|
307
527
|
|
|
308
528
|
const plugins: Plugin[] = [
|
|
309
529
|
...nodePlugins,
|
|
310
530
|
replaceProcessEnv({mode}),
|
|
311
|
-
magicModuleEnv({...env, mode}),
|
|
312
|
-
sourceCode({
|
|
531
|
+
magicModuleEnv({...resolveEnvOption(env), mode}),
|
|
532
|
+
sourceCode({
|
|
533
|
+
mode,
|
|
534
|
+
targets: ['current node'],
|
|
535
|
+
babel: {
|
|
536
|
+
options(options) {
|
|
537
|
+
return {
|
|
538
|
+
...options,
|
|
539
|
+
plugins: [
|
|
540
|
+
...(options?.plugins ?? []),
|
|
541
|
+
require.resolve('@quilted/babel/async'),
|
|
542
|
+
[require.resolve('@quilted/babel/workers'), {noop: true}],
|
|
543
|
+
],
|
|
544
|
+
};
|
|
545
|
+
},
|
|
546
|
+
},
|
|
547
|
+
}),
|
|
548
|
+
esnext({
|
|
549
|
+
mode,
|
|
550
|
+
targets: ['current node'],
|
|
551
|
+
}),
|
|
313
552
|
css({emit: false, minify}),
|
|
314
553
|
rawAssets(),
|
|
315
|
-
staticAssets({
|
|
554
|
+
staticAssets({
|
|
555
|
+
emit: false,
|
|
556
|
+
baseURL,
|
|
557
|
+
inlineLimit: assetsInline
|
|
558
|
+
? typeof assetsInline === 'boolean'
|
|
559
|
+
? undefined
|
|
560
|
+
: assetsInline?.limit
|
|
561
|
+
: Number.POSITIVE_INFINITY,
|
|
562
|
+
}),
|
|
563
|
+
asyncModules({
|
|
564
|
+
baseURL,
|
|
565
|
+
preload: false,
|
|
566
|
+
moduleID: ({imported}) => path.relative(root, imported),
|
|
567
|
+
}),
|
|
316
568
|
removeBuildFiles(['build/server'], {root}),
|
|
317
569
|
];
|
|
318
570
|
|
|
@@ -322,21 +574,30 @@ export async function quiltAppServer({
|
|
|
322
574
|
plugins.push(tsconfigAliases);
|
|
323
575
|
}
|
|
324
576
|
|
|
325
|
-
const appEntry =
|
|
326
|
-
app ??
|
|
327
|
-
(await glob('{App,app,input}.{ts,tsx,mjs,js,jsx}', {
|
|
328
|
-
cwd: root,
|
|
329
|
-
nodir: true,
|
|
330
|
-
absolute: true,
|
|
331
|
-
}).then((files) => files[0]));
|
|
577
|
+
const appEntry = await resolveAppEntry(app, {root, packageJSON});
|
|
332
578
|
|
|
333
579
|
if (appEntry) {
|
|
334
580
|
plugins.push(magicModuleAppComponent({entry: appEntry}));
|
|
335
581
|
}
|
|
336
582
|
|
|
583
|
+
const serverEntry = entry
|
|
584
|
+
? path.resolve(root, entry)
|
|
585
|
+
: await glob('{server,service,backend}.{ts,tsx,mjs,js,jsx}', {
|
|
586
|
+
cwd: root,
|
|
587
|
+
nodir: true,
|
|
588
|
+
absolute: true,
|
|
589
|
+
}).then((files) => files[0]);
|
|
590
|
+
|
|
591
|
+
const finalEntry =
|
|
592
|
+
format === 'request-router'
|
|
593
|
+
? MAGIC_MODULE_ENTRY
|
|
594
|
+
: serverEntry ?? MAGIC_MODULE_ENTRY;
|
|
595
|
+
|
|
337
596
|
plugins.push(
|
|
338
|
-
|
|
339
|
-
|
|
597
|
+
magicModuleAppServerEntry({
|
|
598
|
+
assets: {baseURL},
|
|
599
|
+
}),
|
|
600
|
+
magicModuleAppRequestRouter({entry: serverEntry}),
|
|
340
601
|
magicModuleAppAssetManifests(),
|
|
341
602
|
);
|
|
342
603
|
|
|
@@ -359,17 +620,11 @@ export async function quiltAppServer({
|
|
|
359
620
|
}),
|
|
360
621
|
);
|
|
361
622
|
|
|
362
|
-
const finalEntry =
|
|
363
|
-
entry ??
|
|
364
|
-
(await glob('{server,service,backend}.{ts,tsx,mjs,js,jsx}', {
|
|
365
|
-
cwd: root,
|
|
366
|
-
nodir: true,
|
|
367
|
-
absolute: true,
|
|
368
|
-
}).then((files) => files[0])) ??
|
|
369
|
-
MAGIC_MODULE_ENTRY;
|
|
370
|
-
|
|
371
623
|
return {
|
|
372
|
-
|
|
624
|
+
// If we are using the "magic entry", give it an explicit name of `server`.
|
|
625
|
+
// Otherwise, Rollup will use the file name as the output name.
|
|
626
|
+
input:
|
|
627
|
+
finalEntry === MAGIC_MODULE_ENTRY ? {server: finalEntry} : finalEntry,
|
|
373
628
|
plugins,
|
|
374
629
|
onwarn(warning, defaultWarn) {
|
|
375
630
|
// Removes annoying warnings for React-focused libraries that
|
|
@@ -384,10 +639,15 @@ export async function quiltAppServer({
|
|
|
384
639
|
defaultWarn(warning);
|
|
385
640
|
},
|
|
386
641
|
output: {
|
|
387
|
-
|
|
388
|
-
|
|
642
|
+
format:
|
|
643
|
+
outputFormat === 'commonjs' || outputFormat === 'cjs' ? 'cjs' : 'esm',
|
|
389
644
|
dir: path.resolve(`build/server`),
|
|
390
|
-
entryFileNames: '
|
|
645
|
+
entryFileNames: `[name]${hash === true ? `.[hash]` : ''}.js`,
|
|
646
|
+
chunkFileNames: `[name]${
|
|
647
|
+
hash === true || hash === 'async-only' ? `.[hash]` : ''
|
|
648
|
+
}.js`,
|
|
649
|
+
assetFileNames: `[name]${hash === true ? `.[hash]` : ''}.[ext]`,
|
|
650
|
+
generatedCode: 'es2015',
|
|
391
651
|
},
|
|
392
652
|
} satisfies RollupOptions;
|
|
393
653
|
}
|
|
@@ -472,6 +732,75 @@ export function magicModuleAppBrowserEntry({
|
|
|
472
732
|
});
|
|
473
733
|
}
|
|
474
734
|
|
|
735
|
+
export function magicModuleAppServerEntry({
|
|
736
|
+
host,
|
|
737
|
+
port,
|
|
738
|
+
assets,
|
|
739
|
+
format = 'module',
|
|
740
|
+
}: {
|
|
741
|
+
host?: string;
|
|
742
|
+
port?: number;
|
|
743
|
+
assets?: boolean | {baseURL: string};
|
|
744
|
+
format?: 'module' | 'commonjs';
|
|
745
|
+
} = {}) {
|
|
746
|
+
const baseURL = typeof assets === 'object' ? assets.baseURL : '/assets/';
|
|
747
|
+
|
|
748
|
+
return createMagicModulePlugin({
|
|
749
|
+
name: '@quilted/request-router/app-server',
|
|
750
|
+
module: MAGIC_MODULE_ENTRY,
|
|
751
|
+
sideEffects: true,
|
|
752
|
+
async source() {
|
|
753
|
+
const serveAssets = Boolean(assets);
|
|
754
|
+
|
|
755
|
+
return multiline`
|
|
756
|
+
${serveAssets ? `import * as path from 'path';` : ''}
|
|
757
|
+
${
|
|
758
|
+
serveAssets && format === 'module'
|
|
759
|
+
? `import {fileURLToPath} from 'url';`
|
|
760
|
+
: ''
|
|
761
|
+
}
|
|
762
|
+
import {createServer} from 'http';
|
|
763
|
+
|
|
764
|
+
import requestRouter from ${JSON.stringify(
|
|
765
|
+
MAGIC_MODULE_REQUEST_ROUTER,
|
|
766
|
+
)};
|
|
767
|
+
|
|
768
|
+
import {createHttpRequestListener${
|
|
769
|
+
serveAssets ? ', serveStatic' : ''
|
|
770
|
+
}} from '@quilted/quilt/request-router/node';
|
|
771
|
+
|
|
772
|
+
const port = ${port ?? 'Number.parseInt(process.env.PORT, 10)'};
|
|
773
|
+
const host = ${host ? JSON.stringify(host) : 'process.env.HOST'};
|
|
774
|
+
|
|
775
|
+
${
|
|
776
|
+
serveAssets
|
|
777
|
+
? `const dirname = ${
|
|
778
|
+
format === 'module'
|
|
779
|
+
? 'path.dirname(fileURLToPath(import.meta.url))'
|
|
780
|
+
: '__dirname'
|
|
781
|
+
};\nconst serve = serveStatic(path.resolve(dirname, '../assets'), {
|
|
782
|
+
baseUrl: ${JSON.stringify(baseURL)},
|
|
783
|
+
});`
|
|
784
|
+
: ''
|
|
785
|
+
}
|
|
786
|
+
const listener = createHttpRequestListener(requestRouter);
|
|
787
|
+
|
|
788
|
+
createServer(async (request, response) => {
|
|
789
|
+
${
|
|
790
|
+
serveAssets
|
|
791
|
+
? `if (request.url.startsWith(${JSON.stringify(
|
|
792
|
+
baseURL,
|
|
793
|
+
)})) return serve(request, response);`
|
|
794
|
+
: ''
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
await listener(request, response);
|
|
798
|
+
}).listen(port, host);
|
|
799
|
+
`;
|
|
800
|
+
},
|
|
801
|
+
});
|
|
802
|
+
}
|
|
803
|
+
|
|
475
804
|
export function magicModuleAppAssetManifests() {
|
|
476
805
|
return createMagicModulePlugin({
|
|
477
806
|
name: '@quilted/magic-module/asset-manifests',
|
|
@@ -497,6 +826,8 @@ export function magicModuleAppAssetManifests() {
|
|
|
497
826
|
(manifestA.priority ?? 0) - (manifestB.priority ?? 0),
|
|
498
827
|
);
|
|
499
828
|
|
|
829
|
+
const browserGroupRegexes = await getBrowserGroupRegularExpressions();
|
|
830
|
+
|
|
500
831
|
return multiline`
|
|
501
832
|
import {BrowserAssetsFromManifests} from '@quilted/quilt/server';
|
|
502
833
|
|
|
@@ -506,12 +837,31 @@ export function magicModuleAppAssetManifests() {
|
|
|
506
837
|
JSON.stringify(manifests),
|
|
507
838
|
)});
|
|
508
839
|
|
|
840
|
+
const browserGroupTests = [
|
|
841
|
+
${Object.entries(browserGroupRegexes)
|
|
842
|
+
.map(
|
|
843
|
+
([name, test]) =>
|
|
844
|
+
`[${JSON.stringify(name)}, new RegExp(${JSON.stringify(
|
|
845
|
+
test.source,
|
|
846
|
+
)})]`,
|
|
847
|
+
)
|
|
848
|
+
.join(', ')}
|
|
849
|
+
];
|
|
850
|
+
|
|
509
851
|
// The default manifest is the last one, since it has the widest browser support.
|
|
510
852
|
const defaultManifest = manifests.at(-1);
|
|
511
853
|
|
|
512
854
|
super(manifests, {
|
|
513
855
|
defaultManifest,
|
|
514
856
|
cacheKey(request) {
|
|
857
|
+
const userAgent = request.headers.get('User-Agent');
|
|
858
|
+
|
|
859
|
+
if (userAgent) {
|
|
860
|
+
for (const [name, test] of browserGroupTests) {
|
|
861
|
+
if (test.test(userAgent)) return {browserGroup: name};
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
|
|
515
865
|
return {};
|
|
516
866
|
},
|
|
517
867
|
});
|
|
@@ -541,7 +891,6 @@ const FRAMEWORK_TEST_STRINGS: (string | RegExp)[] = [
|
|
|
541
891
|
];
|
|
542
892
|
|
|
543
893
|
const POLYFILL_TEST_STRINGS = [
|
|
544
|
-
'/node_modules/@quilted/polyfills/',
|
|
545
894
|
'/node_modules/core-js/',
|
|
546
895
|
'/node_modules/whatwg-fetch/',
|
|
547
896
|
'/node_modules/regenerator-runtime/',
|
|
@@ -621,3 +970,30 @@ function createManualChunksSorter(): GetManualChunk {
|
|
|
621
970
|
return `${bundleBaseName}-${relativeId.split(path.sep)[0]?.split('.')[0]}`;
|
|
622
971
|
};
|
|
623
972
|
}
|
|
973
|
+
|
|
974
|
+
async function resolveAppEntry(
|
|
975
|
+
entry: string | undefined,
|
|
976
|
+
{root, packageJSON}: {root: string; packageJSON: PackageJSON},
|
|
977
|
+
) {
|
|
978
|
+
if (entry) {
|
|
979
|
+
return path.resolve(root, entry);
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
if (typeof packageJSON.main === 'string') {
|
|
983
|
+
return path.resolve(root, packageJSON.main);
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
const rootEntry = (packageJSON.exports as any)?.['.'];
|
|
987
|
+
|
|
988
|
+
if (typeof rootEntry === 'string') {
|
|
989
|
+
return path.resolve(root, rootEntry);
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
const globbed = await glob('{App,app,index}.{ts,tsx,mjs,js,jsx}', {
|
|
993
|
+
cwd: root,
|
|
994
|
+
nodir: true,
|
|
995
|
+
absolute: true,
|
|
996
|
+
});
|
|
997
|
+
|
|
998
|
+
return globbed[0];
|
|
999
|
+
}
|