@quilted/rollup 0.1.10 → 0.1.11

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/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "access": "public",
7
7
  "@quilted/registry": "https://registry.npmjs.org"
8
8
  },
9
- "version": "0.1.10",
9
+ "version": "0.1.11",
10
10
  "engines": {
11
11
  "node": ">=14.0.0"
12
12
  },
package/source/app.ts CHANGED
@@ -1,6 +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 {fileURLToPath} from 'url';
4
5
 
5
6
  import type {Plugin, RollupOptions, GetManualChunk} from 'rollup';
6
7
  import type {AssetsBuildManifest} from '@quilted/assets';
@@ -18,6 +19,11 @@ import {getNodePlugins, removeBuildFiles} from './shared/rollup.ts';
18
19
  import {createMagicModulePlugin} from './shared/magic-module.ts';
19
20
 
20
21
  export interface AppOptions {
22
+ /**
23
+ * The root directory containing the source code for your application.
24
+ */
25
+ root?: string | URL;
26
+
21
27
  /**
22
28
  * The entry module for this app. This should be an absolute path, or relative
23
29
  * path from the root directory containing your project. This entry should just be
@@ -106,6 +112,7 @@ export interface AppBrowserAssetsOptions {
106
112
  }
107
113
 
108
114
  export async function quiltAppBrowser({
115
+ root: rootPath = process.cwd(),
109
116
  app,
110
117
  entry,
111
118
  env,
@@ -113,7 +120,7 @@ export async function quiltAppBrowser({
113
120
  module,
114
121
  graphql = true,
115
122
  }: AppBrowserOptions = {}) {
116
- const root = process.cwd();
123
+ const root = fileURLToPath(rootPath);
117
124
  const mode =
118
125
  (typeof env === 'object' ? env?.mode : undefined) ?? 'production';
119
126
  const minify = assets?.minify ?? mode === 'production';
@@ -136,6 +143,11 @@ export async function quiltAppBrowser({
136
143
  const targetName = targets.name ?? 'defaults';
137
144
  return config[targetName] ?? ['defaults'];
138
145
  })());
146
+ const normalizedTargetName =
147
+ targets.name === 'defaults' ? 'default' : targets.name;
148
+ const targetFilenamePart = normalizedTargetName
149
+ ? `.${normalizedTargetName}`
150
+ : '';
139
151
 
140
152
  const [
141
153
  {visualizer},
@@ -205,11 +217,17 @@ export async function quiltAppBrowser({
205
217
 
206
218
  if (graphql) {
207
219
  const {graphql} = await import('./features/graphql.ts');
208
- plugins.push(graphql({manifest: path.resolve(`manifests/graphql.json`)}));
220
+
221
+ plugins.push(
222
+ graphql({
223
+ manifest: path.resolve(`manifests/graphql${targetFilenamePart}.json`),
224
+ }),
225
+ );
209
226
  }
210
227
 
211
228
  if (minify) {
212
229
  const {minify} = await import('rollup-plugin-esbuild');
230
+
213
231
  plugins.push(minify());
214
232
  }
215
233
 
@@ -222,14 +240,16 @@ export async function quiltAppBrowser({
222
240
  id,
223
241
  cacheKey,
224
242
  baseUrl: baseURL,
225
- path: path.resolve(`build/manifests/assets.json`),
243
+ path: path.resolve(`build/manifests/assets${targetFilenamePart}.json`),
226
244
  priority: assets?.priority,
227
245
  }),
228
246
  visualizer({
229
247
  template: 'treemap',
230
248
  open: false,
231
249
  brotliSize: true,
232
- filename: path.resolve(`build/reports/bundle-visualizer.html`),
250
+ filename: path.resolve(
251
+ `build/reports/bundle-visualizer${targetFilenamePart}.html`,
252
+ ),
233
253
  }),
234
254
  );
235
255
 
@@ -261,9 +281,9 @@ export async function quiltAppBrowser({
261
281
  // format: isESM ? 'esm' : 'systemjs',
262
282
  format: 'esm',
263
283
  dir: path.resolve(`build/assets`),
264
- entryFileNames: `app.[hash].js`,
265
- assetFileNames: `[name].[hash].[ext]`,
266
- chunkFileNames: `[name].[hash].js`,
284
+ entryFileNames: `app${targetFilenamePart}.[hash].js`,
285
+ assetFileNames: `[name]${targetFilenamePart}.[hash].[ext]`,
286
+ chunkFileNames: `[name]${targetFilenamePart}.[hash].js`,
267
287
  manualChunks: createManualChunksSorter(),
268
288
  },
269
289
  } satisfies RollupOptions;
@@ -373,8 +393,8 @@ export async function quiltAppServer({
373
393
  visualizer({
374
394
  template: 'treemap',
375
395
  open: false,
376
- brotliSize: true,
377
- filename: path.resolve(`build/reports/bundle-visualizer.html`),
396
+ brotliSize: false,
397
+ filename: path.resolve(`build/reports/bundle-visualizer.server.html`),
378
398
  }),
379
399
  );
380
400
 
package/source/index.ts CHANGED
@@ -5,3 +5,4 @@ export {
5
5
  type AppBrowserOptions,
6
6
  type AppServerOptions,
7
7
  } from './app.ts';
8
+ export {quiltPackageESModules, type PackageOptions} from './package.ts';
@@ -0,0 +1,143 @@
1
+ import * as path from 'path';
2
+ import {Plugin, type RollupOptions} from 'rollup';
3
+ import {glob} from 'glob';
4
+ import {fileURLToPath} from 'url';
5
+
6
+ import {getNodePlugins, removeBuildFiles} from './shared/rollup.ts';
7
+ import {loadPackageJSON, type PackageJSON} from './shared/package-json.ts';
8
+
9
+ export interface PackageOptions {
10
+ /**
11
+ * The root directory containing the source code for your application.
12
+ */
13
+ root?: string | URL;
14
+ }
15
+
16
+ export async function quiltPackageESModules({
17
+ root: rootPath = process.cwd(),
18
+ }: PackageOptions = {}) {
19
+ const root = fileURLToPath(rootPath);
20
+ const outputDirectory = path.join(root, 'build/esm');
21
+
22
+ const [{sourceCode}, nodePlugins, packageJSON] = await Promise.all([
23
+ import('./features/source-code.ts'),
24
+ getNodePlugins(),
25
+ loadPackageJSON(root),
26
+ ]);
27
+
28
+ const [entries] = await Promise.all([
29
+ sourceEntriesForPackage(root, packageJSON),
30
+ ]);
31
+
32
+ let sourceRoot = root;
33
+
34
+ for (const entry of Object.values(entries)) {
35
+ if (!entry.startsWith(root)) continue;
36
+
37
+ sourceRoot = path.resolve(
38
+ root,
39
+ path.relative(root, entry).split(path.sep)[0] ?? '.',
40
+ );
41
+ break;
42
+ }
43
+
44
+ const plugins: Plugin[] = [
45
+ ...nodePlugins,
46
+ sourceCode({mode: 'production'}),
47
+ removeBuildFiles(['build/esm'], {root}),
48
+ ];
49
+
50
+ return {
51
+ input: entries,
52
+ plugins,
53
+ onwarn(warning, defaultWarn) {
54
+ // Removes annoying warnings for React-focused libraries that
55
+ // include 'use client' directives.
56
+ if (
57
+ warning.code === 'MODULE_LEVEL_DIRECTIVE' &&
58
+ /['"]use client['"]/.test(warning.message)
59
+ ) {
60
+ return;
61
+ }
62
+
63
+ defaultWarn(warning);
64
+ },
65
+ output: {
66
+ preserveModules: true,
67
+ preserveModulesRoot: sourceRoot,
68
+ format: 'esm',
69
+ dir: outputDirectory,
70
+ entryFileNames: `[name].mjs`,
71
+ assetFileNames: `[name].[ext]`,
72
+ // chunkFileNames: createChunkNamer({
73
+ // extension: ESM_EXTENSION,
74
+ // sourceRoot: sourceRootDirectory,
75
+ // }),
76
+ },
77
+ } satisfies RollupOptions;
78
+ }
79
+
80
+ async function sourceEntriesForPackage(root: string, packageJSON: PackageJSON) {
81
+ const {main, exports} = packageJSON;
82
+
83
+ const entries: Record<string, string> = {};
84
+
85
+ if (typeof main === 'string') {
86
+ entries['.'] = await resolveTargetFileAsSource(main, root);
87
+ }
88
+
89
+ if (typeof exports === 'string') {
90
+ entries['.'] = await resolveTargetFileAsSource(exports, root);
91
+ return entries;
92
+ } else if (exports == null || typeof exports !== 'object') {
93
+ return entries;
94
+ }
95
+
96
+ for (const [exportPath, exportCondition] of Object.entries(
97
+ exports as Record<string, null | string | Record<string, string>>,
98
+ )) {
99
+ let targetFile: string | null | undefined = null;
100
+
101
+ if (exportCondition == null) continue;
102
+
103
+ if (typeof exportCondition === 'string') {
104
+ targetFile = exportCondition;
105
+ } else {
106
+ targetFile ??=
107
+ exportCondition['source'] ??
108
+ exportCondition['quilt:source'] ??
109
+ exportCondition['quilt:esnext'] ??
110
+ Object.values(exportCondition).find(
111
+ (condition) =>
112
+ typeof condition === 'string' && condition.startsWith('./build/'),
113
+ );
114
+ }
115
+
116
+ if (targetFile == null) continue;
117
+
118
+ const sourceFile = await resolveTargetFileAsSource(targetFile, root);
119
+
120
+ entries[exportPath] = sourceFile;
121
+ }
122
+
123
+ return entries;
124
+ }
125
+
126
+ async function resolveTargetFileAsSource(file: string, root: string) {
127
+ const sourceFile = file.includes('/build/')
128
+ ? (
129
+ await glob(
130
+ file
131
+ .replace(/[/]build[/][^/]+[/]/, '/*/')
132
+ .replace(/(\.d\.ts|\.[\w]+)$/, '.*'),
133
+ {
134
+ cwd: root,
135
+ absolute: true,
136
+ ignore: [path.resolve(root, file)],
137
+ },
138
+ )
139
+ )[0]!
140
+ : path.resolve(root, file);
141
+
142
+ return sourceFile;
143
+ }
@@ -0,0 +1,17 @@
1
+ import * as path from 'path';
2
+ import {fileURLToPath} from 'url';
3
+ import {readFile} from 'fs/promises';
4
+
5
+ export interface PackageJSON {
6
+ name?: string;
7
+ [key: string]: unknown;
8
+ }
9
+
10
+ export async function loadPackageJSON(root: string | URL) {
11
+ const file = await readFile(
12
+ path.join(fileURLToPath(root), 'package.json'),
13
+ 'utf8',
14
+ );
15
+
16
+ return JSON.parse(file) as PackageJSON;
17
+ }