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: relative assets transform #109

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

Support inline relative asset paths from native tags.
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,21 @@ export default defineConfig({
});
```

# Browser asset references

With @marko/vite when a _static relative path_ is used for certain native tag attributes, the relative asset will be imported and processed by Vite.

As an example, with the following template, the `logo.svg` will be imported and processed as if it was a `import` at the root of the file.

```
<img src="./logo.svg">
// Would produce a Vite processed asset and update the src, eg with the following output
<img src="/assets/logo-TwEWmgMb.svg">
```

You can see the list of elements and their attributes which are processed [here](./src/relative-assets-transform.ts).

# Linked Mode

By default this plugin operates in `linked` mode (you can disabled this by passing [`linked: false` as an option](#options.linked)). In `linked` mode the plugin automatically discovers all of the entry `.marko` files while compiling the server, and tells `Vite` which modules to load in the browser.
Expand Down
44 changes: 22 additions & 22 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"@types/babel__core": "^7.20.4",
"@types/jsdom": "^21.1.5",
"@types/mocha": "^10.0.4",
"@types/node": "^20.9.0",
"@types/node": "^20.9.1",
"@types/resolve": "^1.20.5",
"@types/serve-handler": "^6.1.4",
"@typescript-eslint/eslint-plugin": "^6.11.0",
Expand All @@ -38,12 +38,12 @@
"mocha": "^10.2.0",
"mocha-snap": "^5.0.0",
"nyc": "^15.1.0",
"playwright": "^1.39.0",
"playwright": "^1.40.0",
"prettier": "^3.1.0",
"serve-handler": "^6.1.5",
"tsx": "^4.1.2",
"typescript": "^5.2.2",
"vite": "^5.0.0-beta.17"
"vite": "^5.0.0"
},
"files": [
"dist",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<div
id="implicit"
>
<div
id="clickable"
>
Mounted: false Clicks: 0
<img
alt="logo"
src="/assets/logo-[hash].svg"
/>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<div
id="implicit"
>
<div
id="clickable"
>
Mounted: true Clicks: 0
<img
alt="logo"
src="/assets/logo-[hash].svg"
/>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<div
id="implicit"
>
<div
id="clickable"
>
Mounted: true Clicks: 1
<img
alt="logo"
src="/assets/logo-[hash].svg"
/>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<div
id="implicit"
>
<div
id="clickable"
>
Mounted: false Clicks: 0
<img
alt="logo"
src="/src/components/logo.svg"
/>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<div
id="implicit"
>
<div
id="clickable"
>
Mounted: true Clicks: 0
<img
alt="logo"
src="/src/components/logo.svg"
/>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<div
id="implicit"
>
<div
id="clickable"
>
Mounted: true Clicks: 1
<img
alt="logo"
src="/src/components/logo.svg"
/>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// In dev we'll start a Vite dev server in middleware mode,
// and forward requests to our http request handler.

import { createServer } from "vite";
import path from "path";
import url from "url";
import { createRequire } from "module";

// change to import once marko-vite is updated to ESM
const markoPlugin = createRequire(import.meta.url)("../../..").default;

const __dirname = path.dirname(url.fileURLToPath(import.meta.url));

const devServer = await createServer({
root: __dirname,
appType: "custom",
logLevel: "silent",
plugins: [markoPlugin()],
optimizeDeps: { force: true },
server: {
middlewareMode: true,
watch: {
ignored: ["**/node_modules/**", "**/dist/**", "**/__snapshots__/**"],
},
},
});

export default devServer.middlewares.use(async (req, res, next) => {
try {
const { handler } = await devServer.ssrLoadModule(
path.join(__dirname, "./src/index.js")
);
await handler(req, res, next);
} catch (err) {
devServer.ssrFixStacktrace(err);
return next(err);
}
});
18 changes: 18 additions & 0 deletions src/__tests__/fixtures/isomorphic-relative-asset-import/server.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// In production, simply start up the http server.
import path from 'path'
import url from 'url';
import { createServer } from "http";
import serve from "serve-handler";

globalThis.assetsPath = "/my-prefix/";
// dyanmic import so globalThis.assetsPath can be set prior to the imported code executing
const { handler } = await import("./dist/index.mjs");

const __dirname = path.dirname(url.fileURLToPath(import.meta.url));
const serveOpts = { public: path.resolve(__dirname, "dist") };

export default createServer(async (req, res) => {
await handler(req, res);
if (res.headersSent) return;
await serve(req, res, serveOpts);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
class {
onCreate() {
this.state = {
clickCount: 0,
mounted: false
};
}
onMount() {
this.state.mounted = true;
}
handleClick() {
this.state.clickCount++;
}
}

<div#clickable onClick("handleClick")>
Mounted: ${state.mounted}
Clicks: ${state.clickCount}

<img src="./logo.svg" alt="logo">
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
static {
if (typeof window === "object") {
document.body.firstElementChild.append("Loaded Implicit Component");
}
}

<div#implicit>
<class-component/>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
static {
if (typeof window === "object") {
document.body.firstElementChild.append("Loaded Layout Component");
}
}

<!DOCTYPE html>
<html lang="en">
<head>
<title>Hello World</title>
</head>
<body>
<${input.renderBody}/>
</body>
</html>
Loading