From 1220c98ca71d8bc941ca7cce42aa291f7c5a33f3 Mon Sep 17 00:00:00 2001 From: dpiercey Date: Mon, 13 Nov 2023 09:08:54 -0700 Subject: [PATCH] fix: ensure arc plugin always runs first --- .changeset/beige-windows-destroy.md | 5 + package-lock.json | 575 +++++++----------- package.json | 6 +- src/plugins/build-ssr.ts | 9 +- src/plugins/build-web.ts | 14 +- src/plugins/serve.ts | 4 +- src/tests/fixtures/basic/src/entry-server.ts | 8 +- src/tests/fixtures/marko/config.ts | 18 + src/tests/fixtures/marko/src/a.ts | 6 + src/tests/fixtures/marko/src/a[mobile].ts | 6 + .../fixtures/marko/src/b-mobile-only.css | 3 + src/tests/fixtures/marko/src/b.ts | 5 + src/tests/fixtures/marko/src/b[mobile].ts | 6 + src/tests/fixtures/marko/src/c.css | 0 src/tests/fixtures/marko/src/c[mobile].css | 3 + .../fixtures/marko/src/components/app.marko | 7 + src/tests/fixtures/marko/src/entry-server.ts | 11 + src/tests/fixtures/marko/src/index.marko | 11 + src/tests/marko.test.ts | 97 +++ src/tests/types.d.ts | 5 + src/tests/utils/dev-server.ts | 35 +- src/tests/utils/prod-server.ts | 14 +- src/utils/ensure-arc-plugin-is-first.ts | 18 + src/utils/options.ts | 4 +- 24 files changed, 478 insertions(+), 392 deletions(-) create mode 100644 .changeset/beige-windows-destroy.md create mode 100644 src/tests/fixtures/marko/config.ts create mode 100644 src/tests/fixtures/marko/src/a.ts create mode 100644 src/tests/fixtures/marko/src/a[mobile].ts create mode 100644 src/tests/fixtures/marko/src/b-mobile-only.css create mode 100644 src/tests/fixtures/marko/src/b.ts create mode 100644 src/tests/fixtures/marko/src/b[mobile].ts create mode 100644 src/tests/fixtures/marko/src/c.css create mode 100644 src/tests/fixtures/marko/src/c[mobile].css create mode 100644 src/tests/fixtures/marko/src/components/app.marko create mode 100644 src/tests/fixtures/marko/src/entry-server.ts create mode 100644 src/tests/fixtures/marko/src/index.marko create mode 100644 src/tests/marko.test.ts create mode 100644 src/tests/types.d.ts create mode 100644 src/utils/ensure-arc-plugin-is-first.ts diff --git a/.changeset/beige-windows-destroy.md b/.changeset/beige-windows-destroy.md new file mode 100644 index 0000000..6aa24e9 --- /dev/null +++ b/.changeset/beige-windows-destroy.md @@ -0,0 +1,5 @@ +--- +"arc-vite": patch +--- + +Ensure arc plugin always runs first. diff --git a/package-lock.json b/package-lock.json index 11d5893..bfc73c4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,8 @@ "devDependencies": { "@changesets/changelog-github": "^0.4.8", "@changesets/cli": "^2.26.2", - "@marko/compiler": "^5.33.5", + "@marko/compiler": "^5.33.7", + "@marko/vite": "^4.0.0", "@playwright/test": "^1.39.0", "@types/estree": "^1.0.5", "@types/node": "^20.9.0", @@ -31,8 +32,9 @@ "eslint-plugin-import": "^2.29.0", "husky": "^8.0.3", "lint-staged": "^15.0.2", + "marko": "^5.31.17", "playwright": "^1.39.0", - "prettier": "^3.0.3", + "prettier": "^3.1.0", "serve-handler": "^6.1.5", "sort-package-json": "^2.6.0", "tsx": "^4.1.0", @@ -837,54 +839,6 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, - "node_modules/@esbuild/android-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", - "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", - "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", - "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/@esbuild/darwin-arm64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", @@ -901,294 +855,6 @@ "node": ">=12" } }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", - "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", - "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", - "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", - "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", - "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", - "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", - "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", - "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", - "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", - "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", - "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", - "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", - "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", - "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", - "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", - "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", - "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", - "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -1447,9 +1113,9 @@ } }, "node_modules/@marko/babel-utils": { - "version": "6.3.2", - "resolved": "https://registry.npmjs.org/@marko/babel-utils/-/babel-utils-6.3.2.tgz", - "integrity": "sha512-biUkc0tWB7abewfGgseSNox6U4x0+rNjeZWtE+3Snl2O+k8MqJGkX5ip9PFIS10KMhaLVYg6piS2trbtmfmb3A==", + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@marko/babel-utils/-/babel-utils-6.3.3.tgz", + "integrity": "sha512-dVrND1+KLzvm53DtRi9uag53qRFNq6MgKH9LOnEbJIz0Sz2Dg49R3dPOX8Z+9kgyJHGblofnE5zlttUa9RmXew==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", @@ -1458,9 +1124,9 @@ } }, "node_modules/@marko/compiler": { - "version": "5.33.5", - "resolved": "https://registry.npmjs.org/@marko/compiler/-/compiler-5.33.5.tgz", - "integrity": "sha512-CThZ2yynoG2VONAC6nsexow74hWwkGFObquGnBYOvkM5pBz/C0DLRcbjtAKyLwX2ARLrNs3sZv0UAPQOf2cOmg==", + "version": "5.33.7", + "resolved": "https://registry.npmjs.org/@marko/compiler/-/compiler-5.33.7.tgz", + "integrity": "sha512-92ZEPyuvFS6eIatXbu61J/Y7n+4MilHxqvytH71kaOgfabjJinx4uQV1qT4FRg3YGTbgUjtCqxyaqhvOIeECzA==", "dev": true, "dependencies": { "@babel/code-frame": "^7.16.0", @@ -1473,7 +1139,7 @@ "@babel/runtime": "^7.16.0", "@babel/traverse": "^7.16.0", "@babel/types": "^7.16.0", - "@marko/babel-utils": "^6.3.2", + "@marko/babel-utils": "^6.3.3", "complain": "^1.6.0", "he": "^1.2.0", "htmljs-parser": "^5.4.3", @@ -1489,6 +1155,53 @@ "strip-json-comments": "^3.1.1" } }, + "node_modules/@marko/translator-default": { + "version": "5.31.7", + "resolved": "https://registry.npmjs.org/@marko/translator-default/-/translator-default-5.31.7.tgz", + "integrity": "sha512-ZFIWcE2WBEm4re8o7AJ4bC75Znz2cGBJH99I98F2Aj/gmM0+FdxjXLYM8ykXCssAQsoJ5yTo8X/Po5tugYN0fg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.16.0", + "@marko/babel-utils": "^6.3.3", + "escape-string-regexp": "^4.0.0", + "magic-string": "^0.27.0", + "self-closing-tags": "^1.0.1" + }, + "peerDependencies": { + "@marko/compiler": "^5.16.1", + "marko": "^5.17.2" + } + }, + "node_modules/@marko/translator-default/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@marko/vite": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@marko/vite/-/vite-4.0.0.tgz", + "integrity": "sha512-yeYTimM9xQxX1ct6EGTJmJG1rcQk/+DmcB1ErBW1qJB1h8o8qHk3sAGFw/faPrgODneD/V9wtwc1Viih14T61A==", + "dev": true, + "dependencies": { + "anymatch": "^3.1.3", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "htmlparser2": "^9.0.0", + "resolve": "^1.22.8", + "resolve.exports": "^2.0.2" + }, + "peerDependencies": { + "@marko/compiler": "^5", + "vite": "4 - 5" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -1885,6 +1598,25 @@ "node": ">=4" } }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/app-module-path": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/app-module-path/-/app-module-path-2.2.0.tgz", + "integrity": "sha512-gkco+qxENJV+8vFcDiiFhuoSvRXb2a/QPqpSoWhVz829VNJfOTnELbBmPmNKFxf3xdNnw4DWCkzkDaavcX/1YQ==", + "dev": true + }, "node_modules/arc-flag-parser": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/arc-flag-parser/-/arc-flag-parser-2.0.0.tgz", @@ -1935,6 +1667,12 @@ "arc-flag-parser": "^2.0.0" } }, + "node_modules/argly": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/argly/-/argly-1.2.0.tgz", + "integrity": "sha512-+F3InkcH2XOGK7Jf/ZQis4cwZ4wbfmpBKo5J+SAA9bglT1gVd0e9hroHWarU076pJrAfs8JKuRPwDqwPBOKHnw==", + "dev": true + }, "node_modules/argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -2070,6 +1808,15 @@ "node": ">=0.10.0" } }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/available-typed-arrays": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", @@ -2131,6 +1878,12 @@ "wcwidth": "^1.0.1" } }, + "node_modules/browser-refresh-client": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/browser-refresh-client/-/browser-refresh-client-1.1.4.tgz", + "integrity": "sha512-FM/UzMFsG7wJ1ocxCSl6U7qGAIWASEk+tlvfJLP2Pd1JfS4kQ1r4d5f+nNmQI8fB8sXSD8+u/mWErEkAMxUu3w==", + "dev": true + }, "node_modules/browserslist": { "version": "4.22.1", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz", @@ -2334,6 +2087,20 @@ } ] }, + "node_modules/chai": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-3.5.0.tgz", + "integrity": "sha512-eRYY0vPS2a9zt5w5Z0aCeWbrXTEyvk7u/Xf71EzNObrjSCPgMm1Nku/D/u2tiqHBX5j40wWhj54YJLtgn8g55A==", + "dev": true, + "dependencies": { + "assertion-error": "^1.0.1", + "deep-eql": "^0.1.3", + "type-detect": "^1.0.0" + }, + "engines": { + "node": ">= 0.4.0" + } + }, "node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -2576,6 +2343,12 @@ "node": ">= 8" } }, + "node_modules/csstype": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", + "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==", + "dev": true + }, "node_modules/csv": { "version": "5.5.3", "resolved": "https://registry.npmjs.org/csv/-/csv-5.5.3.tgz", @@ -2666,6 +2439,27 @@ "node": ">=0.10.0" } }, + "node_modules/deep-eql": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz", + "integrity": "sha512-6sEotTRGBFiNcqVoeHwnfopbSpi5NbH1VWJmYCVkmxMmaVTT0bUTrNaGyBwhgP4MZL012W/mkzIn3Da+iDYweg==", + "dev": true, + "dependencies": { + "type-detect": "0.1.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/deep-eql/node_modules/type-detect": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz", + "integrity": "sha512-5rqszGVwYgBoDkIm2oUtvkfZMQ0vk29iDMU0W2qCa3rG0vPDNczCMT4hV/bLBgLg8k8ri6+u3Zbt+S/14eMzlA==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -3534,6 +3328,15 @@ "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", "dev": true }, + "node_modules/events-light": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/events-light/-/events-light-1.0.5.tgz", + "integrity": "sha512-jF51LJzg5W+tkJgfZbjlbFCLcyVFEtOjU+xMCBylrXG13X5XHvfp6lNGfyBLF9u1mRTpUsMVYqSDukvpZff1mQ==", + "dev": true, + "dependencies": { + "chai": "^3.5.0" + } + }, "node_modules/execa": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", @@ -4832,6 +4635,12 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/listener-tracker": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/listener-tracker/-/listener-tracker-2.0.0.tgz", + "integrity": "sha512-U6NLzBRyrAsJs9AAjuBYifXtNYnAIDPIp81rNpxNoypXBR7qi/LhsuUWX5399zuTg1sBEQyOnWDYFrBQ28vk/w==", + "dev": true + }, "node_modules/listr2": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/listr2/-/listr2-7.0.2.tgz", @@ -4943,6 +4752,18 @@ "yallist": "^3.0.2" } }, + "node_modules/magic-string": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz", + "integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.13" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/make-dir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", @@ -4970,6 +4791,31 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/marko": { + "version": "5.31.17", + "resolved": "https://registry.npmjs.org/marko/-/marko-5.31.17.tgz", + "integrity": "sha512-QC75Mlsq05LAvL2F/EPm0eLJREzVCo/nQMfcf48uwsqlGr+eAUjlU/m+yN3yLctb95iLjrny7qx5iVKvrCaIBg==", + "dev": true, + "dependencies": { + "@marko/compiler": "^5.33.7", + "@marko/translator-default": "^5.31.7", + "app-module-path": "^2.2.0", + "argly": "^1.2.0", + "browser-refresh-client": "1.1.4", + "complain": "^1.6.0", + "csstype": "^3.1.2", + "events-light": "^1.0.5", + "listener-tracker": "^2.0.0", + "minimatch": "^3.0.4", + "raptor-util": "^3.2.0", + "resolve-from": "^5.0.0", + "self-closing-tags": "^1.0.1", + "warp10": "^2.0.1" + }, + "bin": { + "markoc": "bin/markoc" + } + }, "node_modules/meow": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/meow/-/meow-6.1.1.tgz", @@ -5211,6 +5057,15 @@ "semver": "bin/semver" } }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/npm-run-path": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", @@ -5712,9 +5567,9 @@ } }, "node_modules/prettier": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.3.tgz", - "integrity": "sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.1.0.tgz", + "integrity": "sha512-TQLvXjq5IAibjh8EpBIkNKxO749UEWABoiIZehEPiY4GNpVdhaFKqSTu+QrlU6D2dPAfubRmtJTi4K4YkQ5eXw==", "dev": true, "bin": { "prettier": "bin/prettier.cjs" @@ -5951,6 +5806,15 @@ "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" } }, + "node_modules/resolve.exports": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", + "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/restore-cursor": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", @@ -7086,6 +6950,15 @@ "node": ">= 0.8.0" } }, + "node_modules/type-detect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-1.0.0.tgz", + "integrity": "sha512-f9Uv6ezcpvCQjJU0Zqbg+65qdcszv3qUQsZfjdRbWiZ7AMenrX1u0lNk9EoWWX6e1F+NULyg27mtdeZ5WhpljA==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/type-fest": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", @@ -7333,6 +7206,12 @@ } } }, + "node_modules/warp10": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/warp10/-/warp10-2.1.0.tgz", + "integrity": "sha512-krhkqzJdUxAZv2Cx0Gz6dN1r7TTrG9RDewkDHBbJQIqbNTCdB5ZUHVh7VkA4DgrKW4ZXPPUQKCwmI/3btDse9A==", + "dev": true + }, "node_modules/wcwidth": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", diff --git a/package.json b/package.json index 22a77bd..7de94c1 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,8 @@ "devDependencies": { "@changesets/changelog-github": "^0.4.8", "@changesets/cli": "^2.26.2", - "@marko/compiler": "^5.33.5", + "@marko/compiler": "^5.33.7", + "@marko/vite": "^4.0.0", "@playwright/test": "^1.39.0", "@types/estree": "^1.0.5", "@types/node": "^20.9.0", @@ -63,8 +64,9 @@ "eslint-plugin-import": "^2.29.0", "husky": "^8.0.3", "lint-staged": "^15.0.2", + "marko": "^5.31.17", "playwright": "^1.39.0", - "prettier": "^3.0.3", + "prettier": "^3.1.0", "serve-handler": "^6.1.5", "sort-package-json": "^2.6.0", "tsx": "^4.1.0", diff --git a/src/plugins/build-ssr.ts b/src/plugins/build-ssr.ts index 28772c2..4d27a4a 100644 --- a/src/plugins/build-ssr.ts +++ b/src/plugins/build-ssr.ts @@ -6,6 +6,7 @@ import { indexToId } from "../utils/index-to-id"; import { decodeFileName, encodeFileName } from "../utils/filename-encoding"; import { isCssFile } from "../utils/is-css-file"; import { toPosix } from "../utils/to-posix"; +import { ensureArcPluginIsFirst } from "../utils/ensure-arc-plugin-is-first"; const virtualArcServerModuleId = "\0arc-server-virtual"; const arcPrefix = "\0arc-"; @@ -34,6 +35,9 @@ export function pluginBuildSSR({ apply(config, { command }) { return command === "build" && !!config.build?.ssr; }, + config(config) { + ensureArcPluginIsFirst(config.plugins!); + }, configResolved(config) { root = config.root; }, @@ -64,9 +68,6 @@ export function pluginBuildSSR({ const matches = getMatches(id, flagSets); if (matches) { adaptiveMatchesForId.set(id, matches); - if (!this.getModuleInfo(id)?.ast) { - await this.load(resolved); - } return { id: encodeArcProxyId(id), }; @@ -118,7 +119,7 @@ function partsToString(parts, base, injectAttrs) { id = decodeArcProxyId(id); const adaptiveMatches = adaptiveMatchesForId.get(id); if (adaptiveMatches) { - const info = this.getModuleInfo(id); + const info = await this.load({ id }); if (info) { if (isCssFile(id)) { let code = ""; diff --git a/src/plugins/build-web.ts b/src/plugins/build-web.ts index f84608e..0003577 100644 --- a/src/plugins/build-web.ts +++ b/src/plugins/build-web.ts @@ -13,12 +13,13 @@ import { generateDocManifest, generateInputDoc, } from "../utils/manifest"; +import { ensureArcPluginIsFirst } from "../utils/ensure-arc-plugin-is-first"; const arcPrefix = "\0arc-"; const arcJsSuffix = ".mjs"; const arcProxyPrefix = `${arcPrefix}proxy:`; const arcInitPrefix = `${arcPrefix}init:`; -const arcHTMLChunkReg = /([^/\\]+?)\.arc(?:\.(.+))?\.html$/; +const arcHTMLChunkReg = /(.+)\.arc(?:\.(.+))?\.html$/; export function pluginBuildWeb({ runtimeId, @@ -43,6 +44,9 @@ export function pluginBuildWeb({ name: "arc-vite:build-web", enforce: "pre", apply, + config(config) { + ensureArcPluginIsFirst(config.plugins!); + }, configResolved(config) { basePath = config.base; }, @@ -196,9 +200,7 @@ export function pluginBuildWeb({ importer, resolvedAdaptiveImports, ] of adaptiveImporters) { - const info = - this.getModuleInfo(importer) || - (await this.load({ id: importer })); + const info = await this.load({ id: importer }); for (const child of (info.ast as unknown as estree.Program) .body) { @@ -275,7 +277,7 @@ export function pluginBuildWeb({ if (isArcProxyId(id)) { id = decodeArcProxyId(id); - const info = this.getModuleInfo(id); + const info = await this.load({ id }); if (info) { let code = ""; let syntheticNamedExports: boolean | string = false; @@ -439,7 +441,7 @@ export function pluginBuildWeb({ manifestCode += `:${JSON.stringify(defaultFlaggedAssets.manifest)}`; } - manifestCode += `}return {"head": [""]}};\n`; + manifestCode += `}return {"head": [""]}};\n`; await Promise.all( serverEntryFiles.map((file) => fs.appendFile(file, manifestCode)), diff --git a/src/plugins/serve.ts b/src/plugins/serve.ts index f91c3f2..8d676e6 100644 --- a/src/plugins/serve.ts +++ b/src/plugins/serve.ts @@ -4,6 +4,7 @@ import type { Plugin } from "vite"; import { type InternalPluginOptions } from "../utils/options"; import { getMatches } from "../utils/matches"; import { type FlagSet, hasFlags } from "../utils/flags"; +import { ensureArcPluginIsFirst } from "../utils/ensure-arc-plugin-is-first"; // TODO: support forced flagset for build plugins @@ -28,13 +29,14 @@ export function pluginServe({ if (!flagSet) return; + ensureArcPluginIsFirst(config.plugins!); config.cacheDir = path.resolve( `node_modules/.vite/arc/${flagSet.join(".")}`, ); config.optimizeDeps ??= {}; config.optimizeDeps.esbuildOptions ??= {}; config.optimizeDeps.esbuildOptions.plugins ??= []; - config.optimizeDeps.esbuildOptions.plugins.push({ + config.optimizeDeps.esbuildOptions.plugins.unshift({ name: "arc-vite:serve:esbuild", setup(build) { const arcProxyPrefix = "arc-proxy:"; diff --git a/src/tests/fixtures/basic/src/entry-server.ts b/src/tests/fixtures/basic/src/entry-server.ts index 100c583..09ede5d 100644 --- a/src/tests/fixtures/basic/src/entry-server.ts +++ b/src/tests/fixtures/basic/src/entry-server.ts @@ -1,8 +1,14 @@ +import url from "url"; +import path from "path"; +import { promises as fs } from "fs"; import type { IncomingMessage } from "http"; import { getAssets, withFlags } from "arc-server"; import renderApp from "./entry-web"; -export function render(html: string, req: IncomingMessage) { +const dirname = path.join(url.fileURLToPath(import.meta.url), ".."); +const html = await fs.readFile(path.join(dirname, "../index.html"), "utf-8"); + +export function render(req: IncomingMessage) { const url = new URL(req.url!, `http://${req.headers.host}`); if (url.pathname !== "/") return; diff --git a/src/tests/fixtures/marko/config.ts b/src/tests/fixtures/marko/config.ts new file mode 100644 index 0000000..cc01530 --- /dev/null +++ b/src/tests/fixtures/marko/config.ts @@ -0,0 +1,18 @@ +import { defineConfig } from "vite"; +import markoVite from "@marko/vite"; +import arcVite from "../../.."; +export default () => + defineConfig({ + plugins: [ + markoVite(), + arcVite({ + flags: ["mobile"], + }), + ], + build: { + modulePreload: false, + minify: false, + target: "esnext", + emptyOutDir: false, + }, + }); diff --git a/src/tests/fixtures/marko/src/a.ts b/src/tests/fixtures/marko/src/a.ts new file mode 100644 index 0000000..6dae28c --- /dev/null +++ b/src/tests/fixtures/marko/src/a.ts @@ -0,0 +1,6 @@ +import renderB from "./b"; +const value = "a"; + +export default function render() { + return `${value}, ${renderB()}`; +} diff --git a/src/tests/fixtures/marko/src/a[mobile].ts b/src/tests/fixtures/marko/src/a[mobile].ts new file mode 100644 index 0000000..7b50e32 --- /dev/null +++ b/src/tests/fixtures/marko/src/a[mobile].ts @@ -0,0 +1,6 @@ +import renderB from "./b"; +const value = "a[mobile]"; + +export default function render() { + return `${value}, ${renderB()}`; +} diff --git a/src/tests/fixtures/marko/src/b-mobile-only.css b/src/tests/fixtures/marko/src/b-mobile-only.css new file mode 100644 index 0000000..563d20e --- /dev/null +++ b/src/tests/fixtures/marko/src/b-mobile-only.css @@ -0,0 +1,3 @@ +body { + color: green; +} diff --git a/src/tests/fixtures/marko/src/b.ts b/src/tests/fixtures/marko/src/b.ts new file mode 100644 index 0000000..464aa65 --- /dev/null +++ b/src/tests/fixtures/marko/src/b.ts @@ -0,0 +1,5 @@ +const value = "b"; + +export default function render() { + return `${value}`; +} diff --git a/src/tests/fixtures/marko/src/b[mobile].ts b/src/tests/fixtures/marko/src/b[mobile].ts new file mode 100644 index 0000000..d4f724d --- /dev/null +++ b/src/tests/fixtures/marko/src/b[mobile].ts @@ -0,0 +1,6 @@ +import "./b-mobile-only.css"; +const value = "b[mobile]"; + +export default function render() { + return `${value}`; +} diff --git a/src/tests/fixtures/marko/src/c.css b/src/tests/fixtures/marko/src/c.css new file mode 100644 index 0000000..e69de29 diff --git a/src/tests/fixtures/marko/src/c[mobile].css b/src/tests/fixtures/marko/src/c[mobile].css new file mode 100644 index 0000000..6c791ba --- /dev/null +++ b/src/tests/fixtures/marko/src/c[mobile].css @@ -0,0 +1,3 @@ +body { + background-color: aqua; +} diff --git a/src/tests/fixtures/marko/src/components/app.marko b/src/tests/fixtures/marko/src/components/app.marko new file mode 100644 index 0000000..5b3d624 --- /dev/null +++ b/src/tests/fixtures/marko/src/components/app.marko @@ -0,0 +1,7 @@ +import renderA from "../a"; +import "../c.css"; +class { + +} + +

$!{renderA()}

diff --git a/src/tests/fixtures/marko/src/entry-server.ts b/src/tests/fixtures/marko/src/entry-server.ts new file mode 100644 index 0000000..b838e02 --- /dev/null +++ b/src/tests/fixtures/marko/src/entry-server.ts @@ -0,0 +1,11 @@ +import type { IncomingMessage } from "http"; +import { setFlags } from "arc-server"; +import template from "./index.marko"; + +export function render(req: IncomingMessage) { + const url = new URL(req.url!, `http://${req.headers.host}`); + if (url.pathname !== "/") return; + + setFlags({ mobile: url.searchParams.has("mobile") }); + return template.render({}); +} diff --git a/src/tests/fixtures/marko/src/index.marko b/src/tests/fixtures/marko/src/index.marko new file mode 100644 index 0000000..35a0b0b --- /dev/null +++ b/src/tests/fixtures/marko/src/index.marko @@ -0,0 +1,11 @@ + + + + + + Document + + + + + diff --git a/src/tests/marko.test.ts b/src/tests/marko.test.ts new file mode 100644 index 0000000..f344bc1 --- /dev/null +++ b/src/tests/marko.test.ts @@ -0,0 +1,97 @@ +import url from "node:url"; +import path from "node:path"; +import * as t from "node:test"; +import { type Page } from "playwright"; +import { expect } from "@playwright/test"; +import { getPage } from "./utils/get-page"; +import { createDevServer } from "./utils/dev-server"; +import { createProdServer } from "./utils/prod-server"; + +const fixture = path.join( + url.fileURLToPath(import.meta.url), + "../fixtures/marko", +); + +t.test("marko", async (t) => { + t.beforeEach(() => { + delete process.env.FLAGS; + }); + + await t.test("dev", async (t) => { + await t.test("FLAGS=", async (t) => { + process.env.FLAGS = ""; + const [{ page, port }, server] = await Promise.all([ + getPage(t), + createDevServer(fixture), + ]); + + t.after(await server.listen(port)); + + await page.goto("/"); + + await t.test("has desktop content", async () => { + await assertHasDesktopContent(page); + }); + }); + + await t.test("FLAGS=mobile", async (t) => { + process.env.FLAGS = "mobile"; + const [{ page, port }, server] = await Promise.all([ + getPage(t), + createDevServer(fixture), + ]); + + t.after(await server.listen(port)); + + await page.goto("/"); + + await t.test("has mobile content", async () => { + await assertHasMobileContent(page); + }); + }); + }); + + await t.test("prod", async (t) => { + const [{ page, port }, server] = await Promise.all([ + getPage(t), + createProdServer(fixture), + ]); + + t.after(await server.listen(port)); + + await t.test("FLAGS=", async (t) => { + await page.goto("/"); + await t.test("has desktop content", async () => { + await assertHasDesktopContent(page); + }); + }); + + await t.test("FLAGS=mobile", async (t) => { + await page.goto("/?mobile"); + await t.test("has mobile content", async () => { + await assertHasMobileContent(page); + }); + }); + }); +}); + +async function assertHasDesktopContent(page: Page) { + await expect(page.locator("body")).toHaveCSS( + "background-color", + "rgba(0, 0, 0, 0)", + ); + const heading = page.getByText("a, b"); + await expect(heading).toBeAttached(); + await expect(heading).toHaveCSS("color", "rgb(0, 0, 0)"); +} + +async function assertHasMobileContent(page: Page) { + await page.pause(); + await expect(page.locator("body")).toHaveCSS( + "background-color", + "rgb(0, 255, 255)", + ); + const heading = page.getByText("a[mobile], b[mobile]"); + await expect(heading).toBeAttached(); + await expect(heading).toHaveCSS("color", "rgb(0, 128, 0)"); +} diff --git a/src/tests/types.d.ts b/src/tests/types.d.ts new file mode 100644 index 0000000..4f025bc --- /dev/null +++ b/src/tests/types.d.ts @@ -0,0 +1,5 @@ +declare module "*.marko" { + import { Template } from "marko"; + const template: Template; + export default template; +} diff --git a/src/tests/utils/dev-server.ts b/src/tests/utils/dev-server.ts index d0669f7..7a70b81 100644 --- a/src/tests/utils/dev-server.ts +++ b/src/tests/utils/dev-server.ts @@ -1,35 +1,30 @@ -import path from "node:path"; import events from "node:events"; -import { promises as fs } from "node:fs"; import type { IncomingMessage } from "node:http"; import * as vite from "vite"; export async function createDevServer(fixtureDir: string) { - const [html, devServer] = await Promise.all([ - fs.readFile(path.join(fixtureDir, "index.html"), "utf8"), - import(`${fixtureDir}/config.ts`).then( - ({ default: getConfig }: { default: () => vite.UserConfig }) => - vite.createServer( - vite.mergeConfig(getConfig(), { - root: fixtureDir, - appType: "custom", - configFile: false, - server: { - middlewareMode: true, - }, - }), - ), - ), - ]); + const getConfig: () => vite.UserConfig = ( + await import(`${fixtureDir}/config.ts`) + ).default; + const devServer = await vite.createServer( + vite.mergeConfig(getConfig(), { + root: fixtureDir, + appType: "custom", + configFile: false, + server: { + middlewareMode: true, + }, + }), + ); const app = devServer.middlewares.use(async (req, res, next) => { try { const { render } = (await devServer.ssrLoadModule( "./src/entry-server.ts", )) as { - render(html: string, req: IncomingMessage): string; + render(req: IncomingMessage): string | Promise; }; - const result = render(html, req); + const result = (await render(req))?.toString(); if (result) { res.statusCode = 200; res.end(result); diff --git a/src/tests/utils/prod-server.ts b/src/tests/utils/prod-server.ts index b3a29dc..ef8ed8a 100644 --- a/src/tests/utils/prod-server.ts +++ b/src/tests/utils/prod-server.ts @@ -1,14 +1,13 @@ import path from "node:path"; import http, { type IncomingMessage } from "node:http"; import events from "node:events"; -import { promises as fs } from "node:fs"; import * as vite from "vite"; import serve from "serve-handler"; export async function createProdServer(fixtureDir: string) { - const { default: getConfig } = (await import(`${fixtureDir}/config.ts`)) as { - default: () => vite.UserConfig; - }; + const getConfig: () => vite.UserConfig = ( + await import(`${fixtureDir}/config.ts`) + ).default; const dist = path.join(fixtureDir, "dist"); const config = getConfig(); @@ -32,15 +31,14 @@ export async function createProdServer(fixtureDir: string) { ); const { render } = (await import(path.join(dist, "entry-server.js"))) as { - render(html: string, req: IncomingMessage): string; + render(req: IncomingMessage): string | Promise; }; - const html = await fs.readFile(path.join(dist, "index.html"), "utf8"); return { async listen(port: number) { const server = http - .createServer((req, res) => { - const result = render(html, req); + .createServer(async (req, res) => { + const result = (await render(req))?.toString(); if (result) { res.statusCode = 200; res.end(result); diff --git a/src/utils/ensure-arc-plugin-is-first.ts b/src/utils/ensure-arc-plugin-is-first.ts new file mode 100644 index 0000000..b541b1b --- /dev/null +++ b/src/utils/ensure-arc-plugin-is-first.ts @@ -0,0 +1,18 @@ +import type * as vite from "vite"; +const arcVitePluginNameReg = /^arc-vite/; +export function ensureArcPluginIsFirst(plugins: vite.PluginOption[]) { + for (let i = plugins.length; i--; ) { + const plugin = plugins[i]; + if (!Array.isArray(plugin)) continue; + const [firstPlugin] = plugin; + if ( + firstPlugin && + typeof firstPlugin === "object" && + "name" in firstPlugin && + arcVitePluginNameReg.test(firstPlugin.name) + ) { + plugins[i] = false; + plugins.unshift(plugin); + } + } +} diff --git a/src/utils/options.ts b/src/utils/options.ts index 676b43d..b57d59a 100644 --- a/src/utils/options.ts +++ b/src/utils/options.ts @@ -36,8 +36,8 @@ export function getInternalPluginOptions( FLAGS === undefined ? undefined : FLAGS === "" - ? ([] as unknown as FlagSet) - : normalizeFlagSet(FLAGS.split(".")), + ? ([] as unknown as FlagSet) + : normalizeFlagSet(FLAGS.split(".")), flagSets: "flags" in options ? createFlagSets(options.flags)