@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/server.ts
ADDED
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import * as path from 'path';
|
|
2
|
+
import {Plugin, type RollupOptions} from 'rollup';
|
|
3
|
+
import {glob} from 'glob';
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
RollupNodePluginOptions,
|
|
7
|
+
getNodePlugins,
|
|
8
|
+
removeBuildFiles,
|
|
9
|
+
} from './shared/rollup.ts';
|
|
10
|
+
import {resolveRoot} from './shared/path.ts';
|
|
11
|
+
import {loadPackageJSON, type PackageJSON} from './shared/package-json.ts';
|
|
12
|
+
import {magicModuleRequestRouterEntry} from './features/request-router.ts';
|
|
13
|
+
import {resolveEnvOption, type MagicModuleEnvOptions} from './features/env.ts';
|
|
14
|
+
import {MAGIC_MODULE_ENTRY, MAGIC_MODULE_REQUEST_ROUTER} from './constants.ts';
|
|
15
|
+
import {createMagicModulePlugin} from './shared/magic-module.ts';
|
|
16
|
+
|
|
17
|
+
export interface ServerOptions {
|
|
18
|
+
/**
|
|
19
|
+
* The root directory containing the source code for your application.
|
|
20
|
+
*/
|
|
21
|
+
root?: string | URL;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* The entry module for this server. By default, this module must export
|
|
25
|
+
* a `RequestRouter` object as its default export, which will be wrapped in
|
|
26
|
+
* the specific server runtime you configure. If you set the format to `'custom'`,
|
|
27
|
+
* this entry can be any content — it will be bundled as-is.
|
|
28
|
+
*
|
|
29
|
+
* If not provided, this will default to a file named `server`, `service`,
|
|
30
|
+
* or `backend` in your server’s root directory.
|
|
31
|
+
*/
|
|
32
|
+
entry?: string;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Whether this server code uses the `request-router` library to
|
|
36
|
+
* define itself in a generic way, which can be adapted to a variety
|
|
37
|
+
* of environments. By default, this is `'request-router'`, and when `'request-router'`,
|
|
38
|
+
* the `entry` you specified must export an `RequestRouter` object as
|
|
39
|
+
* its default export. When set to `false`, the app server will be built
|
|
40
|
+
* as a basic server-side JavaScript project, without the special
|
|
41
|
+
* `request-router` adaptor.
|
|
42
|
+
*
|
|
43
|
+
* @default 'request-router'
|
|
44
|
+
*/
|
|
45
|
+
format?: 'request-router' | 'custom';
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Whether to include GraphQL-related code transformations.
|
|
49
|
+
*
|
|
50
|
+
* @default true
|
|
51
|
+
*/
|
|
52
|
+
graphql?: boolean;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Customizes the behavior of environment variables for your module.
|
|
56
|
+
*/
|
|
57
|
+
env?: MagicModuleEnvOptions | MagicModuleEnvOptions['mode'];
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Controls how the server outputs are generated.
|
|
61
|
+
*/
|
|
62
|
+
output?: ServerOutputOptions;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* The port that the server will listen on when it runs. This only applies
|
|
66
|
+
* when you use the `request-router` format — if you use the `custom` format,
|
|
67
|
+
* you are responsible for starting the server yourself.
|
|
68
|
+
*
|
|
69
|
+
* If you do not provide a value here, the server will listen for requests on
|
|
70
|
+
* the port specified by `process.env.NODE_ENV`.
|
|
71
|
+
*/
|
|
72
|
+
port?: number | string;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* The host that the server will listen on when it runs. This only applies
|
|
76
|
+
* when you use the `request-router` format — if you use the `custom` format,
|
|
77
|
+
* you are responsible for starting the server yourself.
|
|
78
|
+
*/
|
|
79
|
+
host?: string;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export interface ServerOutputOptions
|
|
83
|
+
extends Pick<RollupNodePluginOptions, 'bundle'> {
|
|
84
|
+
/**
|
|
85
|
+
* Whether to minify assets created for this server.
|
|
86
|
+
*
|
|
87
|
+
* @default false
|
|
88
|
+
*/
|
|
89
|
+
minify?: boolean;
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Whether to add a hash to the output files for your server. You can set
|
|
93
|
+
* this to `true`, which includes a hash for all files, `false`, which never
|
|
94
|
+
* includes a hash, or `'async-only'`, which only includes a hash for files
|
|
95
|
+
* that are loaded asynchronously (that is, your entry file will not have a
|
|
96
|
+
* hash, but any files it loads will).
|
|
97
|
+
*
|
|
98
|
+
* @default 'async-only'
|
|
99
|
+
*/
|
|
100
|
+
hash?: boolean | 'async-only';
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* What module format to use for the server output.
|
|
104
|
+
*
|
|
105
|
+
* @default 'esmodules'
|
|
106
|
+
*/
|
|
107
|
+
format?: 'esmodules' | 'esm' | 'es' | 'commonjs' | 'cjs';
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export async function quiltServer({
|
|
111
|
+
root: rootPath = process.cwd(),
|
|
112
|
+
entry,
|
|
113
|
+
format = 'request-router',
|
|
114
|
+
env,
|
|
115
|
+
graphql = true,
|
|
116
|
+
output,
|
|
117
|
+
port,
|
|
118
|
+
host,
|
|
119
|
+
}: ServerOptions = {}) {
|
|
120
|
+
const root = resolveRoot(rootPath);
|
|
121
|
+
const mode =
|
|
122
|
+
(typeof env === 'object' ? env?.mode : undefined) ?? 'production';
|
|
123
|
+
const outputDirectory = path.join(root, 'build/server');
|
|
124
|
+
|
|
125
|
+
const minify = output?.minify ?? false;
|
|
126
|
+
const bundle = output?.bundle;
|
|
127
|
+
const hash = output?.hash ?? 'async-only';
|
|
128
|
+
const outputFormat = output?.format ?? 'esmodules';
|
|
129
|
+
|
|
130
|
+
const [
|
|
131
|
+
{visualizer},
|
|
132
|
+
{magicModuleEnv, replaceProcessEnv},
|
|
133
|
+
{sourceCode},
|
|
134
|
+
{esnext},
|
|
135
|
+
nodePlugins,
|
|
136
|
+
packageJSON,
|
|
137
|
+
] = await Promise.all([
|
|
138
|
+
import('rollup-plugin-visualizer'),
|
|
139
|
+
import('./features/env.ts'),
|
|
140
|
+
import('./features/source-code.ts'),
|
|
141
|
+
import('./features/esnext.ts'),
|
|
142
|
+
getNodePlugins({bundle}),
|
|
143
|
+
loadPackageJSON(root),
|
|
144
|
+
]);
|
|
145
|
+
|
|
146
|
+
const serverEntry = entry
|
|
147
|
+
? path.resolve(root, entry)
|
|
148
|
+
: await sourceForServer(root, packageJSON);
|
|
149
|
+
|
|
150
|
+
const finalEntry =
|
|
151
|
+
format === 'request-router'
|
|
152
|
+
? MAGIC_MODULE_ENTRY
|
|
153
|
+
: serverEntry ?? MAGIC_MODULE_ENTRY;
|
|
154
|
+
|
|
155
|
+
const plugins: Plugin[] = [
|
|
156
|
+
...nodePlugins,
|
|
157
|
+
replaceProcessEnv({mode}),
|
|
158
|
+
magicModuleEnv({...resolveEnvOption(env), mode}),
|
|
159
|
+
sourceCode({mode, targets: ['current node']}),
|
|
160
|
+
esnext({mode, targets: ['current node']}),
|
|
161
|
+
removeBuildFiles(['build/server', 'build/reports'], {root}),
|
|
162
|
+
];
|
|
163
|
+
|
|
164
|
+
if (format === 'request-router') {
|
|
165
|
+
plugins.push(
|
|
166
|
+
createMagicModulePlugin({
|
|
167
|
+
name: '@quilted/magic-module/server-request-router',
|
|
168
|
+
module: MAGIC_MODULE_REQUEST_ROUTER,
|
|
169
|
+
alias: serverEntry,
|
|
170
|
+
}),
|
|
171
|
+
magicModuleRequestRouterEntry({
|
|
172
|
+
host,
|
|
173
|
+
port: typeof port === 'string' ? Number.parseInt(port, 10) : port,
|
|
174
|
+
}),
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (graphql) {
|
|
179
|
+
const {graphql} = await import('./features/graphql.ts');
|
|
180
|
+
plugins.push(graphql({manifest: false}));
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (minify) {
|
|
184
|
+
const {minify} = await import('rollup-plugin-esbuild');
|
|
185
|
+
plugins.push(minify());
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
plugins.push(
|
|
189
|
+
visualizer({
|
|
190
|
+
template: 'treemap',
|
|
191
|
+
open: false,
|
|
192
|
+
brotliSize: true,
|
|
193
|
+
filename: path.resolve(root, `build/reports/bundle-visualizer.html`),
|
|
194
|
+
}),
|
|
195
|
+
);
|
|
196
|
+
|
|
197
|
+
return {
|
|
198
|
+
input: finalEntry,
|
|
199
|
+
plugins,
|
|
200
|
+
onwarn(warning, defaultWarn) {
|
|
201
|
+
// Removes annoying warnings for React-focused libraries that
|
|
202
|
+
// include 'use client' directives.
|
|
203
|
+
if (
|
|
204
|
+
warning.code === 'MODULE_LEVEL_DIRECTIVE' &&
|
|
205
|
+
/['"]use client['"]/.test(warning.message)
|
|
206
|
+
) {
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
defaultWarn(warning);
|
|
211
|
+
},
|
|
212
|
+
output: {
|
|
213
|
+
format:
|
|
214
|
+
outputFormat === 'commonjs' || outputFormat === 'cjs' ? 'cjs' : 'esm',
|
|
215
|
+
dir: outputDirectory,
|
|
216
|
+
entryFileNames: `server${hash === true ? `.[hash]` : ''}.js`,
|
|
217
|
+
chunkFileNames: `[name]${
|
|
218
|
+
hash === true || hash === 'async-only' ? `.[hash]` : ''
|
|
219
|
+
}.js`,
|
|
220
|
+
assetFileNames: `[name]${hash === true ? `.[hash]` : ''}.[ext]`,
|
|
221
|
+
generatedCode: 'es2015',
|
|
222
|
+
},
|
|
223
|
+
} satisfies RollupOptions;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
async function sourceForServer(root: string, packageJSON: PackageJSON) {
|
|
227
|
+
const {main, exports} = packageJSON;
|
|
228
|
+
|
|
229
|
+
const entryFromPackageJSON = main ?? (exports as any)?.['.'];
|
|
230
|
+
|
|
231
|
+
if (entryFromPackageJSON) {
|
|
232
|
+
return path.resolve(root, entryFromPackageJSON);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
const possibleSourceFiles = await glob(
|
|
236
|
+
'{index,server,service,backend,entry,input}.{ts,tsx,mjs,js,jsx}',
|
|
237
|
+
{
|
|
238
|
+
cwd: root,
|
|
239
|
+
nodir: true,
|
|
240
|
+
absolute: true,
|
|
241
|
+
},
|
|
242
|
+
);
|
|
243
|
+
|
|
244
|
+
return possibleSourceFiles[0]!;
|
|
245
|
+
}
|
|
@@ -1,32 +1,222 @@
|
|
|
1
|
-
export type
|
|
2
|
-
| string[]
|
|
1
|
+
export type BrowserGroupTargetSelection =
|
|
2
|
+
| readonly string[]
|
|
3
3
|
| {
|
|
4
4
|
name?: string;
|
|
5
|
-
browsers?: string[];
|
|
5
|
+
browsers?: readonly string[];
|
|
6
6
|
};
|
|
7
7
|
|
|
8
|
-
export async function
|
|
9
|
-
targetSelection:
|
|
8
|
+
export async function getBrowserGroupTargetDetails(
|
|
9
|
+
targetSelection: BrowserGroupTargetSelection = {},
|
|
10
10
|
{root}: {root?: string} = {},
|
|
11
11
|
) {
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
const {default: browserslist} = await import('browserslist');
|
|
13
|
+
|
|
14
|
+
const targets: {
|
|
15
|
+
name?: string;
|
|
16
|
+
browsers?: readonly string[];
|
|
17
|
+
} = (
|
|
18
|
+
Array.isArray(targetSelection)
|
|
19
|
+
? {
|
|
20
|
+
browsers: targetSelection,
|
|
21
|
+
}
|
|
22
|
+
: targetSelection
|
|
23
|
+
) as any;
|
|
24
|
+
|
|
17
25
|
const targetBrowsers =
|
|
18
26
|
targets.browsers ??
|
|
19
27
|
(await (async () => {
|
|
20
|
-
const
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
if (config == null) return ['defaults'];
|
|
24
|
-
|
|
25
|
-
const targetName = targets.name ?? 'defaults';
|
|
28
|
+
const config = await getBrowserGroups({root});
|
|
29
|
+
const targetName = targets.name ?? 'default';
|
|
26
30
|
return config[targetName] ?? ['defaults'];
|
|
27
31
|
})());
|
|
28
32
|
|
|
29
|
-
|
|
33
|
+
return {name: targets.name, browsers: browserslist(targetBrowsers)};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface BrowserGroups {
|
|
37
|
+
default: readonly string[];
|
|
38
|
+
[name: string]: readonly string[];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export async function getBrowserGroups({
|
|
42
|
+
root = process.cwd(),
|
|
43
|
+
}: {root?: string} = {}): Promise<BrowserGroups> {
|
|
44
|
+
const {default: browserslist} = await import('browserslist');
|
|
45
|
+
const config = browserslist.findConfig(root);
|
|
46
|
+
|
|
47
|
+
if (config == null) return {default: browserslist(['defaults'])};
|
|
48
|
+
|
|
49
|
+
const {defaults, ...rest} = config;
|
|
50
|
+
|
|
51
|
+
const browserGroups: BrowserGroups = {} as any;
|
|
52
|
+
|
|
53
|
+
const groupsWithFullList = Object.entries(rest)
|
|
54
|
+
.map(([name, browsers]) => ({
|
|
55
|
+
name,
|
|
56
|
+
browsers: browserslist(browsers),
|
|
57
|
+
}))
|
|
58
|
+
.sort((first, second) => first.browsers.length - second.browsers.length);
|
|
59
|
+
|
|
60
|
+
for (const {name, browsers} of groupsWithFullList) {
|
|
61
|
+
browserGroups[name] = browsers;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
browserGroups.default = defaults;
|
|
65
|
+
|
|
66
|
+
return browserGroups;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export async function getBrowserGroupRegularExpressions(
|
|
70
|
+
groups?: BrowserGroups,
|
|
71
|
+
): Promise<Record<string, RegExp>> {
|
|
72
|
+
const [{default: browserslist}, {getUserAgentRegex}] = await Promise.all([
|
|
73
|
+
import('browserslist'),
|
|
74
|
+
import('browserslist-useragent-regexp'),
|
|
75
|
+
]);
|
|
76
|
+
|
|
77
|
+
// Expand the browserslist queries into the full list of supported browsers,
|
|
78
|
+
// and sort by the number of browsers in each group (with the last item having
|
|
79
|
+
// the largest browser support)
|
|
80
|
+
const groupsWithFullList = Object.entries(
|
|
81
|
+
groups ?? (await getBrowserGroups()),
|
|
82
|
+
)
|
|
83
|
+
.map(([name, browsers]) => ({
|
|
84
|
+
name,
|
|
85
|
+
browsers: browserslist(browsers),
|
|
86
|
+
}))
|
|
87
|
+
.sort((first, second) => first.browsers.length - second.browsers.length);
|
|
88
|
+
|
|
89
|
+
if (groupsWithFullList.length === 0) return {};
|
|
90
|
+
|
|
91
|
+
const lastGroup = groupsWithFullList.pop()!;
|
|
92
|
+
|
|
93
|
+
const regexes: Record<string, RegExp> = {};
|
|
94
|
+
|
|
95
|
+
for (const {name, browsers} of groupsWithFullList) {
|
|
96
|
+
const regex = getUserAgentRegex({
|
|
97
|
+
browsers,
|
|
98
|
+
ignoreMinor: true,
|
|
99
|
+
ignorePatch: true,
|
|
100
|
+
allowHigherVersions: true,
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
regexes[name] = regex;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// The last group is the default group, so it should match everything
|
|
107
|
+
regexes[lastGroup.name] = new RegExp('');
|
|
108
|
+
|
|
109
|
+
return regexes;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
let esmBrowserslist: Promise<Set<string>>;
|
|
113
|
+
|
|
114
|
+
export async function targetsSupportModules(targets: readonly string[]) {
|
|
115
|
+
esmBrowserslist ??= (async () => {
|
|
116
|
+
const {default: browserslist} = await import('browserslist');
|
|
117
|
+
|
|
118
|
+
return new Set(
|
|
119
|
+
browserslist(
|
|
120
|
+
'defaults and fully supports es6-module and fully supports es6-module-dynamic-import',
|
|
121
|
+
),
|
|
122
|
+
);
|
|
123
|
+
})();
|
|
124
|
+
|
|
125
|
+
const esmBrowsers = await esmBrowserslist;
|
|
126
|
+
|
|
127
|
+
return targets.every((target) => esmBrowsers.has(target));
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const BROWSESLIST_BROWSER_TO_MDN_BROWSER = new Map([
|
|
131
|
+
['and_chr', 'chrome_android'],
|
|
132
|
+
['and_ff', 'firefox_android'],
|
|
133
|
+
['and_qq', 'qq_android'],
|
|
134
|
+
['and_uc', 'uc_android'],
|
|
135
|
+
['android', 'webview_android'],
|
|
136
|
+
['chrome', 'chrome'],
|
|
137
|
+
['edge', 'edge'],
|
|
138
|
+
['edge_mob', 'edge_mobile'],
|
|
139
|
+
['firefox', 'firefox'],
|
|
140
|
+
['ie', 'ie'],
|
|
141
|
+
['ios_saf', 'safari_ios'],
|
|
142
|
+
['node', 'nodejs'],
|
|
143
|
+
['opera', 'opera'],
|
|
144
|
+
['safari', 'safari'],
|
|
145
|
+
['samsung', 'samsunginternet_android'],
|
|
146
|
+
]);
|
|
147
|
+
|
|
148
|
+
// Roughly adapted from https://github.com/webhintio/hint/blob/main/packages/utils-compat-data/src/browsers.ts
|
|
149
|
+
export async function rollupGenerateOptionsForBrowsers(
|
|
150
|
+
browsers: readonly string[],
|
|
151
|
+
) {
|
|
152
|
+
const [{default: semver}, {default: mdn}] = await Promise.all([
|
|
153
|
+
import('semver'),
|
|
154
|
+
import('@mdn/browser-compat-data', {
|
|
155
|
+
assert: {type: 'json'},
|
|
156
|
+
}) as Promise<any>,
|
|
157
|
+
]);
|
|
158
|
+
|
|
159
|
+
const arrowFunctionsSupport =
|
|
160
|
+
mdn.javascript.functions.arrow_functions.__compat.support;
|
|
161
|
+
const constBindingsSupport = mdn.javascript.statements.const.__compat.support;
|
|
162
|
+
const objectShorthandSupport =
|
|
163
|
+
mdn.javascript.grammar.shorthand_object_literals.__compat.support;
|
|
164
|
+
const symbolsSupport = mdn.javascript.builtins.Symbol.__compat.support;
|
|
165
|
+
|
|
166
|
+
let arrowFunctions = true;
|
|
167
|
+
let constBindings = true;
|
|
168
|
+
let objectShorthand = true;
|
|
169
|
+
let symbols = true;
|
|
170
|
+
|
|
171
|
+
const isSupported = (
|
|
172
|
+
browser: string,
|
|
173
|
+
version: import('semver').SemVer,
|
|
174
|
+
supportList: any,
|
|
175
|
+
) => {
|
|
176
|
+
const supportedVersionDetails = supportList[browser];
|
|
177
|
+
if (supportedVersionDetails == null) return false;
|
|
178
|
+
|
|
179
|
+
const supportedVersion = semver.coerce(
|
|
180
|
+
supportedVersionDetails.version_added,
|
|
181
|
+
);
|
|
182
|
+
if (supportedVersion == null) return false;
|
|
183
|
+
|
|
184
|
+
return semver.gte(version, supportedVersion);
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
for (const browser of browsers) {
|
|
188
|
+
const [name, version] = browser.split(' ');
|
|
189
|
+
|
|
190
|
+
const semverVersion = semver.coerce(version);
|
|
191
|
+
if (semverVersion == null) continue;
|
|
192
|
+
|
|
193
|
+
const mdnBrowser = BROWSESLIST_BROWSER_TO_MDN_BROWSER.get(name!);
|
|
194
|
+
if (mdnBrowser == null) continue;
|
|
195
|
+
|
|
196
|
+
arrowFunctions &&= isSupported(
|
|
197
|
+
mdnBrowser,
|
|
198
|
+
semverVersion,
|
|
199
|
+
arrowFunctionsSupport,
|
|
200
|
+
);
|
|
201
|
+
constBindings &&= isSupported(
|
|
202
|
+
mdnBrowser,
|
|
203
|
+
semverVersion,
|
|
204
|
+
constBindingsSupport,
|
|
205
|
+
);
|
|
206
|
+
objectShorthand &&= isSupported(
|
|
207
|
+
mdnBrowser,
|
|
208
|
+
semverVersion,
|
|
209
|
+
objectShorthandSupport,
|
|
210
|
+
);
|
|
211
|
+
symbols &&= isSupported(mdnBrowser, semverVersion, symbolsSupport);
|
|
212
|
+
}
|
|
30
213
|
|
|
31
|
-
return {
|
|
214
|
+
return {
|
|
215
|
+
preset: 'es2015',
|
|
216
|
+
arrowFunctions,
|
|
217
|
+
constBindings,
|
|
218
|
+
objectShorthand,
|
|
219
|
+
reservedNamesAsProps: objectShorthand,
|
|
220
|
+
symbols,
|
|
221
|
+
} satisfies import('rollup').GeneratedCodeOptions;
|
|
32
222
|
}
|
package/source/shared/rollup.ts
CHANGED
|
@@ -39,7 +39,37 @@ export function removeBuildFiles(
|
|
|
39
39
|
} satisfies Plugin;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
export
|
|
42
|
+
export interface RollupNodeBundle {
|
|
43
|
+
readonly builtins?: boolean;
|
|
44
|
+
readonly dependencies?: boolean;
|
|
45
|
+
readonly devDependencies?: boolean;
|
|
46
|
+
readonly peerDependencies?: boolean;
|
|
47
|
+
readonly exclude?: (string | RegExp)[];
|
|
48
|
+
readonly include?: (string | RegExp)[];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface RollupNodePluginOptions {
|
|
52
|
+
/**
|
|
53
|
+
* Controls how dependencies from node_modules will be bundled into
|
|
54
|
+
* your rollup build. This can either be `true`, indicating that all
|
|
55
|
+
* dependencies (except node builtins, like `fs`) will be bundled;
|
|
56
|
+
* `false`, indicating that all node dependencies should be treated as
|
|
57
|
+
* external in the resulting build; or a `RollupNodeBundle` object
|
|
58
|
+
* that gives fine-grained control over how node dependencies are
|
|
59
|
+
* bundled. The options in the `RollupNodeBundle` object indicate
|
|
60
|
+
* which dependencies to bundle into your project; this is similar to
|
|
61
|
+
* the options provided to [`rollup-plugin-node-externals`](https://github.com/Septh/rollup-plugin-node-externals),
|
|
62
|
+
* except that those options are inverted (e.g., they indicate which
|
|
63
|
+
* modules to externalize, rather than which modules to bundle).
|
|
64
|
+
*
|
|
65
|
+
* @see https://github.com/Septh/rollup-plugin-node-externals
|
|
66
|
+
*/
|
|
67
|
+
bundle?: boolean | RollupNodeBundle;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export async function getNodePlugins({
|
|
71
|
+
bundle = {},
|
|
72
|
+
}: RollupNodePluginOptions = {}) {
|
|
43
73
|
const [
|
|
44
74
|
{default: commonjs},
|
|
45
75
|
{default: json},
|
|
@@ -52,13 +82,81 @@ export async function getNodePlugins() {
|
|
|
52
82
|
import('rollup-plugin-node-externals'),
|
|
53
83
|
]);
|
|
54
84
|
|
|
85
|
+
let nodeExternalsOptions: Parameters<typeof nodeExternals>[0];
|
|
86
|
+
|
|
87
|
+
if (bundle === true) {
|
|
88
|
+
// If the consumer wants to bundle node dependencies, we use our
|
|
89
|
+
// default bundling config, which inlines all node dependencies
|
|
90
|
+
// other than node builtins.
|
|
91
|
+
nodeExternalsOptions = {
|
|
92
|
+
builtins: true,
|
|
93
|
+
builtinsPrefix: 'strip',
|
|
94
|
+
deps: false,
|
|
95
|
+
devDeps: false,
|
|
96
|
+
peerDeps: false,
|
|
97
|
+
optDeps: false,
|
|
98
|
+
};
|
|
99
|
+
} else if (bundle === false) {
|
|
100
|
+
// If the consumer does not want to bundle node dependencies,
|
|
101
|
+
// we mark all dependencies as external.
|
|
102
|
+
nodeExternalsOptions = {
|
|
103
|
+
builtins: true,
|
|
104
|
+
builtinsPrefix: 'add',
|
|
105
|
+
deps: true,
|
|
106
|
+
devDeps: true,
|
|
107
|
+
peerDeps: true,
|
|
108
|
+
optDeps: true,
|
|
109
|
+
};
|
|
110
|
+
} else {
|
|
111
|
+
// Use the customized bundling configuration. Because this option
|
|
112
|
+
// is framed as what you bundle, rather than what you externalize,
|
|
113
|
+
// we need to invert all their options. For options that aren’t set,
|
|
114
|
+
// we default to bundling only development dependencies — production
|
|
115
|
+
// dependencies and node built-ins are not bundled.
|
|
116
|
+
const {
|
|
117
|
+
builtins: bundleBuiltins = false,
|
|
118
|
+
dependencies: bundleDependencies = false,
|
|
119
|
+
devDependencies: bundleDevDependencies = true,
|
|
120
|
+
peerDependencies: bundlePeerDependencies = false,
|
|
121
|
+
include: alwaysBundleDependencies,
|
|
122
|
+
exclude: neverBundleDependencies,
|
|
123
|
+
} = bundle;
|
|
124
|
+
|
|
125
|
+
nodeExternalsOptions = {
|
|
126
|
+
builtins: !bundleBuiltins,
|
|
127
|
+
builtinsPrefix: bundleBuiltins ? 'strip' : 'add',
|
|
128
|
+
deps: !bundleDependencies,
|
|
129
|
+
devDeps: !bundleDevDependencies,
|
|
130
|
+
peerDeps: !bundlePeerDependencies,
|
|
131
|
+
optDeps: !bundlePeerDependencies,
|
|
132
|
+
include: neverBundleDependencies,
|
|
133
|
+
exclude: alwaysBundleDependencies,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
|
|
55
137
|
return [
|
|
56
|
-
nodeExternals(
|
|
138
|
+
nodeExternals(nodeExternalsOptions),
|
|
57
139
|
nodeResolve({
|
|
58
140
|
preferBuiltins: true,
|
|
59
141
|
dedupe: [],
|
|
60
|
-
|
|
61
|
-
|
|
142
|
+
extensions: [
|
|
143
|
+
'.ts',
|
|
144
|
+
'.tsx',
|
|
145
|
+
'.mts',
|
|
146
|
+
'.mtsx',
|
|
147
|
+
'.js',
|
|
148
|
+
'.jsx',
|
|
149
|
+
'.es6',
|
|
150
|
+
'.es',
|
|
151
|
+
'.mjs',
|
|
152
|
+
],
|
|
153
|
+
exportConditions: [
|
|
154
|
+
'esnext',
|
|
155
|
+
'quilt:esnext',
|
|
156
|
+
'default',
|
|
157
|
+
'module',
|
|
158
|
+
'import',
|
|
159
|
+
],
|
|
62
160
|
}),
|
|
63
161
|
commonjs(),
|
|
64
162
|
json(),
|
package/tsconfig.json
CHANGED
|
@@ -5,6 +5,10 @@
|
|
|
5
5
|
"outDir": "build/typescript"
|
|
6
6
|
},
|
|
7
7
|
"include": ["source"],
|
|
8
|
-
"exclude": ["
|
|
9
|
-
"references": [
|
|
8
|
+
"exclude": ["**/*.test.ts", "**/*.test.tsx"],
|
|
9
|
+
"references": [
|
|
10
|
+
{"path": "../assets"},
|
|
11
|
+
{"path": "../babel"},
|
|
12
|
+
{"path": "../graphql"}
|
|
13
|
+
]
|
|
10
14
|
}
|