@quilted/rollup 0.1.13 → 0.1.15

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.
@@ -4,8 +4,27 @@ export interface PackageOptions {
4
4
  * The root directory containing the source code for your application.
5
5
  */
6
6
  root?: string | URL;
7
+ /**
8
+ * Whether to include GraphQL-related code transformations.
9
+ *
10
+ * @default true
11
+ */
12
+ graphql?: boolean;
7
13
  }
8
- export declare function quiltPackageESModules({ root: rootPath, }?: PackageOptions): Promise<{
14
+ export declare function quiltPackageESModules({ root: rootPath, graphql, }?: PackageOptions): Promise<{
15
+ input: string[];
16
+ plugins: Plugin<any>[];
17
+ onwarn(warning: import("rollup").RollupLog, defaultWarn: import("rollup").LoggingFunction): void;
18
+ output: {
19
+ preserveModules: true;
20
+ preserveModulesRoot: string;
21
+ format: "esm";
22
+ dir: string;
23
+ entryFileNames: string;
24
+ assetFileNames: string;
25
+ };
26
+ }>;
27
+ export declare function quiltPackageESNext({ root: rootPath, graphql, }?: PackageOptions): Promise<{
9
28
  input: string[];
10
29
  plugins: Plugin<any>[];
11
30
  onwarn(warning: import("rollup").RollupLog, defaultWarn: import("rollup").LoggingFunction): void;
@@ -1 +1 @@
1
- {"version":3,"file":"package.d.ts","sourceRoot":"","sources":["../../source/package.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,MAAM,EAAqB,MAAM,QAAQ,CAAC;AAOlD,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC;CACrB;AAED,wBAAsB,qBAAqB,CAAC,EAC1C,IAAI,EAAE,QAAwB,GAC/B,GAAE,cAAmB;;;;;;;;;;;;GA2DrB"}
1
+ {"version":3,"file":"package.d.ts","sourceRoot":"","sources":["../../source/package.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,MAAM,EAAqB,MAAM,QAAQ,CAAC;AAOlD,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC;IAEpB;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAsB,qBAAqB,CAAC,EAC1C,IAAI,EAAE,QAAwB,EAC9B,OAAc,GACf,GAAE,cAAmB;;;;;;;;;;;;GAgDrB;AAED,wBAAsB,kBAAkB,CAAC,EACvC,IAAI,EAAE,QAAwB,EAC9B,OAAc,GACf,GAAE,cAAmB;;;;;;;;;;;;GAgDrB"}
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.13",
9
+ "version": "0.1.15",
10
10
  "engines": {
11
11
  "node": ">=14.0.0"
12
12
  },
@@ -22,9 +22,23 @@
22
22
  "quilt:esnext": "./build/esnext/index.esnext",
23
23
  "import": "./build/esm/index.mjs",
24
24
  "require": "./build/cjs/index.cjs"
25
+ },
26
+ "./features/assets": {
27
+ "types": "./build/typescript/features/assets.d.ts",
28
+ "quilt:source": "./source/features/assets.ts",
29
+ "quilt:esnext": "./build/esnext/features/assets.esnext",
30
+ "import": "./build/esm/features/assets.mjs",
31
+ "require": "./build/cjs/features/assets.cjs"
25
32
  }
26
33
  },
27
34
  "types": "./build/typescript/index.d.ts",
35
+ "typesVersions": {
36
+ "*": {
37
+ "features/assets": [
38
+ "./build/typescript/features/assets.d.ts"
39
+ ]
40
+ }
41
+ },
28
42
  "sideEffects": false,
29
43
  "dependencies": {
30
44
  "@babel/core": "^7.23.0",
@@ -40,7 +54,7 @@
40
54
  "@rollup/plugin-commonjs": "^25.0.5",
41
55
  "@rollup/plugin-json": "^6.0.1",
42
56
  "@rollup/plugin-node-resolve": "^15.2.3",
43
- "@quilted/assets": "^0.0.4",
57
+ "@quilted/assets": "^0.0.5",
44
58
  "@quilted/graphql": "^2.0.0",
45
59
  "@types/babel__preset-env": "^7.9.0",
46
60
  "browserslist": "^4.22.1",
@@ -52,7 +66,7 @@
52
66
  "mrmime": "^1.0.1",
53
67
  "rollup-plugin-esbuild": "^6.1.0",
54
68
  "rollup-plugin-node-externals": "^6.1.2",
55
- "rollup-plugin-visualizer": "^5.9.0",
69
+ "rollup-plugin-visualizer": "^5.9.2",
56
70
  "systemjs": "^6.14.2"
57
71
  },
58
72
  "peerDependencies": {
@@ -64,8 +78,7 @@
64
78
  }
65
79
  },
66
80
  "devDependencies": {
67
- "@quilted/testing": "^0.1.0",
68
- "rollup": "^4.0.0"
81
+ "rollup": "^4.1.4"
69
82
  },
70
83
  "eslintConfig": {
71
84
  "extends": [
package/source/app.ts CHANGED
@@ -151,16 +151,14 @@ export async function quiltAppBrowser({
151
151
 
152
152
  const [
153
153
  {visualizer},
154
- {assetManifest},
155
154
  {sourceCode},
156
155
  {createTSConfigAliasPlugin},
157
156
  {css},
158
- {rawAssets, staticAssets},
157
+ {assetManifest, rawAssets, staticAssets},
159
158
  {systemJS},
160
159
  nodePlugins,
161
160
  ] = await Promise.all([
162
161
  import('rollup-plugin-visualizer'),
163
- import('@quilted/assets/rollup'),
164
162
  import('./features/source-code.ts'),
165
163
  import('./features/typescript.ts'),
166
164
  import('./features/css.ts'),
@@ -235,12 +233,11 @@ export async function quiltAppBrowser({
235
233
  const id = targets.name ? targets.name : undefined;
236
234
 
237
235
  plugins.push(
238
- // @ts-expect-error The plugin still depends on Rollup 3
239
236
  assetManifest({
240
237
  id,
241
238
  cacheKey,
242
- baseUrl: baseURL,
243
- path: path.resolve(`build/manifests/assets${targetFilenamePart}.json`),
239
+ baseURL,
240
+ file: path.resolve(`build/manifests/assets${targetFilenamePart}.json`),
244
241
  priority: assets?.priority,
245
242
  }),
246
243
  visualizer({
@@ -1,10 +1,158 @@
1
1
  import * as path from 'path';
2
- import {readFile} from 'fs/promises';
2
+ import * as fs from 'fs/promises';
3
3
  import {createHash} from 'crypto';
4
4
 
5
- import type {Plugin} from 'rollup';
5
+ import type {
6
+ NormalizedOutputOptions,
7
+ OutputBundle,
8
+ OutputChunk,
9
+ Plugin,
10
+ PluginContext,
11
+ } from 'rollup';
6
12
  import * as mime from 'mrmime';
7
13
 
14
+ import type {
15
+ AssetsBuildManifest,
16
+ AssetsBuildManifestEntry,
17
+ } from '@quilted/assets';
18
+
19
+ export interface AssetManifestOptions {
20
+ id?: string;
21
+ file: string;
22
+ baseURL: string;
23
+ priority?: number;
24
+ cacheKey?: Record<string, any>;
25
+ }
26
+
27
+ export function assetManifest(manifestOptions: AssetManifestOptions): Plugin {
28
+ return {
29
+ name: '@quilted/asset-manifest',
30
+ async generateBundle(options, bundle) {
31
+ await writeManifestForBundle.call(this, bundle, manifestOptions, options);
32
+ },
33
+ };
34
+ }
35
+
36
+ async function writeManifestForBundle(
37
+ this: PluginContext,
38
+ bundle: OutputBundle,
39
+ {id, file, baseURL, cacheKey, priority}: AssetManifestOptions,
40
+ {format}: NormalizedOutputOptions,
41
+ ) {
42
+ const outputs = Object.values(bundle);
43
+
44
+ const entries = outputs.filter(
45
+ (output): output is OutputChunk =>
46
+ output.type === 'chunk' && output.isEntry,
47
+ );
48
+
49
+ if (entries.length === 0) {
50
+ throw new Error(`Could not find any entries in your rollup bundle...`);
51
+ }
52
+
53
+ // We assume the first entry is the "main" one. There can be
54
+ // more than one because each worker script is also listed as an
55
+ // entry (though, from a separate build).
56
+ const entryChunk = entries[0]!;
57
+
58
+ const dependencyMap = new Map<string, string[]>();
59
+
60
+ for (const output of outputs) {
61
+ if (output.type !== 'chunk') continue;
62
+ dependencyMap.set(output.fileName, output.imports);
63
+ }
64
+
65
+ const assets: string[] = [];
66
+ const assetIdMap = new Map<string, number>();
67
+
68
+ function getAssetId(file: string) {
69
+ let id = assetIdMap.get(file);
70
+
71
+ if (id == null) {
72
+ assets.push(`${baseURL}${file}`);
73
+ id = assets.length - 1;
74
+ assetIdMap.set(file, id);
75
+ }
76
+
77
+ return id;
78
+ }
79
+
80
+ const manifest: AssetsBuildManifest<any> = {
81
+ id,
82
+ priority,
83
+ cacheKey,
84
+ assets,
85
+ attributes: format === 'es' ? {scripts: {type: 'module'}} : undefined,
86
+ entries: {
87
+ default: createAssetsEntry([...entryChunk.imports, entryChunk.fileName], {
88
+ dependencyMap,
89
+ getAssetId,
90
+ }),
91
+ },
92
+ modules: {},
93
+ };
94
+
95
+ for (const output of outputs) {
96
+ if (output.type !== 'chunk') continue;
97
+
98
+ const originalModuleId =
99
+ output.facadeModuleId ?? output.moduleIds[output.moduleIds.length - 1];
100
+
101
+ if (originalModuleId == null) continue;
102
+
103
+ // This metadata is added by the rollup plugin for @quilted/async
104
+ const moduleId = this.getModuleInfo(originalModuleId)?.meta.quilt?.moduleId;
105
+
106
+ if (moduleId == null) continue;
107
+
108
+ manifest.modules[moduleId] = createAssetsEntry(
109
+ [...output.imports, output.fileName],
110
+ {dependencyMap, getAssetId},
111
+ );
112
+ }
113
+
114
+ await fs.mkdir(path.dirname(file), {recursive: true});
115
+ await fs.writeFile(file, JSON.stringify(manifest, null, 2));
116
+ }
117
+
118
+ function createAssetsEntry(
119
+ files: string[],
120
+ {
121
+ dependencyMap,
122
+ getAssetId,
123
+ }: {
124
+ dependencyMap: Map<string, string[]>;
125
+ getAssetId(file: string): number;
126
+ },
127
+ ): AssetsBuildManifestEntry {
128
+ const styles: number[] = [];
129
+ const scripts: number[] = [];
130
+
131
+ const allFiles = new Set<string>();
132
+ const addFile = (file: string) => {
133
+ if (allFiles.has(file)) return;
134
+ allFiles.add(file);
135
+
136
+ for (const dependency of dependencyMap.get(file) ?? []) {
137
+ addFile(dependency);
138
+ }
139
+ };
140
+
141
+ for (const file of files) {
142
+ addFile(file);
143
+ }
144
+
145
+ for (const file of allFiles) {
146
+ if (file.endsWith('.css')) {
147
+ styles.push(getAssetId(file));
148
+ } else {
149
+ scripts.push(getAssetId(file));
150
+ }
151
+ }
152
+
153
+ return {scripts, styles};
154
+ }
155
+
8
156
  const QUERY_PATTERN = /\?.*$/s;
9
157
  const HASH_PATTERN = /#.*$/s;
10
158
  const RAW_PATTERN = /(\?|&)raw(?:&|$)/;
@@ -56,7 +204,7 @@ export function rawAssets(): Plugin {
56
204
 
57
205
  this.addWatchFile(moduleId);
58
206
 
59
- const file = await readFile(moduleId, {
207
+ const file = await fs.readFile(moduleId, {
60
208
  encoding: 'utf-8',
61
209
  });
62
210
 
@@ -103,7 +251,7 @@ export function staticAssets({
103
251
  }
104
252
 
105
253
  const file = cleanModuleIdentifier(id);
106
- const content = await readFile(file);
254
+ const content = await fs.readFile(file);
107
255
 
108
256
  let url: string;
109
257
 
@@ -1,16 +1,29 @@
1
1
  import {createRequire} from 'module';
2
2
 
3
3
  import babel from '@rollup/plugin-babel';
4
+ import esbuild from 'rollup-plugin-esbuild';
4
5
 
5
6
  const require = createRequire(import.meta.url);
6
7
 
7
8
  export function sourceCode({
8
9
  mode,
9
10
  targets,
11
+ babel: useBabel = true,
10
12
  }: {
11
13
  mode?: 'development' | 'production';
12
14
  targets?: string[];
15
+ babel?: boolean;
13
16
  }) {
17
+ if (!useBabel) {
18
+ return esbuild({
19
+ // Support very modern features
20
+ target: 'es2022',
21
+ jsx: 'automatic',
22
+ jsxImportSource: 'react',
23
+ exclude: 'node_modules/**',
24
+ });
25
+ }
26
+
14
27
  return babel({
15
28
  envName: mode,
16
29
  configFile: false,
package/source/index.ts CHANGED
@@ -5,4 +5,8 @@ export {
5
5
  type AppBrowserOptions,
6
6
  type AppServerOptions,
7
7
  } from './app.ts';
8
- export {quiltPackageESModules, type PackageOptions} from './package.ts';
8
+ export {
9
+ quiltPackageESModules,
10
+ quiltPackageESNext,
11
+ type PackageOptions,
12
+ } from './package.ts';
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);
@@ -26,32 +34,74 @@ export async function quiltPackageESModules({
26
34
  loadPackageJSON(root),
27
35
  ]);
28
36
 
29
- const [entries] = await Promise.all([
30
- sourceEntriesForPackage(root, packageJSON),
31
- ]);
37
+ const source = await sourceForPackage(root, packageJSON);
32
38
 
33
- let sourceRoot = root;
39
+ const plugins: Plugin[] = [
40
+ ...nodePlugins,
41
+ sourceCode({mode: 'production'}),
42
+ removeBuildFiles(['build/esm'], {root}),
43
+ ];
34
44
 
35
- const sourceEntryFiles = Object.values(entries);
45
+ if (graphql) {
46
+ const {graphql} = await import('./features/graphql.ts');
47
+ plugins.push(graphql({manifest: false}));
48
+ }
36
49
 
37
- for (const entry of sourceEntryFiles) {
38
- if (!entry.startsWith(root)) continue;
50
+ return {
51
+ input: source.files,
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
+ }
39
62
 
40
- sourceRoot = path.resolve(
41
- root,
42
- path.relative(root, entry).split(path.sep)[0] ?? '.',
43
- );
44
- break;
45
- }
63
+ defaultWarn(warning);
64
+ },
65
+ output: {
66
+ preserveModules: true,
67
+ preserveModulesRoot: source.root,
68
+ format: 'esm',
69
+ dir: outputDirectory,
70
+ entryFileNames: `[name].mjs`,
71
+ assetFileNames: `[name].[ext]`,
72
+ },
73
+ } satisfies RollupOptions;
74
+ }
75
+
76
+ export async function quiltPackageESNext({
77
+ root: rootPath = process.cwd(),
78
+ graphql = true,
79
+ }: PackageOptions = {}) {
80
+ const root =
81
+ typeof rootPath === 'string' ? rootPath : fileURLToPath(rootPath);
82
+ const outputDirectory = path.join(root, 'build/esnext');
83
+
84
+ const [{sourceCode}, nodePlugins, packageJSON] = await Promise.all([
85
+ import('./features/source-code.ts'),
86
+ getNodePlugins(),
87
+ loadPackageJSON(root),
88
+ ]);
89
+
90
+ const source = await sourceForPackage(root, packageJSON);
46
91
 
47
92
  const plugins: Plugin[] = [
48
93
  ...nodePlugins,
49
- sourceCode({mode: 'production'}),
50
- removeBuildFiles(['build/esm'], {root}),
94
+ sourceCode({mode: 'production', babel: false}),
95
+ removeBuildFiles(['build/esnext'], {root}),
51
96
  ];
52
97
 
98
+ if (graphql) {
99
+ const {graphql} = await import('./features/graphql.ts');
100
+ plugins.push(graphql({manifest: false}));
101
+ }
102
+
53
103
  return {
54
- input: sourceEntryFiles,
104
+ input: source.files,
55
105
  plugins,
56
106
  onwarn(warning, defaultWarn) {
57
107
  // Removes annoying warnings for React-focused libraries that
@@ -67,15 +117,37 @@ export async function quiltPackageESModules({
67
117
  },
68
118
  output: {
69
119
  preserveModules: true,
70
- preserveModulesRoot: sourceRoot,
120
+ preserveModulesRoot: source.root,
71
121
  format: 'esm',
72
122
  dir: outputDirectory,
73
- entryFileNames: `[name].mjs`,
123
+ entryFileNames: `[name].esnext`,
74
124
  assetFileNames: `[name].[ext]`,
75
125
  },
76
126
  } satisfies RollupOptions;
77
127
  }
78
128
 
129
+ async function sourceForPackage(root: string, packageJSON: PackageJSON) {
130
+ const [entries] = await Promise.all([
131
+ sourceEntriesForPackage(root, packageJSON),
132
+ ]);
133
+
134
+ let sourceRoot = root;
135
+
136
+ const sourceEntryFiles = Object.values(entries);
137
+
138
+ for (const entry of sourceEntryFiles) {
139
+ if (!entry.startsWith(root)) continue;
140
+
141
+ sourceRoot = path.resolve(
142
+ root,
143
+ path.relative(root, entry).split(path.sep)[0] ?? '.',
144
+ );
145
+ break;
146
+ }
147
+
148
+ return {root: sourceRoot, files: sourceEntryFiles};
149
+ }
150
+
79
151
  async function sourceEntriesForPackage(root: string, packageJSON: PackageJSON) {
80
152
  const {main, exports} = packageJSON;
81
153