Skip to content

Commit

Permalink
move vitejs code into adapter
Browse files Browse the repository at this point in the history
  • Loading branch information
Applelo committed Nov 18, 2023
1 parent be8fe5a commit 96c5547
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 50 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ This plugin adds preload links by getting output assets from the build tools you

Supporting:
- Vite 4 and 5 **(on build only)**
- Webpack 5 (with HTMLWebpackPlugin 5)
- Rspack (with HTMLWebpackPlugin 5)
- Webpack 5 (with HtmlWebpackPlugin 5)
- Rspack (with HtmlWebpackPlugin 5)

> [!NOTE]
> This plugin combines [vite-plugin-inject-preload](https://github.com/Applelo/vite-plugin-inject-preload) and [html-webpack-inject-preload](https://github.com/principalstudio/html-webpack-inject-preload) into one package.
Expand Down Expand Up @@ -46,7 +46,7 @@ Example: [`playground/vitejs`](./playground/vitejs)
<br></details>

<details>
<summary>Webpack (with HTMLWebpackPlugin)</summary><br>
<summary>Webpack (with HtmlWebpackPlugin)</summary><br>

```ts
// webpack.config.js
Expand All @@ -66,7 +66,7 @@ Example: [`playground/webpack`](./playground/webpack)
<br></details>

<details>
<summary>Rspack (with HTMLWebpackPlugin)</summary><br>
<summary>Rspack (with HtmlWebpackPlugin)</summary><br>

```ts
// rspack.config.js
Expand Down
8 changes: 4 additions & 4 deletions src/adapter/HTMLWebpackPlugin.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { Compilation } from 'webpack'
import type { HtmlTagDescriptor } from 'vite'
import { getHTMLWebpackPlugin } from '../helper/getHTMLWebpackPlugin'
import { getHtmlWebpackPlugin } from '../helper/getHtmlWebpackPlugin'
import type { Options, UnpluginCompiler } from '../types'
import { getTagsAttributes } from '../helper/getTagsAttributes'
import { serializeTags } from '../helper/serializer'
Expand All @@ -16,11 +16,11 @@ export function htmlWebpackPluginAdapter(args: {
compiler.hooks.compilation.tap(name, async (compilation) => {
const isWebpack = 'assetsInfo' in compilation
const logger = compilation.getLogger(name)
const HTMLWebpackPlugin = await getHTMLWebpackPlugin(isWebpack)
if (!HTMLWebpackPlugin)
const HtmlWebpackPlugin = await getHtmlWebpackPlugin(isWebpack)
if (!HtmlWebpackPlugin)
return

const hooks = HTMLWebpackPlugin.default.getHooks(compilation as Compilation)
const hooks = HtmlWebpackPlugin.default.getHooks(compilation as Compilation)
let tagsAttributes: any[] = []

hooks.alterAssetTagGroups.tapAsync(
Expand Down
56 changes: 56 additions & 0 deletions src/adapter/vite.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import type { HtmlTagDescriptor, Logger } from 'vite'
import type { OutputBundle } from 'rollup'
import { getAssetsForViteJS } from '../helper/getAssets'
import type { Options } from '../types'
import { getTagsAttributes } from '../helper/getTagsAttributes'
import { serializeTags } from '../helper/serializer'

export function viteAdapter(args: {
bundle: OutputBundle
html: string
options: Options
customInject: RegExp
viteBasePath: string
viteLogger: Logger
}) {
const {
bundle,
html,
options,
customInject,
viteBasePath,
viteLogger,
} = args

const injectTo
= (options.injectTo && options.injectTo !== 'custom')
? options.injectTo
: 'head-prepend'

const assets = getAssetsForViteJS(bundle)
const tags: HtmlTagDescriptor[] = []
const tagsAttributes = getTagsAttributes(
assets,
options,
viteBasePath,
viteLogger,
)

tagsAttributes.forEach((attrs) => {
tags.push({
tag: 'link',
attrs,
injectTo,
})
})

if (options.injectTo === 'custom') {
return html.replace(
customInject,
(match, p1) => `\n${serializeTags(tags, p1)}`,
)
}
else {
return tags
}
}
6 changes: 3 additions & 3 deletions src/helper/getHTMLWebpackPlugin.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export async function getHTMLWebpackPlugin(throwError = true) {
export async function getHtmlWebpackPlugin(throwError = true) {
try {
const HTMLWebpackPlugin = await import('html-webpack-plugin')
return HTMLWebpackPlugin
const HtmlWebpackPlugin = await import('html-webpack-plugin')
return HtmlWebpackPlugin
}
catch (error) {
if (throwError) {
Expand Down
40 changes: 8 additions & 32 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import type { UnpluginFactory } from 'unplugin'
import { createUnplugin } from 'unplugin'
import type { HtmlTagDescriptor, IndexHtmlTransformContext, Logger } from 'vite'
import type { IndexHtmlTransformContext, Logger } from 'vite'
import type { Options } from './types'
import { getTagsAttributes } from './helper/getTagsAttributes'
import { serializeTags } from './helper/serializer'
import { getAssetsForViteJS } from './helper/getAssets'
import { htmlRspackPluginAdapter } from './adapter/HtmlRspackPlugin'
import { htmlWebpackPluginAdapter } from './adapter/HTMLWebpackPlugin'
import { htmlWebpackPluginAdapter } from './adapter/HtmlWebpackPlugin'

Check failure on line 6 in src/index.ts

View workflow job for this annotation

GitHub Actions / Lint: node-16, ubuntu-latest

Cannot find module './adapter/HtmlWebpackPlugin' or its corresponding type declarations.

Check failure on line 6 in src/index.ts

View workflow job for this annotation

GitHub Actions / Coverage

Cannot find module './adapter/HtmlWebpackPlugin' or its corresponding type declarations.

Check failure on line 6 in src/index.ts

View workflow job for this annotation

GitHub Actions / test (14, ubuntu-latest)

Cannot find module './adapter/HtmlWebpackPlugin' or its corresponding type declarations.

Check failure on line 6 in src/index.ts

View workflow job for this annotation

GitHub Actions / test (16, ubuntu-latest)

Cannot find module './adapter/HtmlWebpackPlugin' or its corresponding type declarations.

Check failure on line 6 in src/index.ts

View workflow job for this annotation

GitHub Actions / test (18, ubuntu-latest)

Cannot find module './adapter/HtmlWebpackPlugin' or its corresponding type declarations.

Check failure on line 6 in src/index.ts

View workflow job for this annotation

GitHub Actions / test (20, ubuntu-latest)

Cannot find module './adapter/HtmlWebpackPlugin' or its corresponding type declarations.
import { viteAdapter } from './adapter/vite'

const customInject = /([ \t]*)<!--__unplugin-inject-preload__-->/i
let viteBasePath: string
Expand All @@ -26,42 +24,20 @@ export const unpluginFactory: UnpluginFactory<Options> = options => ({
order: 'post',
handler(html, ctx) {
const bundle: IndexHtmlTransformContext['bundle'] = ctx.bundle

// ignore next because the bundle will be always here on build
/* c8 ignore next */
if (!bundle)
return html

const injectTo
= (options.injectTo && options.injectTo !== 'custom')
? options.injectTo
: 'head-prepend'

const assets = getAssetsForViteJS(bundle)
const tags: HtmlTagDescriptor[] = []
const tagsAttributes = getTagsAttributes(
assets,
return viteAdapter({
bundle,
html,
options,
customInject,
viteBasePath,
viteLogger,
)

tagsAttributes.forEach((attrs) => {
tags.push({
tag: 'link',
attrs,
injectTo,
})
})

if (options.injectTo === 'custom') {
return html.replace(
customInject,
(match, p1) => `\n${serializeTags(tags, p1)}`,
)
}
else {
return tags
}
},
},
},
Expand Down
14 changes: 7 additions & 7 deletions test/getHTMLWebpackPlugin.test.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { describe, expect, it, vi } from 'vitest'
import { getHTMLWebpackPlugin } from '../src/helper/getHTMLWebpackPlugin'
import { getHtmlWebpackPlugin } from '../src/helper/getHtmlWebpackPlugin'

describe('excerpt get HTMLWebpackPlugin', () => {
it('get HTMLWebpackPlugin', async () => {
const HTMLWebpackPlugin = await getHTMLWebpackPlugin()
expect(HTMLWebpackPlugin).not.toBeNull()
describe('excerpt get HtmlWebpackPlugin', () => {
it('get HtmlWebpackPlugin', async () => {
const HtmlWebpackPlugin = await getHtmlWebpackPlugin()
expect(HtmlWebpackPlugin).not.toBeNull()
})

it('failed get HTMLWebpackPlugin', async () => {
it('failed get HtmlWebpackPlugin', async () => {
vi.doMock('html-webpack-plugin', () => {})
try {
await getHTMLWebpackPlugin()
await getHtmlWebpackPlugin()
}
catch (error) {
expect(error).toBeDefined()
Expand Down

0 comments on commit 96c5547

Please sign in to comment.