@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.
- package/CHANGELOG.md +19 -0
- package/build/esm/app.mjs +443 -219
- package/build/esm/constants.mjs +5 -5
- package/build/esm/features/assets.mjs +93 -81
- package/build/esm/features/async.mjs +186 -0
- package/build/esm/features/css.mjs +26 -39
- package/build/esm/features/env.mjs +47 -44
- package/build/esm/features/esnext.mjs +57 -0
- package/build/esm/features/graphql/transform.mjs +60 -56
- package/build/esm/features/graphql.mjs +65 -47
- package/build/esm/features/request-router.mjs +6 -4
- package/build/esm/features/source-code.mjs +54 -28
- package/build/esm/features/system-js.mjs +13 -18
- package/build/esm/features/typescript.mjs +13 -10
- package/build/esm/features/workers.mjs +173 -0
- package/build/esm/index.mjs +3 -2
- package/build/esm/module.mjs +69 -62
- package/build/esm/package.mjs +275 -84
- package/build/esm/server.mjs +118 -0
- package/build/esm/shared/browserslist.mjs +141 -16
- package/build/esm/shared/magic-module.mjs +9 -7
- package/build/esm/shared/package-json.mjs +7 -1
- package/build/esm/shared/path.mjs +7 -0
- package/build/esm/shared/rollup.mjs +89 -25
- package/build/esm/shared/strings.mjs +7 -6
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/typescript/app.d.ts +126 -27
- package/build/typescript/app.d.ts.map +1 -1
- package/build/typescript/features/assets.d.ts +1 -2
- package/build/typescript/features/assets.d.ts.map +1 -1
- package/build/typescript/features/async.d.ts +10 -0
- package/build/typescript/features/async.d.ts.map +1 -0
- package/build/typescript/features/css.d.ts +2 -1
- package/build/typescript/features/css.d.ts.map +1 -1
- package/build/typescript/features/env.d.ts +1 -0
- package/build/typescript/features/env.d.ts.map +1 -1
- package/build/typescript/features/esnext.d.ts +9 -0
- package/build/typescript/features/esnext.d.ts.map +1 -0
- package/build/typescript/features/graphql.d.ts +2 -2
- package/build/typescript/features/graphql.d.ts.map +1 -1
- package/build/typescript/features/source-code.d.ts +9 -3
- package/build/typescript/features/source-code.d.ts.map +1 -1
- package/build/typescript/features/workers.d.ts +52 -0
- package/build/typescript/features/workers.d.ts.map +1 -0
- package/build/typescript/index.d.ts +3 -2
- package/build/typescript/index.d.ts.map +1 -1
- package/build/typescript/module.d.ts +24 -6
- package/build/typescript/module.d.ts.map +1 -1
- package/build/typescript/package.d.ts +196 -4
- package/build/typescript/package.d.ts.map +1 -1
- package/build/typescript/server.d.ts +98 -0
- package/build/typescript/server.d.ts.map +1 -0
- package/build/typescript/shared/browserslist.d.ts +20 -3
- package/build/typescript/shared/browserslist.d.ts.map +1 -1
- package/build/typescript/shared/path.d.ts +2 -0
- package/build/typescript/shared/path.d.ts.map +1 -0
- package/build/typescript/shared/rollup.d.ts +27 -1
- package/build/typescript/shared/rollup.d.ts.map +1 -1
- package/configuration/rollup.config.js +40 -0
- package/package.json +61 -8
- package/source/app.ts +466 -96
- package/source/features/assets.ts +5 -7
- package/source/features/async.ts +249 -0
- package/source/features/css.ts +4 -2
- package/source/features/env.ts +6 -0
- package/source/features/esnext.ts +70 -0
- package/source/features/graphql.ts +4 -2
- package/source/features/source-code.ts +26 -8
- package/source/features/workers.ts +292 -0
- package/source/index.ts +4 -0
- package/source/module.ts +45 -19
- package/source/package.ts +394 -36
- package/source/server.ts +245 -0
- package/source/shared/browserslist.ts +208 -18
- package/source/shared/path.ts +5 -0
- package/source/shared/rollup.ts +102 -4
- package/tsconfig.json +6 -2
- package/build/cjs/app.cjs +0 -441
- package/build/cjs/constants.cjs +0 -13
- package/build/cjs/features/assets.cjs +0 -240
- package/build/cjs/features/css.cjs +0 -71
- package/build/cjs/features/env.cjs +0 -135
- package/build/cjs/features/graphql/transform.cjs +0 -186
- package/build/cjs/features/graphql.cjs +0 -86
- package/build/cjs/features/request-router.cjs +0 -31
- package/build/cjs/features/source-code.cjs +0 -54
- package/build/cjs/features/system-js.cjs +0 -36
- package/build/cjs/features/typescript.cjs +0 -56
- package/build/cjs/index.cjs +0 -13
- package/build/cjs/module.cjs +0 -121
- package/build/cjs/package.cjs +0 -170
- package/build/cjs/shared/browserslist.cjs +0 -25
- package/build/cjs/shared/magic-module.cjs +0 -32
- package/build/cjs/shared/package-json.cjs +0 -31
- package/build/cjs/shared/rollup.cjs +0 -72
- package/build/cjs/shared/strings.cjs +0 -16
- package/build/esnext/app.esnext +0 -414
- package/build/esnext/constants.esnext +0 -7
- package/build/esnext/features/assets.esnext +0 -215
- package/build/esnext/features/css.esnext +0 -69
- package/build/esnext/features/env.esnext +0 -112
- package/build/esnext/features/graphql/transform.esnext +0 -181
- package/build/esnext/features/graphql.esnext +0 -84
- package/build/esnext/features/request-router.esnext +0 -29
- package/build/esnext/features/source-code.esnext +0 -51
- package/build/esnext/features/system-js.esnext +0 -33
- package/build/esnext/features/typescript.esnext +0 -34
- package/build/esnext/index.esnext +0 -3
- package/build/esnext/module.esnext +0 -100
- package/build/esnext/package.esnext +0 -148
- package/build/esnext/shared/browserslist.esnext +0 -23
- package/build/esnext/shared/magic-module.esnext +0 -30
- package/build/esnext/shared/package-json.esnext +0 -10
- package/build/esnext/shared/rollup.esnext +0 -49
- package/build/esnext/shared/strings.esnext +0 -14
- package/build/typescript/env.d.ts +0 -55
- package/build/typescript/env.d.ts.map +0 -1
- package/build/typescript/graphql/transform.d.ts +0 -17
- package/build/typescript/graphql/transform.d.ts.map +0 -1
- package/build/typescript/graphql.d.ts +0 -6
- package/build/typescript/graphql.d.ts.map +0 -1
- package/build/typescript/request-router.d.ts +0 -15
- package/build/typescript/request-router.d.ts.map +0 -1
- package/build/typescript/shared/source-code.d.ts +0 -5
- package/build/typescript/shared/source-code.d.ts.map +0 -1
- package/quilt.project.ts +0 -5
package/build/esm/constants.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
const MAGIC_MODULE_ENV =
|
|
2
|
-
const MAGIC_MODULE_ENTRY =
|
|
3
|
-
const MAGIC_MODULE_APP_COMPONENT =
|
|
4
|
-
const MAGIC_MODULE_BROWSER_ASSETS =
|
|
5
|
-
const MAGIC_MODULE_REQUEST_ROUTER =
|
|
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
6
|
|
|
7
7
|
export { MAGIC_MODULE_APP_COMPONENT, MAGIC_MODULE_BROWSER_ASSETS, MAGIC_MODULE_ENTRY, MAGIC_MODULE_ENV, MAGIC_MODULE_REQUEST_ROUTER };
|
|
@@ -5,57 +5,43 @@ import * as mime from 'mrmime';
|
|
|
5
5
|
|
|
6
6
|
function assetManifest(manifestOptions) {
|
|
7
7
|
return {
|
|
8
|
-
name:
|
|
8
|
+
name: "@quilted/asset-manifest",
|
|
9
9
|
async generateBundle(options, bundle) {
|
|
10
10
|
await writeManifestForBundle.call(this, bundle, manifestOptions, options);
|
|
11
11
|
}
|
|
12
12
|
};
|
|
13
13
|
}
|
|
14
|
-
async function writeManifestForBundle(bundle, {
|
|
15
|
-
id,
|
|
16
|
-
file,
|
|
17
|
-
baseURL,
|
|
18
|
-
cacheKey,
|
|
19
|
-
priority
|
|
20
|
-
}, {
|
|
21
|
-
format
|
|
22
|
-
}) {
|
|
14
|
+
async function writeManifestForBundle(bundle, { file, baseURL, cacheKey, priority }, { format }) {
|
|
23
15
|
const outputs = Object.values(bundle);
|
|
24
|
-
const entries = outputs.filter(
|
|
16
|
+
const entries = outputs.filter(
|
|
17
|
+
(output) => output.type === "chunk" && output.isEntry
|
|
18
|
+
);
|
|
25
19
|
if (entries.length === 0) {
|
|
26
20
|
throw new Error(`Could not find any entries in your rollup bundle...`);
|
|
27
21
|
}
|
|
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
22
|
const entryChunk = entries[0];
|
|
33
|
-
const dependencyMap = new Map();
|
|
23
|
+
const dependencyMap = /* @__PURE__ */ new Map();
|
|
34
24
|
for (const output of outputs) {
|
|
35
|
-
if (output.type !==
|
|
25
|
+
if (output.type !== "chunk")
|
|
26
|
+
continue;
|
|
36
27
|
dependencyMap.set(output.fileName, output.imports);
|
|
37
28
|
}
|
|
38
29
|
const assets = [];
|
|
39
|
-
const assetIdMap = new Map();
|
|
40
|
-
function getAssetId(
|
|
41
|
-
let id = assetIdMap.get(
|
|
30
|
+
const assetIdMap = /* @__PURE__ */ new Map();
|
|
31
|
+
function getAssetId(file2) {
|
|
32
|
+
let id = assetIdMap.get(file2);
|
|
42
33
|
if (id == null) {
|
|
43
|
-
assets.push(`${baseURL}${
|
|
34
|
+
assets.push(`${baseURL}${file2}`);
|
|
44
35
|
id = assets.length - 1;
|
|
45
|
-
assetIdMap.set(
|
|
36
|
+
assetIdMap.set(file2, id);
|
|
46
37
|
}
|
|
47
38
|
return id;
|
|
48
39
|
}
|
|
49
40
|
const manifest = {
|
|
50
|
-
id,
|
|
51
41
|
priority,
|
|
52
|
-
cacheKey,
|
|
42
|
+
cacheKey: cacheKey && cacheKey.size > 0 ? cacheKey.toString() : void 0,
|
|
53
43
|
assets,
|
|
54
|
-
attributes: format ===
|
|
55
|
-
scripts: {
|
|
56
|
-
type: 'module'
|
|
57
|
-
}
|
|
58
|
-
} : undefined,
|
|
44
|
+
attributes: format === "es" ? { scripts: { type: "module" } } : void 0,
|
|
59
45
|
entries: {
|
|
60
46
|
default: createAssetsEntry([...entryChunk.imports, entryChunk.fileName], {
|
|
61
47
|
dependencyMap,
|
|
@@ -65,21 +51,20 @@ async function writeManifestForBundle(bundle, {
|
|
|
65
51
|
modules: {}
|
|
66
52
|
};
|
|
67
53
|
for (const output of outputs) {
|
|
68
|
-
if (output.type !==
|
|
54
|
+
if (output.type !== "chunk")
|
|
55
|
+
continue;
|
|
69
56
|
const originalModuleId = output.facadeModuleId ?? output.moduleIds[output.moduleIds.length - 1];
|
|
70
|
-
if (originalModuleId == null)
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
manifest.modules[moduleId] = createAssetsEntry(
|
|
76
|
-
|
|
77
|
-
getAssetId
|
|
78
|
-
|
|
57
|
+
if (originalModuleId == null)
|
|
58
|
+
continue;
|
|
59
|
+
const moduleId = this.getModuleInfo(originalModuleId)?.meta.quilt?.moduleID;
|
|
60
|
+
if (moduleId == null)
|
|
61
|
+
continue;
|
|
62
|
+
manifest.modules[moduleId] = createAssetsEntry(
|
|
63
|
+
[...output.imports, output.fileName],
|
|
64
|
+
{ dependencyMap, getAssetId }
|
|
65
|
+
);
|
|
79
66
|
}
|
|
80
|
-
await fs.mkdir(path.dirname(file), {
|
|
81
|
-
recursive: true
|
|
82
|
-
});
|
|
67
|
+
await fs.mkdir(path.dirname(file), { recursive: true });
|
|
83
68
|
await fs.writeFile(file, JSON.stringify(manifest, null, 2));
|
|
84
69
|
}
|
|
85
70
|
function createAssetsEntry(files, {
|
|
@@ -88,9 +73,10 @@ function createAssetsEntry(files, {
|
|
|
88
73
|
}) {
|
|
89
74
|
const styles = [];
|
|
90
75
|
const scripts = [];
|
|
91
|
-
const allFiles = new Set();
|
|
92
|
-
const addFile = file => {
|
|
93
|
-
if (allFiles.has(file))
|
|
76
|
+
const allFiles = /* @__PURE__ */ new Set();
|
|
77
|
+
const addFile = (file) => {
|
|
78
|
+
if (allFiles.has(file))
|
|
79
|
+
return;
|
|
94
80
|
allFiles.add(file);
|
|
95
81
|
for (const dependency of dependencyMap.get(file) ?? []) {
|
|
96
82
|
addFile(dependency);
|
|
@@ -100,42 +86,59 @@ function createAssetsEntry(files, {
|
|
|
100
86
|
addFile(file);
|
|
101
87
|
}
|
|
102
88
|
for (const file of allFiles) {
|
|
103
|
-
if (file.endsWith(
|
|
89
|
+
if (file.endsWith(".css")) {
|
|
104
90
|
styles.push(getAssetId(file));
|
|
105
91
|
} else {
|
|
106
92
|
scripts.push(getAssetId(file));
|
|
107
93
|
}
|
|
108
94
|
}
|
|
109
|
-
return {
|
|
110
|
-
scripts,
|
|
111
|
-
styles
|
|
112
|
-
};
|
|
95
|
+
return { scripts, styles };
|
|
113
96
|
}
|
|
114
97
|
const QUERY_PATTERN = /\?.*$/s;
|
|
115
98
|
const HASH_PATTERN = /#.*$/s;
|
|
116
99
|
const RAW_PATTERN = /(\?|&)raw(?:&|$)/;
|
|
117
100
|
const DEFAULT_INLINE_LIMIT = 4096;
|
|
118
|
-
const DEFAULT_OUTPUT_PATTERN =
|
|
101
|
+
const DEFAULT_OUTPUT_PATTERN = "[name].[hash].[ext]";
|
|
119
102
|
const DEFAULT_STATIC_ASSET_EXTENSIONS = [
|
|
120
|
-
// images
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
103
|
+
// images
|
|
104
|
+
".png",
|
|
105
|
+
".jpg",
|
|
106
|
+
".jpeg",
|
|
107
|
+
".gif",
|
|
108
|
+
".svg",
|
|
109
|
+
".ico",
|
|
110
|
+
".webp",
|
|
111
|
+
".avif",
|
|
112
|
+
// media
|
|
113
|
+
".mp4",
|
|
114
|
+
".webm",
|
|
115
|
+
".ogg",
|
|
116
|
+
".mp3",
|
|
117
|
+
".wav",
|
|
118
|
+
".flac",
|
|
119
|
+
".aac",
|
|
120
|
+
// fonts
|
|
121
|
+
".woff",
|
|
122
|
+
".woff2",
|
|
123
|
+
".eot",
|
|
124
|
+
".ttf",
|
|
125
|
+
".otf",
|
|
126
|
+
// other
|
|
127
|
+
".webmanifest",
|
|
128
|
+
".pdf",
|
|
129
|
+
".txt"
|
|
130
|
+
];
|
|
128
131
|
function rawAssets() {
|
|
129
132
|
return {
|
|
130
|
-
name:
|
|
133
|
+
name: "@quilted/raw-assets",
|
|
131
134
|
async load(id) {
|
|
132
|
-
if (id.startsWith(
|
|
135
|
+
if (id.startsWith("\0") || !RAW_PATTERN.test(id)) {
|
|
133
136
|
return null;
|
|
134
137
|
}
|
|
135
138
|
const moduleId = cleanModuleIdentifier(id);
|
|
136
139
|
this.addWatchFile(moduleId);
|
|
137
140
|
const file = await fs.readFile(moduleId, {
|
|
138
|
-
encoding:
|
|
141
|
+
encoding: "utf-8"
|
|
139
142
|
});
|
|
140
143
|
return `export default ${JSON.stringify(file)}`;
|
|
141
144
|
}
|
|
@@ -143,17 +146,21 @@ function rawAssets() {
|
|
|
143
146
|
}
|
|
144
147
|
function staticAssets({
|
|
145
148
|
emit = true,
|
|
146
|
-
baseURL =
|
|
149
|
+
baseURL = "/",
|
|
147
150
|
extensions = DEFAULT_STATIC_ASSET_EXTENSIONS,
|
|
148
151
|
inlineLimit = DEFAULT_INLINE_LIMIT,
|
|
149
152
|
outputPattern = DEFAULT_OUTPUT_PATTERN
|
|
150
153
|
} = {}) {
|
|
151
|
-
const assetCache = new Map();
|
|
152
|
-
const assetMatcher = new RegExp(
|
|
154
|
+
const assetCache = /* @__PURE__ */ new Map();
|
|
155
|
+
const assetMatcher = new RegExp(
|
|
156
|
+
`\\.(` + extensions.map(
|
|
157
|
+
(extension) => extension.startsWith(".") ? extension.slice(1) : extension
|
|
158
|
+
).join("|") + `)(\\?.*)?$`
|
|
159
|
+
);
|
|
153
160
|
return {
|
|
154
|
-
name:
|
|
161
|
+
name: "@quilted/static-assets",
|
|
155
162
|
async load(id) {
|
|
156
|
-
if (id.startsWith(
|
|
163
|
+
if (id.startsWith("\0") || !assetMatcher.test(id)) {
|
|
157
164
|
return null;
|
|
158
165
|
}
|
|
159
166
|
const cached = assetCache.get(id);
|
|
@@ -163,17 +170,20 @@ function staticAssets({
|
|
|
163
170
|
const file = cleanModuleIdentifier(id);
|
|
164
171
|
const content = await fs.readFile(file);
|
|
165
172
|
let url;
|
|
166
|
-
if (!file.endsWith(
|
|
167
|
-
|
|
168
|
-
url = `data:${mime.lookup(file)};base64,${content.toString('base64')}`;
|
|
173
|
+
if (!file.endsWith(".svg") && content.length < inlineLimit) {
|
|
174
|
+
url = `data:${mime.lookup(file)};base64,${content.toString("base64")}`;
|
|
169
175
|
} else {
|
|
170
176
|
const contentHash = getHash(content);
|
|
171
|
-
const filename = assetFileNamesToFileName(
|
|
172
|
-
|
|
177
|
+
const filename = assetFileNamesToFileName(
|
|
178
|
+
outputPattern,
|
|
179
|
+
file,
|
|
180
|
+
contentHash
|
|
181
|
+
);
|
|
182
|
+
url = `${baseURL.endsWith("/") ? baseURL.slice(0, -1) : baseURL}/${filename}`;
|
|
173
183
|
if (emit) {
|
|
174
184
|
this.emitFile({
|
|
175
185
|
name: file,
|
|
176
|
-
type:
|
|
186
|
+
type: "asset",
|
|
177
187
|
fileName: filename,
|
|
178
188
|
source: content
|
|
179
189
|
});
|
|
@@ -191,25 +201,27 @@ function assetFileNamesToFileName(pattern, file, contentHash) {
|
|
|
191
201
|
const ext = extname.substring(1);
|
|
192
202
|
const name = basename.slice(0, -extname.length);
|
|
193
203
|
const hash = contentHash;
|
|
194
|
-
return pattern.replace(/\[\w+\]/g, placeholder => {
|
|
204
|
+
return pattern.replace(/\[\w+\]/g, (placeholder) => {
|
|
195
205
|
switch (placeholder) {
|
|
196
|
-
case
|
|
206
|
+
case "[ext]":
|
|
197
207
|
return ext;
|
|
198
|
-
case
|
|
208
|
+
case "[extname]":
|
|
199
209
|
return extname;
|
|
200
|
-
case
|
|
210
|
+
case "[hash]":
|
|
201
211
|
return hash;
|
|
202
|
-
case
|
|
212
|
+
case "[name]":
|
|
203
213
|
return name;
|
|
204
214
|
}
|
|
205
|
-
throw new Error(
|
|
215
|
+
throw new Error(
|
|
216
|
+
`invalid placeholder ${placeholder} in assetFileNames "${pattern}"`
|
|
217
|
+
);
|
|
206
218
|
});
|
|
207
219
|
}
|
|
208
220
|
function getHash(text) {
|
|
209
|
-
return createHash(
|
|
221
|
+
return createHash("sha256").update(text).digest("hex").substring(0, 8);
|
|
210
222
|
}
|
|
211
223
|
function cleanModuleIdentifier(url) {
|
|
212
|
-
return url.replace(HASH_PATTERN,
|
|
224
|
+
return url.replace(HASH_PATTERN, "").replace(QUERY_PATTERN, "");
|
|
213
225
|
}
|
|
214
226
|
|
|
215
227
|
export { assetManifest, rawAssets, staticAssets };
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { sep, posix } from 'node:path';
|
|
3
|
+
import { multiline } from '../shared/strings.mjs';
|
|
4
|
+
import MagicString from 'magic-string';
|
|
5
|
+
|
|
6
|
+
const MODULE_PREFIX = "quilt-async-module:";
|
|
7
|
+
const IMPORT_PREFIX = "quilt-async-import:";
|
|
8
|
+
function asyncModules({
|
|
9
|
+
preload = true,
|
|
10
|
+
baseURL = "/assets/",
|
|
11
|
+
moduleID: getModuleID = defaultModuleID
|
|
12
|
+
} = {}) {
|
|
13
|
+
return {
|
|
14
|
+
name: "@quilted/async",
|
|
15
|
+
async resolveId(id, importer) {
|
|
16
|
+
if (id.startsWith(IMPORT_PREFIX))
|
|
17
|
+
return `\0${id}`;
|
|
18
|
+
if (!id.startsWith(MODULE_PREFIX))
|
|
19
|
+
return null;
|
|
20
|
+
const imported = id.replace(MODULE_PREFIX, "");
|
|
21
|
+
const resolved = await this.resolve(imported, importer, {
|
|
22
|
+
skipSelf: true
|
|
23
|
+
});
|
|
24
|
+
if (resolved == null)
|
|
25
|
+
return null;
|
|
26
|
+
return `\0${MODULE_PREFIX}${resolved.id}`;
|
|
27
|
+
},
|
|
28
|
+
resolveDynamicImport(specifier) {
|
|
29
|
+
if (typeof specifier === "string" && specifier.startsWith(IMPORT_PREFIX)) {
|
|
30
|
+
return `\0${specifier}`;
|
|
31
|
+
}
|
|
32
|
+
return null;
|
|
33
|
+
},
|
|
34
|
+
async load(id) {
|
|
35
|
+
if (id.startsWith(`\0${MODULE_PREFIX}`)) {
|
|
36
|
+
const imported = id.replace(`\0${MODULE_PREFIX}`, "");
|
|
37
|
+
const moduleID = getModuleID({ imported });
|
|
38
|
+
const code = multiline`
|
|
39
|
+
const id = ${JSON.stringify(moduleID)};
|
|
40
|
+
|
|
41
|
+
export default function createAsyncModule(load) {
|
|
42
|
+
return {
|
|
43
|
+
id,
|
|
44
|
+
import: () => import(${JSON.stringify(
|
|
45
|
+
`${IMPORT_PREFIX}${imported}`
|
|
46
|
+
)}).then((module) => module.default),
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
`;
|
|
50
|
+
return code;
|
|
51
|
+
}
|
|
52
|
+
if (id.startsWith(`\0${IMPORT_PREFIX}`)) {
|
|
53
|
+
const imported = id.replace(`\0${IMPORT_PREFIX}`, "");
|
|
54
|
+
const moduleID = getModuleID({ imported });
|
|
55
|
+
const code = multiline`
|
|
56
|
+
import * as AsyncModule from ${JSON.stringify(imported)};
|
|
57
|
+
|
|
58
|
+
((globalThis[Symbol.for('quilt')] ??= {}).AsyncModules ??= new Map).set(${JSON.stringify(
|
|
59
|
+
moduleID
|
|
60
|
+
)}, AsyncModule);
|
|
61
|
+
|
|
62
|
+
export default AsyncModule;
|
|
63
|
+
`;
|
|
64
|
+
return {
|
|
65
|
+
code,
|
|
66
|
+
meta: {
|
|
67
|
+
quilt: { moduleID }
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
return null;
|
|
72
|
+
},
|
|
73
|
+
transform: baseURL ? (code) => code.replace(/__QUILT_ASSETS_BASE_URL__/g, JSON.stringify(baseURL)) : void 0,
|
|
74
|
+
async generateBundle(options, bundle) {
|
|
75
|
+
if (preload) {
|
|
76
|
+
switch (options.format) {
|
|
77
|
+
case "es": {
|
|
78
|
+
await preloadAsyncAssetsInESMBundle(bundle);
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
case "system": {
|
|
82
|
+
await preloadAsyncAssetsInSystemJSBundle(bundle);
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
function defaultModuleID({ imported }) {
|
|
91
|
+
const name = imported.split(sep).pop().split(".")[0];
|
|
92
|
+
const hash = createHash("sha256").update(imported).digest("hex").substring(0, 8);
|
|
93
|
+
return `${name}_${hash}`;
|
|
94
|
+
}
|
|
95
|
+
async function preloadAsyncAssetsInESMBundle(bundle) {
|
|
96
|
+
const { parse: parseImports } = await import('es-module-lexer');
|
|
97
|
+
for (const chunk of Object.values(bundle)) {
|
|
98
|
+
if (chunk.type !== "chunk")
|
|
99
|
+
continue;
|
|
100
|
+
if (chunk.dynamicImports.length === 0)
|
|
101
|
+
continue;
|
|
102
|
+
const { code } = chunk;
|
|
103
|
+
const newCode = new MagicString(code);
|
|
104
|
+
const imports = (await parseImports(code))[0];
|
|
105
|
+
for (const imported of imports) {
|
|
106
|
+
const { s: start, e: end, ss: importStart, d: dynamicStart } = imported;
|
|
107
|
+
if (dynamicStart < 0)
|
|
108
|
+
continue;
|
|
109
|
+
const importSource = code.slice(start + 1, end - 1);
|
|
110
|
+
const dependencies = getDependenciesForImport(
|
|
111
|
+
importSource,
|
|
112
|
+
chunk,
|
|
113
|
+
bundle
|
|
114
|
+
);
|
|
115
|
+
if (dependencies.size === 1)
|
|
116
|
+
continue;
|
|
117
|
+
const originalImport = code.slice(importStart, end + 1);
|
|
118
|
+
newCode.overwrite(
|
|
119
|
+
importStart,
|
|
120
|
+
end + 1,
|
|
121
|
+
preloadContentForDependencies(dependencies, originalImport)
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
chunk.code = newCode.toString();
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
async function preloadAsyncAssetsInSystemJSBundle(bundle) {
|
|
128
|
+
for (const chunk of Object.values(bundle)) {
|
|
129
|
+
if (chunk.type !== "chunk")
|
|
130
|
+
continue;
|
|
131
|
+
if (chunk.dynamicImports.length === 0)
|
|
132
|
+
continue;
|
|
133
|
+
const { code } = chunk;
|
|
134
|
+
const newCode = new MagicString(code);
|
|
135
|
+
const systemDynamicImportRegex = /\bmodule\.import\(([^)]*)\)/g;
|
|
136
|
+
let match;
|
|
137
|
+
while (match = systemDynamicImportRegex.exec(code)) {
|
|
138
|
+
const [originalImport, imported] = match;
|
|
139
|
+
const importSource = imported.trim().slice(1, imported.length - 1);
|
|
140
|
+
const dependencies = getDependenciesForImport(
|
|
141
|
+
importSource,
|
|
142
|
+
chunk,
|
|
143
|
+
bundle
|
|
144
|
+
);
|
|
145
|
+
if (dependencies.size === 1)
|
|
146
|
+
continue;
|
|
147
|
+
newCode.overwrite(
|
|
148
|
+
match.index,
|
|
149
|
+
match.index + originalImport.length,
|
|
150
|
+
preloadContentForDependencies(dependencies, originalImport)
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
chunk.code = newCode.toString();
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
function preloadContentForDependencies(dependencies, originalExpression) {
|
|
157
|
+
return `Promise.resolve().then(() => globalThis[Symbol.for('quilt')]?.AsyncModules?.preload?.(${Array.from(
|
|
158
|
+
dependencies
|
|
159
|
+
).map((dependency) => JSON.stringify(dependency)).join(",")})).then(function(){return ${originalExpression}})`;
|
|
160
|
+
}
|
|
161
|
+
function getDependenciesForImport(imported, chunk, bundle) {
|
|
162
|
+
const originalFilename = chunk.fileName;
|
|
163
|
+
const dependencies = /* @__PURE__ */ new Set();
|
|
164
|
+
const analyzed = /* @__PURE__ */ new Set();
|
|
165
|
+
const normalizedFile = posix.join(posix.dirname(originalFilename), imported);
|
|
166
|
+
const addDependencies = (filename) => {
|
|
167
|
+
if (filename === originalFilename)
|
|
168
|
+
return;
|
|
169
|
+
if (analyzed.has(filename))
|
|
170
|
+
return;
|
|
171
|
+
analyzed.add(filename);
|
|
172
|
+
const chunk2 = bundle[filename];
|
|
173
|
+
if (chunk2 == null)
|
|
174
|
+
return;
|
|
175
|
+
dependencies.add(chunk2.fileName);
|
|
176
|
+
if (chunk2.type !== "chunk")
|
|
177
|
+
return;
|
|
178
|
+
for (const imported2 of chunk2.imports) {
|
|
179
|
+
addDependencies(imported2);
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
addDependencies(normalizedFile);
|
|
183
|
+
return dependencies;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export { asyncModules };
|
|
@@ -1,63 +1,50 @@
|
|
|
1
1
|
const CSS_REGEX = /\.css$/;
|
|
2
2
|
const CSS_MODULE_REGEX = /\.module\.css$/;
|
|
3
|
-
function css({
|
|
4
|
-
|
|
5
|
-
emit = true
|
|
6
|
-
}) {
|
|
7
|
-
const styles = new Map();
|
|
3
|
+
function css({ minify = true, emit = true, targets }) {
|
|
4
|
+
const styles = /* @__PURE__ */ new Map();
|
|
8
5
|
return {
|
|
9
|
-
name:
|
|
6
|
+
name: "@quilted/css",
|
|
10
7
|
async transform(code, id) {
|
|
11
|
-
if (!CSS_REGEX.test(id))
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
} = await import('lightningcss');
|
|
8
|
+
if (!CSS_REGEX.test(id))
|
|
9
|
+
return;
|
|
10
|
+
const { transform, browserslistToTargets } = await import('lightningcss');
|
|
15
11
|
const transformed = transform({
|
|
16
12
|
filename: id,
|
|
17
13
|
code: new TextEncoder().encode(code),
|
|
18
14
|
cssModules: CSS_MODULE_REGEX.test(id),
|
|
19
|
-
minify: emit && minify
|
|
15
|
+
minify: emit && minify,
|
|
16
|
+
targets: targets ? browserslistToTargets(targets) : void 0
|
|
20
17
|
});
|
|
21
18
|
styles.set(id, new TextDecoder().decode(transformed.code));
|
|
22
|
-
const exports = transformed.exports ? Object.fromEntries(
|
|
19
|
+
const exports = transformed.exports ? Object.fromEntries(
|
|
20
|
+
Object.entries(transformed.exports).map(([key, exported]) => [
|
|
21
|
+
key,
|
|
22
|
+
exported.name
|
|
23
|
+
])
|
|
24
|
+
) : void 0;
|
|
23
25
|
return {
|
|
24
|
-
code: exports ? `export default JSON.parse(${JSON.stringify(
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
},
|
|
28
|
-
moduleSideEffects:
|
|
26
|
+
code: exports ? `export default JSON.parse(${JSON.stringify(
|
|
27
|
+
JSON.stringify(exports)
|
|
28
|
+
)})` : `export default undefined;`,
|
|
29
|
+
map: { mappings: "" },
|
|
30
|
+
moduleSideEffects: "no-treeshake"
|
|
29
31
|
};
|
|
30
32
|
},
|
|
31
33
|
async renderChunk(_, chunk) {
|
|
32
|
-
if (!emit)
|
|
33
|
-
|
|
34
|
+
if (!emit)
|
|
35
|
+
return null;
|
|
36
|
+
let chunkCss = "";
|
|
34
37
|
for (const id of Object.keys(chunk.modules)) {
|
|
35
38
|
if (CSS_REGEX.test(id) && styles.has(id)) {
|
|
36
39
|
chunkCss += styles.get(id);
|
|
37
40
|
}
|
|
38
41
|
}
|
|
39
|
-
if (chunkCss.length === 0)
|
|
42
|
+
if (chunkCss.length === 0)
|
|
43
|
+
return null;
|
|
40
44
|
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
45
|
const fileHandle = this.emitFile({
|
|
59
|
-
type:
|
|
60
|
-
name: `${chunk.fileName.split(
|
|
46
|
+
type: "asset",
|
|
47
|
+
name: `${chunk.fileName.split(".")[0]}.css`,
|
|
61
48
|
source: code
|
|
62
49
|
});
|
|
63
50
|
chunk.imports.push(this.getFileName(fileHandle));
|