Skip to content

Commit

Permalink
Merge branch 'main' into new-router
Browse files Browse the repository at this point in the history
  • Loading branch information
meteorlxy authored Dec 20, 2023
2 parents aab1ee2 + 634af03 commit 4aa2362
Show file tree
Hide file tree
Showing 14 changed files with 202 additions and 38 deletions.
2 changes: 1 addition & 1 deletion e2e/cypress.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { defineConfig } from 'cypress'

export default defineConfig({
e2e: {
baseUrl: 'http://localhost:8080',
baseUrl: 'http://localhost:9080',
specPattern: 'tests/**/*.cy.ts',
},
env: {
Expand Down
12 changes: 10 additions & 2 deletions e2e/docs/.vuepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@ import { path } from '@vuepress/utils'
import { e2eTheme } from './theme/node/e2eTheme.js'

const E2E_BASE = (process.env.E2E_BASE ?? '/') as '/' | `/${string}/`
const E2E_BUNDLER = process.env.E2E_BUNDLER ?? 'vite'

export default defineUserConfig({
base: E2E_BASE,

dest: path.join(__dirname, 'dist', E2E_BASE),

port: 9080,

head: [
['meta', { name: 'foo', content: 'foo' }],
['meta', { name: 'bar', content: 'bar' }],
Expand Down Expand Up @@ -40,8 +43,13 @@ export default defineUserConfig({
},
},

bundler:
process.env.E2E_BUNDLER === 'webpack' ? webpackBundler() : viteBundler(),
markdown: {
assets: {
absolutePathPrependBase: E2E_BUNDLER === 'webpack',
},
},

bundler: E2E_BUNDLER === 'webpack' ? webpackBundler() : viteBundler(),

theme: e2eTheme(),

Expand Down
3 changes: 3 additions & 0 deletions e2e/docs/markdown/images/images.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
![logo-public](/logo.png)

![logo-relative](./logo-relative.png)
Binary file added e2e/docs/markdown/images/logo-relative.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 4 additions & 4 deletions e2e/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
"scripts": {
"e2e:build": "vuepress-cli build docs --clean-cache --clean-temp",
"e2e:build-webpack": "E2E_BUNDLER=webpack pnpm e2e:build",
"e2e:ci:build": "pnpm e2e:build && start-server-and-test e2e:serve http-get://localhost:8088 'pnpm e2e:run --config baseUrl=http://localhost:8088'",
"e2e:ci:dev": "start-server-and-test e2e:dev http-get://127.0.0.1:8080 'pnpm e2e:run --config baseUrl=http://localhost:8080'",
"e2e:clean": "rimraf .vuepress/.temp .vuepress/.cache .vuepress/dist",
"e2e:ci:build": "pnpm e2e:build && start-server-and-test e2e:serve http-get://localhost:9080 e2e:run",
"e2e:ci:dev": "start-server-and-test e2e:dev http-get://127.0.0.1:9080 e2e:run",
"e2e:clean": "rimraf docs/.vuepress/.temp docs/.vuepress/.cache docs/.vuepress/dist",
"e2e:dev": "vuepress-cli dev docs --clean-cache --clean-temp",
"e2e:dev-webpack": "E2E_BUNDLER=webpack pnpm e2e:dev",
"e2e:run": "cypress run",
"e2e:serve": "anywhere -s -h localhost -p 8088 -d docs/.vuepress/dist"
"e2e:serve": "anywhere -s -h localhost -p 9080 -d docs/.vuepress/dist"
},
"dependencies": {
"@vuepress/bundler-vite": "workspace:*",
Expand Down
22 changes: 22 additions & 0 deletions e2e/tests/markdown/images.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
describe('markdown > images', () => {
it('should render images correctly', () => {
cy.visit('/markdown/images/images.html')

cy.get('.e2e-theme-content img')
.should('have.length', 2)
.each<HTMLImageElement>(([el]) => {
cy.request({ url: el.src, failOnStatusCode: false }).then((res) => {
expect(res.status).to.equal(200)
expect(el.naturalWidth).to.be.greaterThan(0)
})
})

cy.get('.e2e-theme-content img')
.first()
.should('have.attr', 'alt', 'logo-public')

cy.get('.e2e-theme-content img')
.last()
.should('have.attr', 'alt', 'logo-relative')
})
})
5 changes: 3 additions & 2 deletions packages/bundler-vite/src/plugins/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './mainPlugin.js'
export * from './userConfigPlugin.js'
export * from './vuepressMainPlugin.js'
export * from './vuepressUserConfigPlugin.js'
export * from './vuepressVuePlugin.js'
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import type { AliasOptions, Connect, Plugin, UserConfig } from 'vite'
/**
* The main plugin to compat vuepress with vite
*/
export const mainPlugin = ({
export const vuepressMainPlugin = ({
app,
isBuild,
isServer,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import type { ViteBundlerOptions } from '../types.js'
/**
* A plugin to allow user config to override vite config
*/
export const userConfigPlugin = (options: ViteBundlerOptions): Plugin => ({
export const vuepressUserConfigPlugin = (
options: ViteBundlerOptions,
): Plugin => ({
name: 'vuepress:user-config',
config: () => options.viteOptions ?? {},
})
58 changes: 58 additions & 0 deletions packages/bundler-vite/src/plugins/vuepressVuePlugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import vuePlugin from '@vitejs/plugin-vue'
import type { Plugin } from 'vite'
import type { AssetURLOptions, AssetURLTagConfig } from 'vue/compiler-sfc'
import type { ViteBundlerOptions } from '../types.js'

/**
* Wrapper of official vue plugin
*/
export const vuepressVuePlugin = (options: ViteBundlerOptions): Plugin => {
return vuePlugin({
...options.vuePluginOptions,
template: {
...options.vuePluginOptions?.template,
transformAssetUrls: resolveTransformAssetUrls(options),
},
})
}

/**
* Determine if the given `transformAssetUrls` option is `AssetURLTagConfig`
*/
const isAssetURLTagConfig = (
transformAssetUrls: AssetURLOptions | AssetURLTagConfig,
): transformAssetUrls is AssetURLTagConfig =>
Object.values(transformAssetUrls).some((val) => Array.isArray(val))

/**
* Resolve `template.transformAssetUrls` option from user config
*/
const resolveTransformAssetUrls = (
options: ViteBundlerOptions,
): AssetURLOptions => {
// default transformAssetUrls option
const defaultTransformAssetUrls = { includeAbsolute: true }

// user provided transformAssetUrls option
const { transformAssetUrls: userTransformAssetUrls } =
options.vuePluginOptions?.template ?? {}

// if user does not provide an object as transformAssetUrls
if (typeof userTransformAssetUrls !== 'object') {
return defaultTransformAssetUrls
}

// AssetURLTagConfig
if (isAssetURLTagConfig(userTransformAssetUrls)) {
return {
...defaultTransformAssetUrls,
tags: userTransformAssetUrls,
}
}

// AssetURLOptions
return {
...defaultTransformAssetUrls,
...userTransformAssetUrls,
}
}
13 changes: 8 additions & 5 deletions packages/bundler-vite/src/resolveViteConfig.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { default as vuePlugin } from '@vitejs/plugin-vue'
import type { App } from '@vuepress/core'
import type { InlineConfig } from 'vite'
import { mergeConfig } from 'vite'
import { mainPlugin, userConfigPlugin } from './plugins/index.js'
import {
vuepressMainPlugin,
vuepressUserConfigPlugin,
vuepressVuePlugin,
} from './plugins/index.js'
import type { ViteBundlerOptions } from './types.js'

export const resolveViteConfig = async ({
Expand All @@ -25,9 +28,9 @@ export const resolveViteConfig = async ({
charset: 'utf8',
},
plugins: [
vuePlugin(options.vuePluginOptions),
mainPlugin({ app, isBuild, isServer }),
userConfigPlugin(options),
vuepressVuePlugin(options),
vuepressMainPlugin({ app, isBuild, isServer }),
vuepressUserConfigPlugin(options),
],
},
// some vite options would not take effect inside a plugin, so we still need to merge them here in addition to userConfigPlugin
Expand Down
47 changes: 28 additions & 19 deletions packages/markdown/src/plugins/assetsPlugin/assetsPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ import type { MarkdownEnv } from '../../types.js'
import { resolveLink } from './resolveLink.js'

export interface AssetsPluginOptions {
/**
* Whether to prepend base to absolute path
*/
absolutePathPrependBase?: boolean

/**
* Prefix to add to relative assets links
*/
Expand All @@ -15,7 +20,10 @@ export interface AssetsPluginOptions {
*/
export const assetsPlugin: PluginWithOptions<AssetsPluginOptions> = (
md,
{ relativePathPrefix = '@source' }: AssetsPluginOptions = {},
{
absolutePathPrependBase = false,
relativePathPrefix = '@source',
}: AssetsPluginOptions = {},
) => {
// wrap raw image renderer rule
const rawImageRule = md.renderer.rules.image!
Expand All @@ -27,7 +35,10 @@ export const assetsPlugin: PluginWithOptions<AssetsPluginOptions> = (

if (link) {
// replace the original link with resolved link
token.attrSet('src', resolveLink(link, relativePathPrefix, env))
token.attrSet(
'src',
resolveLink(link, { env, absolutePathPrependBase, relativePathPrefix }),
)
}

return rawImageRule(tokens, idx, options, env, self)
Expand All @@ -43,12 +54,12 @@ export const assetsPlugin: PluginWithOptions<AssetsPluginOptions> = (
.replace(
/(<img\b.*?src=)(['"])([^\2]*?)\2/gs,
(_, prefix: string, quote: string, src: string) =>
`${prefix}${quote}${resolveLink(
src.trim(),
relativePathPrefix,
`${prefix}${quote}${resolveLink(src.trim(), {
env,
true,
)}${quote}`,
absolutePathPrependBase,
relativePathPrefix,
strict: true,
})}${quote}`,
)
// handle srcset
.replace(
Expand All @@ -57,18 +68,16 @@ export const assetsPlugin: PluginWithOptions<AssetsPluginOptions> = (
`${prefix}${quote}${srcset
.split(',')
.map((item) =>
item
.trim()
.replace(
/^([^ ]*?)([ \n].*)?$/,
(_, url, descriptor = '') =>
`${resolveLink(
url.trim(),
relativePathPrefix,
env,
true,
)}${descriptor.replace(/[ \n]+/g, ' ').trimEnd()}`,
),
item.trim().replace(
/^([^ ]*?)([ \n].*)?$/,
(_, url, descriptor = '') =>
`${resolveLink(url.trim(), {
env,
absolutePathPrependBase,
relativePathPrefix,
strict: true,
})}${descriptor.replace(/[ \n]+/g, ' ').trimEnd()}`,
),
)
.join(', ')}${quote}`,
)
Expand Down
21 changes: 18 additions & 3 deletions packages/markdown/src/plugins/assetsPlugin/resolveLink.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,21 @@ import { path } from '@vuepress/utils'
import { decode } from 'mdurl'
import type { MarkdownEnv } from '../../types.js'

interface ResolveLinkOptions {
env: MarkdownEnv
absolutePathPrependBase?: boolean
relativePathPrefix: string
strict?: boolean
}

export const resolveLink = (
link: string,
relativePathPrefix: string,
env: MarkdownEnv,
strict = false,
{
env,
absolutePathPrependBase = false,
relativePathPrefix,
strict = false,
}: ResolveLinkOptions,
): string => {
// do not resolve data uri
if (link.startsWith('data:')) return link
Expand All @@ -30,5 +40,10 @@ export const resolveLink = (
)}`
}

// prepend base to absolute path if needed
if (absolutePathPrependBase && env.base && link.startsWith('/')) {
resolvedLink = path.join(env.base, resolvedLink)
}

return resolvedLink
}
43 changes: 43 additions & 0 deletions packages/markdown/tests/plugins/assetsPlugin.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ describe('@vuepress/markdown > plugins > assetsPlugin', () => {
description: 'should handle assets link with default options',
md: MarkdownIt().use(assetsPlugin),
env: {
base: '/base/',
filePathRelative: 'sub/foo.md',
},
expected: [
Expand Down Expand Up @@ -83,6 +84,48 @@ describe('@vuepress/markdown > plugins > assetsPlugin', () => {
'<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+P+/HgAFhAJ/wr4H/wAAAABJRU5ErkJggg==" alt="data-uri">',
],
},
{
description: 'should respect `absolutePathPrependBase` option',
md: MarkdownIt().use(assetsPlugin, {
absolutePathPrependBase: true,
}),
env: {
base: '/base/',
filePathRelative: 'sub/foo.md',
},
expected: [
// relative paths
'<img src="@source/sub/foo.png" alt="foo">',
'<img src="@source/sub/foo.png" alt="foo2">',
'<img src="@source/sub/foo/bar.png" alt="foo-bar">',
'<img src="@source/sub/foo/bar.png" alt="foo-bar2">',
'<img src="@source/baz.png" alt="baz">',
'<img src="@source/../out.png" alt="out">',
'<img src="@source/sub/汉字.png" alt="汉字">',
'<img src="@source/sub/100%.png" alt="100%">',
// absolute paths
'<img src="/base/absolute.png" alt="absolute">',
'<img src="/base/foo/absolute.png" alt="absolute-foo">',
// no-prefix paths
'<img src="@source/sub/no-prefix.png" alt="no-prefix">',
'<img src="@source/sub/foo/no-prefix.png" alt="no-prefix-foo">',
'<img src="@source/sub/@alias/foo.png" alt="alias">',
'<img src="@source/sub/@alias/汉字.png" alt="汉字">',
'<img src="@source/sub/@alias/100%.png" alt="100%">',
'<img src="@source/sub/~@alias/foo.png" alt="~alias">',
'<img src="@source/sub/~@alias/汉字.png" alt="~汉字">',
'<img src="@source/sub/~@alias/100%.png" alt="~100%">',
// keep as is
'<img src="http://foobar.com/icon.png" alt="url">',
'<img src="" alt="empty">',
// invalid paths
'<img src="@source/sub/.../invalid.png" alt="invalid">',
'<img src="@source/sub/.../汉字.png" alt="汉字">',
'<img src="@source/sub/.../100%.png" alt="100%">',
// data uri
'<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+P+/HgAFhAJ/wr4H/wAAAABJRU5ErkJggg==" alt="data-uri">',
],
},
{
description: 'should respect `relativePathPrefix` option',
md: MarkdownIt().use(assetsPlugin, {
Expand Down

0 comments on commit 4aa2362

Please sign in to comment.