rollup-plugin-html-insert
Advanced tools
Comparing version 1.0.0 to 1.0.1
@@ -5,33 +5,109 @@ 'use strict'; | ||
// console.log(1111) | ||
// import * as fs from 'fs' | ||
// import * as path from 'path' | ||
// import { parse, HTMLElement, TextNode } from 'node-html-parser' | ||
var fs = require('fs'); | ||
var path = require('path'); | ||
var nodeHtmlParser = require('node-html-parser'); | ||
function _interopNamespaceDefault(e) { | ||
var n = Object.create(null); | ||
if (e) { | ||
Object.keys(e).forEach(function (k) { | ||
if (k !== 'default') { | ||
var d = Object.getOwnPropertyDescriptor(e, k); | ||
Object.defineProperty(n, k, d.get ? d : { | ||
enumerable: true, | ||
get: function () { return e[k]; } | ||
}); | ||
} | ||
}); | ||
} | ||
n.default = e; | ||
return Object.freeze(n); | ||
} | ||
var fs__namespace = /*#__PURE__*/_interopNamespaceDefault(fs); | ||
const getFiles = (bundle) => { | ||
const result = {}; | ||
for (const file of Object.values(bundle)) { | ||
const { fileName } = file; | ||
const extension = path.extname(fileName).substring(1); | ||
result[extension] = (result[extension] || []).concat(file); | ||
} | ||
return result; | ||
}; | ||
const getChildElement = (node, tag, append = true) => { | ||
let child = node.querySelector(tag); | ||
if (!child) { | ||
child = new nodeHtmlParser.HTMLElement(tag, {}, '', node, [0, 0]); | ||
if (append) { | ||
node.appendChild(child); | ||
} | ||
else { | ||
node.childNodes.unshift(child); | ||
} | ||
} | ||
return child; | ||
}; | ||
const defaults = { | ||
fileName: 'index.html', | ||
entryFileNames: 'index.html', | ||
insert: 'code', | ||
template: 'public/index.html' | ||
publicPath: './', | ||
template: './public/index.html' | ||
}; | ||
function htmlInsert(opts = {}) { | ||
const { template, insert, fileName } = Object.assign(defaults, opts); | ||
const { template, insert, entryFileNames, publicPath } = Object.assign(defaults, opts); | ||
return { | ||
name: 'htmlInsert', | ||
async generateBundle(output, bundle) { | ||
// const source = await template({ | ||
// attributes, | ||
// bundle, | ||
// files, | ||
// meta, | ||
// publicPath, | ||
// title | ||
// }); | ||
// let distDir = process.cwd() | ||
// const htmlFileName = path.resolve(distDir, path.basename(template)) | ||
// const htmlTpl = fs.readFileSync(template).toString() | ||
const source = ''; | ||
const htmlTpl = fs__namespace.readFileSync(template).toString(); | ||
const doc = nodeHtmlParser.parse(htmlTpl, { comment: true }); | ||
const html = doc.querySelector('html'); | ||
const head = getChildElement(html, 'head', false); | ||
const body = getChildElement(html, 'body'); | ||
/** { js: [], css: [] } */ | ||
const files = getFiles(bundle); | ||
console.log('files', files); | ||
// 通过路劲加载资源 | ||
if (insert === 'path') { | ||
const scripts = (files.js || []); | ||
for (let index = 0; index < scripts.length; index++) { | ||
const { fileName, name } = scripts[index]; | ||
const entry = new nodeHtmlParser.HTMLElement('script', { id: name }, '', body, [0, 0]); | ||
entry.setAttribute('src', `${publicPath}${fileName}`); | ||
body.appendChild(entry); | ||
} | ||
const links = (files.css || []); | ||
for (let index = 0; index < links.length; index++) { | ||
const { fileName, name } = links[index]; | ||
const entry = new nodeHtmlParser.HTMLElement('link', { id: name }, '', head, [0, 0]); | ||
entry.setAttribute('href', `${publicPath}${fileName}`); | ||
entry.setAttribute('rel', 'stylesheet'); | ||
body.appendChild(entry); | ||
} | ||
} | ||
// 直接将打包好的代码插入html | ||
if (insert === 'code') { | ||
const scripts = (files.js || []); | ||
for (let index = 0; index < scripts.length; index++) { | ||
const { name, code } = scripts[index]; | ||
const entry = new nodeHtmlParser.HTMLElement('script', { id: name }, '', body, [0, 0]); | ||
entry.appendChild(new nodeHtmlParser.TextNode(code, entry)); | ||
body.appendChild(entry); | ||
} | ||
const links = (files.css || []); | ||
for (let index = 0; index < links.length; index++) { | ||
const { source, name } = links[index]; | ||
const entry = new nodeHtmlParser.HTMLElement('style', { id: name }, '', head, [0, 0]); | ||
entry.appendChild(new nodeHtmlParser.TextNode(source, entry)); | ||
body.appendChild(entry); | ||
} | ||
} | ||
const source = doc.toString(); | ||
const htmlFile = { | ||
type: 'asset', | ||
source, | ||
name: 'htmlFileName', | ||
fileName | ||
name: 'public_html', | ||
fileName: entryFileNames | ||
}; | ||
@@ -38,0 +114,0 @@ this.emitFile(htmlFile); |
@@ -1,32 +0,89 @@ | ||
// console.log(1111) | ||
// import * as fs from 'fs' | ||
// import * as path from 'path' | ||
// import { parse, HTMLElement, TextNode } from 'node-html-parser' | ||
import * as fs from 'fs'; | ||
import { extname } from 'path'; | ||
import { parse, HTMLElement, TextNode } from 'node-html-parser'; | ||
const getFiles = (bundle) => { | ||
const result = {}; | ||
for (const file of Object.values(bundle)) { | ||
const { fileName } = file; | ||
const extension = extname(fileName).substring(1); | ||
result[extension] = (result[extension] || []).concat(file); | ||
} | ||
return result; | ||
}; | ||
const getChildElement = (node, tag, append = true) => { | ||
let child = node.querySelector(tag); | ||
if (!child) { | ||
child = new HTMLElement(tag, {}, '', node, [0, 0]); | ||
if (append) { | ||
node.appendChild(child); | ||
} | ||
else { | ||
node.childNodes.unshift(child); | ||
} | ||
} | ||
return child; | ||
}; | ||
const defaults = { | ||
fileName: 'index.html', | ||
entryFileNames: 'index.html', | ||
insert: 'code', | ||
template: 'public/index.html' | ||
publicPath: './', | ||
template: './public/index.html' | ||
}; | ||
function htmlInsert(opts = {}) { | ||
const { template, insert, fileName } = Object.assign(defaults, opts); | ||
const { template, insert, entryFileNames, publicPath } = Object.assign(defaults, opts); | ||
return { | ||
name: 'htmlInsert', | ||
async generateBundle(output, bundle) { | ||
// const source = await template({ | ||
// attributes, | ||
// bundle, | ||
// files, | ||
// meta, | ||
// publicPath, | ||
// title | ||
// }); | ||
// let distDir = process.cwd() | ||
// const htmlFileName = path.resolve(distDir, path.basename(template)) | ||
// const htmlTpl = fs.readFileSync(template).toString() | ||
const source = ''; | ||
const htmlTpl = fs.readFileSync(template).toString(); | ||
const doc = parse(htmlTpl, { comment: true }); | ||
const html = doc.querySelector('html'); | ||
const head = getChildElement(html, 'head', false); | ||
const body = getChildElement(html, 'body'); | ||
/** { js: [], css: [] } */ | ||
const files = getFiles(bundle); | ||
console.log('files', files); | ||
// 通过路劲加载资源 | ||
if (insert === 'path') { | ||
const scripts = (files.js || []); | ||
for (let index = 0; index < scripts.length; index++) { | ||
const { fileName, name } = scripts[index]; | ||
const entry = new HTMLElement('script', { id: name }, '', body, [0, 0]); | ||
entry.setAttribute('src', `${publicPath}${fileName}`); | ||
body.appendChild(entry); | ||
} | ||
const links = (files.css || []); | ||
for (let index = 0; index < links.length; index++) { | ||
const { fileName, name } = links[index]; | ||
const entry = new HTMLElement('link', { id: name }, '', head, [0, 0]); | ||
entry.setAttribute('href', `${publicPath}${fileName}`); | ||
entry.setAttribute('rel', 'stylesheet'); | ||
body.appendChild(entry); | ||
} | ||
} | ||
// 直接将打包好的代码插入html | ||
if (insert === 'code') { | ||
const scripts = (files.js || []); | ||
for (let index = 0; index < scripts.length; index++) { | ||
const { name, code } = scripts[index]; | ||
const entry = new HTMLElement('script', { id: name }, '', body, [0, 0]); | ||
entry.appendChild(new TextNode(code, entry)); | ||
body.appendChild(entry); | ||
} | ||
const links = (files.css || []); | ||
for (let index = 0; index < links.length; index++) { | ||
const { source, name } = links[index]; | ||
const entry = new HTMLElement('style', { id: name }, '', head, [0, 0]); | ||
entry.appendChild(new TextNode(source, entry)); | ||
body.appendChild(entry); | ||
} | ||
} | ||
const source = doc.toString(); | ||
const htmlFile = { | ||
type: 'asset', | ||
source, | ||
name: 'htmlFileName', | ||
fileName | ||
name: 'public_html', | ||
fileName: entryFileNames | ||
}; | ||
@@ -33,0 +90,0 @@ this.emitFile(htmlFile); |
{ | ||
"name": "rollup-plugin-html-insert", | ||
"version": "1.0.0", | ||
"version": "1.0.1", | ||
"description": "rollup plugin to edit html template", | ||
@@ -10,4 +10,5 @@ "type": "module", | ||
"scripts": { | ||
"dev": "rollup -c -w", | ||
"build": "rollup -c", | ||
"test": "ava", | ||
"test": "ava -w", | ||
"clear:ava": "rm -rf test/snapshots/", | ||
@@ -14,0 +15,0 @@ "test:ts": "tsc --noEmit" |
100
src/index.ts
import * as fs from 'fs' | ||
import * as path from 'path' | ||
import { extname } from 'path' | ||
import { parse, HTMLElement, TextNode } from 'node-html-parser' | ||
import type { Plugin, NormalizedOutputOptions, OutputBundle, EmittedAsset } from 'rollup' | ||
import type { RollupHtmlOptions } from '../types' | ||
import type { RollupHtmlOptions, RollupHtmlTemplateOptions } from '../types' | ||
const getFiles = (bundle: OutputBundle): RollupHtmlTemplateOptions['files'] => { | ||
const result = {} as ReturnType<typeof getFiles> | ||
for (const file of Object.values(bundle)) { | ||
const { fileName } = file | ||
const extension = extname(fileName).substring(1) | ||
result[extension] = (result[extension] || []).concat(file) | ||
} | ||
return result | ||
} | ||
const getChildElement = (node: any, tag: any, append = true) => { | ||
let child = node.querySelector(tag) | ||
if (!child) { | ||
child = new HTMLElement(tag, {}, '', node, [0, 0]) | ||
if (append) { | ||
node.appendChild(child) | ||
} else { | ||
node.childNodes.unshift(child) | ||
} | ||
} | ||
return child | ||
} | ||
const defaults = { | ||
fileName: 'index.html', | ||
entryFileNames: 'index.html', | ||
insert: 'code', | ||
template: 'public/index.html' | ||
publicPath: './', | ||
template: './public/index.html' | ||
} | ||
export default function htmlInsert(opts: RollupHtmlOptions = {}): Plugin { | ||
const { template, insert, fileName } = Object.assign(defaults, opts) | ||
const { template, insert, entryFileNames, publicPath } = Object.assign(defaults, opts) | ||
@@ -20,23 +47,56 @@ return { | ||
async generateBundle(output: NormalizedOutputOptions, bundle: OutputBundle) { | ||
if (insert === 'code') { | ||
// console.log(output, bundle); | ||
} | ||
// const source = await template({ | ||
// attributes, | ||
// bundle, | ||
// files, | ||
// meta, | ||
// publicPath, | ||
// title | ||
// }); | ||
// let distDir = process.cwd() | ||
// const htmlFileName = path.resolve(distDir, path.basename(template)) | ||
// const htmlTpl = fs.readFileSync(template).toString() | ||
const source = '' | ||
const htmlTpl = fs.readFileSync(template).toString() | ||
const doc = parse(htmlTpl, { comment: true }) | ||
const html = doc.querySelector('html') | ||
const head = getChildElement(html, 'head', false) | ||
const body = getChildElement(html, 'body') | ||
/** { js: [], css: [] } */ | ||
const files = getFiles(bundle) | ||
console.log('files', files) | ||
// 通过路劲加载资源 | ||
if (insert === 'path') { | ||
const scripts = (files.js || []) | ||
for (let index = 0; index < scripts.length; index++) { | ||
const { fileName, name } = scripts[index]; | ||
const entry = new HTMLElement('script', {id: name}, '', body, [0, 0]) | ||
entry.setAttribute('src', `${publicPath}${fileName}`) | ||
body.appendChild(entry) | ||
} | ||
const links = (files.css || []) | ||
for (let index = 0; index < links.length; index++) { | ||
const { fileName, name } = links[index]; | ||
const entry = new HTMLElement('link', {id: name}, '', head, [0, 0]) | ||
entry.setAttribute('href', `${publicPath}${fileName}`) | ||
entry.setAttribute('rel', 'stylesheet') | ||
body.appendChild(entry) | ||
} | ||
} | ||
// 直接将打包好的代码插入html | ||
if (insert === 'code') { | ||
const scripts = (files.js || []) | ||
for (let index = 0; index < scripts.length; index++) { | ||
const { name, code } = scripts[index]; | ||
const entry = new HTMLElement('script', {id: name}, '', body, [0, 0]) | ||
entry.appendChild(new TextNode(code, entry)) | ||
body.appendChild(entry) | ||
} | ||
const links = (files.css || []) | ||
for (let index = 0; index < links.length; index++) { | ||
const { source, name } = links[index]; | ||
const entry = new HTMLElement('style', {id: name}, '', head, [0, 0]) | ||
entry.appendChild(new TextNode(source, entry)) | ||
body.appendChild(entry) | ||
} | ||
} | ||
const source = doc.toString() | ||
const htmlFile: EmittedAsset = { | ||
type: 'asset', | ||
source, | ||
name: 'htmlFileName', | ||
fileName | ||
name: 'public_html', | ||
fileName: entryFileNames | ||
} | ||
@@ -43,0 +103,0 @@ |
@@ -29,4 +29,30 @@ # Snapshot report for `test/test.js` | ||
map: undefined, | ||
source: '', | ||
source: `<!DOCTYPE html>␍␊ | ||
<html lang="en">␍␊ | ||
<head>␍␊ | ||
<meta charset="UTF-8" >␍␊ | ||
<meta http-equiv="X-UA-Compatible" content="IE=edge" >␍␊ | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0" >␍␊ | ||
<title>test</title>␍␊ | ||
<!-- <style href=""></style> -->␍␊ | ||
</head>␍␊ | ||
<body>␍␊ | ||
<noscript>␍␊ | ||
<strong>We're sorry but webapp doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>␍␊ | ||
</noscript>␍␊ | ||
<div id="app"></div>␍␊ | ||
<!-- built files will be auto injected -->␍␊ | ||
␍␊ | ||
␍␊ | ||
<script id="batman">(function () {␊ | ||
'use strict';␊ | ||
␊ | ||
const hello = 'hello word';␍␊ | ||
console.log(hello);␊ | ||
␊ | ||
})();␊ | ||
</script></body>␍␊ | ||
</html>␍␊ | ||
`, | ||
}, | ||
] |
@@ -25,3 +25,3 @@ import test from 'ava' | ||
input: 'test/fixtures/batman.js', | ||
plugins: [htmlInsert()] | ||
plugins: [htmlInsert({ template: 'test/public/index.html' })] | ||
}) | ||
@@ -28,0 +28,0 @@ const code = await getCode(bundle, output, true) |
@@ -5,3 +5,3 @@ { | ||
"esModuleInterop": true, | ||
"lib": ["es6"], | ||
"lib": ["es2019"], | ||
"module": "commonjs", | ||
@@ -8,0 +8,0 @@ "moduleResolution": "node", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
30941
446
4