diff --git a/.changeset/thick-carrots-run.md b/.changeset/thick-carrots-run.md new file mode 100644 index 0000000000..2da50fae79 --- /dev/null +++ b/.changeset/thick-carrots-run.md @@ -0,0 +1,5 @@ +--- +"@astrojs/markdown-remark": minor +--- + +Fixes usage in browser environments by using subpath imports diff --git a/packages/markdown/remark/package.json b/packages/markdown/remark/package.json index 66ba1ddda3..60c75b954b 100644 --- a/packages/markdown/remark/package.json +++ b/packages/markdown/remark/package.json @@ -16,6 +16,12 @@ ".": "./dist/index.js", "./dist/internal.js": "./dist/internal.js" }, + "imports": { + "#import-plugin": { + "browser": "./dist/import-plugin-browser.js", + "default": "./dist/import-plugin-default.js" + } + }, "files": [ "dist" ], @@ -52,6 +58,7 @@ "@types/unist": "^3.0.2", "astro-scripts": "workspace:*", "chai": "^4.3.7", + "esbuild": "^0.19.6", "mdast-util-mdx-expression": "^2.0.0", "mocha": "^10.2.0" }, diff --git a/packages/markdown/remark/src/import-plugin-browser.ts b/packages/markdown/remark/src/import-plugin-browser.ts new file mode 100644 index 0000000000..5fb90ad0b0 --- /dev/null +++ b/packages/markdown/remark/src/import-plugin-browser.ts @@ -0,0 +1,8 @@ +// This file should be imported as `#import-plugin` +import type * as unified from 'unified'; + +// In the browser, we can try to do a plain import +export async function importPlugin(p: string): Promise { + const importResult = await import(p); + return importResult.default; +} diff --git a/packages/markdown/remark/src/import-plugin-default.ts b/packages/markdown/remark/src/import-plugin-default.ts new file mode 100644 index 0000000000..ede7cba7d8 --- /dev/null +++ b/packages/markdown/remark/src/import-plugin-default.ts @@ -0,0 +1,22 @@ +// This file should be imported as `#import-plugin` +import { resolve as importMetaResolve } from 'import-meta-resolve'; +import path from 'node:path'; +import { pathToFileURL } from 'node:url'; +import type * as unified from 'unified'; + +let cwdUrlStr: string | undefined; + +// In non-browser enviroments, we can try to resolve from the filesystem too +export async function importPlugin(p: string): Promise { + // Try import from this package first + try { + const importResult = await import(p); + return importResult.default; + } catch {} + + // Try import from user project + cwdUrlStr ??= pathToFileURL(path.join(process.cwd(), 'package.json')).toString(); + const resolved = importMetaResolve(p, cwdUrlStr); + const importResult = await import(resolved); + return importResult.default; +} diff --git a/packages/markdown/remark/src/load-plugins.ts b/packages/markdown/remark/src/load-plugins.ts index e1bad94a1c..a120b5ab1a 100644 --- a/packages/markdown/remark/src/load-plugins.ts +++ b/packages/markdown/remark/src/load-plugins.ts @@ -1,26 +1,12 @@ -import { resolve as importMetaResolve } from 'import-meta-resolve'; -import path from 'node:path'; -import { pathToFileURL } from 'node:url'; import type * as unified from 'unified'; +import { importPlugin as _importPlugin } from '#import-plugin'; -let cwdUrlStr: string | undefined; - -async function importPlugin(p: string | unified.Plugin): Promise { +async function importPlugin(p: string | unified.Plugin) { if (typeof p === 'string') { - // Try import from this package first - try { - const importResult = await import(p); - return importResult.default; - } catch {} - - // Try import from user project - cwdUrlStr ??= pathToFileURL(path.join(process.cwd(), 'package.json')).toString(); - const resolved = importMetaResolve(p, cwdUrlStr); - const importResult = await import(resolved); - return importResult.default; + return await _importPlugin(p); + } else { + return p; } - - return p; } export function loadPlugins( diff --git a/packages/markdown/remark/test/browser.test.js b/packages/markdown/remark/test/browser.test.js new file mode 100644 index 0000000000..d78593fca1 --- /dev/null +++ b/packages/markdown/remark/test/browser.test.js @@ -0,0 +1,15 @@ +import esbuild from 'esbuild'; +import { expect } from 'chai'; + +describe('Bundle for browsers', async () => { + it('esbuild browser build should work', async () => { + const result = await esbuild.build({ + platform: 'browser', + entryPoints: ['@astrojs/markdown-remark'], + bundle: true, + write: false, + }); + // If some non-browser-safe stuff sneaks in, esbuild should error before reaching here + expect(result.outputFiles.length).to.be.greaterThan(0); + }); +}); diff --git a/packages/markdown/remark/tsconfig.json b/packages/markdown/remark/tsconfig.json index 1504b4b6df..4c6fe85616 100644 --- a/packages/markdown/remark/tsconfig.json +++ b/packages/markdown/remark/tsconfig.json @@ -2,6 +2,7 @@ "extends": "../../../tsconfig.base.json", "include": ["src"], "compilerOptions": { - "outDir": "./dist" + "outDir": "./dist", + "rootDir": "./src", } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 521a110880..1b26199840 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5059,6 +5059,9 @@ importers: chai: specifier: ^4.3.7 version: 4.3.10 + esbuild: + specifier: ^0.19.6 + version: 0.19.11 mdast-util-mdx-expression: specifier: ^2.0.0 version: 2.0.0