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

fix: improve tags api support #158

Merged
merged 1 commit into from
Nov 18, 2024
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/fair-fireants-burn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@marko/vite": major
---

Drop support for passing in a dynamic compiler (rely on peerDependency).
5 changes: 5 additions & 0 deletions .changeset/shy-penguins-stare.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@marko/vite": minor
---

Detect when native tags api translator is in use and tweak virtual files to work properly.
11 changes: 4 additions & 7 deletions src/esbuild-plugin.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import fs from "fs";
import path from "path";
import type * as vite from "vite";
import type * as Compiler from "@marko/compiler";
import * as compiler from "@marko/compiler";

type ESBuildOptions = Exclude<
vite.DepOptimizationConfig["esbuildOptions"],
Expand All @@ -12,10 +12,7 @@ type ESBuildLoader = Exclude<ESBuildOptions["loader"], undefined>[string];

const markoErrorRegExp = /^(.+?)(?:\((\d+)(?:\s*,\s*(\d+))?\))?: (.*)$/gm;

export default function esbuildPlugin(
compiler: typeof Compiler,
config: Compiler.Config,
): ESBuildPlugin {
export default function esbuildPlugin(config: compiler.Config): ESBuildPlugin {
return {
name: "marko",
async setup(build) {
Expand All @@ -24,7 +21,7 @@ export default function esbuildPlugin(
(v) => v.name === "vite:dep-scan",
);
const virtualFiles = new Map<string, { code: string; map?: unknown }>();
const finalConfig: Compiler.Config = {
const finalConfig: compiler.Config = {
...config,
output: platform === "browser" ? "dom" : "html",
resolveVirtualDependency(from, dep) {
Expand All @@ -33,7 +30,7 @@ export default function esbuildPlugin(
},
};

const scanConfig: Compiler.Config = {
const scanConfig: compiler.Config = {
...finalConfig,
output: "hydrate",
};
Expand Down
36 changes: 17 additions & 19 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type * as vite from "vite";
import type * as Compiler from "@marko/compiler";
import * as compiler from "@marko/compiler";
import defaultConfig from "@marko/compiler/config";

import fs from "fs";
import path from "path";
Expand Down Expand Up @@ -33,16 +34,14 @@ export namespace API {
export interface Options {
// Defaults to true, set to false to disable automatic component discovery and hydration.
linked?: boolean;
// Override the Marko compiler instance being used. (primarily for tools wrapping this module)
compiler?: string;
// Sets a custom runtimeId to avoid conflicts with multiple copies of Marko on the same page.
runtimeId?: string;
// Overrides the Marko translator being used.
translator?: string;
// If set, will use the provided string as a variable name and prefix all assets paths with that variable.
basePathVar?: string;
// Overrides the Babel config that Marko will use.
babelConfig?: Compiler.Config["babelConfig"];
babelConfig?: compiler.Config["babelConfig"];
}

interface BrowserManifest {
Expand Down Expand Up @@ -92,7 +91,7 @@ const htmlExt = ".html";
const resolveOpts = { skipSelf: true };
const configsByFileSystem = new Map<
typeof fs,
Map<Compiler.Config, Compiler.Config>
Map<compiler.Config, compiler.Config>
>();
const cache = new Map<unknown, unknown>();
const babelCaller = {
Expand All @@ -106,22 +105,21 @@ const babelCaller = {
let registeredTagLib = false;

// This package has a dependency on @parcel/source-map which uses native addons.
// Some enviroments like Stackblitz don't support loading these. So... load it
// Some environments like Stackblitz don't support loading these. So... load it
// with a dynamic import to avoid everything failing.
let cjsToEsm: typeof import("@chialab/cjs-to-esm").transform | null | undefined;

export default function markoPlugin(opts: Options = {}): vite.Plugin[] {
let compiler: typeof Compiler;
let { linked = true } = opts;
let runtimeId: string | undefined;
let basePathVar: string | undefined;
let baseConfig: Compiler.Config;
let ssrConfig: Compiler.Config;
let ssrCjsConfig: Compiler.Config;
let domConfig: Compiler.Config;
let hydrateConfig: Compiler.Config;
let baseConfig: compiler.Config;
let ssrConfig: compiler.Config;
let ssrCjsConfig: compiler.Config;
let domConfig: compiler.Config;
let hydrateConfig: compiler.Config;

const resolveVirtualDependency: Compiler.Config["resolveVirtualDependency"] =
const resolveVirtualDependency: compiler.Config["resolveVirtualDependency"] =
(from, dep) => {
const normalizedFrom = normalizePath(from);
const query = `${virtualFileQuery}&id=${
Expand Down Expand Up @@ -152,6 +150,9 @@ export default function markoPlugin(opts: Options = {}): vite.Plugin[] {
let serverManifest: ServerManifest | undefined;
let basePath = "/";
let getMarkoAssetFns: undefined | API.getMarkoAssetCodeForEntry[];
const tagsAPI = !/^@marko\/translator-(?:default|interop-class-tags)$/.test(
opts.translator ?? defaultConfig.translator,
);
const entryIds = new Set<string>();
const cachedSources = new Map<string, string>();
const transformWatchFiles = new Map<string, string[]>();
Expand All @@ -175,10 +176,6 @@ export default function markoPlugin(opts: Options = {}): vite.Plugin[] {
process.env.MARKO_DEBUG = optimize ? "false" : "true";
}

compiler ??= (await import(
opts.compiler || "@marko/compiler"
)) as typeof Compiler;

runtimeId = opts.runtimeId;
basePathVar = opts.basePathVar;

Expand Down Expand Up @@ -296,7 +293,7 @@ export default function markoPlugin(opts: Options = {}): vite.Plugin[] {

const esbuildOptions = (optimizeDeps.esbuildOptions ??= {});
const esbuildPlugins = (esbuildOptions.plugins ??= []);
esbuildPlugins.push(esbuildPlugin(compiler, baseConfig));
esbuildPlugins.push(esbuildPlugin(baseConfig));

const ssr = (config.ssr ??= {});
const { noExternal } = ssr;
Expand Down Expand Up @@ -658,6 +655,7 @@ export default function markoPlugin(opts: Options = {}): vite.Plugin[] {
entryData,
runtimeId,
basePathVar: isBuild ? basePathVar : undefined,
tagsAPI,
});
}
}
Expand Down Expand Up @@ -940,7 +938,7 @@ function stripVersionAndTimeStamp(id: string) {
*/
function getConfigForFileSystem(
info: vite.Rollup.ModuleInfo | undefined | null,
config: Compiler.Config,
config: compiler.Config,
) {
const fileSystem = info?.meta.arcFS;
if (!fileSystem) return config;
Expand Down
2 changes: 1 addition & 1 deletion src/render-assets-transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ function renderAssetsCall(t: typeof types, slot: string) {
return t.markoPlaceholder(
t.callExpression(
t.memberExpression(
t.memberExpression(t.identifier("out"), t.identifier("global")),
t.identifier("$global"),
t.identifier("___viteRenderAssets"),
),
[t.stringLiteral(slot)],
Expand Down
29 changes: 17 additions & 12 deletions src/server-entry-template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,42 +5,47 @@ export default async (opts: {
entryData: string[];
runtimeId?: string;
basePathVar?: string;
tagsAPI?: boolean;
}): Promise<string> => {
const addAssetsCall = `addAssets($global, [${opts.entryData.join(",")}])`;
const fileNameStr = JSON.stringify(`./${path.basename(opts.fileName)}`);
return `import template from ${fileNameStr};
export * from ${fileNameStr};
import { addAssets } from "${renderAssetsRuntimeId}";

$ const g = out.global;
$ const writeSync = addAssets(g, [${opts.entryData.join(",")}]);
${opts.tagsAPI ? `<const/writeSync=${addAssetsCall}/>` : `$ const writeSync = ${addAssetsCall};`}

<if(writeSync)>
$!{
g.___viteRenderAssets("head-prepend") +
g.___viteRenderAssets("head") +
g.___viteRenderAssets("body-prepend")
$global.___viteRenderAssets("head-prepend") +
$global.___viteRenderAssets("head") +
$global.___viteRenderAssets("body-prepend")
}
</>
<else>
<__flush_here_and_after__>
$!{
g.___viteRenderAssets("head-prepend") +
g.___viteRenderAssets("head") +
g.___viteRenderAssets("body-prepend")
$global.___viteRenderAssets("head-prepend") +
$global.___viteRenderAssets("head") +
$global.___viteRenderAssets("body-prepend")
}
</__flush_here_and_after__>
</>

<\${template} ...input/>
<\${template} ...input/>${
opts.tagsAPI
? ""
: `
<init-components/>
<await-reorderer/>
<await-reorderer/>`
}

<if(writeSync)>
$!{g.___viteRenderAssets("body")}
$!{$global.___viteRenderAssets("body")}
</>
<else>
<__flush_here_and_after__>
$!{g.___viteRenderAssets("body")}
$!{$global.___viteRenderAssets("body")}
</__flush_here_and_after__>
</>
`;
Expand Down
Loading