@quilted/rollup 0.1.14 → 0.1.16

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 (44) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/build/cjs/app.cjs +21 -47
  3. package/build/cjs/features/assets.cjs +112 -2
  4. package/build/cjs/features/source-code.cjs +3 -2
  5. package/build/cjs/features/system-js.cjs +2 -1
  6. package/build/cjs/index.cjs +2 -0
  7. package/build/cjs/module.cjs +155 -0
  8. package/build/cjs/package.cjs +20 -2
  9. package/build/cjs/shared/browserslist.cjs +25 -0
  10. package/build/esm/app.mjs +21 -47
  11. package/build/esm/features/assets.mjs +112 -4
  12. package/build/esm/features/source-code.mjs +1 -1
  13. package/build/esm/index.mjs +1 -0
  14. package/build/esm/module.mjs +134 -0
  15. package/build/esm/package.mjs +20 -2
  16. package/build/esm/shared/browserslist.mjs +23 -0
  17. package/build/esnext/app.esnext +21 -47
  18. package/build/esnext/features/assets.esnext +112 -4
  19. package/build/esnext/features/source-code.esnext +1 -1
  20. package/build/esnext/index.esnext +1 -0
  21. package/build/esnext/module.esnext +134 -0
  22. package/build/esnext/package.esnext +20 -2
  23. package/build/esnext/shared/browserslist.esnext +23 -0
  24. package/build/tsconfig.tsbuildinfo +1 -1
  25. package/build/typescript/app.d.ts +4 -6
  26. package/build/typescript/app.d.ts.map +1 -1
  27. package/build/typescript/features/assets.d.ts +10 -2
  28. package/build/typescript/features/assets.d.ts.map +1 -1
  29. package/build/typescript/index.d.ts +1 -0
  30. package/build/typescript/index.d.ts.map +1 -1
  31. package/build/typescript/module.d.ts +45 -0
  32. package/build/typescript/module.d.ts.map +1 -0
  33. package/build/typescript/package.d.ts +8 -2
  34. package/build/typescript/package.d.ts.map +1 -1
  35. package/build/typescript/shared/browserslist.d.ts +11 -0
  36. package/build/typescript/shared/browserslist.d.ts.map +1 -0
  37. package/package.json +18 -5
  38. package/source/app.ts +21 -53
  39. package/source/features/assets.ts +152 -4
  40. package/source/features/source-code.ts +1 -1
  41. package/source/index.ts +1 -0
  42. package/source/module.ts +223 -0
  43. package/source/package.ts +19 -0
  44. package/source/shared/browserslist.ts +32 -0
@@ -0,0 +1,223 @@
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
+ import {
9
+ getBrowserTargetDetails,
10
+ type BrowserTargetSelection,
11
+ } from './shared/browserslist.ts';
12
+ import type {MagicModuleEnvOptions} from './features/env.ts';
13
+
14
+ export interface ModuleOptions {
15
+ /**
16
+ * The root directory containing the source code for your application.
17
+ */
18
+ root?: string | URL;
19
+
20
+ /**
21
+ * Whether to include GraphQL-related code transformations.
22
+ *
23
+ * @default true
24
+ */
25
+ graphql?: boolean;
26
+
27
+ /**
28
+ * Customizes the behavior of environment variables for your module.
29
+ */
30
+ env?: MagicModuleEnvOptions;
31
+
32
+ /**
33
+ * Customizes the assets created for your module.
34
+ */
35
+ assets?: ModuleAssetsOptions;
36
+ }
37
+
38
+ export interface ModuleAssetsOptions {
39
+ /**
40
+ * Whether to minify assets created for this module.
41
+ *
42
+ * @default true
43
+ */
44
+ minify?: boolean;
45
+ hash?: boolean;
46
+ targets?: BrowserTargetSelection;
47
+ }
48
+
49
+ export async function quiltModule({
50
+ root: rootPath = process.cwd(),
51
+ env,
52
+ assets,
53
+ graphql = true,
54
+ }: ModuleOptions = {}) {
55
+ const root =
56
+ typeof rootPath === 'string' ? rootPath : fileURLToPath(rootPath);
57
+ const mode =
58
+ (typeof env === 'object' ? env?.mode : undefined) ?? 'production';
59
+ const outputDirectory = path.join(root, 'build/assets');
60
+
61
+ const minify = assets?.minify ?? true;
62
+ const hash = assets?.hash ?? true;
63
+ const hashFilenamePart = hash ? '.[hash]' : '';
64
+
65
+ const browserTarget = await getBrowserTargetDetails(assets?.targets, {root});
66
+ const targetFilenamePart = browserTarget.name ? `.${browserTarget.name}` : '';
67
+
68
+ const [
69
+ {visualizer},
70
+ {magicModuleEnv, replaceProcessEnv},
71
+ {sourceCode},
72
+ nodePlugins,
73
+ packageJSON,
74
+ ] = await Promise.all([
75
+ import('rollup-plugin-visualizer'),
76
+ import('./features/env.ts'),
77
+ import('./features/source-code.ts'),
78
+ getNodePlugins(),
79
+ loadPackageJSON(root),
80
+ ]);
81
+
82
+ const source = await sourceForPackage(root, packageJSON);
83
+
84
+ const plugins: Plugin[] = [
85
+ ...nodePlugins,
86
+ replaceProcessEnv({mode}),
87
+ magicModuleEnv({...env, mode}),
88
+ sourceCode({mode: 'production'}),
89
+ removeBuildFiles(['build/assets', 'build/reports'], {root}),
90
+ ];
91
+
92
+ if (graphql) {
93
+ const {graphql} = await import('./features/graphql.ts');
94
+ plugins.push(graphql({manifest: false}));
95
+ }
96
+
97
+ if (minify) {
98
+ const {minify} = await import('rollup-plugin-esbuild');
99
+ plugins.push(minify());
100
+ }
101
+
102
+ plugins.push(
103
+ visualizer({
104
+ template: 'treemap',
105
+ open: false,
106
+ brotliSize: true,
107
+ filename: path.resolve(
108
+ root,
109
+ `build/reports/bundle-visualizer${targetFilenamePart}.html`,
110
+ ),
111
+ }),
112
+ );
113
+
114
+ return {
115
+ input: source.files,
116
+ plugins,
117
+ onwarn(warning, defaultWarn) {
118
+ // Removes annoying warnings for React-focused libraries that
119
+ // include 'use client' directives.
120
+ if (
121
+ warning.code === 'MODULE_LEVEL_DIRECTIVE' &&
122
+ /['"]use client['"]/.test(warning.message)
123
+ ) {
124
+ return;
125
+ }
126
+
127
+ defaultWarn(warning);
128
+ },
129
+ output: {
130
+ format: 'esm',
131
+ dir: outputDirectory,
132
+ entryFileNames: `[name]${targetFilenamePart}${hashFilenamePart}.js`,
133
+ assetFileNames: `[name]${targetFilenamePart}${hashFilenamePart}.[ext]`,
134
+ },
135
+ } satisfies RollupOptions;
136
+ }
137
+
138
+ async function sourceForPackage(root: string, packageJSON: PackageJSON) {
139
+ const [entries] = await Promise.all([
140
+ sourceEntriesForPackage(root, packageJSON),
141
+ ]);
142
+
143
+ let sourceRoot = root;
144
+
145
+ const sourceEntryFiles = Object.values(entries);
146
+
147
+ for (const entry of sourceEntryFiles) {
148
+ if (!entry.startsWith(root)) continue;
149
+
150
+ sourceRoot = path.resolve(
151
+ root,
152
+ path.relative(root, entry).split(path.sep)[0] ?? '.',
153
+ );
154
+ break;
155
+ }
156
+
157
+ return {root: sourceRoot, files: sourceEntryFiles};
158
+ }
159
+
160
+ async function sourceEntriesForPackage(root: string, packageJSON: PackageJSON) {
161
+ const {main, exports} = packageJSON;
162
+
163
+ const entries: Record<string, string> = {};
164
+
165
+ if (typeof main === 'string') {
166
+ entries['.'] = await resolveTargetFileAsSource(main, root);
167
+ }
168
+
169
+ if (typeof exports === 'string') {
170
+ entries['.'] = await resolveTargetFileAsSource(exports, root);
171
+ return entries;
172
+ } else if (exports == null || typeof exports !== 'object') {
173
+ return entries;
174
+ }
175
+
176
+ for (const [exportPath, exportCondition] of Object.entries(
177
+ exports as Record<string, null | string | Record<string, string>>,
178
+ )) {
179
+ let targetFile: string | null | undefined = null;
180
+
181
+ if (exportCondition == null) continue;
182
+
183
+ if (typeof exportCondition === 'string') {
184
+ targetFile = exportCondition;
185
+ } else {
186
+ targetFile ??=
187
+ exportCondition['source'] ??
188
+ exportCondition['quilt:source'] ??
189
+ exportCondition['quilt:esnext'] ??
190
+ Object.values(exportCondition).find(
191
+ (condition) =>
192
+ typeof condition === 'string' && condition.startsWith('./build/'),
193
+ );
194
+ }
195
+
196
+ if (targetFile == null) continue;
197
+
198
+ const sourceFile = await resolveTargetFileAsSource(targetFile, root);
199
+
200
+ entries[exportPath] = sourceFile;
201
+ }
202
+
203
+ return entries;
204
+ }
205
+
206
+ async function resolveTargetFileAsSource(file: string, root: string) {
207
+ const sourceFile = file.includes('/build/')
208
+ ? (
209
+ await glob(
210
+ file
211
+ .replace(/[/]build[/][^/]+[/]/, '/*/')
212
+ .replace(/(\.d\.ts|\.[\w]+)$/, '.*'),
213
+ {
214
+ cwd: root,
215
+ absolute: true,
216
+ ignore: [path.resolve(root, file)],
217
+ },
218
+ )
219
+ )[0]!
220
+ : path.resolve(root, file);
221
+
222
+ return sourceFile;
223
+ }
package/source/package.ts CHANGED
@@ -11,10 +11,18 @@ export interface PackageOptions {
11
11
  * The root directory containing the source code for your application.
12
12
  */
13
13
  root?: string | URL;
14
+
15
+ /**
16
+ * Whether to include GraphQL-related code transformations.
17
+ *
18
+ * @default true
19
+ */
20
+ graphql?: boolean;
14
21
  }
15
22
 
16
23
  export async function quiltPackageESModules({
17
24
  root: rootPath = process.cwd(),
25
+ graphql = true,
18
26
  }: PackageOptions = {}) {
19
27
  const root =
20
28
  typeof rootPath === 'string' ? rootPath : fileURLToPath(rootPath);
@@ -34,6 +42,11 @@ export async function quiltPackageESModules({
34
42
  removeBuildFiles(['build/esm'], {root}),
35
43
  ];
36
44
 
45
+ if (graphql) {
46
+ const {graphql} = await import('./features/graphql.ts');
47
+ plugins.push(graphql({manifest: false}));
48
+ }
49
+
37
50
  return {
38
51
  input: source.files,
39
52
  plugins,
@@ -62,6 +75,7 @@ export async function quiltPackageESModules({
62
75
 
63
76
  export async function quiltPackageESNext({
64
77
  root: rootPath = process.cwd(),
78
+ graphql = true,
65
79
  }: PackageOptions = {}) {
66
80
  const root =
67
81
  typeof rootPath === 'string' ? rootPath : fileURLToPath(rootPath);
@@ -81,6 +95,11 @@ export async function quiltPackageESNext({
81
95
  removeBuildFiles(['build/esnext'], {root}),
82
96
  ];
83
97
 
98
+ if (graphql) {
99
+ const {graphql} = await import('./features/graphql.ts');
100
+ plugins.push(graphql({manifest: false}));
101
+ }
102
+
84
103
  return {
85
104
  input: source.files,
86
105
  plugins,
@@ -0,0 +1,32 @@
1
+ export type BrowserTargetSelection =
2
+ | string[]
3
+ | {
4
+ name?: string;
5
+ browsers?: string[];
6
+ };
7
+
8
+ export async function getBrowserTargetDetails(
9
+ targetSelection: BrowserTargetSelection = {},
10
+ {root}: {root?: string} = {},
11
+ ) {
12
+ const targets = Array.isArray(targetSelection)
13
+ ? {
14
+ browsers: targetSelection,
15
+ }
16
+ : targetSelection;
17
+ const targetBrowsers =
18
+ targets.browsers ??
19
+ (await (async () => {
20
+ const {default: browserslist} = await import('browserslist');
21
+ const config = browserslist.findConfig(root!);
22
+
23
+ if (config == null) return ['defaults'];
24
+
25
+ const targetName = targets.name ?? 'defaults';
26
+ return config[targetName] ?? ['defaults'];
27
+ })());
28
+
29
+ const name = targets.name === 'defaults' ? 'default' : targets.name;
30
+
31
+ return {name, browsers: targetBrowsers};
32
+ }