aboutsummaryrefslogtreecommitdiff
path: root/packages/integrations/alpinejs
diff options
context:
space:
mode:
Diffstat (limited to 'packages/integrations/alpinejs')
-rw-r--r--packages/integrations/alpinejs/CHANGELOG.md157
-rw-r--r--packages/integrations/alpinejs/README.md38
-rw-r--r--packages/integrations/alpinejs/package.json49
-rw-r--r--packages/integrations/alpinejs/src/index.ts111
-rw-r--r--packages/integrations/alpinejs/test/basics.test.js13
-rw-r--r--packages/integrations/alpinejs/test/directive.test.js13
-rw-r--r--packages/integrations/alpinejs/test/fixtures/basics/astro.config.mjs6
-rw-r--r--packages/integrations/alpinejs/test/fixtures/basics/package.json11
-rw-r--r--packages/integrations/alpinejs/test/fixtures/basics/src/pages/index.astro8
-rw-r--r--packages/integrations/alpinejs/test/fixtures/directive/astro.config.mjs8
-rw-r--r--packages/integrations/alpinejs/test/fixtures/directive/package.json11
-rw-r--r--packages/integrations/alpinejs/test/fixtures/directive/src/entrypoint.ts7
-rw-r--r--packages/integrations/alpinejs/test/fixtures/directive/src/pages/index.astro8
-rw-r--r--packages/integrations/alpinejs/test/fixtures/plugin-script-import/astro.config.mjs6
-rw-r--r--packages/integrations/alpinejs/test/fixtures/plugin-script-import/package.json11
-rw-r--r--packages/integrations/alpinejs/test/fixtures/plugin-script-import/src/pages/index.astro19
-rw-r--r--packages/integrations/alpinejs/test/plugin-script-import.test.js13
-rw-r--r--packages/integrations/alpinejs/test/test-utils.js64
-rw-r--r--packages/integrations/alpinejs/tsconfig.json7
19 files changed, 560 insertions, 0 deletions
diff --git a/packages/integrations/alpinejs/CHANGELOG.md b/packages/integrations/alpinejs/CHANGELOG.md
new file mode 100644
index 000000000..4c0bd60b8
--- /dev/null
+++ b/packages/integrations/alpinejs/CHANGELOG.md
@@ -0,0 +1,157 @@
+# @astrojs/alpinejs
+
+## 0.4.8
+
+### Patch Changes
+
+- [#13731](https://github.com/withastro/astro/pull/13731) [`c3e80c2`](https://github.com/withastro/astro/commit/c3e80c25b90c803e2798b752583a8e77cdad3146) Thanks [@jsparkdev](https://github.com/jsparkdev)! - update vite to latest version for fixing CVE
+
+## 0.4.7
+
+### Patch Changes
+
+- [#13591](https://github.com/withastro/astro/pull/13591) [`5dd2d3f`](https://github.com/withastro/astro/commit/5dd2d3fde8a138ed611dedf39ffa5dfeeed315f8) Thanks [@florian-lefebvre](https://github.com/florian-lefebvre)! - Removes unused code
+
+## 0.4.6
+
+### Patch Changes
+
+- [#13596](https://github.com/withastro/astro/pull/13596) [`3752519`](https://github.com/withastro/astro/commit/375251966d1b28a570bff45ff0fe7e7d2fe46f72) Thanks [@jsparkdev](https://github.com/jsparkdev)! - update vite to latest version to fix CVE
+
+- [#13547](https://github.com/withastro/astro/pull/13547) [`360cb91`](https://github.com/withastro/astro/commit/360cb9199a4314f90825c5639ff4396760e9cfcc) Thanks [@jsparkdev](https://github.com/jsparkdev)! - Updates vite to the latest version
+
+## 0.4.5
+
+### Patch Changes
+
+- [#13526](https://github.com/withastro/astro/pull/13526) [`ff9d69e`](https://github.com/withastro/astro/commit/ff9d69e3443c80059c54f6296d19f66bb068ead3) Thanks [@jsparkdev](https://github.com/jsparkdev)! - update `vite` to the latest version
+
+## 0.4.4
+
+### Patch Changes
+
+- [#13505](https://github.com/withastro/astro/pull/13505) [`a98ae5b`](https://github.com/withastro/astro/commit/a98ae5b8f5c33900379012e9e253a755c0a8927e) Thanks [@ematipico](https://github.com/ematipico)! - Updates the dependency `vite` to the latest.
+
+## 0.4.3
+
+### Patch Changes
+
+- [#13014](https://github.com/withastro/astro/pull/13014) [`820eee3`](https://github.com/withastro/astro/commit/820eee334b66e40d9e794daab04d0d1cf48f0185) Thanks [@jasonlav](https://github.com/jasonlav)! - Fixes an issue with user scripts running after `Alpine.start()`
+
+## 0.4.2
+
+### Patch Changes
+
+- [#13011](https://github.com/withastro/astro/pull/13011) [`cf30880`](https://github.com/withastro/astro/commit/cf3088060d45227dcb48e041c4ed5e0081d71398) Thanks [@ascorbic](https://github.com/ascorbic)! - Upgrades Vite
+
+## 0.4.1
+
+### Patch Changes
+
+- [#12799](https://github.com/withastro/astro/pull/12799) [`739dbfb`](https://github.com/withastro/astro/commit/739dbfba4214107cf8fc40c702834dad33eed3b0) Thanks [@ascorbic](https://github.com/ascorbic)! - Upgrades Vite to pin esbuild
+
+## 0.4.0
+
+### Minor Changes
+
+- [#9751](https://github.com/withastro/astro/pull/9751) [`1153331cbbaa66a88645d15c6e949432210d4acc`](https://github.com/withastro/astro/commit/1153331cbbaa66a88645d15c6e949432210d4acc) Thanks [@florian-lefebvre](https://github.com/florian-lefebvre)! - Allows extending Alpine using the new `entrypoint` configuration
+
+ You can extend Alpine by setting the `entrypoint` option to a root-relative import specifier (for example, `entrypoint: "/src/entrypoint"`).
+
+ The default export of this file should be a function that accepts an Alpine instance prior to starting, allowing the use of custom directives, plugins and other customizations for advanced use cases.
+
+ ```js
+ // astro.config.mjs
+ import { defineConfig } from 'astro/config';
+ import alpine from '@astrojs/alpinejs';
+
+ export default defineConfig({
+ // ...
+ integrations: [alpine({ entrypoint: '/src/entrypoint' })],
+ });
+ ```
+
+ ```js
+ // src/entrypoint.ts
+ import type { Alpine } from 'alpinejs'
+
+ export default (Alpine: Alpine) => {
+ Alpine.directive('foo', el => {
+ el.textContent = 'bar';
+ })
+ }
+ ```
+
+## 0.3.2
+
+### Patch Changes
+
+- [#9479](https://github.com/withastro/astro/pull/9479) [`1baf0b0d3cbd0564954c2366a7278794fad6726e`](https://github.com/withastro/astro/commit/1baf0b0d3cbd0564954c2366a7278794fad6726e) Thanks [@sarah11918](https://github.com/sarah11918)! - Updates README
+
+## 0.3.1
+
+### Patch Changes
+
+- [#8737](https://github.com/withastro/astro/pull/8737) [`6f60da805`](https://github.com/withastro/astro/commit/6f60da805e0014bc50dd07bef972e91c73560c3c) Thanks [@ematipico](https://github.com/ematipico)! - Add provenance statement when publishing the library from CI
+
+## 0.3.0
+
+### Minor Changes
+
+- [#8188](https://github.com/withastro/astro/pull/8188) [`d0679a666`](https://github.com/withastro/astro/commit/d0679a666f37da0fca396d42b9b32bbb25d29312) Thanks [@ematipico](https://github.com/ematipico)! - Remove support for Node 16. The lowest supported version by Astro and all integrations is now v18.14.1. As a reminder, Node 16 will be deprecated on the 11th September 2023.
+
+- [#8179](https://github.com/withastro/astro/pull/8179) [`6011d52d3`](https://github.com/withastro/astro/commit/6011d52d38e43c3e3d52bc3bc41a60e36061b7b7) Thanks [@matthewp](https://github.com/matthewp)! - Astro 3.0 Release Candidate
+
+## 0.3.0-rc.1
+
+### Minor Changes
+
+- [#8179](https://github.com/withastro/astro/pull/8179) [`6011d52d3`](https://github.com/withastro/astro/commit/6011d52d38e43c3e3d52bc3bc41a60e36061b7b7) Thanks [@matthewp](https://github.com/matthewp)! - Astro 3.0 Release Candidate
+
+## 0.3.0-beta.0
+
+### Minor Changes
+
+- [`1eae2e3f7`](https://github.com/withastro/astro/commit/1eae2e3f7d693c9dfe91c8ccfbe606d32bf2fb81) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Remove support for Node 16. The lowest supported version by Astro and all integrations is now v18.14.1. As a reminder, Node 16 will be deprecated on the 11th September 2023.
+
+## 0.2.2
+
+### Patch Changes
+
+- [#7104](https://github.com/withastro/astro/pull/7104) [`826e02890`](https://github.com/withastro/astro/commit/826e0289005f645b902375b98d5549c6a95ccafa) Thanks [@bluwy](https://github.com/bluwy)! - Specify `"files"` field to only publish necessary files
+
+## 0.2.1
+
+### Patch Changes
+
+- [#6494](https://github.com/withastro/astro/pull/6494) [`a13e9d7e3`](https://github.com/withastro/astro/commit/a13e9d7e33baccf51e7d4815f99b481ad174bc57) Thanks [@Yan-Thomas](https://github.com/Yan-Thomas)! - Consistency improvements to several package descriptions
+
+## 0.2.0
+
+### Minor Changes
+
+- [#6213](https://github.com/withastro/astro/pull/6213) [`afbbc4d5b`](https://github.com/withastro/astro/commit/afbbc4d5bfafc1779bac00b41c2a1cb1c90f2808) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Updated compilation settings to disable downlevelling for Node 14
+
+## 0.1.3
+
+### Patch Changes
+
+- [#5478](https://github.com/withastro/astro/pull/5478) [`1c7eef308`](https://github.com/withastro/astro/commit/1c7eef308e808aa5ed4662b53e67ec8d1b814d1f) Thanks [@nemo0](https://github.com/nemo0)! - Update READMEs for consistency
+
+## 0.1.2
+
+### Patch Changes
+
+- [#4622](https://github.com/withastro/astro/pull/4622) [`63cd9d89e`](https://github.com/withastro/astro/commit/63cd9d89e8b83ce5e39cdae84a8342e28d1940cc) Thanks [@mohammed-elhaouari](https://github.com/mohammed-elhaouari)! - Update homepage link
+
+## 0.1.1
+
+### Patch Changes
+
+- [#4501](https://github.com/withastro/astro/pull/4501) [`17e217856`](https://github.com/withastro/astro/commit/17e2178568d5a5a8134743bfb87c62f4c04979e5) Thanks [@mohammed-elhaouari](https://github.com/mohammed-elhaouari)! - add renderer category to alpinejs package keywords
+
+## 0.1.0
+
+### Minor Changes
+
+- [#4406](https://github.com/withastro/astro/pull/4406) [`7310e8a17`](https://github.com/withastro/astro/commit/7310e8a1780dff2ffb57f8a6cfd3d021d019f6b8) Thanks [@FredKSchott](https://github.com/FredKSchott)! - Add new official Alpine.js integration
diff --git a/packages/integrations/alpinejs/README.md b/packages/integrations/alpinejs/README.md
new file mode 100644
index 000000000..1e82694c1
--- /dev/null
+++ b/packages/integrations/alpinejs/README.md
@@ -0,0 +1,38 @@
+# @astrojs/alpinejs
+
+This **[Astro integration][astro-integration]** adds [Alpine.js](https://alpinejs.dev/) to your project so that you can use Alpine.js anywhere on your page.
+
+## Documentation
+
+Read the [`@astrojs/alpinejs` docs][docs]
+
+## Support
+
+- Get help in the [Astro Discord][discord]. Post questions in our `#support` forum, or visit our dedicated `#dev` channel to discuss current development and more!
+
+- Check our [Astro Integration Documentation][astro-integration] for more on integrations.
+
+- Submit bug reports and feature requests as [GitHub issues][issues].
+
+## Contributing
+
+This package is maintained by Astro's Core team. You're welcome to submit an issue or PR! These links will help you get started:
+
+- [Contributor Manual][contributing]
+- [Code of Conduct][coc]
+- [Community Guide][community]
+
+## License
+
+MIT
+
+Copyright (c) 2023–present [Astro][astro]
+
+[astro]: https://astro.build/
+[docs]: https://docs.astro.build/en/guides/integrations-guide/alpinejs/
+[contributing]: https://github.com/withastro/astro/blob/main/CONTRIBUTING.md
+[coc]: https://github.com/withastro/.github/blob/main/CODE_OF_CONDUCT.md
+[community]: https://github.com/withastro/.github/blob/main/COMMUNITY_GUIDE.md
+[discord]: https://astro.build/chat/
+[issues]: https://github.com/withastro/astro/issues
+[astro-integration]: https://docs.astro.build/en/guides/integrations-guide/
diff --git a/packages/integrations/alpinejs/package.json b/packages/integrations/alpinejs/package.json
new file mode 100644
index 000000000..2d674e5ef
--- /dev/null
+++ b/packages/integrations/alpinejs/package.json
@@ -0,0 +1,49 @@
+{
+ "name": "@astrojs/alpinejs",
+ "description": "Use Alpine within Astro",
+ "version": "0.4.8",
+ "type": "module",
+ "types": "./dist/index.d.ts",
+ "author": "withastro",
+ "license": "MIT",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/withastro/astro.git",
+ "directory": "packages/integrations/alpinejs"
+ },
+ "keywords": [
+ "astro-integration",
+ "astro-component",
+ "renderer",
+ "alpinejs",
+ "performance"
+ ],
+ "bugs": "https://github.com/withastro/astro/issues",
+ "homepage": "https://docs.astro.build/en/guides/integrations-guide/alpinejs",
+ "exports": {
+ ".": "./dist/index.js",
+ "./package.json": "./package.json"
+ },
+ "files": [
+ "dist"
+ ],
+ "scripts": {
+ "build": "astro-scripts build \"src/**/*.ts\" && tsc",
+ "build:ci": "astro-scripts build \"src/**/*.ts\"",
+ "dev": "astro-scripts dev \"src/**/*.ts\"",
+ "test:e2e": "playwright test"
+ },
+ "peerDependencies": {
+ "@types/alpinejs": "^3.0.0",
+ "alpinejs": "^3.0.0"
+ },
+ "devDependencies": {
+ "@playwright/test": "1.51.1",
+ "astro": "workspace:*",
+ "astro-scripts": "workspace:*",
+ "vite": "^6.3.4"
+ },
+ "publishConfig": {
+ "provenance": true
+ }
+}
diff --git a/packages/integrations/alpinejs/src/index.ts b/packages/integrations/alpinejs/src/index.ts
new file mode 100644
index 000000000..61a50d705
--- /dev/null
+++ b/packages/integrations/alpinejs/src/index.ts
@@ -0,0 +1,111 @@
+import { resolve } from 'node:path';
+import type { AstroIntegration } from 'astro';
+import type { Plugin } from 'vite';
+
+interface Options {
+ /**
+ * You can extend Alpine by setting this option to a root-relative import specifier (for example, `entrypoint: "/src/entrypoint"`).
+ *
+ * The default export of this file should be a function that accepts an Alpine instance prior to starting, allowing the use of custom directives, plugins and other customizations for advanced use cases.
+ *
+ * ```js
+ * // astro.config.mjs
+ * import { defineConfig } from 'astro/config';
+ * import alpine from '@astrojs/alpinejs';
+ *
+ * export default defineConfig({
+ * // ...
+ * integrations: [alpine({ entrypoint: '/src/entrypoint' })],
+ * });
+ * ```
+ *
+ * ```js
+ * // src/entrypoint.ts
+ * import type { Alpine } from 'alpinejs'
+ *
+ * export default (Alpine: Alpine) => {
+ * Alpine.directive('foo', el => {
+ * el.textContent = 'bar';
+ * })
+ * }
+ * ```
+ */
+ entrypoint?: string;
+}
+
+function virtualEntrypoint(options?: Options): Plugin {
+ const virtualModuleId = 'virtual:@astrojs/alpinejs/entrypoint';
+ const resolvedVirtualModuleId = '\0' + virtualModuleId;
+
+ let isBuild: boolean;
+ let root: string;
+ let entrypoint: string | undefined;
+
+ return {
+ name: '@astrojs/alpinejs/virtual-entrypoint',
+ config(_, { command }) {
+ isBuild = command === 'build';
+ },
+ configResolved(config) {
+ root = config.root;
+ if (options?.entrypoint) {
+ entrypoint = options.entrypoint.startsWith('.')
+ ? resolve(root, options.entrypoint)
+ : options.entrypoint;
+ }
+ },
+ resolveId(id) {
+ if (id === virtualModuleId) {
+ return resolvedVirtualModuleId;
+ }
+ },
+ load(id) {
+ if (id === resolvedVirtualModuleId) {
+ if (entrypoint) {
+ return `\
+import * as mod from ${JSON.stringify(entrypoint)};
+
+export const setup = (Alpine) => {
+ if ('default' in mod) {
+ mod.default(Alpine);
+ } else {
+ ${
+ !isBuild
+ ? `console.warn("[@astrojs/alpinejs] entrypoint \`" + ${JSON.stringify(
+ entrypoint,
+ )} + "\` does not export a default function. Check out https://docs.astro.build/en/guides/integrations-guide/alpinejs/#entrypoint.");`
+ : ''
+ }
+ }
+}`;
+ }
+ return `export const setup = () => {};`;
+ }
+ },
+ };
+}
+
+export default function createPlugin(options?: Options): AstroIntegration {
+ return {
+ name: '@astrojs/alpinejs',
+ hooks: {
+ 'astro:config:setup': ({ injectScript, updateConfig }) => {
+ // This gets injected into the user's page, so the import will pull
+ // from the project's version of Alpine.js in their package.json.
+ injectScript(
+ 'page',
+ `import Alpine from 'alpinejs';
+import { setup } from 'virtual:@astrojs/alpinejs/entrypoint';
+setup(Alpine);
+window.Alpine = Alpine;
+document.addEventListener('DOMContentLoaded', () => Alpine.start());`,
+ );
+ updateConfig({
+ vite: {
+ plugins: [virtualEntrypoint(options)],
+ },
+ });
+ },
+ },
+ };
+}
diff --git a/packages/integrations/alpinejs/test/basics.test.js b/packages/integrations/alpinejs/test/basics.test.js
new file mode 100644
index 000000000..440e2a6b5
--- /dev/null
+++ b/packages/integrations/alpinejs/test/basics.test.js
@@ -0,0 +1,13 @@
+import { expect } from '@playwright/test';
+import { prepareTestFactory } from './test-utils.js';
+
+const { test } = prepareTestFactory({ root: './fixtures/basics/' });
+
+test.describe('Basics', () => {
+ test('Alpine is working', async ({ page, astro }) => {
+ await page.goto(astro.resolveUrl('/'));
+
+ const el = page.locator('#foo');
+ expect(await el.textContent()).toBe('bar');
+ });
+});
diff --git a/packages/integrations/alpinejs/test/directive.test.js b/packages/integrations/alpinejs/test/directive.test.js
new file mode 100644
index 000000000..440e2a6b5
--- /dev/null
+++ b/packages/integrations/alpinejs/test/directive.test.js
@@ -0,0 +1,13 @@
+import { expect } from '@playwright/test';
+import { prepareTestFactory } from './test-utils.js';
+
+const { test } = prepareTestFactory({ root: './fixtures/basics/' });
+
+test.describe('Basics', () => {
+ test('Alpine is working', async ({ page, astro }) => {
+ await page.goto(astro.resolveUrl('/'));
+
+ const el = page.locator('#foo');
+ expect(await el.textContent()).toBe('bar');
+ });
+});
diff --git a/packages/integrations/alpinejs/test/fixtures/basics/astro.config.mjs b/packages/integrations/alpinejs/test/fixtures/basics/astro.config.mjs
new file mode 100644
index 000000000..ea1225a00
--- /dev/null
+++ b/packages/integrations/alpinejs/test/fixtures/basics/astro.config.mjs
@@ -0,0 +1,6 @@
+import alpine from '@astrojs/alpinejs';
+import { defineConfig } from 'astro/config';
+
+export default defineConfig({
+ integrations: [alpine()],
+})
diff --git a/packages/integrations/alpinejs/test/fixtures/basics/package.json b/packages/integrations/alpinejs/test/fixtures/basics/package.json
new file mode 100644
index 000000000..6723712fe
--- /dev/null
+++ b/packages/integrations/alpinejs/test/fixtures/basics/package.json
@@ -0,0 +1,11 @@
+{
+ "name": "@test/alpinejs-basics",
+ "version": "0.0.0",
+ "private": true,
+ "dependencies": {
+ "@astrojs/alpinejs": "workspace:*",
+ "@types/alpinejs": "^3.13.11",
+ "alpinejs": "^3.14.9",
+ "astro": "workspace:*"
+ }
+}
diff --git a/packages/integrations/alpinejs/test/fixtures/basics/src/pages/index.astro b/packages/integrations/alpinejs/test/fixtures/basics/src/pages/index.astro
new file mode 100644
index 000000000..6197e0c64
--- /dev/null
+++ b/packages/integrations/alpinejs/test/fixtures/basics/src/pages/index.astro
@@ -0,0 +1,8 @@
+<html>
+ <head>
+ <title>Testing</title>
+ </head>
+ <body>
+ <div id="foo" x-data="{ foo: 'bar' }" x-text="foo"></div>
+ </body>
+</html>
diff --git a/packages/integrations/alpinejs/test/fixtures/directive/astro.config.mjs b/packages/integrations/alpinejs/test/fixtures/directive/astro.config.mjs
new file mode 100644
index 000000000..995f86b08
--- /dev/null
+++ b/packages/integrations/alpinejs/test/fixtures/directive/astro.config.mjs
@@ -0,0 +1,8 @@
+import alpine from '@astrojs/alpinejs';
+import { defineConfig } from 'astro/config';
+
+export default defineConfig({
+ integrations: [alpine({
+ entrypoint: "./src/entrypoint.ts"
+ })],
+})
diff --git a/packages/integrations/alpinejs/test/fixtures/directive/package.json b/packages/integrations/alpinejs/test/fixtures/directive/package.json
new file mode 100644
index 000000000..8b4404f33
--- /dev/null
+++ b/packages/integrations/alpinejs/test/fixtures/directive/package.json
@@ -0,0 +1,11 @@
+{
+ "name": "@test/alpinejs-directive",
+ "version": "0.0.0",
+ "private": true,
+ "dependencies": {
+ "@astrojs/alpinejs": "workspace:*",
+ "@types/alpinejs": "^3.13.11",
+ "alpinejs": "^3.14.9",
+ "astro": "workspace:*"
+ }
+}
diff --git a/packages/integrations/alpinejs/test/fixtures/directive/src/entrypoint.ts b/packages/integrations/alpinejs/test/fixtures/directive/src/entrypoint.ts
new file mode 100644
index 000000000..7a49c044a
--- /dev/null
+++ b/packages/integrations/alpinejs/test/fixtures/directive/src/entrypoint.ts
@@ -0,0 +1,7 @@
+import type { Alpine } from 'alpinejs'
+
+export default (Alpine: Alpine) => {
+ Alpine.directive('foo', el => {
+ el.textContent = 'bar';
+ })
+} \ No newline at end of file
diff --git a/packages/integrations/alpinejs/test/fixtures/directive/src/pages/index.astro b/packages/integrations/alpinejs/test/fixtures/directive/src/pages/index.astro
new file mode 100644
index 000000000..73753209a
--- /dev/null
+++ b/packages/integrations/alpinejs/test/fixtures/directive/src/pages/index.astro
@@ -0,0 +1,8 @@
+<html>
+ <head>
+ <title>Testing</title>
+ </head>
+ <body>
+ <div id="foo" x-data x-foo></div>
+ </body>
+</html>
diff --git a/packages/integrations/alpinejs/test/fixtures/plugin-script-import/astro.config.mjs b/packages/integrations/alpinejs/test/fixtures/plugin-script-import/astro.config.mjs
new file mode 100644
index 000000000..ea1225a00
--- /dev/null
+++ b/packages/integrations/alpinejs/test/fixtures/plugin-script-import/astro.config.mjs
@@ -0,0 +1,6 @@
+import alpine from '@astrojs/alpinejs';
+import { defineConfig } from 'astro/config';
+
+export default defineConfig({
+ integrations: [alpine()],
+})
diff --git a/packages/integrations/alpinejs/test/fixtures/plugin-script-import/package.json b/packages/integrations/alpinejs/test/fixtures/plugin-script-import/package.json
new file mode 100644
index 000000000..2fe4f6eee
--- /dev/null
+++ b/packages/integrations/alpinejs/test/fixtures/plugin-script-import/package.json
@@ -0,0 +1,11 @@
+{
+ "name": "@test/alpinejs-plugin-script-import",
+ "version": "0.0.0",
+ "private": true,
+ "dependencies": {
+ "@astrojs/alpinejs": "workspace:*",
+ "@types/alpinejs": "^3.13.11",
+ "alpinejs": "^3.14.9",
+ "astro": "workspace:*"
+ }
+}
diff --git a/packages/integrations/alpinejs/test/fixtures/plugin-script-import/src/pages/index.astro b/packages/integrations/alpinejs/test/fixtures/plugin-script-import/src/pages/index.astro
new file mode 100644
index 000000000..3d1559eaa
--- /dev/null
+++ b/packages/integrations/alpinejs/test/fixtures/plugin-script-import/src/pages/index.astro
@@ -0,0 +1,19 @@
+<html>
+ <head>
+ <title>Testing</title>
+ <script defer src="https://cdn.jsdelivr.net/npm/@alpinejs/collapse@3.x.x/dist/cdn.min.js"></script>
+ </head>
+ <body>
+ <div x-data="{ expanded: false }">
+ <button @click="expanded = ! expanded">Toggle Content</button>
+
+ <p id="foo" x-show="expanded" x-collapse>
+ Lorem ipsum dolor sit amet consectetur adipisicing elit.
+ Doloribus eum placeat modi deserunt reiciendis aspernatur
+ praesentium natus, reprehenderit fugiat cupiditate, eaque
+ voluptatibus mollitia alias dicta at, perferendis cum.
+ Cumque, dignissimos?
+ </p>
+ </div>
+ </body>
+</html>
diff --git a/packages/integrations/alpinejs/test/plugin-script-import.test.js b/packages/integrations/alpinejs/test/plugin-script-import.test.js
new file mode 100644
index 000000000..c280e5597
--- /dev/null
+++ b/packages/integrations/alpinejs/test/plugin-script-import.test.js
@@ -0,0 +1,13 @@
+import { expect } from '@playwright/test';
+import { prepareTestFactory } from './test-utils.js';
+
+const { test } = prepareTestFactory({ root: './fixtures/plugin-script-import/' });
+
+test.describe('Plugin Script Import', () => {
+ test('Extending Alpine using a script import should work', async ({ page, astro }) => {
+ await page.goto(astro.resolveUrl('/'));
+
+ const el = page.locator('#foo');
+ expect(await el.getAttribute('hidden')).toBe('');
+ });
+});
diff --git a/packages/integrations/alpinejs/test/test-utils.js b/packages/integrations/alpinejs/test/test-utils.js
new file mode 100644
index 000000000..dbc133ec3
--- /dev/null
+++ b/packages/integrations/alpinejs/test/test-utils.js
@@ -0,0 +1,64 @@
+import fs from 'node:fs/promises';
+import path from 'node:path';
+import { fileURLToPath } from 'node:url';
+import { test as testBase } from '@playwright/test';
+import { loadFixture as baseLoadFixture } from '../../../astro/test/test-utils.js';
+
+// Get all test files in directory, assign unique port for each of them so they don't conflict
+const testFiles = await fs.readdir(new URL('.', import.meta.url));
+const testFileToPort = new Map();
+for (let i = 0; i < testFiles.length; i++) {
+ const file = testFiles[i];
+ if (file.endsWith('.test.js')) {
+ testFileToPort.set(file.slice(0, -8), 4000 + i);
+ }
+}
+
+function loadFixture(inlineConfig) {
+ if (!inlineConfig?.root) throw new Error("Must provide { root: './fixtures/...' }");
+
+ // resolve the relative root (i.e. "./fixtures/tailwindcss") to a full filepath
+ // without this, the main `loadFixture` helper will resolve relative to `packages/astro/test`
+ return baseLoadFixture({
+ ...inlineConfig,
+ root: fileURLToPath(new URL(inlineConfig.root, import.meta.url)),
+ server: {
+ port: testFileToPort.get(path.basename(inlineConfig.root)),
+ },
+ });
+}
+
+function testFactory(inlineConfig) {
+ let fixture;
+
+ const test = testBase.extend({
+ astro: async ({}, use) => {
+ fixture = fixture || (await loadFixture(inlineConfig));
+ await use(fixture);
+ },
+ });
+
+ test.afterEach(() => {
+ fixture.resetAllFiles();
+ });
+
+ return test;
+}
+
+export function prepareTestFactory(opts) {
+ const test = testFactory(opts);
+
+ let devServer;
+
+ test.beforeAll(async ({ astro }) => {
+ devServer = await astro.startDevServer();
+ });
+
+ test.afterAll(async () => {
+ await devServer.stop();
+ });
+
+ return {
+ test,
+ };
+}
diff --git a/packages/integrations/alpinejs/tsconfig.json b/packages/integrations/alpinejs/tsconfig.json
new file mode 100644
index 000000000..1504b4b6d
--- /dev/null
+++ b/packages/integrations/alpinejs/tsconfig.json
@@ -0,0 +1,7 @@
+{
+ "extends": "../../../tsconfig.base.json",
+ "include": ["src"],
+ "compilerOptions": {
+ "outDir": "./dist"
+ }
+}