Skip to content

Commit d533f5e

Browse files
[vite-plugin]: fix applications not being able to import assets from dependencies (#8672)
* [vite-plugin]: fix applications not being able to import assets from dependencies * remove runtime checking in favour of config validation * update lock file * add missing optional chaining * add e2e to make sure validation takes place * add TODO * Apply suggestions from code review Co-authored-by: James Opstad <[email protected]> * update inline snapshots * problematic -> disallowed * fix typo in filename * update changeset --------- Co-authored-by: James Opstad <[email protected]>
1 parent 654e1b9 commit d533f5e

25 files changed

+480
-105
lines changed

.changeset/twenty-ads-follow.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
"@cloudflare/vite-plugin": patch
3+
---
4+
5+
replace modules runtime checks with vite environment config validation
6+
7+
currently at runtime the vite plugin applies checks to make sure that
8+
external files are not being imported, such checks are however too
9+
restrictive and prevent worker code to perform some valid imports from
10+
node_modules (e.g. `import stylesheet from "<some-package>/styles.css?url";`)
11+
12+
the changes here replace the runtime checks (allowing valid imports from
13+
node_modules) with some validation to the worker vite environment configurations,
14+
specifically they make sure that the environment doesn't specify invalid
15+
`optimizeDeps.exclude` and `resolve.external` options
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export default {
2+
async fetch() {
3+
return new Response("Hello World!");
4+
},
5+
};
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"name": "@vite-plugin-cloudflare-e2e/invalid-worker-env-configs",
3+
"private": true,
4+
"type": "module",
5+
"scripts": {
6+
"dev": "vite dev"
7+
},
8+
"devDependencies": {
9+
"@cloudflare/vite-plugin": "*",
10+
"vite": "^6.2.3"
11+
}
12+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { cloudflare } from "@cloudflare/vite-plugin";
2+
import { defineConfig } from "vite";
3+
4+
export default defineConfig({
5+
plugins: [
6+
cloudflare({
7+
inspectorPort: false,
8+
persistState: false,
9+
viteEnvironment: { name: "worker" },
10+
}),
11+
],
12+
environments: {
13+
worker: {
14+
optimizeDeps: {
15+
exclude: ["pkg"],
16+
},
17+
},
18+
},
19+
});
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
name = "worker"
2+
main = "./index.js"
3+
compatibility_date = "2024-12-30"
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { describe } from "vitest";
2+
import { test } from "./helpers.js";
3+
4+
// Note: the test here just makes sure that the validation does take place, for more fine grained
5+
// testing regarding the validation there are unit tests in src/__tests__/validate_worker_environments_resolved_configs.spec.ts
6+
7+
describe("during development wrangler config files are validated", () => {
8+
test("for the entry worker", async ({ expect, seed, viteDev }) => {
9+
const projectPath = await seed("invalid-worker-env-configs", "pnpm");
10+
11+
const proc = viteDev(projectPath);
12+
13+
expect(await proc.exitCode).not.toBe(0);
14+
expect(proc.stderr).toContain(
15+
"The following environment configurations are incompatible with the Cloudflare vite plugin"
16+
);
17+
});
18+
});
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { expect, test } from "vitest";
2+
import { getTextResponse } from "../../__test-utils__";
3+
4+
test("it is possible to import assets from dependencies", async () => {
5+
expect(await getTextResponse()).toMatch(
6+
/Hello! This is an application built using vite@[^ ]+? \(information retrieved from "[^"]+?\.json"\)/
7+
);
8+
});
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"name": "@playground/deps-assets-importing",
3+
"private": true,
4+
"type": "module",
5+
"scripts": {
6+
"build": "vite build --app",
7+
"check:types": "tsc --build",
8+
"dev": "vite dev",
9+
"preview": "vite preview"
10+
},
11+
"devDependencies": {
12+
"@cloudflare/vite-plugin": "workspace:*",
13+
"@cloudflare/workers-tsconfig": "workspace:*",
14+
"@cloudflare/workers-types": "^4.20250321.0",
15+
"typescript": "catalog:default",
16+
"vite": "catalog:vite-plugin",
17+
"wrangler": "workspace:*"
18+
}
19+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import vitePackageJson from "vite/package.json?raw";
2+
import url from "vite/package.json?url";
3+
4+
export default {
5+
async fetch() {
6+
const json = JSON.parse(vitePackageJson);
7+
return new Response(
8+
`Hello! This is an application built using ${json.name}@${json.version} (information retrieved from "${url}")`
9+
);
10+
},
11+
} satisfies ExportedHandler;
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"files": [],
3+
"references": [
4+
{ "path": "./tsconfig.node.json" },
5+
{ "path": "./tsconfig.worker.json" }
6+
]
7+
}

0 commit comments

Comments
 (0)