@quilted/rollup 0.1.19 → 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.
Files changed (126) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/build/esm/app.mjs +443 -219
  3. package/build/esm/constants.mjs +5 -5
  4. package/build/esm/features/assets.mjs +93 -81
  5. package/build/esm/features/async.mjs +186 -0
  6. package/build/esm/features/css.mjs +26 -39
  7. package/build/esm/features/env.mjs +47 -44
  8. package/build/esm/features/esnext.mjs +57 -0
  9. package/build/esm/features/graphql/transform.mjs +60 -56
  10. package/build/esm/features/graphql.mjs +65 -47
  11. package/build/esm/features/request-router.mjs +6 -4
  12. package/build/esm/features/source-code.mjs +54 -28
  13. package/build/esm/features/system-js.mjs +13 -18
  14. package/build/esm/features/typescript.mjs +13 -10
  15. package/build/esm/features/workers.mjs +173 -0
  16. package/build/esm/index.mjs +3 -2
  17. package/build/esm/module.mjs +69 -62
  18. package/build/esm/package.mjs +275 -84
  19. package/build/esm/server.mjs +118 -0
  20. package/build/esm/shared/browserslist.mjs +141 -16
  21. package/build/esm/shared/magic-module.mjs +9 -7
  22. package/build/esm/shared/package-json.mjs +7 -1
  23. package/build/esm/shared/path.mjs +7 -0
  24. package/build/esm/shared/rollup.mjs +89 -25
  25. package/build/esm/shared/strings.mjs +7 -6
  26. package/build/tsconfig.tsbuildinfo +1 -1
  27. package/build/typescript/app.d.ts +126 -27
  28. package/build/typescript/app.d.ts.map +1 -1
  29. package/build/typescript/features/assets.d.ts +1 -2
  30. package/build/typescript/features/assets.d.ts.map +1 -1
  31. package/build/typescript/features/async.d.ts +10 -0
  32. package/build/typescript/features/async.d.ts.map +1 -0
  33. package/build/typescript/features/css.d.ts +2 -1
  34. package/build/typescript/features/css.d.ts.map +1 -1
  35. package/build/typescript/features/env.d.ts +1 -0
  36. package/build/typescript/features/env.d.ts.map +1 -1
  37. package/build/typescript/features/esnext.d.ts +9 -0
  38. package/build/typescript/features/esnext.d.ts.map +1 -0
  39. package/build/typescript/features/graphql.d.ts +2 -2
  40. package/build/typescript/features/graphql.d.ts.map +1 -1
  41. package/build/typescript/features/source-code.d.ts +9 -3
  42. package/build/typescript/features/source-code.d.ts.map +1 -1
  43. package/build/typescript/features/workers.d.ts +52 -0
  44. package/build/typescript/features/workers.d.ts.map +1 -0
  45. package/build/typescript/index.d.ts +3 -2
  46. package/build/typescript/index.d.ts.map +1 -1
  47. package/build/typescript/module.d.ts +24 -6
  48. package/build/typescript/module.d.ts.map +1 -1
  49. package/build/typescript/package.d.ts +196 -4
  50. package/build/typescript/package.d.ts.map +1 -1
  51. package/build/typescript/server.d.ts +98 -0
  52. package/build/typescript/server.d.ts.map +1 -0
  53. package/build/typescript/shared/browserslist.d.ts +20 -3
  54. package/build/typescript/shared/browserslist.d.ts.map +1 -1
  55. package/build/typescript/shared/path.d.ts +2 -0
  56. package/build/typescript/shared/path.d.ts.map +1 -0
  57. package/build/typescript/shared/rollup.d.ts +27 -1
  58. package/build/typescript/shared/rollup.d.ts.map +1 -1
  59. package/configuration/rollup.config.js +40 -0
  60. package/package.json +61 -8
  61. package/source/app.ts +466 -96
  62. package/source/features/assets.ts +5 -7
  63. package/source/features/async.ts +249 -0
  64. package/source/features/css.ts +4 -2
  65. package/source/features/env.ts +6 -0
  66. package/source/features/esnext.ts +70 -0
  67. package/source/features/graphql.ts +4 -2
  68. package/source/features/source-code.ts +26 -8
  69. package/source/features/workers.ts +292 -0
  70. package/source/index.ts +4 -0
  71. package/source/module.ts +45 -19
  72. package/source/package.ts +394 -36
  73. package/source/server.ts +245 -0
  74. package/source/shared/browserslist.ts +208 -18
  75. package/source/shared/path.ts +5 -0
  76. package/source/shared/rollup.ts +102 -4
  77. package/tsconfig.json +6 -2
  78. package/build/cjs/app.cjs +0 -441
  79. package/build/cjs/constants.cjs +0 -13
  80. package/build/cjs/features/assets.cjs +0 -240
  81. package/build/cjs/features/css.cjs +0 -71
  82. package/build/cjs/features/env.cjs +0 -135
  83. package/build/cjs/features/graphql/transform.cjs +0 -186
  84. package/build/cjs/features/graphql.cjs +0 -86
  85. package/build/cjs/features/request-router.cjs +0 -31
  86. package/build/cjs/features/source-code.cjs +0 -54
  87. package/build/cjs/features/system-js.cjs +0 -36
  88. package/build/cjs/features/typescript.cjs +0 -56
  89. package/build/cjs/index.cjs +0 -13
  90. package/build/cjs/module.cjs +0 -121
  91. package/build/cjs/package.cjs +0 -170
  92. package/build/cjs/shared/browserslist.cjs +0 -25
  93. package/build/cjs/shared/magic-module.cjs +0 -32
  94. package/build/cjs/shared/package-json.cjs +0 -31
  95. package/build/cjs/shared/rollup.cjs +0 -72
  96. package/build/cjs/shared/strings.cjs +0 -16
  97. package/build/esnext/app.esnext +0 -414
  98. package/build/esnext/constants.esnext +0 -7
  99. package/build/esnext/features/assets.esnext +0 -215
  100. package/build/esnext/features/css.esnext +0 -69
  101. package/build/esnext/features/env.esnext +0 -112
  102. package/build/esnext/features/graphql/transform.esnext +0 -181
  103. package/build/esnext/features/graphql.esnext +0 -84
  104. package/build/esnext/features/request-router.esnext +0 -29
  105. package/build/esnext/features/source-code.esnext +0 -51
  106. package/build/esnext/features/system-js.esnext +0 -33
  107. package/build/esnext/features/typescript.esnext +0 -34
  108. package/build/esnext/index.esnext +0 -3
  109. package/build/esnext/module.esnext +0 -100
  110. package/build/esnext/package.esnext +0 -148
  111. package/build/esnext/shared/browserslist.esnext +0 -23
  112. package/build/esnext/shared/magic-module.esnext +0 -30
  113. package/build/esnext/shared/package-json.esnext +0 -10
  114. package/build/esnext/shared/rollup.esnext +0 -49
  115. package/build/esnext/shared/strings.esnext +0 -14
  116. package/build/typescript/env.d.ts +0 -55
  117. package/build/typescript/env.d.ts.map +0 -1
  118. package/build/typescript/graphql/transform.d.ts +0 -17
  119. package/build/typescript/graphql/transform.d.ts.map +0 -1
  120. package/build/typescript/graphql.d.ts +0 -6
  121. package/build/typescript/graphql.d.ts.map +0 -1
  122. package/build/typescript/request-router.d.ts +0 -15
  123. package/build/typescript/request-router.d.ts.map +0 -1
  124. package/build/typescript/shared/source-code.d.ts +0 -5
  125. package/build/typescript/shared/source-code.d.ts.map +0 -1
  126. package/quilt.project.ts +0 -5
@@ -1,414 +0,0 @@
1
- import * as path from 'node:path';
2
- import * as fs from 'node:fs/promises';
3
- import { glob } from 'glob';
4
- import { fileURLToPath } from 'node:url';
5
- import { MAGIC_MODULE_ENTRY, MAGIC_MODULE_APP_COMPONENT, MAGIC_MODULE_REQUEST_ROUTER, MAGIC_MODULE_BROWSER_ASSETS } from './constants.esnext';
6
- import { multiline } from './shared/strings.esnext';
7
- import { getNodePlugins, removeBuildFiles } from './shared/rollup.esnext';
8
- import { createMagicModulePlugin } from './shared/magic-module.esnext';
9
- import { getBrowserTargetDetails } from './shared/browserslist.esnext';
10
-
11
- async function quiltAppBrowser({
12
- root: rootPath = process.cwd(),
13
- app,
14
- entry,
15
- env,
16
- assets,
17
- module,
18
- graphql = true
19
- } = {}) {
20
- const root = typeof rootPath === 'string' ? rootPath : fileURLToPath(rootPath);
21
- const mode = (typeof env === 'object' ? env?.mode : undefined) ?? 'production';
22
- const minify = assets?.minify ?? mode === 'production';
23
- const baseURL = assets?.baseURL ?? '/assets/';
24
- const browserTarget = await getBrowserTargetDetails(assets?.targets, {
25
- root
26
- });
27
- const targetFilenamePart = browserTarget.name ? `.${browserTarget.name}` : '';
28
- const [{
29
- visualizer
30
- }, {
31
- magicModuleEnv,
32
- replaceProcessEnv
33
- }, {
34
- sourceCode
35
- }, {
36
- createTSConfigAliasPlugin
37
- }, {
38
- css
39
- }, {
40
- assetManifest,
41
- rawAssets,
42
- staticAssets
43
- }, {
44
- systemJS
45
- }, nodePlugins] = await Promise.all([import('rollup-plugin-visualizer'), import('./features/env.esnext'), import('./features/source-code.esnext'), import('./features/typescript.esnext'), import('./features/css.esnext'), import('./features/assets.esnext'), import('./features/system-js.esnext'), getNodePlugins()]);
46
- const plugins = [...nodePlugins, systemJS({
47
- minify
48
- }), replaceProcessEnv({
49
- mode
50
- }), magicModuleEnv({
51
- ...env,
52
- mode
53
- }), sourceCode({
54
- mode,
55
- targets: browserTarget.browsers
56
- }), css({
57
- minify,
58
- emit: true
59
- }), rawAssets(), staticAssets({
60
- baseURL,
61
- emit: true
62
- }), removeBuildFiles(['build/assets', 'build/manifests', 'build/reports'], {
63
- root
64
- })];
65
- const tsconfigAliases = await createTSConfigAliasPlugin();
66
- if (tsconfigAliases) {
67
- plugins.push(tsconfigAliases);
68
- }
69
- const appEntry = app ?? (await glob('{App,app,input}.{ts,tsx,mjs,js,jsx}', {
70
- cwd: root,
71
- nodir: true,
72
- absolute: true
73
- }).then(files => files[0]));
74
- if (appEntry) {
75
- plugins.push(magicModuleAppComponent({
76
- entry: appEntry
77
- }));
78
- }
79
- plugins.push(magicModuleAppBrowserEntry(module));
80
- if (graphql) {
81
- const {
82
- graphql
83
- } = await import('./features/graphql.esnext');
84
- plugins.push(graphql({
85
- manifest: path.resolve(`manifests/graphql${targetFilenamePart}.json`)
86
- }));
87
- }
88
- if (minify) {
89
- const {
90
- minify
91
- } = await import('rollup-plugin-esbuild');
92
- plugins.push(minify());
93
- }
94
- const cacheKey = browserTarget.name ? {
95
- browserTarget: browserTarget.name
96
- } : undefined;
97
- const id = browserTarget.name ? browserTarget.name : undefined;
98
- plugins.push(assetManifest({
99
- id,
100
- cacheKey,
101
- baseURL,
102
- file: path.resolve(`build/manifests/assets${targetFilenamePart}.json`),
103
- priority: assets?.priority
104
- }), visualizer({
105
- template: 'treemap',
106
- open: false,
107
- brotliSize: true,
108
- filename: path.resolve(`build/reports/bundle-visualizer${targetFilenamePart}.html`)
109
- }));
110
- const finalEntry = entry ?? (await glob('{browser,client}.{ts,tsx,mjs,js,jsx}', {
111
- cwd: root,
112
- nodir: true,
113
- absolute: true
114
- }).then(files => files[0])) ?? MAGIC_MODULE_ENTRY;
115
- return {
116
- input: finalEntry,
117
- plugins,
118
- onwarn(warning, defaultWarn) {
119
- // Removes annoying warnings for React-focused libraries that
120
- // include 'use client' directives.
121
- if (warning.code === 'MODULE_LEVEL_DIRECTIVE' && /['"]use client['"]/.test(warning.message)) {
122
- return;
123
- }
124
- defaultWarn(warning);
125
- },
126
- output: {
127
- // format: isESM ? 'esm' : 'systemjs',
128
- format: 'esm',
129
- dir: path.resolve(`build/assets`),
130
- entryFileNames: `app${targetFilenamePart}.[hash].js`,
131
- assetFileNames: `[name]${targetFilenamePart}.[hash].[ext]`,
132
- chunkFileNames: `[name]${targetFilenamePart}.[hash].js`,
133
- manualChunks: createManualChunksSorter()
134
- }
135
- };
136
- }
137
- async function quiltAppServer({
138
- app,
139
- env,
140
- entry,
141
- graphql = true,
142
- minify = false
143
- } = {}) {
144
- const root = process.cwd();
145
- const mode = (typeof env === 'object' ? env?.mode : undefined) ?? 'production';
146
- const [{
147
- visualizer
148
- }, {
149
- magicModuleEnv,
150
- replaceProcessEnv
151
- }, {
152
- sourceCode
153
- }, {
154
- createTSConfigAliasPlugin
155
- }, {
156
- css
157
- }, {
158
- rawAssets,
159
- staticAssets
160
- }, {
161
- magicModuleRequestRouterEntry
162
- }, nodePlugins] = await Promise.all([import('rollup-plugin-visualizer'), import('./features/env.esnext'), import('./features/source-code.esnext'), import('./features/typescript.esnext'), import('./features/css.esnext'), import('./features/assets.esnext'), import('./features/request-router.esnext'), getNodePlugins()]);
163
- const plugins = [...nodePlugins, replaceProcessEnv({
164
- mode
165
- }), magicModuleEnv({
166
- ...env,
167
- mode
168
- }), sourceCode({
169
- mode,
170
- targets: ['current node']
171
- }), css({
172
- emit: false,
173
- minify
174
- }), rawAssets(), staticAssets({
175
- emit: false
176
- }), removeBuildFiles(['build/server'], {
177
- root
178
- })];
179
- const tsconfigAliases = await createTSConfigAliasPlugin();
180
- if (tsconfigAliases) {
181
- plugins.push(tsconfigAliases);
182
- }
183
- const appEntry = app ?? (await glob('{App,app,input}.{ts,tsx,mjs,js,jsx}', {
184
- cwd: root,
185
- nodir: true,
186
- absolute: true
187
- }).then(files => files[0]));
188
- if (appEntry) {
189
- plugins.push(magicModuleAppComponent({
190
- entry: appEntry
191
- }));
192
- }
193
- plugins.push(magicModuleRequestRouterEntry(), magicModuleAppRequestRouter({
194
- entry
195
- }), magicModuleAppAssetManifests());
196
- if (graphql) {
197
- const {
198
- graphql
199
- } = await import('./features/graphql.esnext');
200
- plugins.push(graphql({
201
- manifest: false
202
- }));
203
- }
204
- if (minify) {
205
- const {
206
- minify
207
- } = await import('rollup-plugin-esbuild');
208
- plugins.push(minify());
209
- }
210
- plugins.push(visualizer({
211
- template: 'treemap',
212
- open: false,
213
- brotliSize: false,
214
- filename: path.resolve(`build/reports/bundle-visualizer.server.html`)
215
- }));
216
- const finalEntry = entry ?? (await glob('{server,service,backend}.{ts,tsx,mjs,js,jsx}', {
217
- cwd: root,
218
- nodir: true,
219
- absolute: true
220
- }).then(files => files[0])) ?? MAGIC_MODULE_ENTRY;
221
- return {
222
- input: finalEntry,
223
- plugins,
224
- onwarn(warning, defaultWarn) {
225
- // Removes annoying warnings for React-focused libraries that
226
- // include 'use client' directives.
227
- if (warning.code === 'MODULE_LEVEL_DIRECTIVE' && /['"]use client['"]/.test(warning.message)) {
228
- return;
229
- }
230
- defaultWarn(warning);
231
- },
232
- output: {
233
- // format: isESM ? 'esm' : 'systemjs',
234
- format: 'esm',
235
- dir: path.resolve(`build/server`),
236
- entryFileNames: 'server.js'
237
- }
238
- };
239
- }
240
- function magicModuleAppComponent({
241
- entry
242
- }) {
243
- return createMagicModulePlugin({
244
- name: '@quilted/magic-module/app',
245
- module: MAGIC_MODULE_APP_COMPONENT,
246
- alias: entry
247
- });
248
- }
249
- function magicModuleAppRequestRouter({
250
- entry
251
- } = {}) {
252
- return createMagicModulePlugin({
253
- name: '@quilted/magic-module/app-request-router',
254
- module: MAGIC_MODULE_REQUEST_ROUTER,
255
- alias: entry,
256
- source: entry ? undefined : async function source() {
257
- return multiline`
258
- import '@quilted/quilt/globals';
259
-
260
- import {jsx} from 'react/jsx-runtime';
261
- import {RequestRouter} from '@quilted/quilt/request-router';
262
- import {renderToResponse} from '@quilted/quilt/server';
263
-
264
- import App from ${JSON.stringify(MAGIC_MODULE_APP_COMPONENT)};
265
- import {BrowserAssets} from ${JSON.stringify(MAGIC_MODULE_BROWSER_ASSETS)};
266
-
267
- const router = new RequestRouter();
268
- const assets = new BrowserAssets();
269
-
270
- // For all GET requests, render our React application.
271
- router.get(async (request) => {
272
- const response = await renderToResponse(jsx(App), {
273
- request,
274
- assets,
275
- });
276
-
277
- return response;
278
- });
279
-
280
- export default router;
281
- `;
282
- }
283
- });
284
- }
285
- function magicModuleAppBrowserEntry({
286
- hydrate = true,
287
- selector = '#app'
288
- } = {}) {
289
- return createMagicModulePlugin({
290
- name: '@quilted/magic-module/app-browser-entry',
291
- module: MAGIC_MODULE_ENTRY,
292
- sideEffects: true,
293
- async source() {
294
- const reactRootFunction = hydrate ? 'hydrateRoot' : 'createRoot';
295
- return multiline`
296
- import '@quilted/quilt/globals';
297
-
298
- import {jsx} from 'react/jsx-runtime';
299
- import {${reactRootFunction}} from 'react-dom/client';
300
-
301
- import App from ${JSON.stringify(MAGIC_MODULE_APP_COMPONENT)};
302
-
303
- const element = document.querySelector(${JSON.stringify(selector)});
304
-
305
- ${hydrate ? `${reactRootFunction}(element, jsx(App));` : `${reactRootFunction}(element).render(jsx(App));`}
306
- `;
307
- }
308
- });
309
- }
310
- function magicModuleAppAssetManifests() {
311
- return createMagicModulePlugin({
312
- name: '@quilted/magic-module/asset-manifests',
313
- module: MAGIC_MODULE_BROWSER_ASSETS,
314
- async source() {
315
- const {
316
- glob
317
- } = await import('glob');
318
- const manifestFiles = await glob('assets*.json', {
319
- nodir: true,
320
- absolute: true,
321
- cwd: path.resolve(`build/manifests`)
322
- });
323
- const manifests = await Promise.all(manifestFiles.map(async file => JSON.parse(await fs.readFile(file, 'utf8'))));
324
- manifests.sort((manifestA, manifestB) => (manifestA.priority ?? 0) - (manifestB.priority ?? 0));
325
- return multiline`
326
- import {BrowserAssetsFromManifests} from '@quilted/quilt/server';
327
-
328
- export class BrowserAssets extends BrowserAssetsFromManifests {
329
- constructor() {
330
- const manifests = JSON.parse(${JSON.stringify(JSON.stringify(manifests))});
331
-
332
- // The default manifest is the last one, since it has the widest browser support.
333
- const defaultManifest = manifests.at(-1);
334
-
335
- super(manifests, {
336
- defaultManifest,
337
- cacheKey(request) {
338
- return {};
339
- },
340
- });
341
- }
342
- }
343
- `;
344
- }
345
- });
346
- }
347
- const FRAMEWORK_CHUNK_NAME = 'framework';
348
- const POLYFILLS_CHUNK_NAME = 'polyfills';
349
- const VENDOR_CHUNK_NAME = 'vendor';
350
- const INTERNALS_CHUNK_NAME = 'internals';
351
- const SHARED_CHUNK_NAME = 'shared';
352
- const PACKAGES_CHUNK_NAME = 'packages';
353
- const GLOBAL_CHUNK_NAME = 'global';
354
- const FRAMEWORK_TEST_STRINGS = ['/node_modules/preact/', '/node_modules/react/', '/node_modules/js-cookie/', '/node_modules/@quilted/quilt/', '/node_modules/@preact/signals/', '/node_modules/@preact/signals-core/',
355
- // TODO I should turn this into an allowlist
356
- /node_modules[/]@quilted[/](?!react-query|swr)/];
357
- const POLYFILL_TEST_STRINGS = ['/node_modules/@quilted/polyfills/', '/node_modules/core-js/', '/node_modules/whatwg-fetch/', '/node_modules/regenerator-runtime/', '/node_modules/abort-controller/'];
358
- const INTERNALS_TEST_STRINGS = ['\x00commonjsHelpers.js', '/node_modules/@babel/runtime/'];
359
-
360
- // When building from source, quilt packages are not in node_modules,
361
- // so we instead add their repo paths to the list of framework test strings.
362
- if (process.env.QUILT_FROM_SOURCE) {
363
- FRAMEWORK_TEST_STRINGS.push('/quilt/packages/');
364
- }
365
-
366
- // Inspired by Vite: https://github.com/vitejs/vite/blob/c69f83615292953d40f07b1178d1ed1d72abe695/packages/vite/source/node/build.ts#L567
367
- function createManualChunksSorter() {
368
- // TODO: make this more configurable, and make it so that we bundle more intelligently
369
- // for split entries
370
- const packagesPath = path.resolve('packages') + path.sep;
371
- const globalPath = path.resolve('global') + path.sep;
372
- const sharedPath = path.resolve('shared') + path.sep;
373
- return (id, {
374
- getModuleInfo
375
- }) => {
376
- if (INTERNALS_TEST_STRINGS.some(test => id.includes(test))) {
377
- return INTERNALS_CHUNK_NAME;
378
- }
379
- if (FRAMEWORK_TEST_STRINGS.some(test => typeof test === 'string' ? id.includes(test) : test.test(id))) {
380
- return FRAMEWORK_CHUNK_NAME;
381
- }
382
- if (POLYFILL_TEST_STRINGS.some(test => id.includes(test))) {
383
- return POLYFILLS_CHUNK_NAME;
384
- }
385
- let bundleBaseName;
386
- let relativeId;
387
- if (id.includes('/node_modules/')) {
388
- const moduleInfo = getModuleInfo(id);
389
-
390
- // If the only dependency is another vendor, let Rollup handle the naming
391
- if (moduleInfo == null) return;
392
- if (moduleInfo.importers.length > 0 && moduleInfo.importers.every(importer => importer.includes('/node_modules/'))) {
393
- return;
394
- }
395
- bundleBaseName = VENDOR_CHUNK_NAME;
396
- relativeId = id.replace(/^.*[/]node_modules[/]/, '');
397
- } else if (id.startsWith(packagesPath)) {
398
- bundleBaseName = PACKAGES_CHUNK_NAME;
399
- relativeId = id.replace(packagesPath, '');
400
- } else if (id.startsWith(globalPath)) {
401
- bundleBaseName = GLOBAL_CHUNK_NAME;
402
- relativeId = id.replace(globalPath, '');
403
- } else if (id.startsWith(sharedPath)) {
404
- bundleBaseName = SHARED_CHUNK_NAME;
405
- relativeId = id.replace(sharedPath, '');
406
- }
407
- if (bundleBaseName == null || relativeId == null) {
408
- return;
409
- }
410
- return `${bundleBaseName}-${relativeId.split(path.sep)[0]?.split('.')[0]}`;
411
- };
412
- }
413
-
414
- export { magicModuleAppAssetManifests, magicModuleAppBrowserEntry, magicModuleAppComponent, magicModuleAppRequestRouter, quiltAppBrowser, quiltAppServer };
@@ -1,7 +0,0 @@
1
- const MAGIC_MODULE_ENV = 'quilt:module/env';
2
- const MAGIC_MODULE_ENTRY = 'quilt:module/entry';
3
- const MAGIC_MODULE_APP_COMPONENT = 'quilt:module/app';
4
- const MAGIC_MODULE_BROWSER_ASSETS = 'quilt:module/assets';
5
- const MAGIC_MODULE_REQUEST_ROUTER = 'quilt:module/request-router';
6
-
7
- export { MAGIC_MODULE_APP_COMPONENT, MAGIC_MODULE_BROWSER_ASSETS, MAGIC_MODULE_ENTRY, MAGIC_MODULE_ENV, MAGIC_MODULE_REQUEST_ROUTER };
@@ -1,215 +0,0 @@
1
- import * as path from 'node:path';
2
- import * as fs from 'node:fs/promises';
3
- import { createHash } from 'node:crypto';
4
- import * as mime from 'mrmime';
5
-
6
- function assetManifest(manifestOptions) {
7
- return {
8
- name: '@quilted/asset-manifest',
9
- async generateBundle(options, bundle) {
10
- await writeManifestForBundle.call(this, bundle, manifestOptions, options);
11
- }
12
- };
13
- }
14
- async function writeManifestForBundle(bundle, {
15
- id,
16
- file,
17
- baseURL,
18
- cacheKey,
19
- priority
20
- }, {
21
- format
22
- }) {
23
- const outputs = Object.values(bundle);
24
- const entries = outputs.filter(output => output.type === 'chunk' && output.isEntry);
25
- if (entries.length === 0) {
26
- throw new Error(`Could not find any entries in your rollup bundle...`);
27
- }
28
-
29
- // We assume the first entry is the "main" one. There can be
30
- // more than one because each worker script is also listed as an
31
- // entry (though, from a separate build).
32
- const entryChunk = entries[0];
33
- const dependencyMap = new Map();
34
- for (const output of outputs) {
35
- if (output.type !== 'chunk') continue;
36
- dependencyMap.set(output.fileName, output.imports);
37
- }
38
- const assets = [];
39
- const assetIdMap = new Map();
40
- function getAssetId(file) {
41
- let id = assetIdMap.get(file);
42
- if (id == null) {
43
- assets.push(`${baseURL}${file}`);
44
- id = assets.length - 1;
45
- assetIdMap.set(file, id);
46
- }
47
- return id;
48
- }
49
- const manifest = {
50
- id,
51
- priority,
52
- cacheKey,
53
- assets,
54
- attributes: format === 'es' ? {
55
- scripts: {
56
- type: 'module'
57
- }
58
- } : undefined,
59
- entries: {
60
- default: createAssetsEntry([...entryChunk.imports, entryChunk.fileName], {
61
- dependencyMap,
62
- getAssetId
63
- })
64
- },
65
- modules: {}
66
- };
67
- for (const output of outputs) {
68
- if (output.type !== 'chunk') continue;
69
- const originalModuleId = output.facadeModuleId ?? output.moduleIds[output.moduleIds.length - 1];
70
- if (originalModuleId == null) continue;
71
-
72
- // This metadata is added by the rollup plugin for @quilted/async
73
- const moduleId = this.getModuleInfo(originalModuleId)?.meta.quilt?.moduleId;
74
- if (moduleId == null) continue;
75
- manifest.modules[moduleId] = createAssetsEntry([...output.imports, output.fileName], {
76
- dependencyMap,
77
- getAssetId
78
- });
79
- }
80
- await fs.mkdir(path.dirname(file), {
81
- recursive: true
82
- });
83
- await fs.writeFile(file, JSON.stringify(manifest, null, 2));
84
- }
85
- function createAssetsEntry(files, {
86
- dependencyMap,
87
- getAssetId
88
- }) {
89
- const styles = [];
90
- const scripts = [];
91
- const allFiles = new Set();
92
- const addFile = file => {
93
- if (allFiles.has(file)) return;
94
- allFiles.add(file);
95
- for (const dependency of dependencyMap.get(file) ?? []) {
96
- addFile(dependency);
97
- }
98
- };
99
- for (const file of files) {
100
- addFile(file);
101
- }
102
- for (const file of allFiles) {
103
- if (file.endsWith('.css')) {
104
- styles.push(getAssetId(file));
105
- } else {
106
- scripts.push(getAssetId(file));
107
- }
108
- }
109
- return {
110
- scripts,
111
- styles
112
- };
113
- }
114
- const QUERY_PATTERN = /\?.*$/s;
115
- const HASH_PATTERN = /#.*$/s;
116
- const RAW_PATTERN = /(\?|&)raw(?:&|$)/;
117
- const DEFAULT_INLINE_LIMIT = 4096;
118
- const DEFAULT_OUTPUT_PATTERN = '[name].[hash].[ext]';
119
- const DEFAULT_STATIC_ASSET_EXTENSIONS = [
120
- // images
121
- '.png', '.jpg', '.jpeg', '.gif', '.svg', '.ico', '.webp', '.avif',
122
- // media
123
- '.mp4', '.webm', '.ogg', '.mp3', '.wav', '.flac', '.aac',
124
- // fonts
125
- '.woff', '.woff2', '.eot', '.ttf', '.otf',
126
- // other
127
- '.webmanifest', '.pdf', '.txt'];
128
- function rawAssets() {
129
- return {
130
- name: '@quilted/raw-assets',
131
- async load(id) {
132
- if (id.startsWith('\0') || !RAW_PATTERN.test(id)) {
133
- return null;
134
- }
135
- const moduleId = cleanModuleIdentifier(id);
136
- this.addWatchFile(moduleId);
137
- const file = await fs.readFile(moduleId, {
138
- encoding: 'utf-8'
139
- });
140
- return `export default ${JSON.stringify(file)}`;
141
- }
142
- };
143
- }
144
- function staticAssets({
145
- emit = true,
146
- baseURL = '/',
147
- extensions = DEFAULT_STATIC_ASSET_EXTENSIONS,
148
- inlineLimit = DEFAULT_INLINE_LIMIT,
149
- outputPattern = DEFAULT_OUTPUT_PATTERN
150
- } = {}) {
151
- const assetCache = new Map();
152
- const assetMatcher = new RegExp(`\\.(` + extensions.map(extension => extension.startsWith('.') ? extension.slice(1) : extension).join('|') + `)(\\?.*)?$`);
153
- return {
154
- name: '@quilted/static-assets',
155
- async load(id) {
156
- if (id.startsWith('\0') || !assetMatcher.test(id)) {
157
- return null;
158
- }
159
- const cached = assetCache.get(id);
160
- if (cached) {
161
- return cached;
162
- }
163
- const file = cleanModuleIdentifier(id);
164
- const content = await fs.readFile(file);
165
- let url;
166
- if (!file.endsWith('.svg') && content.length < inlineLimit) {
167
- // base64 inlined as a string
168
- url = `data:${mime.lookup(file)};base64,${content.toString('base64')}`;
169
- } else {
170
- const contentHash = getHash(content);
171
- const filename = assetFileNamesToFileName(outputPattern, file, contentHash);
172
- url = `${baseURL.endsWith('/') ? baseURL.slice(0, -1) : baseURL}/${filename}`;
173
- if (emit) {
174
- this.emitFile({
175
- name: file,
176
- type: 'asset',
177
- fileName: filename,
178
- source: content
179
- });
180
- }
181
- }
182
- const source = `export default ${JSON.stringify(url)};`;
183
- assetCache.set(id, source);
184
- return source;
185
- }
186
- };
187
- }
188
- function assetFileNamesToFileName(pattern, file, contentHash) {
189
- const basename = path.basename(file);
190
- const extname = path.extname(basename);
191
- const ext = extname.substring(1);
192
- const name = basename.slice(0, -extname.length);
193
- const hash = contentHash;
194
- return pattern.replace(/\[\w+\]/g, placeholder => {
195
- switch (placeholder) {
196
- case '[ext]':
197
- return ext;
198
- case '[extname]':
199
- return extname;
200
- case '[hash]':
201
- return hash;
202
- case '[name]':
203
- return name;
204
- }
205
- throw new Error(`invalid placeholder ${placeholder} in assetFileNames "${pattern}"`);
206
- });
207
- }
208
- function getHash(text) {
209
- return createHash('sha256').update(text).digest('hex').substring(0, 8);
210
- }
211
- function cleanModuleIdentifier(url) {
212
- return url.replace(HASH_PATTERN, '').replace(QUERY_PATTERN, '');
213
- }
214
-
215
- export { assetManifest, rawAssets, staticAssets };
@@ -1,69 +0,0 @@
1
- const CSS_REGEX = /\.css$/;
2
- const CSS_MODULE_REGEX = /\.module\.css$/;
3
- function css({
4
- minify = true,
5
- emit = true
6
- }) {
7
- const styles = new Map();
8
- return {
9
- name: '@quilted/css',
10
- async transform(code, id) {
11
- if (!CSS_REGEX.test(id)) return;
12
- const {
13
- transform
14
- } = await import('lightningcss');
15
- const transformed = transform({
16
- filename: id,
17
- code: new TextEncoder().encode(code),
18
- cssModules: CSS_MODULE_REGEX.test(id),
19
- minify: emit && minify
20
- });
21
- styles.set(id, new TextDecoder().decode(transformed.code));
22
- const exports = transformed.exports ? Object.fromEntries(Object.entries(transformed.exports).map(([key, exported]) => [key, exported.name])) : undefined;
23
- return {
24
- code: exports ? `export default JSON.parse(${JSON.stringify(JSON.stringify(exports))})` : `export default undefined;`,
25
- map: {
26
- mappings: ''
27
- },
28
- moduleSideEffects: 'no-treeshake'
29
- };
30
- },
31
- async renderChunk(_, chunk) {
32
- if (!emit) return null;
33
- let chunkCss = '';
34
- for (const id of Object.keys(chunk.modules)) {
35
- if (CSS_REGEX.test(id) && styles.has(id)) {
36
- chunkCss += styles.get(id);
37
- }
38
- }
39
- if (chunkCss.length === 0) return null;
40
- const code = chunkCss;
41
-
42
- // if (minify) {
43
- // const {default: CleanCSS} = await import('clean-css');
44
-
45
- // const cleaner = new CleanCSS({
46
- // rebase: false,
47
- // });
48
-
49
- // const minified = cleaner.minify(chunkCss);
50
-
51
- // if (minified.errors.length > 0) {
52
- // throw minified.errors[0];
53
- // }
54
-
55
- // code = minified.styles;
56
- // }
57
-
58
- const fileHandle = this.emitFile({
59
- type: 'asset',
60
- name: `${chunk.fileName.split('.')[0]}.css`,
61
- source: code
62
- });
63
- chunk.imports.push(this.getFileName(fileHandle));
64
- return null;
65
- }
66
- };
67
- }
68
-
69
- export { css };