Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: supporting changing module preload mode #2531

Merged
merged 3 commits into from Apr 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
563 changes: 289 additions & 274 deletions docs.md

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions docs/finalize.js
Expand Up @@ -11,8 +11,9 @@ docs = docs.replace(/\x1b\[[0-9;]*m/g, '');
docs = docs.replace(/jspm\/[^\n]+\n/g, '');
docs = docs.replace(/^([a-zA-Z-_]+):$/mg, '### $1');
docs = docs.replace(/ ((-[a-zA-Z], )?--[a-zA-Z-_]+)/mg, '* `$1`');
docs = docs.replace(/\$ (jspm[^\n]+)\n/g, '\n```\n$1```');
docs = docs.replace(/\<([a-zA-Z0-9]+)\>/g, '_&lt;$1&gt;_');
docs = docs.replace(/\$ (jspm[^\n]+)\n/g, '\n```\n$1\n```');
docs = docs.replace(/\<([a-zA-Z0-9]+)\>/g, '_&lt;$1&gt;_'); // <opts>
docs = docs.replace(/\[mode\]/g, '_[mode]_'); // --preload [mode]

const intro = readFileSync('docs/intro.md', 'utf8');
const config = readFileSync('docs/config.md', 'utf8');
Expand Down
575 changes: 289 additions & 286 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions package.json
Expand Up @@ -12,7 +12,7 @@
"jspm.js"
],
"dependencies": {
"@jspm/generator": "^1.1.6",
"@jspm/generator": "^1.1.7",
"cac": "^6.7.14",
"ora": "^6.3.0",
"picocolors": "^1.0.0"
Expand All @@ -22,7 +22,7 @@
"@babel/core": "^7.21.4",
"@types/node": "^18.15.11",
"esbuild": "^0.16.17",
"eslint": "^8.37.0",
"eslint": "^8.38.0",
"eslint-config-prettier": "^8.8.0",
"prettier": "^2.8.7",
"tinyspy": "^1.1.1",
Expand Down
16 changes: 8 additions & 8 deletions src/cli.ts
Expand Up @@ -63,9 +63,9 @@ const outputOpt: opt = [
{},
];
const preloadOpt: opt = [
"--preload",
"Add module preloads to HTML output",
{ default: false },
"--preload [mode]",
"Add module preloads to HTML output (default: static, dynamic)",
{},
];
const integrityOpt: opt = [
"--integrity",
Expand Down Expand Up @@ -118,8 +118,8 @@ cli
.option(...providerOpt)
.option(...cacheOpt)
.option(...rootOpt)
.option(...integrityOpt)
.option(...preloadOpt)
.option(...integrityOpt)
.option(...compactOpt)
.option(...freezeOpt)
.option(...stdoutOpt)
Expand All @@ -137,7 +137,7 @@ cli
(
name
) => `Link an HTML file and update its import map including preload and integrity tags
$ ${name} link --map index.html --integrity --preload
$ ${name} link --map index.html --integrity --preload static
`
)
.usage(
Expand Down Expand Up @@ -165,8 +165,8 @@ cli
.option(...providerOpt)
.option(...cacheOpt)
.option(...rootOpt)
.option(...integrityOpt)
.option(...preloadOpt)
.option(...integrityOpt)
.option(...compactOpt)
.option(...freezeOpt)
.option(...stdoutOpt)
Expand Down Expand Up @@ -220,8 +220,8 @@ cli
.option(...providerOpt)
.option(...cacheOpt)
.option(...rootOpt)
.option(...integrityOpt)
.option(...preloadOpt)
.option(...integrityOpt)
.option(...compactOpt)
.option(...freezeOpt)
.option(...stdoutOpt)
Expand Down Expand Up @@ -249,8 +249,8 @@ cli
.option(...providerOpt)
.option(...cacheOpt)
.option(...rootOpt)
.option(...integrityOpt)
.option(...preloadOpt)
.option(...integrityOpt)
.option(...compactOpt)
.option(...freezeOpt)
.option(...stdoutOpt)
Expand Down
24 changes: 13 additions & 11 deletions src/install.ts
Expand Up @@ -2,14 +2,14 @@ import c from "picocolors";
import { withType } from "./logger";
import type { Flags } from "./types";
import {
JspmError,
getEnv,
getGenerator,
getInput,
isUrlLikeNotPackage,
startSpinner,
stopSpinner,
writeOutput
JspmError,
getEnv,
getGenerator,
getInput,
isUrlLikeNotPackage,
startSpinner,
stopSpinner,
writeOutput,
} from "./utils";

export default async function install(packages: string[], flags: Flags) {
Expand All @@ -25,10 +25,9 @@ export default async function install(packages: string[], flags: Flags) {
return { alias, target };
});


// Packages that can be installed by the generator:
const resolvedPackages = parsedPackages.filter(isInstallable);

// Packages that can be installed directly as URLs, see the issue:
// https://github.com/jspm/generator/issues/291
const urlLikePackages = parsedPackages.filter((p) => !isInstallable(p));
Expand All @@ -43,7 +42,10 @@ export default async function install(packages: string[], flags: Flags) {
if (urlLikePackages?.length) {
const imports = {};
for (const { alias, target } of urlLikePackages) {
if (!alias) throw new JspmError(`URL-like target "${target}" must be given an alias to install under, such as "name=${target}".`);
if (!alias)
throw new JspmError(
`URL-like target "${target}" must be given an alias to install under, such as "name=${target}".`
);

imports[alias] = target;
}
Expand Down
2 changes: 1 addition & 1 deletion src/types.ts
Expand Up @@ -8,7 +8,7 @@ export interface Flags {
root?: string;
provider?: string;
stdout?: boolean;
preload?: boolean;
preload?: boolean | string;
integrity?: boolean;
compact?: boolean;
freeze?: boolean;
Expand Down
34 changes: 28 additions & 6 deletions src/utils.ts
Expand Up @@ -129,7 +129,7 @@ async function writeHtmlOutput(
pins: pins ?? true,
htmlUrl: generator.mapUrl, // URL of the output map
rootUrl: generator.rootUrl,
preload: flags.preload,
preload: getPreloadMode(flags),
integrity: flags.integrity,
whitespace: !flags.compact,
comment: false,
Expand Down Expand Up @@ -361,16 +361,39 @@ function getCacheMode(flags: Flags): "offline" | boolean {
"online"
)} Use a locally cached module if available and fresh.\n\t${c.bold(
"offline"
)} Use a locally cached module if available, even if stale.\n\t${c.bold(
)} Use a locally cached module if available, even if stale.\n\t${c.bold(
"no-cache"
)} Never use the local cache.`
)} Never use the local cache.`
);

if (flags.cache === "offline") return "offline";
if (flags.cache === "online") return true;
return false;
}

const validPreloadModes = ["static", "dynamic"];
function getPreloadMode(flags: Flags): boolean | string {
if (flags.preload === null || flags.preload === undefined) return false;
if (typeof flags.preload === "boolean") {
return flags.preload;
}

if (!validPreloadModes.includes(flags.preload))
Bubblyworld marked this conversation as resolved.
Show resolved Hide resolved
throw new JspmError(
`Invalid preload mode "${
flags.preload
}". Available modes are: "${validPreloadModes.join('", "')}".\n\t${c.bold(
"static"
)} Inject preload tags for static dependencies.\n\t${c.bold(
"dynamic"
)} Inject preload tags for static and dynamic dependencies.`
);

if (flags.preload === "static") return "static";
if (flags.preload === "dynamic") return "all";
return false; // should never get here
}

const spinner = ora({ spinner: "dots" });

export function startSpinner(text: string) {
Expand Down Expand Up @@ -422,14 +445,13 @@ export function parsePackageSpec(pkgTarget: string): string {
* Returns true if the given specifier is a relative URL or a URL.
*/
export function isUrlLikeNotPackage(spec: string): boolean {
if (spec.endsWith('/'))
return false;
if (spec.endsWith("/")) return false;
if (spec.startsWith("./") || spec.startsWith("../") || spec.startsWith("/"))
return true;
try {
// eslint-disable-next-line no-new
new URL(spec);
return spec[spec.indexOf(':') + 1] === '/';
return spec[spec.indexOf(":") + 1] === "/";
} catch {
return false;
}
Expand Down
4 changes: 2 additions & 2 deletions test/html.test.ts
Expand Up @@ -45,7 +45,7 @@ const scenarios: Scenario[] = [
},
{
files: importMap,
commands: ["jspm link react -o index.html --preload"],
commands: ["jspm link react -o index.html --preload static"],
validationFn: async (files: Map<string, string>) => {
// The index.html should contain the react version from the import map,
// and integrities for it, but nothing else:
Expand All @@ -58,7 +58,7 @@ const scenarios: Scenario[] = [
},
{
files: importMap,
commands: ["jspm install react -o index.html --integrity"],
commands: ["jspm install react -o index.html --preload --integrity"],
validationFn: async (files: Map<string, string>) => {
// The index.html should contain all the pins, and integrities for them:
// NOTE: this will break if we change the CDN build!
Expand Down