Skip to content

Commit

Permalink
feat(html): implement scripts on head tag (#1816)
Browse files Browse the repository at this point in the history
* impl feat

* chore: refactor option name

---------

Co-authored-by: shellscape <[email protected]>
  • Loading branch information
TrueXPixells and shellscape authored Dec 15, 2024
1 parent 8670bdb commit a0ff1a5
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 12 deletions.
7 changes: 7 additions & 0 deletions packages/html/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,13 @@ Once run successfully, an HTML file should be written to the bundle output desti

## Options

### `addScriptsToHead`

Type: `Boolean`<br>
Default: `false`

Place scripts in the `<head>` tag instead of `<body>`.

### `attributes`

Type: `Object`<br>
Expand Down
9 changes: 7 additions & 2 deletions packages/html/recipes/external-files/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
* @param {Array} externals List of external files.
* The format is: [{ type: 'js', file: '//xxxx1.js', pos: 'before' }, { type: 'css', file: '//xxxx1.css' }]
*
* @return {Function} The templae method required by plugin-html
* @return {Function} The template method required by plugin-html
*/
export default function htmlTemplate(externals) {
return ({ attributes, files, meta, publicPath, title }) => {
return ({ attributes, files, meta, publicPath, title, addScriptsToHead }) => {
let scripts = [...(files.js || [])];
let links = [...(files.css || [])];

Expand Down Expand Up @@ -43,6 +43,11 @@ export default function htmlTemplate(externals) {
})
.join('\n');

if (addScriptsToHead === true) {
links += scripts;
scripts = '';
}

const metas = meta
.map((input) => {
const attrs = makeHtmlAttributes(input);
Expand Down
27 changes: 21 additions & 6 deletions packages/html/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,22 +31,28 @@ const defaultTemplate = async ({
files,
meta,
publicPath,
title
title,
addScriptsToHead
}: RollupHtmlTemplateOptions) => {
const scripts = (files.js || [])
let scripts = (files.js || [])
.map(({ fileName }) => {
const attrs = makeHtmlAttributes(attributes.script);
return `<script src="${publicPath}${fileName}"${attrs}></script>`;
})
.join('\n');

const links = (files.css || [])
let links = (files.css || [])
.map(({ fileName }) => {
const attrs = makeHtmlAttributes(attributes.link);
return `<link href="${publicPath}${fileName}" rel="stylesheet"${attrs}>`;
})
.join('\n');

if (addScriptsToHead === true) {
links += scripts;
scripts = '';
}

const metas = meta
.map((input) => {
const attrs = makeHtmlAttributes(input);
Expand Down Expand Up @@ -80,12 +86,20 @@ const defaults: Required<RollupHtmlOptions> = {
meta: [{ charset: 'utf-8' }],
publicPath: '',
template: defaultTemplate,
title: 'Rollup Bundle'
title: 'Rollup Bundle',
addScriptsToHead: false
};

export default function html(opts: RollupHtmlOptions = {}): Plugin {
const { attributes, fileName, meta, publicPath, template, title }: Required<RollupHtmlOptions> =
Object.assign({}, defaults, opts);
const {
addScriptsToHead,
attributes,
fileName,
meta,
publicPath,
template,
title
}: Required<RollupHtmlOptions> = Object.assign({}, defaults, opts);

return {
name: 'html',
Expand All @@ -110,6 +124,7 @@ export default function html(opts: RollupHtmlOptions = {}): Plugin {
const files = getFiles(bundle);
const source = await template({
attributes,
addScriptsToHead,
bundle,
files,
meta,
Expand Down
46 changes: 46 additions & 0 deletions packages/html/test/snapshots/test.js.md
Original file line number Diff line number Diff line change
Expand Up @@ -353,3 +353,49 @@ Generated by [AVA](https://avajs.dev).
source: '<html><body><main></main></body></html>',
},
]

## scripts on head

> Snapshot 1
[
{
code: `(function (factory) {␊
typeof define === 'function' && define.amd ? define(factory) :␊
factory();␊
})((function () { 'use strict';␊
}));␊
`,
fileName: 'joker.js',
map: null,
source: undefined,
},
{
code: undefined,
fileName: 'joker.css',
map: undefined,
source: Buffer @Uint8Array [
2a207b20 77696474 683a2031 3030253b 207d0a
],
},
{
code: undefined,
fileName: 'index.html',
map: undefined,
source: `␊
<!doctype html>␊
<html>␊
<head>␊
<meta charset="utf-8">␊
<title>Rollup Bundle</title>␊
<link href="joker.css" rel="stylesheet"><script src="joker.js" defer="true"></script>␊
</head>␊
<body>␊
</body>␊
</html>`,
},
]
Binary file modified packages/html/test/snapshots/test.js.snap
Binary file not shown.
17 changes: 17 additions & 0 deletions packages/html/test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,3 +120,20 @@ test.serial('template', async (t) => {
const code = await getCode(bundle, output, true);
t.snapshot(code);
});

test.serial('scripts on head', async (t) => {
const bundle = await rollup({
input: 'joker.js',
plugins: [
css({ extract: true }),
html({
attributes: {
script: { defer: true }
},
addScriptsToHead: true
})
]
});
const code = await getCode(bundle, output, true);
t.snapshot(code);
});
10 changes: 6 additions & 4 deletions packages/html/types/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
import type { Plugin, OutputChunk, OutputAsset, OutputBundle } from 'rollup';

export interface RollupHtmlTemplateOptions {
title: string;
addScriptsToHead?: boolean;
attributes: Record<string, any>;
publicPath: string;
meta: Record<string, any>[];
bundle: OutputBundle;
files: Record<string, (OutputChunk | OutputAsset)[]>;
meta: Record<string, any>[];
publicPath: string;
title: string;
}

export interface RollupHtmlOptions {
title?: string;
addScriptsToHead?: boolean;
attributes?: Record<string, any>;
fileName?: string;
meta?: Record<string, any>[];
publicPath?: string;
template?: (templateoptions: RollupHtmlTemplateOptions) => string | Promise<string>;
title?: string;
}

export function makeHtmlAttributes(attributes: Record<string, string>): string;
Expand Down

0 comments on commit a0ff1a5

Please sign in to comment.