@remix-run/assets 0.4.4 → 0.5.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/README.md +322 -56
- package/dist/assets.d.ts +2 -1
- package/dist/assets.d.ts.map +1 -1
- package/dist/assets.js +2 -2
- package/dist/lib/access.d.ts +6 -2
- package/dist/lib/access.d.ts.map +1 -1
- package/dist/lib/access.js +300 -5
- package/dist/lib/asset-server.d.ts +118 -5
- package/dist/lib/asset-server.d.ts.map +1 -1
- package/dist/lib/asset-server.js +260 -24
- package/dist/lib/compilation-error.d.ts +1 -1
- package/dist/lib/compilation-error.d.ts.map +1 -1
- package/dist/lib/file-matcher.js +1 -1
- package/dist/lib/files/compiler.d.ts.map +1 -1
- package/dist/lib/files/compiler.js +7 -6
- package/dist/lib/files/config.js +1 -1
- package/dist/lib/hmr.d.ts +37 -0
- package/dist/lib/hmr.d.ts.map +1 -0
- package/dist/lib/hmr.js +357 -0
- package/dist/lib/injected-packages.d.ts.map +1 -1
- package/dist/lib/injected-packages.js +36 -13
- package/dist/lib/loaders.d.ts +57 -0
- package/dist/lib/loaders.d.ts.map +1 -0
- package/dist/lib/loaders.js +1 -0
- package/dist/lib/module-store.d.ts +24 -0
- package/dist/lib/module-store.d.ts.map +1 -1
- package/dist/lib/module-store.js +136 -11
- package/dist/lib/routes.js +1 -1
- package/dist/lib/scripts/compiler.d.ts +24 -1
- package/dist/lib/scripts/compiler.d.ts.map +1 -1
- package/dist/lib/scripts/compiler.js +183 -29
- package/dist/lib/scripts/conditions.d.ts +2 -0
- package/dist/lib/scripts/conditions.d.ts.map +1 -0
- package/dist/lib/scripts/conditions.js +1 -0
- package/dist/lib/scripts/emit.d.ts +3 -0
- package/dist/lib/scripts/emit.d.ts.map +1 -1
- package/dist/lib/scripts/emit.js +24 -5
- package/dist/lib/scripts/resolve.d.ts +4 -0
- package/dist/lib/scripts/resolve.d.ts.map +1 -1
- package/dist/lib/scripts/resolve.js +70 -5
- package/dist/lib/scripts/transform.d.ts +9 -0
- package/dist/lib/scripts/transform.d.ts.map +1 -1
- package/dist/lib/scripts/transform.js +222 -18
- package/dist/lib/source-maps.js +1 -1
- package/dist/lib/styles/compiler.d.ts +14 -1
- package/dist/lib/styles/compiler.d.ts.map +1 -1
- package/dist/lib/styles/compiler.js +78 -14
- package/dist/lib/styles/emit.js +4 -4
- package/dist/lib/styles/resolve.d.ts.map +1 -1
- package/dist/lib/styles/resolve.js +8 -7
- package/dist/lib/styles/transform.js +3 -3
- package/dist/lib/target.d.ts +1 -1
- package/dist/lib/target.d.ts.map +1 -1
- package/dist/lib/watch.js +1 -1
- package/dist/types/hmr.d.ts +36 -0
- package/package.json +17 -11
- package/src/assets.ts +2 -1
- package/src/lib/access.ts +386 -5
- package/src/lib/asset-server.ts +429 -18
- package/src/lib/compilation-error.ts +1 -0
- package/src/lib/files/compiler.ts +7 -3
- package/src/lib/hmr.ts +397 -0
- package/src/lib/injected-packages.ts +41 -11
- package/src/lib/loaders.ts +80 -0
- package/src/lib/module-store.ts +190 -9
- package/src/lib/scripts/compiler.ts +248 -24
- package/src/lib/scripts/conditions.ts +1 -0
- package/src/lib/scripts/emit.ts +50 -5
- package/src/lib/scripts/resolve.ts +124 -2
- package/src/lib/scripts/transform.ts +290 -19
- package/src/lib/styles/compiler.ts +108 -8
- package/src/lib/styles/emit.ts +1 -1
- package/src/lib/styles/resolve.ts +11 -7
- package/src/types/hmr.d.ts +36 -0
|
@@ -18,7 +18,10 @@ type EmitResult = {
|
|
|
18
18
|
error: AssetServerCompilationError;
|
|
19
19
|
};
|
|
20
20
|
export declare function emitResolvedModule(resolvedModule: ResolvedModule, options: {
|
|
21
|
+
getHmrImportTimestamp(identityPath: string): number | null;
|
|
21
22
|
getServedUrl(identityPath: string): Promise<string>;
|
|
23
|
+
getStableUrl(identityPath: string): string;
|
|
24
|
+
hmrClientPathname?: string;
|
|
22
25
|
sourceMaps?: 'external' | 'inline';
|
|
23
26
|
}): Promise<EmitResult>;
|
|
24
27
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emit.d.ts","sourceRoot":"","sources":["../../../src/lib/scripts/emit.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAElD,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAA;AAE1E,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,YAAY,CAAA;IAClB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,SAAS,EAAE,YAAY,GAAG,IAAI,CAAA;CAC/B,CAAA;AAED,KAAK,UAAU,GACX;IACE,EAAE,EAAE,IAAI,CAAA;IACR,KAAK,EAAE,aAAa,CAAA;CACrB,GACD;IACE,EAAE,EAAE,KAAK,CAAA;IACT,KAAK,EAAE,2BAA2B,CAAA;CACnC,CAAA;
|
|
1
|
+
{"version":3,"file":"emit.d.ts","sourceRoot":"","sources":["../../../src/lib/scripts/emit.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAElD,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAA;AAE1E,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,YAAY,CAAA;IAClB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,SAAS,EAAE,YAAY,GAAG,IAAI,CAAA;CAC/B,CAAA;AAED,KAAK,UAAU,GACX;IACE,EAAE,EAAE,IAAI,CAAA;IACR,KAAK,EAAE,aAAa,CAAA;CACrB,GACD;IACE,EAAE,EAAE,KAAK,CAAA;IACT,KAAK,EAAE,2BAA2B,CAAA;CACnC,CAAA;AAQL,wBAAsB,kBAAkB,CACtC,cAAc,EAAE,cAAc,EAC9B,OAAO,EAAE;IACP,qBAAqB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IAC1D,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IACnD,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAAA;IAC1C,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,UAAU,CAAC,EAAE,UAAU,GAAG,QAAQ,CAAA;CACnC,GACA,OAAO,CAAC,UAAU,CAAC,CAkCrB"}
|
package/dist/lib/scripts/emit.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import MagicString from 'magic-string';
|
|
2
|
-
import { createAssetServerCompilationError, isAssetServerCompilationError, } from
|
|
3
|
-
import { hashContent } from
|
|
4
|
-
import { composeSourceMaps } from
|
|
2
|
+
import { createAssetServerCompilationError, isAssetServerCompilationError, } from '../compilation-error.js';
|
|
3
|
+
import { hashContent } from '../fingerprint.js';
|
|
4
|
+
import { composeSourceMaps } from '../source-maps.js';
|
|
5
5
|
export async function emitResolvedModule(resolvedModule, options) {
|
|
6
6
|
try {
|
|
7
7
|
let importUrls = await Promise.all(resolvedModule.deps.map((depPath) => options.getServedUrl(depPath)));
|
|
8
8
|
let rewriteResult = await rewriteImports(resolvedModule, options);
|
|
9
|
-
let finalCode = rewriteResult.code;
|
|
9
|
+
let finalCode = prependHmrContext(resolvedModule, rewriteResult.code, options);
|
|
10
10
|
if (rewriteResult.sourceMap) {
|
|
11
11
|
if (options.sourceMaps === 'inline') {
|
|
12
12
|
let encoded = Buffer.from(rewriteResult.sourceMap).toString('base64');
|
|
@@ -39,14 +39,33 @@ async function rewriteImports(resolvedModule, options) {
|
|
|
39
39
|
let rewrittenSource = new MagicString(resolvedModule.rawCode);
|
|
40
40
|
for (let imported of resolvedModule.imports) {
|
|
41
41
|
let url = await options.getServedUrl(imported.depPath);
|
|
42
|
+
let hmrImportTimestamp = options.getHmrImportTimestamp(imported.depPath);
|
|
43
|
+
if (hmrImportTimestamp !== null) {
|
|
44
|
+
url = addTimestampQuery(url, hmrImportTimestamp);
|
|
45
|
+
}
|
|
42
46
|
rewrittenSource.overwrite(imported.start, imported.end, imported.quote ? `${imported.quote}${url}${imported.quote}` : url);
|
|
43
47
|
}
|
|
48
|
+
for (let acceptedDep of resolvedModule.hmr.acceptedDeps) {
|
|
49
|
+
let url = options.getStableUrl(acceptedDep.depPath);
|
|
50
|
+
rewrittenSource.overwrite(acceptedDep.start, acceptedDep.end, acceptedDep.quote ? `${acceptedDep.quote}${url}${acceptedDep.quote}` : url);
|
|
51
|
+
}
|
|
44
52
|
let code = rewrittenSource.toString();
|
|
45
|
-
let sourceMap = resolvedModule.sourceMap &&
|
|
53
|
+
let sourceMap = resolvedModule.sourceMap &&
|
|
54
|
+
(resolvedModule.imports.length > 0 || resolvedModule.hmr.acceptedDeps.length > 0)
|
|
46
55
|
? composeSourceMaps(rewrittenSource.generateMap({ hires: true }).toString(), resolvedModule.sourceMap)
|
|
47
56
|
: resolvedModule.sourceMap;
|
|
48
57
|
return { code, sourceMap };
|
|
49
58
|
}
|
|
59
|
+
function addTimestampQuery(pathname, timestamp) {
|
|
60
|
+
return `${pathname}${pathname.includes('?') ? '&' : '?'}t=${timestamp}`;
|
|
61
|
+
}
|
|
62
|
+
function prependHmrContext(resolvedModule, code, options) {
|
|
63
|
+
if (!options.hmrClientPathname || !resolvedModule.hmr.usesImportMetaHot)
|
|
64
|
+
return code;
|
|
65
|
+
return (`import { createHotContext as __remixCreateHotContext } from ${JSON.stringify(options.hmrClientPathname)};\n` +
|
|
66
|
+
`import.meta.hot = __remixCreateHotContext(${JSON.stringify(resolvedModule.stableUrlPathname)});\n` +
|
|
67
|
+
code);
|
|
68
|
+
}
|
|
50
69
|
async function createEmittedAsset(content) {
|
|
51
70
|
return {
|
|
52
71
|
content,
|
|
@@ -18,9 +18,13 @@ type ResolvedImport = {
|
|
|
18
18
|
quote?: '"' | "'" | '`';
|
|
19
19
|
start: number;
|
|
20
20
|
};
|
|
21
|
+
type ResolvedHmrAcceptedDependency = ResolvedImport;
|
|
21
22
|
export type ResolvedModule = {
|
|
22
23
|
deps: string[];
|
|
23
24
|
fingerprint: string | null;
|
|
25
|
+
hmr: Omit<TransformedModule['hmr'], 'acceptedDeps'> & {
|
|
26
|
+
acceptedDeps: ResolvedHmrAcceptedDependency[];
|
|
27
|
+
};
|
|
24
28
|
identityPath: string;
|
|
25
29
|
imports: ResolvedImport[];
|
|
26
30
|
trackedFiles: string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../../src/lib/scripts/resolve.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAMnD,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAA;AAM1E,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAEtE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAClD,OAAO,KAAK,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAC5E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AAE9C,KAAK,YAAY,GAAG,YAAY,CAAC,iBAAiB,EAAE,cAAc,EAAE,aAAa,CAAC,CAAA;AAElF,eAAO,MAAM,sBAAsB;;;;CAIC,CAAA;AAEpC,eAAO,MAAM,kBAAkB,UAAiD,CAAA;AAChF,eAAO,MAAM,yBAAyB,UAAiD,CAAA;AAGvF,KAAK,cAAc,GAAG;IACpB,OAAO,EAAE,MAAM,CAAA;IACf,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,CAAC,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,CAAA;IACvB,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;
|
|
1
|
+
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../../src/lib/scripts/resolve.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAMnD,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAA;AAM1E,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAEtE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAClD,OAAO,KAAK,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAC5E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AAE9C,KAAK,YAAY,GAAG,YAAY,CAAC,iBAAiB,EAAE,cAAc,EAAE,aAAa,CAAC,CAAA;AAElF,eAAO,MAAM,sBAAsB;;;;CAIC,CAAA;AAEpC,eAAO,MAAM,kBAAkB,UAAiD,CAAA;AAChF,eAAO,MAAM,yBAAyB,UAAiD,CAAA;AAGvF,KAAK,cAAc,GAAG;IACpB,OAAO,EAAE,MAAM,CAAA;IACf,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,CAAC,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,CAAA;IACvB,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAED,KAAK,6BAA6B,GAAG,cAAc,CAAA;AAYnD,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,GAAG,EAAE,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,EAAE,cAAc,CAAC,GAAG;QACpD,YAAY,EAAE,6BAA6B,EAAE,CAAA;KAC9C,CAAA;IACD,YAAY,EAAE,MAAM,CAAA;IACpB,OAAO,EAAE,cAAc,EAAE,CAAA;IACzB,YAAY,EAAE,MAAM,EAAE,CAAA;IACtB,OAAO,EAAE,MAAM,CAAA;IACf,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,iBAAiB,EAAE,MAAM,CAAA;CAC1B,CAAA;AAED,KAAK,aAAa,GAAG;IACnB,QAAQ,EAAE,cAAc,CAAA;CACzB,GAAG,CACA;IACE,EAAE,EAAE,IAAI,CAAA;IACR,KAAK,EAAE,cAAc,CAAA;CACtB,GACD;IACE,EAAE,EAAE,KAAK,CAAA;IACT,KAAK,EAAE,2BAA2B,CAAA;CACnC,CACJ,CAAA;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,SAAS,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAA;IACxC,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAA;IACzC,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,mBAAmB,GAAG,IAAI,CAAA;IACnE,eAAe,EAAE,eAAe,CAAA;IAChC,MAAM,EAAE,cAAc,CAAA;CACvB,CAAA;AAaD,wBAAsB,aAAa,CACjC,MAAM,EAAE,YAAY,EACpB,WAAW,EAAE,iBAAiB,EAC9B,IAAI,EAAE,WAAW,GAChB,OAAO,CAAC,aAAa,CAAC,CA2PxB"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as fs from 'node:fs';
|
|
2
2
|
import * as path from 'node:path';
|
|
3
|
-
import { createAssetServerCompilationError, isAssetServerCompilationError, } from
|
|
4
|
-
import { getInjectedPackageNameForSpecifier, getInjectedPackageImporterPath, restoreAuthoredInjectedPackageSpecifier, } from
|
|
5
|
-
import { normalizeFilePath } from
|
|
3
|
+
import { createAssetServerCompilationError, isAssetServerCompilationError, } from '../compilation-error.js';
|
|
4
|
+
import { getInjectedPackageNameForSpecifier, getInjectedPackageImporterPath, restoreAuthoredInjectedPackageSpecifier, } from '../injected-packages.js';
|
|
5
|
+
import { normalizeFilePath } from '../paths.js';
|
|
6
6
|
export const resolverExtensionAlias = {
|
|
7
7
|
'.js': ['.js', '.ts', '.tsx', '.jsx'],
|
|
8
8
|
'.jsx': ['.jsx', '.tsx'],
|
|
@@ -27,6 +27,7 @@ export async function resolveModule(record, transformed, args) {
|
|
|
27
27
|
});
|
|
28
28
|
}
|
|
29
29
|
let importsWithPaths = [];
|
|
30
|
+
let acceptedDepsWithPaths = [];
|
|
30
31
|
let deps = new Set();
|
|
31
32
|
for (let unresolved of transformed.unresolvedImports) {
|
|
32
33
|
let displaySpecifier = getDisplayImportSpecifier(unresolved.specifier);
|
|
@@ -46,8 +47,8 @@ export async function resolveModule(record, transformed, args) {
|
|
|
46
47
|
}), trackedFiles, trackedResolutions, transformed.resolvedPath, { isWatchIgnored: args.isWatchIgnored, trackedResolution });
|
|
47
48
|
}
|
|
48
49
|
if (!args.isAllowed(resolvedImport.identityPath)) {
|
|
49
|
-
return failResolve(createAssetServerCompilationError(`Import "${displaySpecifier}" in ${transformed.resolvedPath}, resolved to "${resolvedImport.identityPath}", is not allowed by the asset server
|
|
50
|
-
`Add a matching
|
|
50
|
+
return failResolve(createAssetServerCompilationError(`Import "${displaySpecifier}" in ${transformed.resolvedPath}, resolved to "${resolvedImport.identityPath}", is not allowed by the asset server access configuration. ` +
|
|
51
|
+
`Add a matching allowFiles or allowPackages rule, remove a conflicting denyFiles rule, or mark this import as external.`, {
|
|
51
52
|
code: 'IMPORT_NOT_ALLOWED',
|
|
52
53
|
}), trackedFiles, trackedResolutions, transformed.resolvedPath, { isWatchIgnored: args.isWatchIgnored, trackedResolution });
|
|
53
54
|
}
|
|
@@ -78,12 +79,73 @@ export async function resolveModule(record, transformed, args) {
|
|
|
78
79
|
start: unresolved.start,
|
|
79
80
|
});
|
|
80
81
|
}
|
|
82
|
+
for (let unresolved of transformed.hmr.acceptedDeps) {
|
|
83
|
+
if (isBrowserExternalModuleUrl(unresolved.specifier))
|
|
84
|
+
continue;
|
|
85
|
+
let displaySpecifier = getDisplayImportSpecifier(unresolved.specifier);
|
|
86
|
+
let trackedResolution = getTrackedRelativeImportResolution(transformed.importerDir, displaySpecifier, args.isWatchIgnored);
|
|
87
|
+
let resolvedSpec = resolvedImports.get(unresolved.specifier);
|
|
88
|
+
if (!resolvedSpec?.absolutePath) {
|
|
89
|
+
try {
|
|
90
|
+
resolvedSpec = await batchResolveSpecifiers([unresolved.specifier], transformed.resolvedPath, args.resolverFactory).then((resolved) => resolved.get(unresolved.specifier));
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
return failResolve(error, trackedFiles, trackedResolutions, transformed.resolvedPath, {
|
|
94
|
+
isWatchIgnored: args.isWatchIgnored,
|
|
95
|
+
trackedResolution,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (!resolvedSpec?.absolutePath) {
|
|
100
|
+
return failResolve(createAssetServerCompilationError(`Failed to resolve accepted HMR dependency "${displaySpecifier}" in ${transformed.resolvedPath}. ` +
|
|
101
|
+
`Ensure it resolves to a file within the configured asset server fileMap, or mark it as external.`, {
|
|
102
|
+
code: 'IMPORT_RESOLUTION_FAILED',
|
|
103
|
+
}), trackedFiles, trackedResolutions, transformed.resolvedPath, { isWatchIgnored: args.isWatchIgnored, trackedResolution });
|
|
104
|
+
}
|
|
105
|
+
let resolvedImport = args.resolveModulePath(resolvedSpec.absolutePath);
|
|
106
|
+
if (!resolvedImport) {
|
|
107
|
+
return failResolve(createAssetServerCompilationError(`Accepted HMR dependency "${displaySpecifier}" in ${transformed.resolvedPath}, resolved to "${resolvedSpec.absolutePath}", is not a supported script file. ` +
|
|
108
|
+
`Supported extensions are ${supportedScriptExtensions.join(', ')}.`, {
|
|
109
|
+
code: 'IMPORT_NOT_SUPPORTED',
|
|
110
|
+
}), trackedFiles, trackedResolutions, transformed.resolvedPath, { isWatchIgnored: args.isWatchIgnored, trackedResolution });
|
|
111
|
+
}
|
|
112
|
+
if (!args.isAllowed(resolvedImport.identityPath)) {
|
|
113
|
+
return failResolve(createAssetServerCompilationError(`Accepted HMR dependency "${displaySpecifier}" in ${transformed.resolvedPath}, resolved to "${resolvedImport.identityPath}", is not allowed by the asset server allow/deny configuration. ` +
|
|
114
|
+
`Add a matching allow rule for this file path, remove a conflicting deny rule for this file path, or mark this import as external.`, {
|
|
115
|
+
code: 'IMPORT_NOT_ALLOWED',
|
|
116
|
+
}), trackedFiles, trackedResolutions, transformed.resolvedPath, { isWatchIgnored: args.isWatchIgnored, trackedResolution });
|
|
117
|
+
}
|
|
118
|
+
let stableUrlPathname = args.routes.toUrlPathname(resolvedImport.identityPath);
|
|
119
|
+
if (!stableUrlPathname) {
|
|
120
|
+
return failResolve(createAssetServerCompilationError(`Accepted HMR dependency "${displaySpecifier}" in ${transformed.resolvedPath}, resolved to "${resolvedImport.identityPath}", is outside all configured fileMap entries. ` +
|
|
121
|
+
`Add a matching fileMap entry for this file path, or mark this import as external.`, {
|
|
122
|
+
code: 'IMPORT_OUTSIDE_FILE_MAP',
|
|
123
|
+
}), trackedFiles, trackedResolutions, transformed.resolvedPath, { isWatchIgnored: args.isWatchIgnored, trackedResolution });
|
|
124
|
+
}
|
|
125
|
+
if (trackedResolution) {
|
|
126
|
+
trackedResolutions.push({
|
|
127
|
+
...trackedResolution,
|
|
128
|
+
resolvedIdentityPath: resolvedImport.identityPath,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
acceptedDepsWithPaths.push({
|
|
132
|
+
depPath: resolvedImport.identityPath,
|
|
133
|
+
end: unresolved.end,
|
|
134
|
+
quote: unresolved.quote,
|
|
135
|
+
start: unresolved.start,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
81
138
|
return {
|
|
82
139
|
ok: true,
|
|
83
140
|
tracking: toResolveTracking(trackedFiles, trackedResolutions),
|
|
84
141
|
value: {
|
|
85
142
|
deps: [...deps],
|
|
86
143
|
fingerprint: transformed.fingerprint,
|
|
144
|
+
hmr: {
|
|
145
|
+
acceptedDeps: acceptedDepsWithPaths,
|
|
146
|
+
selfAccepting: transformed.hmr.selfAccepting,
|
|
147
|
+
usesImportMetaHot: transformed.hmr.usesImportMetaHot,
|
|
148
|
+
},
|
|
87
149
|
identityPath: record.identityPath,
|
|
88
150
|
imports: importsWithPaths,
|
|
89
151
|
trackedFiles: [...trackedFiles],
|
|
@@ -226,6 +288,9 @@ function normalizeSpecifierResolution(specifier, importerPath) {
|
|
|
226
288
|
function getDisplayImportSpecifier(specifier) {
|
|
227
289
|
return restoreAuthoredInjectedPackageSpecifier(specifier) ?? specifier;
|
|
228
290
|
}
|
|
291
|
+
function isBrowserExternalModuleUrl(url) {
|
|
292
|
+
return url.startsWith('data:') || url.startsWith('http://') || url.startsWith('https://');
|
|
293
|
+
}
|
|
229
294
|
function failResolve(error, trackedFiles, trackedResolutions, importerPath, options = {}) {
|
|
230
295
|
return {
|
|
231
296
|
ok: false,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { TsConfigJsonResolved } from 'get-tsconfig';
|
|
2
2
|
import type { AssetServerCompilationError } from '../compilation-error.ts';
|
|
3
3
|
import type { ModuleRecord, ModuleTracking } from '../module-store.ts';
|
|
4
|
+
import type { ModuleLoader } from '../loaders.ts';
|
|
4
5
|
import type { CompiledRoutes } from '../routes.ts';
|
|
5
6
|
import type { EmittedModule } from './emit.ts';
|
|
6
7
|
import type { ResolvedScriptTarget } from '../target.ts';
|
|
@@ -16,8 +17,14 @@ type UnresolvedImport = {
|
|
|
16
17
|
specifier: string;
|
|
17
18
|
start: number;
|
|
18
19
|
};
|
|
20
|
+
type HmrAcceptedDependency = UnresolvedImport;
|
|
19
21
|
export type TransformedModule = {
|
|
20
22
|
fingerprint: string | null;
|
|
23
|
+
hmr: {
|
|
24
|
+
acceptedDeps: HmrAcceptedDependency[];
|
|
25
|
+
selfAccepting: boolean;
|
|
26
|
+
usesImportMetaHot: boolean;
|
|
27
|
+
};
|
|
21
28
|
identityPath: string;
|
|
22
29
|
importerDir: string;
|
|
23
30
|
packageSpecifiers: string[];
|
|
@@ -48,6 +55,7 @@ export type TransformArgs = {
|
|
|
48
55
|
externalSet: ReadonlySet<string>;
|
|
49
56
|
isWatchIgnored(filePath: string): boolean;
|
|
50
57
|
minify: boolean;
|
|
58
|
+
loaders: readonly ModuleLoader[];
|
|
51
59
|
resolveActualPath(identityPath: string): string | null;
|
|
52
60
|
routes: CompiledRoutes;
|
|
53
61
|
sourceMapSourcePaths: 'absolute' | 'url';
|
|
@@ -60,5 +68,6 @@ export declare function createTsconfigTransformOptionsResolver(): {
|
|
|
60
68
|
getTransformOptions(filePath: string, isWatchIgnored: (filePath: string) => boolean): TsconfigTransformOptions;
|
|
61
69
|
};
|
|
62
70
|
export declare function transformModule(record: ScriptRecord, args: TransformArgs): Promise<TransformResult>;
|
|
71
|
+
export declare function getHmrAnalysis(rawCode: string): TransformedModule['hmr'];
|
|
63
72
|
export {};
|
|
64
73
|
//# sourceMappingURL=transform.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../../../src/lib/scripts/transform.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../../../src/lib/scripts/transform.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
import * as fs from 'node:fs';
|
|
2
2
|
import * as fsp from 'node:fs/promises';
|
|
3
3
|
import * as path from 'node:path';
|
|
4
|
+
import { pathToFileURL } from 'node:url';
|
|
4
5
|
import { getTsconfig } from 'get-tsconfig';
|
|
5
6
|
import MagicString from 'magic-string';
|
|
6
7
|
import { minify } from 'oxc-minify';
|
|
7
8
|
import { parseSync, visitorKeys } from 'oxc-parser';
|
|
8
9
|
import { transform as oxcTransform } from 'oxc-transform';
|
|
9
10
|
import { init as esModuleLexerInit, parse as esModuleLexer } from 'es-module-lexer';
|
|
10
|
-
import { isCommonJS, mayContainCommonJSModuleGlobals } from
|
|
11
|
-
import { createAssetServerCompilationError, isAssetServerCompilationError, } from
|
|
12
|
-
import { generateFingerprint } from
|
|
13
|
-
import { maskAuthoredInjectedPackageSpecifier, mayContainInjectedPackageSpecifier, restoreAuthoredInjectedPackageSpecifier, } from
|
|
14
|
-
import { normalizeFilePath } from
|
|
15
|
-
import { composeSourceMaps, rewriteSourceMapSources, stringifySourceMap } from
|
|
11
|
+
import { isCommonJS, mayContainCommonJSModuleGlobals } from './cjs-check.js';
|
|
12
|
+
import { createAssetServerCompilationError, isAssetServerCompilationError, } from '../compilation-error.js';
|
|
13
|
+
import { generateFingerprint } from '../fingerprint.js';
|
|
14
|
+
import { maskAuthoredInjectedPackageSpecifier, mayContainInjectedPackageSpecifier, restoreAuthoredInjectedPackageSpecifier, } from '../injected-packages.js';
|
|
15
|
+
import { normalizeFilePath } from '../paths.js';
|
|
16
|
+
import { composeSourceMaps, rewriteSourceMapSources, stringifySourceMap } from '../source-maps.js';
|
|
17
|
+
import { scriptLoaderConditions } from './conditions.js';
|
|
16
18
|
const scriptModuleTypes = [
|
|
17
19
|
{ extension: '.js', lang: 'js' },
|
|
18
20
|
{ extension: '.jsx', lang: 'jsx' },
|
|
@@ -105,9 +107,17 @@ export async function transformModule(record, args) {
|
|
|
105
107
|
};
|
|
106
108
|
}
|
|
107
109
|
try {
|
|
110
|
+
let stableUrlPathname = args.routes.toUrlPathname(record.identityPath);
|
|
111
|
+
if (!stableUrlPathname) {
|
|
112
|
+
throw createAssetServerCompilationError(`File ${record.identityPath} is outside all configured fileMap entries.`, {
|
|
113
|
+
code: 'FILE_OUTSIDE_FILE_MAP',
|
|
114
|
+
});
|
|
115
|
+
}
|
|
108
116
|
let analysis = await analyzeModuleSource(sourceText, resolvedPath, transformOptions, {
|
|
109
117
|
define: args.define ?? undefined,
|
|
110
118
|
minify: args.minify,
|
|
119
|
+
loaders: args.loaders,
|
|
120
|
+
moduleUrl: stableUrlPathname,
|
|
111
121
|
sourceMaps: args.sourceMaps ?? undefined,
|
|
112
122
|
target: args.target ?? undefined,
|
|
113
123
|
});
|
|
@@ -119,12 +129,6 @@ export async function transformModule(record, args) {
|
|
|
119
129
|
code: 'COMMONJS_NOT_SUPPORTED',
|
|
120
130
|
});
|
|
121
131
|
}
|
|
122
|
-
let stableUrlPathname = args.routes.toUrlPathname(record.identityPath);
|
|
123
|
-
if (!stableUrlPathname) {
|
|
124
|
-
throw createAssetServerCompilationError(`File ${record.identityPath} is outside all configured fileMap entries.`, {
|
|
125
|
-
code: 'FILE_OUTSIDE_FILE_MAP',
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
132
|
let sourceMap = analysis.sourceMap
|
|
129
133
|
? rewriteSourceMapSources(analysis.sourceMap, resolvedPath, stableUrlPathname, args.sourceMapSourcePaths, sourceText)
|
|
130
134
|
: null;
|
|
@@ -140,6 +144,7 @@ export async function transformModule(record, args) {
|
|
|
140
144
|
buildId: args.buildId,
|
|
141
145
|
content: sourceText,
|
|
142
146
|
}),
|
|
147
|
+
hmr: getHmrAnalysis(analysis.rawCode),
|
|
143
148
|
identityPath: record.identityPath,
|
|
144
149
|
importerDir: path.dirname(resolvedPath),
|
|
145
150
|
packageSpecifiers: analysis.unresolvedImports
|
|
@@ -164,6 +169,105 @@ export async function transformModule(record, args) {
|
|
|
164
169
|
};
|
|
165
170
|
}
|
|
166
171
|
}
|
|
172
|
+
export function getHmrAnalysis(rawCode) {
|
|
173
|
+
let mayUseImportMetaHot = rawCode.includes('import.meta.hot');
|
|
174
|
+
let usesImportMetaHot = false;
|
|
175
|
+
let acceptedDeps = [];
|
|
176
|
+
let selfAccepting = false;
|
|
177
|
+
if (mayUseImportMetaHot) {
|
|
178
|
+
try {
|
|
179
|
+
let parseResult = parseSync('hmr-analysis.js', rawCode, {
|
|
180
|
+
lang: 'js',
|
|
181
|
+
sourceType: 'module',
|
|
182
|
+
});
|
|
183
|
+
if (parseResult.errors.length > 0) {
|
|
184
|
+
throw createAssetServerCompilationError(`Failed to analyze HMR usage in transformed script. ${parseResult.errors[0]?.message ?? 'Unknown parse error'}`, {
|
|
185
|
+
code: 'TRANSFORM_FAILED',
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
walkAst(parseResult.program, (node) => {
|
|
189
|
+
if (isImportMetaHotNode(node)) {
|
|
190
|
+
usesImportMetaHot = true;
|
|
191
|
+
}
|
|
192
|
+
if (node.type !== 'CallExpression')
|
|
193
|
+
return;
|
|
194
|
+
if (!isImportMetaHotAcceptCallee(node.callee))
|
|
195
|
+
return;
|
|
196
|
+
let [firstArgument] = node.arguments;
|
|
197
|
+
if (firstArgument === undefined || !isAcceptedDependencyArgument(firstArgument)) {
|
|
198
|
+
selfAccepting = true;
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
acceptedDeps.push(...getAcceptedDependencies(firstArgument, rawCode));
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
catch (error) {
|
|
205
|
+
if (isAssetServerCompilationError(error))
|
|
206
|
+
throw error;
|
|
207
|
+
throw createAssetServerCompilationError(`Failed to analyze HMR usage in transformed script.`, {
|
|
208
|
+
cause: error,
|
|
209
|
+
code: 'TRANSFORM_FAILED',
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
return {
|
|
214
|
+
acceptedDeps,
|
|
215
|
+
selfAccepting,
|
|
216
|
+
usesImportMetaHot,
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
function isImportMetaHotAcceptCallee(node) {
|
|
220
|
+
let callee = unwrapChainExpression(node);
|
|
221
|
+
if (callee.type !== 'MemberExpression')
|
|
222
|
+
return false;
|
|
223
|
+
if (callee.computed || !isIdentifierNode(callee.property, 'accept'))
|
|
224
|
+
return false;
|
|
225
|
+
return isImportMetaHotNode(callee.object);
|
|
226
|
+
}
|
|
227
|
+
function isImportMetaHotNode(node) {
|
|
228
|
+
let hot = unwrapChainExpression(node);
|
|
229
|
+
if (hot.type !== 'MemberExpression')
|
|
230
|
+
return false;
|
|
231
|
+
if (hot.computed || !isIdentifierNode(hot.property, 'hot'))
|
|
232
|
+
return false;
|
|
233
|
+
let meta = unwrapChainExpression(hot.object);
|
|
234
|
+
return (meta.type === 'MetaProperty' &&
|
|
235
|
+
isIdentifierNode(meta.meta, 'import') &&
|
|
236
|
+
isIdentifierNode(meta.property, 'meta'));
|
|
237
|
+
}
|
|
238
|
+
function unwrapChainExpression(node) {
|
|
239
|
+
return node.type === 'ChainExpression' ? node.expression : node;
|
|
240
|
+
}
|
|
241
|
+
function isIdentifierNode(node, name) {
|
|
242
|
+
return node.type === 'Identifier' && node.name === name;
|
|
243
|
+
}
|
|
244
|
+
function isAcceptedDependencyArgument(node) {
|
|
245
|
+
return isStringLiteralNode(node) || node.type === 'ArrayExpression';
|
|
246
|
+
}
|
|
247
|
+
function getAcceptedDependencies(node, source) {
|
|
248
|
+
if (isStringLiteralNode(node)) {
|
|
249
|
+
return [
|
|
250
|
+
{
|
|
251
|
+
end: node.end - 1,
|
|
252
|
+
specifier: node.value,
|
|
253
|
+
start: node.start + 1,
|
|
254
|
+
},
|
|
255
|
+
];
|
|
256
|
+
}
|
|
257
|
+
if (node.type !== 'ArrayExpression')
|
|
258
|
+
return [];
|
|
259
|
+
let deps = [];
|
|
260
|
+
for (let element of node.elements) {
|
|
261
|
+
if (!isStringLiteralNode(element))
|
|
262
|
+
continue;
|
|
263
|
+
deps.push({
|
|
264
|
+
end: element.end - 1,
|
|
265
|
+
specifier: element.value,
|
|
266
|
+
start: element.start + 1,
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
return deps;
|
|
270
|
+
}
|
|
167
271
|
function findNearestTsconfigPath(directory) {
|
|
168
272
|
let currentDirectory = directory;
|
|
169
273
|
while (true) {
|
|
@@ -203,6 +307,38 @@ async function analyzeModuleSource(sourceText, resolvedPath, transformOptions, o
|
|
|
203
307
|
}
|
|
204
308
|
let rawCode = transformResult.code.trimEnd();
|
|
205
309
|
let sourceMap = stringifySourceMap(transformResult.map);
|
|
310
|
+
if (options.loaders.length > 0) {
|
|
311
|
+
let loaderUrl = pathToFileURL(resolvedPath).href;
|
|
312
|
+
let loaderInputSource = sourceMap ? appendInlineSourceMap(rawCode, sourceMap) : rawCode;
|
|
313
|
+
let loaderOutputSource;
|
|
314
|
+
try {
|
|
315
|
+
let loaderResult = runModuleLoaders(loaderUrl, {
|
|
316
|
+
format: 'module',
|
|
317
|
+
loaders: options.loaders,
|
|
318
|
+
moduleUrl: options.moduleUrl,
|
|
319
|
+
source: loaderInputSource,
|
|
320
|
+
});
|
|
321
|
+
loaderOutputSource = moduleLoadSourceToString(getModuleLoadSource(loaderUrl, loaderResult));
|
|
322
|
+
}
|
|
323
|
+
catch (error) {
|
|
324
|
+
if (isAssetServerCompilationError(error))
|
|
325
|
+
throw error;
|
|
326
|
+
throw createAssetServerCompilationError(`Module loader failed for ${loaderUrl}. ${formatUnknownError(error)}`, {
|
|
327
|
+
cause: error,
|
|
328
|
+
code: 'LOADER_FAILED',
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
if (loaderOutputSource !== loaderInputSource) {
|
|
332
|
+
let loaderOutput = extractInlineSourceMap(loaderOutputSource);
|
|
333
|
+
rawCode = loaderOutput.code.trimEnd();
|
|
334
|
+
sourceMap =
|
|
335
|
+
loaderOutput.sourceMap && loaderOutput.sourceMap !== sourceMap
|
|
336
|
+
? sourceMap
|
|
337
|
+
? composeSourceMaps(loaderOutput.sourceMap, sourceMap)
|
|
338
|
+
: loaderOutput.sourceMap
|
|
339
|
+
: null;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
206
342
|
if (options.minify) {
|
|
207
343
|
let minifyResult = await minifyModule(rawCode, resolvedPath, options.target, options.sourceMaps);
|
|
208
344
|
rawCode = minifyResult.code.trimEnd();
|
|
@@ -220,6 +356,76 @@ async function analyzeModuleSource(sourceText, resolvedPath, transformOptions, o
|
|
|
220
356
|
unresolvedImports: await getUnresolvedImportsFromLexer(rawCode),
|
|
221
357
|
};
|
|
222
358
|
}
|
|
359
|
+
function runModuleLoaders(url, options) {
|
|
360
|
+
let loadContext = {
|
|
361
|
+
conditions: [...scriptLoaderConditions],
|
|
362
|
+
format: options.format,
|
|
363
|
+
importAttributes: {},
|
|
364
|
+
moduleUrl: options.moduleUrl,
|
|
365
|
+
};
|
|
366
|
+
let load = (_url, context) => ({
|
|
367
|
+
format: context?.format ?? options.format,
|
|
368
|
+
source: options.source,
|
|
369
|
+
});
|
|
370
|
+
for (let loader of options.loaders) {
|
|
371
|
+
let nextLoad = load;
|
|
372
|
+
load = (nextUrl, nextContext) => {
|
|
373
|
+
let nextLoadCalled = false;
|
|
374
|
+
let wrappedNextLoad = (wrappedUrl, wrappedContext) => {
|
|
375
|
+
if (wrappedUrl !== nextUrl) {
|
|
376
|
+
throw createAssetServerCompilationError(`Module loader for ${nextUrl} attempted to change the module URL to ${wrappedUrl}. Loaders cannot change module URLs.`, {
|
|
377
|
+
code: 'LOADER_FAILED',
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
nextLoadCalled = true;
|
|
381
|
+
return nextLoad(wrappedUrl, wrappedContext);
|
|
382
|
+
};
|
|
383
|
+
let result = loader(nextUrl, {
|
|
384
|
+
conditions: nextContext?.conditions ?? loadContext.conditions,
|
|
385
|
+
format: nextContext?.format ?? loadContext.format,
|
|
386
|
+
importAttributes: nextContext?.importAttributes ?? loadContext.importAttributes,
|
|
387
|
+
moduleUrl: nextContext?.moduleUrl ?? loadContext.moduleUrl,
|
|
388
|
+
}, wrappedNextLoad);
|
|
389
|
+
if (!nextLoadCalled && result.shortCircuit !== true) {
|
|
390
|
+
throw createAssetServerCompilationError(`Module loader for ${nextUrl} returned without calling nextLoad or setting shortCircuit: true.`, {
|
|
391
|
+
code: 'LOADER_FAILED',
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
return result;
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
return load(url, loadContext);
|
|
398
|
+
}
|
|
399
|
+
function getModuleLoadSource(url, result) {
|
|
400
|
+
if (result.format !== 'module') {
|
|
401
|
+
throw createAssetServerCompilationError(`Module loader for ${url} returned unsupported format ${JSON.stringify(result.format)}. Only "module" is supported.`, {
|
|
402
|
+
code: 'LOADER_FAILED',
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
if (result.source !== undefined && result.source !== null)
|
|
406
|
+
return result.source;
|
|
407
|
+
throw createAssetServerCompilationError(`Module loader for ${url} did not return source.`, {
|
|
408
|
+
code: 'LOADER_FAILED',
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
function moduleLoadSourceToString(source) {
|
|
412
|
+
if (typeof source === 'string')
|
|
413
|
+
return source;
|
|
414
|
+
return new TextDecoder().decode(source);
|
|
415
|
+
}
|
|
416
|
+
function appendInlineSourceMap(source, sourceMap) {
|
|
417
|
+
let encoded = Buffer.from(sourceMap).toString('base64');
|
|
418
|
+
return `${source}\n//# sourceMappingURL=data:application/json;base64,${encoded}`;
|
|
419
|
+
}
|
|
420
|
+
function extractInlineSourceMap(source) {
|
|
421
|
+
let sourceMapPattern = /(?:\/\/# sourceMappingURL=data:application\/json;base64,([A-Za-z0-9+/=]+)|\/\*# sourceMappingURL=data:application\/json;base64,([A-Za-z0-9+/=]+) \*\/)\s*$/g;
|
|
422
|
+
let sourceMap = null;
|
|
423
|
+
let code = source.replace(sourceMapPattern, (_match, lineComment, blockComment) => {
|
|
424
|
+
sourceMap = Buffer.from(lineComment ?? blockComment, 'base64').toString('utf-8');
|
|
425
|
+
return '';
|
|
426
|
+
});
|
|
427
|
+
return { code, sourceMap };
|
|
428
|
+
}
|
|
223
429
|
async function minifyModule(rawCode, resolvedPath, target, sourceMaps) {
|
|
224
430
|
try {
|
|
225
431
|
let result = await minify(resolvedPath, rawCode, {
|
|
@@ -324,7 +530,7 @@ async function getUnresolvedImportsFromLexer(rawCode) {
|
|
|
324
530
|
let unresolvedImports = [];
|
|
325
531
|
for (let imported of imports) {
|
|
326
532
|
let specifier = getStaticImportSpecifier(rawCode, imported);
|
|
327
|
-
if (specifier == null ||
|
|
533
|
+
if (specifier == null || isBrowserExternalModuleUrl(specifier))
|
|
328
534
|
continue;
|
|
329
535
|
unresolvedImports.push({
|
|
330
536
|
specifier,
|
|
@@ -338,6 +544,9 @@ async function getUnresolvedImportsFromLexer(rawCode) {
|
|
|
338
544
|
function getDisplayImportSpecifier(specifier) {
|
|
339
545
|
return restoreAuthoredInjectedPackageSpecifier(specifier) ?? specifier;
|
|
340
546
|
}
|
|
547
|
+
function isBrowserExternalModuleUrl(url) {
|
|
548
|
+
return url.startsWith('data:') || url.startsWith('http://') || url.startsWith('https://');
|
|
549
|
+
}
|
|
341
550
|
function maskAuthoredInjectedPackageImports(sourceText, resolvedPath) {
|
|
342
551
|
if (!mayContainInjectedPackageSpecifier(sourceText)) {
|
|
343
552
|
return sourceText;
|
|
@@ -423,11 +632,6 @@ function getStaticImportSpecifier(source, imported) {
|
|
|
423
632
|
function isStaticTemplateLiteral(specifier) {
|
|
424
633
|
return specifier.startsWith('`') && specifier.endsWith('`') && !specifier.includes('${');
|
|
425
634
|
}
|
|
426
|
-
function shouldSkipImportSpecifier(specifier) {
|
|
427
|
-
return (specifier.startsWith('data:') ||
|
|
428
|
-
specifier.startsWith('http://') ||
|
|
429
|
-
specifier.startsWith('https://'));
|
|
430
|
-
}
|
|
431
635
|
function getImportQuote(source, start) {
|
|
432
636
|
let firstCharacter = source[start];
|
|
433
637
|
if (firstCharacter === '"' || firstCharacter === "'" || firstCharacter === '`') {
|
package/dist/lib/source-maps.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SourceMapConsumer, SourceMapGenerator } from 'source-map-js';
|
|
2
|
-
import { normalizeFilePath } from
|
|
2
|
+
import { normalizeFilePath } from './paths.js';
|
|
3
3
|
export function composeSourceMaps(rewriteSourceMap, transformSourceMap) {
|
|
4
4
|
let rewriteConsumer = new SourceMapConsumer(JSON.parse(rewriteSourceMap));
|
|
5
5
|
let transformConsumer = new SourceMapConsumer(JSON.parse(transformSourceMap));
|
|
@@ -24,6 +24,9 @@ type StyleCompilerOptions = {
|
|
|
24
24
|
getServedFileUrl?(identityPath: string, options: {
|
|
25
25
|
transform: readonly string[] | null;
|
|
26
26
|
}): Promise<string>;
|
|
27
|
+
hmr?: {
|
|
28
|
+
send(pathname: string, timestamp: number): void;
|
|
29
|
+
};
|
|
27
30
|
isAllowed(absolutePath: string): boolean;
|
|
28
31
|
isServedFilePath(filePath: string): boolean;
|
|
29
32
|
minify: boolean;
|
|
@@ -31,6 +34,10 @@ type StyleCompilerOptions = {
|
|
|
31
34
|
add: string[];
|
|
32
35
|
remove: string[];
|
|
33
36
|
}) => void;
|
|
37
|
+
onWatchFilesChange?: (delta: {
|
|
38
|
+
add: string[];
|
|
39
|
+
remove: string[];
|
|
40
|
+
}) => void;
|
|
34
41
|
rootDir: string;
|
|
35
42
|
routes: CompiledRoutes;
|
|
36
43
|
sourceMapSourcePaths: 'absolute' | 'url';
|
|
@@ -42,7 +49,13 @@ type StyleCompiler = {
|
|
|
42
49
|
getHref(filePath: string): Promise<string>;
|
|
43
50
|
getPreloadLayers(filePath: string | readonly string[]): Promise<string[][]>;
|
|
44
51
|
getStyle(filePath: string, options: StyleGetOptions): Promise<StyleGetResult>;
|
|
45
|
-
|
|
52
|
+
classifyHmrFileEvent(filePath: string, event: 'add' | 'change' | 'unlink'): Promise<StyleHmrUpdate[]>;
|
|
53
|
+
invalidateFileEvent(filePath: string, event: 'add' | 'change' | 'unlink'): void;
|
|
54
|
+
};
|
|
55
|
+
export type StyleHmrUpdate = {
|
|
56
|
+
filePath: string;
|
|
57
|
+
path: string;
|
|
58
|
+
timestamp: number;
|
|
46
59
|
};
|
|
47
60
|
export declare function createStyleCompiler(options: StyleCompilerOptions): StyleCompiler;
|
|
48
61
|
export declare function isStyleFilePath(filePath: string): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../../../src/lib/styles/compiler.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAClD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAEvD,OAAO,KAAK,EAAE,YAAY,EAAgB,MAAM,WAAW,CAAA;AAS3D,KAAK,kBAAkB,GAAG;IACxB,IAAI,EAAE,YAAY,CAAA;IAClB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,SAAS,EAAE,YAAY,GAAG,IAAI,CAAA;CAC/B,CAAA;AAED,KAAK,cAAc,GACf;IACE,KAAK,EAAE,kBAAkB,CAAA;IACzB,IAAI,EAAE,OAAO,CAAA;CACd,GACD;IACE,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,cAAc,CAAA;CACrB,CAAA;AAEL,KAAK,eAAe,GAAG;IACrB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,kBAAkB,EAAE,OAAO,CAAA;IAC3B,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAA;CACpC,CAAA;AAED,KAAK,oBAAoB,GAAG;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,iBAAiB,EAAE,OAAO,CAAA;IAC1B,gBAAgB,CAAC,CACf,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE;QACP,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAA;KACpC,GACA,OAAO,CAAC,MAAM,CAAC,CAAA;IAClB,SAAS,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAA;IACxC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAA;IAC3C,MAAM,EAAE,OAAO,CAAA;IACf,wBAAwB,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,GAAG,EAAE,MAAM,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,KAAK,IAAI,CAAA;IAC/E,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,cAAc,CAAA;IACtB,oBAAoB,EAAE,UAAU,GAAG,KAAK,CAAA;IACxC,UAAU,CAAC,EAAE,UAAU,GAAG,QAAQ,CAAA;IAClC,OAAO,CAAC,EAAE,mBAAmB,CAAA;IAC7B,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAChC,CAAA;AAED,KAAK,aAAa,GAAG;IACnB,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IAC1C,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;IAC3E,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CAAA;IAC7E,
|
|
1
|
+
{"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../../../src/lib/styles/compiler.ts"],"names":[],"mappings":"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"}
|