@quilted/rollup 0.1.3 → 0.1.5
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 +14 -0
- package/build/cjs/app.cjs +150 -136
- package/build/cjs/features/assets.cjs +130 -0
- package/build/cjs/{env.cjs → features/env.cjs} +4 -4
- package/build/cjs/{request-router.cjs → features/request-router.cjs} +3 -3
- package/build/cjs/features/source-code.cjs +40 -0
- package/build/cjs/features/system-js.cjs +35 -0
- package/build/cjs/index.cjs +0 -7
- package/build/cjs/shared/rollup.cjs +0 -4
- package/build/esm/app.mjs +152 -138
- package/build/esm/features/assets.mjs +107 -0
- package/build/esm/{env.mjs → features/env.mjs} +4 -4
- package/build/esm/{request-router.mjs → features/request-router.mjs} +3 -3
- package/build/esm/features/source-code.mjs +38 -0
- package/build/esm/features/system-js.mjs +33 -0
- package/build/esm/index.mjs +1 -3
- package/build/esm/shared/rollup.mjs +1 -4
- package/build/esnext/app.esnext +152 -138
- package/build/esnext/features/assets.esnext +107 -0
- package/build/esnext/{env.esnext → features/env.esnext} +4 -4
- package/build/esnext/{request-router.esnext → features/request-router.esnext} +3 -3
- package/build/esnext/features/source-code.esnext +38 -0
- package/build/esnext/features/system-js.esnext +33 -0
- package/build/esnext/index.esnext +1 -3
- package/build/esnext/shared/rollup.esnext +1 -4
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/typescript/app.d.ts +32 -144
- package/build/typescript/app.d.ts.map +1 -1
- package/build/typescript/features/assets.d.ts +13 -0
- package/build/typescript/features/assets.d.ts.map +1 -0
- package/build/typescript/features/css.d.ts +16 -0
- package/build/typescript/features/css.d.ts.map +1 -0
- package/build/typescript/features/env.d.ts +57 -0
- package/build/typescript/features/env.d.ts.map +1 -0
- package/build/typescript/features/graphql/transform.d.ts +17 -0
- package/build/typescript/features/graphql/transform.d.ts.map +1 -0
- package/build/typescript/features/graphql.d.ts +6 -0
- package/build/typescript/features/graphql.d.ts.map +1 -0
- package/build/typescript/features/request-router.d.ts +15 -0
- package/build/typescript/features/request-router.d.ts.map +1 -0
- package/build/typescript/features/source-code.d.ts +5 -0
- package/build/typescript/features/source-code.d.ts.map +1 -0
- package/build/typescript/features/system-js.d.ts +7 -0
- package/build/typescript/features/system-js.d.ts.map +1 -0
- package/build/typescript/index.d.ts +1 -3
- package/build/typescript/index.d.ts.map +1 -1
- package/build/typescript/shared/source-code.d.ts +5 -0
- package/build/typescript/shared/source-code.d.ts.map +1 -0
- package/package.json +15 -2
- package/source/app.ts +173 -118
- package/source/features/assets.ts +183 -0
- package/source/features/css.ts +91 -0
- package/source/{env.ts → features/env.ts} +4 -4
- package/source/{request-router.ts → features/request-router.ts} +3 -3
- package/source/features/source-code.ts +64 -0
- package/source/features/system-js.ts +36 -0
- package/source/index.ts +0 -5
- /package/build/cjs/{graphql → features/graphql}/transform.cjs +0 -0
- /package/build/cjs/{graphql.cjs → features/graphql.cjs} +0 -0
- /package/build/esm/{graphql → features/graphql}/transform.mjs +0 -0
- /package/build/esm/{graphql.mjs → features/graphql.mjs} +0 -0
- /package/build/esnext/{graphql → features/graphql}/transform.esnext +0 -0
- /package/build/esnext/{graphql.esnext → features/graphql.esnext} +0 -0
- /package/source/{graphql → features/graphql}/transform.ts +0 -0
- /package/source/{graphql.ts → features/graphql.ts} +0 -0
package/source/app.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as path from 'path';
|
|
2
2
|
|
|
3
|
-
import type {
|
|
3
|
+
import type {Plugin, RollupOptions, GetManualChunk} from 'rollup';
|
|
4
4
|
|
|
5
5
|
import {
|
|
6
6
|
MAGIC_MODULE_ENTRY,
|
|
@@ -8,10 +8,10 @@ import {
|
|
|
8
8
|
MAGIC_MODULE_BROWSER_ASSETS,
|
|
9
9
|
MAGIC_MODULE_REQUEST_ROUTER,
|
|
10
10
|
} from './constants.ts';
|
|
11
|
-
import type {MagicModuleEnvOptions} from './env.ts';
|
|
11
|
+
import type {MagicModuleEnvOptions} from './features/env.ts';
|
|
12
12
|
|
|
13
13
|
import {multiline} from './shared/strings.ts';
|
|
14
|
-
import {getNodePlugins
|
|
14
|
+
import {getNodePlugins} from './shared/rollup.ts';
|
|
15
15
|
import {createMagicModulePlugin} from './shared/magic-module.ts';
|
|
16
16
|
|
|
17
17
|
export interface AppOptions {
|
|
@@ -22,8 +22,9 @@ export interface AppOptions {
|
|
|
22
22
|
* to create browser and server-side entries for your project.
|
|
23
23
|
*
|
|
24
24
|
* If you only want to use a custom entry module for the browser build, use the
|
|
25
|
-
* `
|
|
26
|
-
* for the server-side build, use the `server.entry` option
|
|
25
|
+
* `entry` option of the `quiltAppBrowser()` instead. If you only want to use a
|
|
26
|
+
* custom entry module for the server-side build, use the `server.entry` option
|
|
27
|
+
* instead.
|
|
27
28
|
*
|
|
28
29
|
* @example './App.tsx'
|
|
29
30
|
*/
|
|
@@ -46,7 +47,18 @@ export interface AppOptions {
|
|
|
46
47
|
|
|
47
48
|
export interface AppBrowserOptions extends AppOptions {
|
|
48
49
|
/**
|
|
49
|
-
*
|
|
50
|
+
* The entry module for this browser. This should be an absolute path, or relative
|
|
51
|
+
* path from the root directory containing your project. This entry should be the
|
|
52
|
+
* browser entrypoint.
|
|
53
|
+
*
|
|
54
|
+
* @example './browser.tsx'
|
|
55
|
+
* @default 'quilt:module/entry'
|
|
56
|
+
*/
|
|
57
|
+
entry?: string;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Customizes the magic `quilt:module/entry` module, which can be used as a "magic"
|
|
61
|
+
* entry for your application.
|
|
50
62
|
*/
|
|
51
63
|
module?: AppBrowserModuleOptions;
|
|
52
64
|
|
|
@@ -81,82 +93,92 @@ export interface AppBrowserAssetsOptions {
|
|
|
81
93
|
minify?: boolean;
|
|
82
94
|
}
|
|
83
95
|
|
|
84
|
-
export function quiltAppBrowser({
|
|
96
|
+
export async function quiltAppBrowser({
|
|
85
97
|
app,
|
|
98
|
+
entry = MAGIC_MODULE_ENTRY,
|
|
86
99
|
env,
|
|
87
100
|
assets,
|
|
88
101
|
module,
|
|
89
102
|
graphql = true,
|
|
90
103
|
}: AppBrowserOptions = {}) {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
104
|
+
const mode =
|
|
105
|
+
(typeof env === 'object' ? env?.mode : undefined) ?? 'production';
|
|
106
|
+
const minify = assets?.minify ?? true;
|
|
107
|
+
|
|
108
|
+
const [
|
|
109
|
+
{visualizer},
|
|
110
|
+
{sourceCode},
|
|
111
|
+
{rawAssets, staticAssets},
|
|
112
|
+
{systemJS},
|
|
113
|
+
nodePlugins,
|
|
114
|
+
] = await Promise.all([
|
|
115
|
+
import('rollup-plugin-visualizer'),
|
|
116
|
+
import('./features/source-code.ts'),
|
|
117
|
+
import('./features/assets.ts'),
|
|
118
|
+
import('./features/system-js.ts'),
|
|
119
|
+
getNodePlugins(),
|
|
120
|
+
]);
|
|
121
|
+
|
|
122
|
+
const plugins: Plugin[] = [
|
|
123
|
+
...nodePlugins,
|
|
124
|
+
systemJS(),
|
|
125
|
+
sourceCode({mode}),
|
|
126
|
+
rawAssets(),
|
|
127
|
+
staticAssets(),
|
|
128
|
+
];
|
|
129
|
+
|
|
130
|
+
if (env) {
|
|
131
|
+
const {magicModuleEnv, replaceProcessEnv} = await import(
|
|
132
|
+
'./features/env.ts'
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
if (typeof env === 'boolean') {
|
|
136
|
+
plugins.push(replaceProcessEnv({mode}));
|
|
137
|
+
plugins.push(magicModuleEnv({mode}));
|
|
138
|
+
} else {
|
|
139
|
+
plugins.push(replaceProcessEnv({mode}));
|
|
140
|
+
plugins.push(magicModuleEnv({mode}));
|
|
141
|
+
}
|
|
142
|
+
}
|
|
119
143
|
|
|
120
|
-
|
|
144
|
+
if (app) {
|
|
145
|
+
plugins.push(magicModuleAppComponent({entry: app}));
|
|
146
|
+
}
|
|
121
147
|
|
|
122
|
-
|
|
123
|
-
const {graphql} = await import('./graphql.ts');
|
|
124
|
-
newPlugins.push(
|
|
125
|
-
graphql({manifest: path.resolve(`manifests/graphql.json`)}),
|
|
126
|
-
);
|
|
127
|
-
}
|
|
148
|
+
plugins.push(magicModuleAppBrowserEntry(module));
|
|
128
149
|
|
|
129
|
-
|
|
150
|
+
if (graphql) {
|
|
151
|
+
const {graphql} = await import('./features/graphql.ts');
|
|
152
|
+
plugins.push(graphql({manifest: path.resolve(`manifests/graphql.json`)}));
|
|
153
|
+
}
|
|
130
154
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
155
|
+
if (minify) {
|
|
156
|
+
const {minify} = await import('rollup-plugin-esbuild');
|
|
157
|
+
plugins.push(minify());
|
|
158
|
+
}
|
|
135
159
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
160
|
+
plugins.push(
|
|
161
|
+
visualizer({
|
|
162
|
+
template: 'treemap',
|
|
163
|
+
open: false,
|
|
164
|
+
brotliSize: true,
|
|
165
|
+
filename: path.resolve(`reports/bundle-visualizer.html`),
|
|
166
|
+
}),
|
|
167
|
+
);
|
|
144
168
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
manualChunks: createManualChunksSorter(),
|
|
157
|
-
};
|
|
169
|
+
return {
|
|
170
|
+
input: entry,
|
|
171
|
+
plugins,
|
|
172
|
+
output: {
|
|
173
|
+
// format: isESM ? 'esm' : 'systemjs',
|
|
174
|
+
format: 'esm',
|
|
175
|
+
dir: path.resolve(`build/assets`),
|
|
176
|
+
entryFileNames: `app.[hash].js`,
|
|
177
|
+
assetFileNames: `[name].[hash].[ext]`,
|
|
178
|
+
chunkFileNames: `[name].[hash].js`,
|
|
179
|
+
manualChunks: createManualChunksSorter(),
|
|
158
180
|
},
|
|
159
|
-
} satisfies
|
|
181
|
+
} satisfies RollupOptions;
|
|
160
182
|
}
|
|
161
183
|
|
|
162
184
|
export interface AppServerOptions extends AppOptions {
|
|
@@ -166,63 +188,96 @@ export interface AppServerOptions extends AppOptions {
|
|
|
166
188
|
* the specific server runtime you configure.
|
|
167
189
|
*/
|
|
168
190
|
entry?: string;
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Whether to minify the JavaScript outputs for your server.
|
|
194
|
+
*
|
|
195
|
+
* @default false
|
|
196
|
+
*/
|
|
197
|
+
minify?: boolean;
|
|
169
198
|
}
|
|
170
199
|
|
|
171
|
-
export function quiltAppServer({
|
|
200
|
+
export async function quiltAppServer({
|
|
172
201
|
app,
|
|
173
202
|
env,
|
|
174
203
|
graphql,
|
|
175
|
-
entry,
|
|
204
|
+
entry = MAGIC_MODULE_ENTRY,
|
|
205
|
+
minify = false,
|
|
176
206
|
}: AppServerOptions = {}) {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
207
|
+
const mode =
|
|
208
|
+
(typeof env === 'object' ? env?.mode : undefined) ?? 'production';
|
|
209
|
+
|
|
210
|
+
const [
|
|
211
|
+
{visualizer},
|
|
212
|
+
{sourceCode},
|
|
213
|
+
{rawAssets, staticAssets},
|
|
214
|
+
{magicModuleRequestRouterEntry},
|
|
215
|
+
nodePlugins,
|
|
216
|
+
] = await Promise.all([
|
|
217
|
+
import('rollup-plugin-visualizer'),
|
|
218
|
+
import('./features/source-code.ts'),
|
|
219
|
+
import('./features/assets.ts'),
|
|
220
|
+
import('./features/request-router.ts'),
|
|
221
|
+
getNodePlugins(),
|
|
222
|
+
]);
|
|
223
|
+
|
|
224
|
+
const plugins: Plugin[] = [
|
|
225
|
+
...nodePlugins,
|
|
226
|
+
sourceCode({mode}),
|
|
227
|
+
rawAssets(),
|
|
228
|
+
staticAssets({emit: false}),
|
|
229
|
+
];
|
|
230
|
+
|
|
231
|
+
if (env) {
|
|
232
|
+
const {magicModuleEnv, replaceProcessEnv} = await import(
|
|
233
|
+
'./features/env.ts'
|
|
234
|
+
);
|
|
235
|
+
|
|
236
|
+
if (typeof env === 'boolean') {
|
|
237
|
+
plugins.push(replaceProcessEnv({mode}));
|
|
238
|
+
plugins.push(magicModuleEnv({mode}));
|
|
239
|
+
} else {
|
|
240
|
+
plugins.push(replaceProcessEnv({mode}));
|
|
241
|
+
plugins.push(magicModuleEnv({mode}));
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
if (app) {
|
|
246
|
+
plugins.push(magicModuleAppComponent({entry: app}));
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
plugins.push(magicModuleRequestRouterEntry());
|
|
250
|
+
plugins.push(magicModuleAppRequestRouter({entry}));
|
|
251
|
+
|
|
252
|
+
if (graphql) {
|
|
253
|
+
const {graphql} = await import('./features/graphql.ts');
|
|
254
|
+
plugins.push(graphql({manifest: false}));
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
if (minify) {
|
|
258
|
+
const {minify} = await import('rollup-plugin-esbuild');
|
|
259
|
+
plugins.push(minify());
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
plugins.push(
|
|
263
|
+
visualizer({
|
|
264
|
+
template: 'treemap',
|
|
265
|
+
open: false,
|
|
266
|
+
brotliSize: true,
|
|
267
|
+
filename: path.resolve(`reports/bundle-visualizer.html`),
|
|
268
|
+
}),
|
|
269
|
+
);
|
|
213
270
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
entryFileNames: 'server.js',
|
|
223
|
-
};
|
|
271
|
+
return {
|
|
272
|
+
input: entry,
|
|
273
|
+
plugins,
|
|
274
|
+
output: {
|
|
275
|
+
// format: isESM ? 'esm' : 'systemjs',
|
|
276
|
+
format: 'esm',
|
|
277
|
+
dir: path.resolve(`build/server`),
|
|
278
|
+
entryFileNames: 'server.js',
|
|
224
279
|
},
|
|
225
|
-
} satisfies
|
|
280
|
+
} satisfies RollupOptions;
|
|
226
281
|
}
|
|
227
282
|
|
|
228
283
|
export function magicModuleAppComponent({entry}: {entry: string}) {
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import * as path from 'path';
|
|
2
|
+
import {readFile} from 'fs/promises';
|
|
3
|
+
import {createHash} from 'crypto';
|
|
4
|
+
|
|
5
|
+
import type {Plugin} from 'rollup';
|
|
6
|
+
import * as mime from 'mrmime';
|
|
7
|
+
|
|
8
|
+
const QUERY_PATTERN = /\?.*$/s;
|
|
9
|
+
const HASH_PATTERN = /#.*$/s;
|
|
10
|
+
const RAW_PATTERN = /(\?|&)raw(?:&|$)/;
|
|
11
|
+
|
|
12
|
+
const DEFAULT_INLINE_LIMIT = 4096;
|
|
13
|
+
const DEFAULT_OUTPUT_PATTERN = '[name].[hash].[ext]';
|
|
14
|
+
const DEFAULT_STATIC_ASSET_EXTENSIONS = [
|
|
15
|
+
// images
|
|
16
|
+
'.png',
|
|
17
|
+
'.jpg',
|
|
18
|
+
'.jpeg',
|
|
19
|
+
'.gif',
|
|
20
|
+
'.svg',
|
|
21
|
+
'.ico',
|
|
22
|
+
'.webp',
|
|
23
|
+
'.avif',
|
|
24
|
+
|
|
25
|
+
// media
|
|
26
|
+
'.mp4',
|
|
27
|
+
'.webm',
|
|
28
|
+
'.ogg',
|
|
29
|
+
'.mp3',
|
|
30
|
+
'.wav',
|
|
31
|
+
'.flac',
|
|
32
|
+
'.aac',
|
|
33
|
+
|
|
34
|
+
// fonts
|
|
35
|
+
'.woff',
|
|
36
|
+
'.woff2',
|
|
37
|
+
'.eot',
|
|
38
|
+
'.ttf',
|
|
39
|
+
'.otf',
|
|
40
|
+
|
|
41
|
+
// other
|
|
42
|
+
'.webmanifest',
|
|
43
|
+
'.pdf',
|
|
44
|
+
'.txt',
|
|
45
|
+
];
|
|
46
|
+
|
|
47
|
+
export function rawAssets(): Plugin {
|
|
48
|
+
return {
|
|
49
|
+
name: '@quilted/raw-assets',
|
|
50
|
+
async load(id) {
|
|
51
|
+
if (id.startsWith('\0') || !RAW_PATTERN.test(id)) {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const moduleId = cleanModuleIdentifier(id);
|
|
56
|
+
|
|
57
|
+
this.addWatchFile(moduleId);
|
|
58
|
+
|
|
59
|
+
const file = await readFile(moduleId, {
|
|
60
|
+
encoding: 'utf-8',
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
return `export default ${JSON.stringify(file)}`;
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function staticAssets({
|
|
69
|
+
emit = true,
|
|
70
|
+
baseURL = '/',
|
|
71
|
+
extensions = DEFAULT_STATIC_ASSET_EXTENSIONS,
|
|
72
|
+
inlineLimit = DEFAULT_INLINE_LIMIT,
|
|
73
|
+
outputPattern = DEFAULT_OUTPUT_PATTERN,
|
|
74
|
+
}: {
|
|
75
|
+
emit?: boolean;
|
|
76
|
+
baseURL?: string;
|
|
77
|
+
extensions?: readonly string[];
|
|
78
|
+
inlineLimit?: number;
|
|
79
|
+
outputPattern?: string;
|
|
80
|
+
} = {}) {
|
|
81
|
+
const assetCache = new Map<string, string>();
|
|
82
|
+
const assetMatcher = new RegExp(
|
|
83
|
+
`\\.(` +
|
|
84
|
+
extensions
|
|
85
|
+
.map((extension) =>
|
|
86
|
+
extension.startsWith('.') ? extension.slice(1) : extension,
|
|
87
|
+
)
|
|
88
|
+
.join('|') +
|
|
89
|
+
`)(\\?.*)?$`,
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
return {
|
|
93
|
+
name: '@quilted/static-assets',
|
|
94
|
+
async load(id) {
|
|
95
|
+
if (id.startsWith('\0') || !assetMatcher.test(id)) {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const cached = assetCache.get(id);
|
|
100
|
+
|
|
101
|
+
if (cached) {
|
|
102
|
+
return cached;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const file = cleanModuleIdentifier(id);
|
|
106
|
+
const content = await readFile(file);
|
|
107
|
+
|
|
108
|
+
let url: string;
|
|
109
|
+
|
|
110
|
+
if (!file.endsWith('.svg') && content.length < inlineLimit) {
|
|
111
|
+
// base64 inlined as a string
|
|
112
|
+
url = `data:${mime.lookup(file)};base64,${content.toString('base64')}`;
|
|
113
|
+
} else {
|
|
114
|
+
const contentHash = getHash(content);
|
|
115
|
+
|
|
116
|
+
const filename = assetFileNamesToFileName(
|
|
117
|
+
outputPattern,
|
|
118
|
+
file,
|
|
119
|
+
contentHash,
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
url = `${
|
|
123
|
+
baseURL.endsWith('/') ? baseURL.slice(0, -1) : baseURL
|
|
124
|
+
}/${filename}`;
|
|
125
|
+
|
|
126
|
+
if (emit) {
|
|
127
|
+
this.emitFile({
|
|
128
|
+
name: file,
|
|
129
|
+
type: 'asset',
|
|
130
|
+
fileName: filename,
|
|
131
|
+
source: content,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const source = `export default ${JSON.stringify(url)};`;
|
|
137
|
+
|
|
138
|
+
assetCache.set(id, source);
|
|
139
|
+
|
|
140
|
+
return source;
|
|
141
|
+
},
|
|
142
|
+
} satisfies Plugin;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function assetFileNamesToFileName(
|
|
146
|
+
pattern: string,
|
|
147
|
+
file: string,
|
|
148
|
+
contentHash: string,
|
|
149
|
+
): string {
|
|
150
|
+
const basename = path.basename(file);
|
|
151
|
+
|
|
152
|
+
const extname = path.extname(basename);
|
|
153
|
+
const ext = extname.substring(1);
|
|
154
|
+
const name = basename.slice(0, -extname.length);
|
|
155
|
+
const hash = contentHash;
|
|
156
|
+
|
|
157
|
+
return pattern.replace(/\[\w+\]/g, (placeholder) => {
|
|
158
|
+
switch (placeholder) {
|
|
159
|
+
case '[ext]':
|
|
160
|
+
return ext;
|
|
161
|
+
|
|
162
|
+
case '[extname]':
|
|
163
|
+
return extname;
|
|
164
|
+
|
|
165
|
+
case '[hash]':
|
|
166
|
+
return hash;
|
|
167
|
+
|
|
168
|
+
case '[name]':
|
|
169
|
+
return name;
|
|
170
|
+
}
|
|
171
|
+
throw new Error(
|
|
172
|
+
`invalid placeholder ${placeholder} in assetFileNames "${pattern}"`,
|
|
173
|
+
);
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function getHash(text: Buffer | string): string {
|
|
178
|
+
return createHash('sha256').update(text).digest('hex').substring(0, 8);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function cleanModuleIdentifier(url: string) {
|
|
182
|
+
return url.replace(HASH_PATTERN, '').replace(QUERY_PATTERN, '');
|
|
183
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import type {Plugin} from 'rollup';
|
|
2
|
+
|
|
3
|
+
export interface Options {
|
|
4
|
+
minify?: boolean;
|
|
5
|
+
extract?: boolean;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const CSS_REGEX = /\.css$/;
|
|
9
|
+
const CSS_MODULE_REGEX = /\.module\.css$/;
|
|
10
|
+
|
|
11
|
+
export function cssRollupPlugin({minify = true, extract = true}: Options) {
|
|
12
|
+
const styles = new Map<string, string>();
|
|
13
|
+
|
|
14
|
+
return {
|
|
15
|
+
name: '@quilted/css',
|
|
16
|
+
async transform(code, id) {
|
|
17
|
+
if (!CSS_REGEX.test(id)) return;
|
|
18
|
+
|
|
19
|
+
const {transform} = await import('lightningcss');
|
|
20
|
+
|
|
21
|
+
const transformed = transform({
|
|
22
|
+
filename: id,
|
|
23
|
+
code: new TextEncoder().encode(code),
|
|
24
|
+
cssModules: CSS_MODULE_REGEX.test(id),
|
|
25
|
+
minify,
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
styles.set(id, new TextDecoder().decode(transformed.code));
|
|
29
|
+
|
|
30
|
+
const exports = transformed.exports
|
|
31
|
+
? Object.fromEntries(
|
|
32
|
+
Object.entries(transformed.exports).map(([key, exported]) => [
|
|
33
|
+
key,
|
|
34
|
+
exported.name,
|
|
35
|
+
]),
|
|
36
|
+
)
|
|
37
|
+
: undefined;
|
|
38
|
+
|
|
39
|
+
return {
|
|
40
|
+
code: exports
|
|
41
|
+
? `export default JSON.parse(${JSON.stringify(
|
|
42
|
+
JSON.stringify(exports),
|
|
43
|
+
)})`
|
|
44
|
+
: `export default undefined;`,
|
|
45
|
+
map: {mappings: ''},
|
|
46
|
+
moduleSideEffects: 'no-treeshake',
|
|
47
|
+
};
|
|
48
|
+
},
|
|
49
|
+
async renderChunk(_, chunk) {
|
|
50
|
+
if (!extract) return null;
|
|
51
|
+
|
|
52
|
+
let chunkCss = '';
|
|
53
|
+
|
|
54
|
+
for (const id of Object.keys(chunk.modules)) {
|
|
55
|
+
if (CSS_REGEX.test(id) && styles.has(id)) {
|
|
56
|
+
chunkCss += styles.get(id);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (chunkCss.length === 0) return null;
|
|
61
|
+
|
|
62
|
+
const code = chunkCss;
|
|
63
|
+
|
|
64
|
+
// if (minify) {
|
|
65
|
+
// const {default: CleanCSS} = await import('clean-css');
|
|
66
|
+
|
|
67
|
+
// const cleaner = new CleanCSS({
|
|
68
|
+
// rebase: false,
|
|
69
|
+
// });
|
|
70
|
+
|
|
71
|
+
// const minified = cleaner.minify(chunkCss);
|
|
72
|
+
|
|
73
|
+
// if (minified.errors.length > 0) {
|
|
74
|
+
// throw minified.errors[0];
|
|
75
|
+
// }
|
|
76
|
+
|
|
77
|
+
// code = minified.styles;
|
|
78
|
+
// }
|
|
79
|
+
|
|
80
|
+
const fileHandle = this.emitFile({
|
|
81
|
+
type: 'asset',
|
|
82
|
+
name: `${chunk.fileName.split('.')[0]}.css`,
|
|
83
|
+
source: code,
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
chunk.imports.push(this.getFileName(fileHandle));
|
|
87
|
+
|
|
88
|
+
return null;
|
|
89
|
+
},
|
|
90
|
+
} satisfies Plugin;
|
|
91
|
+
}
|
|
@@ -3,10 +3,10 @@ import * as fs from 'fs';
|
|
|
3
3
|
|
|
4
4
|
import type {PluginContext} from 'rollup';
|
|
5
5
|
|
|
6
|
-
import {MAGIC_MODULE_ENV} from '
|
|
7
|
-
import {multiline} from '
|
|
8
|
-
import {smartReplace} from '
|
|
9
|
-
import {createMagicModulePlugin} from '
|
|
6
|
+
import {MAGIC_MODULE_ENV} from '../constants.ts';
|
|
7
|
+
import {multiline} from '../shared/strings.ts';
|
|
8
|
+
import {smartReplace} from '../shared/rollup.ts';
|
|
9
|
+
import {createMagicModulePlugin} from '../shared/magic-module.ts';
|
|
10
10
|
|
|
11
11
|
const EMPTY_PROCESS_ENV_OBJECT = {
|
|
12
12
|
'globalThis.process.env.': `({}).`,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {MAGIC_MODULE_ENTRY, MAGIC_MODULE_REQUEST_ROUTER} from '
|
|
1
|
+
import {MAGIC_MODULE_ENTRY, MAGIC_MODULE_REQUEST_ROUTER} from '../constants.ts';
|
|
2
2
|
|
|
3
|
-
import {createMagicModulePlugin} from '
|
|
4
|
-
import {multiline} from '
|
|
3
|
+
import {createMagicModulePlugin} from '../shared/magic-module.ts';
|
|
4
|
+
import {multiline} from '../shared/strings.ts';
|
|
5
5
|
|
|
6
6
|
export function magicModuleRequestRouterEntry({
|
|
7
7
|
host,
|