123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- const { JSDOM } = require('jsdom');
- const fs = require('fs')
- const path = require('path')
- const request = require('request')
- const UglifyJS = require("uglify-js");
- const CleanCSS = require('clean-css');
- const minifyHtml = require('html-minifier').minify
- /**
- * 抽取所有脚本css等文件
- * @param {Document} document jsdom
- */
- function scriptFilter(document) {
- let ret = {script: [], link: []}
- for (let i = 0, dom = document.querySelectorAll('script'); i < dom.length; i++) {
- let src = dom[i].getAttribute('src')
- ret.script.push(src ?
- {content: src, type: 1, url: src} :
- {content: dom[i].innerHTML, type: 0, url: src}
- )
- dom[i].parentNode.removeChild(dom[i]);
- }
- for (let i = 0, dom = document.querySelectorAll('link[rel="stylesheet"],style'); i < dom.length; i++) {
- let tagName = dom[i].tagName
- ret.link.push(tagName === 'LINK' ?
- {content: dom[i].getAttribute('href'), type: 1} :
- {content: dom[i].innerHTML, type: 0}
-
- )
- dom[i].parentNode.removeChild(dom[i]);
- }
- return ret
- }
- /**
- * 下载所有资源
- * @param {String} dir 文件所在的路径
- * @param {Array} contents 文件
- */
- async function downContent(dir, contents) {
- let labels = ['script', 'link']
- for (let i = 0, label; label = labels[i]; i++) {
- for (let j = 0, item; item = contents[label][j]; j++) {
- if (item.type === 1) {
- let src = path.join(dir, item.content)
- src = ~src.indexOf('?') ? src.substring(0, src.indexOf('?')) : src
- if (fs.existsSync(src)) {
- item.content = fs.readFileSync(src).toString()
- } else {
- await new Promise(resolve => {
- request.get(item.content, (err, response) => {
- if (!err && response.statusCode === 200) {
- item.content = response.body
- } else {
- item.content = ''
- }
- resolve()
- })
- });
- }
- }
- }
- }
- return contents
- }
- /**
- * 合并资源,并压缩
- * @param {JSON} contents 所有资源
- */
- function mergeStatic (contents) {
- let ret = {script: '', link: ''}
- Object.keys(ret).forEach(label => {
- contents[label].forEach(item => {
- ret[label] += item.content
- label === 'script' && (ret[label] += ';')
- })
- })
- ret.script = UglifyJS.minify(ret.script, {
- compress: {
- dead_code: true,
- global_defs: {
- DEBUG: false
- }
- }
- }).code
- ret.link = new CleanCSS({}).minify(ret.link).styles
- return ret
- }
- async function main (file) {
- let src = path.join(process.cwd(), file)
- console.log(src)
- let document = new JSDOM(fs.readFileSync(src)).window.document
- let dir = path.join(src, '../')
- let contents = await downContent(
- path.join(src, '../'),
- scriptFilter(document)
- )
- let ret = mergeStatic(contents)
- let $script = document.createElement('script')
- let $link = document.createElement('link')
- $script.setAttribute('src', 'js/minify-script.js')
- $link.setAttribute('rel', 'stylesheet')
- $link.setAttribute('href', 'css/minify-style.css')
- document.head.appendChild($link)
- document.body.appendChild($script)
- let html = `
- <!doctype html>
- <html>
- ${document.documentElement.innerHTML}
- </html>
- `
- fs.writeFileSync(path.join(dir, 'js/minify-script.js'), ret.script)
- fs.writeFileSync(path.join(dir, 'css/minify-style.css'), ret.link)
- fs.writeFileSync(path.join(dir, 'minify-temp.html'), minifyHtml(html, {
- removeComments: true,
- collapseWhitespace: true,
- }))
- }
- main(...process.argv.splice(2))
|