npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

gulp-html-assets-extract

v1.1.7

Published

a gulp plugin to extract assets from html files

Downloads

14

Readme

gulp-html-assets-extract

gulp-html-assets-extract 是构建于gulp之上的一款思想超前的插件。它的工作方式类似于webpack和rollup的 tree shaking —— 以HTML文件作为输入,提取出文档中有用的资源,pipe下去做进一步处理

重要更新日志

  • 1.1.5 -修正Demo中一个拼写错误
  • 1.1.1 -更新Demo案例(演示如何使用gulp-filter过滤未被标记文件,以及如何搭配lazypipe和gulp.parallel使gulp执行速度大幅提升!!)
  • 1.1.0 -在之前的1.0.x版本中,插件没有提取未用/start:xx//end/包裹住的资源,该逻辑目前已修正。在这次版本更新后,使用者可以正确得到文件中引用的所有css和js资源了!

安装

使用Node的包管理工具NPM来安装该插件。

npm install gulp-html-assets-extract -D

gulp-html-assets-extract是怎样炼成的?

机缘巧合之下,我接手了一个项目,需要配合安卓和iOS端开发Webview页面。该项目采用原生html+css+js,没有使用任何前端框架,也没有打包工具。
一开始我打算采用webpack进行打包,但webpack与传统开发模式并不契合,配置起来也较困难,我便将目光投向了gulp。
一开始还算顺利,但慢慢地一个问题暴露了出来 —— 以前我们借助三大框架及webpack,可以打包我们项目真正需要的资源(Tree Shaking),以及对JS和CSS文件做合并压缩处理。但当我们使用html+gulp的时候,这点却很难实现。为什么呢?原因很简单,gulp的功能依托于插件,而在浩瀚如林的gulp插件中,并没有能实现类似于webpack这种打包机制的插件,于是我便动手自己开发了一个。

gulp-html-assets-extract有什么独特之处?

  gulp-html-assets-extract以HTML文件作为输入!它寻找文件中做了标记的资源引用,将标记的引用合并成一个文件,未做标记的资源,作为独立的文件,pipe 给下面的插件做进一步处理

gulp-html-assets-extract的使用场景?

所有以HTML而非JS文件作为入口的开发场景(其实就是不借助三大框架的传统开发模式)

gulp-html-assets-extract的工作方式?

  上文提到gulp-html-assets-extract会在html文件中寻找标记。那什么是标记呢?其实这是本插件事先定义好的HTML文档特殊注释(在w3c规范的HTML注释<!-- -->中间加上/start:xxx//end/,如<!-- /start:demo.js/ -->)gulp-html-assets-extract 会从注释包裹的内容中提取资源路径,根据路径将文件内容从磁盘读出来后合成一个文件 pipe 下去。
Q: 为什么要用注释的方式来提取资源呢?
A: 原因有以下几点:
① HTML中可能引用了第三方的js和css,这类型的资源可能做好了优化处理。如果再把它们拿出来进行二次加工,将会导致加工时间的增长以及潜在的错误。怎样规避这类问题呢?只要将它们置于标记外即可
② 如果一个注释里包含了多个css或js资源,插件是会将它们从磁盘中读取出来并合并为一个文件的。这时候就面对一个问题了,合并后的文件它叫什么,放于什么位置?为了让插件更灵活,插件采用这种方式将选择权交给了读者,让读者充分DIY(<!-- /start:xxx/ -->中的xxx就包含了合并后生成文件的位置和名称。如<!-- /start:path/to/folder/foo.js/ -->就会生成foo.js文件,放于path目录下的to文件夹下的folder文件夹内)。
③ 增加页面的可重塑性 —— 用户可以自行决定哪些资源需要作为一组进行合并,哪些作为另一组进行合并

gulp-html-assets-extract的优势

说了这么多,gulp-html-assets-extract 到底有哪些优点呢

  • 简单 - 只需注释就可实现一站式功能
  • 灵活 - 用户可在页面内充分DIY
  • 高效 - 高性能的正则匹配
  • 节约 - 以HTML为导向,只专注有用资源,节约时间,节省资源

Demo

下面提供一个简单的例子:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <!-- /start:combine.css/ -->
    <link rel="stylesheet" href="/css/style1.css" />
    <link rel="stylesheet" href="/css/style2.css" />
    <!-- /end/ -->
    <title>title</title>
  </head>
  <body>
    <div>nothing</div>
    <!-- /start:combine1.js/ -->
    <script src="./js/test.js"></script>
    <!-- /end/ -->
    <!-- /start:combine2.js/ -->
    <script src="./js/test2.js"></script>
    <script src="./js/test3.js"></script>
    <!-- /end/ -->
  </body>
</html>
const extract = require('gulp-html-assets-extract');
const filter = require('gulp-filter');
const htmlmin = require('gulp-htmlmin');
const uglify = require('gulp-uglify');
const cleanCSS = require('gulp-clean-css');
const autoprefixer = require('gulp-autoprefixer');
const lazypipe = require('lazypipe')

gulp.task('html-assets-extract',function(cb){
  // 感叹号开头,过滤掉文件路径中包含lib文件夹的所有js文件
  const jsFilter = filter(['**/*.js', '!**/lib/**'])
  // 感叹号开头,过滤掉文件路径中包含lib文件夹的所有css文件
  const cssFilter = filter(['**/*.css', '!**/lib/**'])
  const htmlFilter = filter("**/*.html")
  const readSrc = () => gulp.src("./src/**/*.html",{base: 'src'});
  // 初始化一个lazypipe
  const assetsPipe = lazypipe().pipe(readSrc).pipe(extract)();
  // html文件处理函数,函数体根据自身需求定义
  function html(cb){
    assetsPipe.pipe(htmlFilter).pipe(htmlmin(htmlMinOptions)).pipe(gulp.dest(devPath.buildPath));
    cb();
  }
  // js文件处理函数,函数体根据自身需求定义
  function js(cb){
    assetsPipe.pipe(jsFilter).pipe(babel({presets: ['@babel/env']}))
    .pipe(uglify())
    .pipe(gulp.dest(devPath.buildPath))
    cb()
  }
  // css文件处理函数,函数体根据自身需求定义
  function css(cb){
    assetsPipe.pipe(cssFilter).pipe(cleanCSS())
    .pipe(autoprefixer({
      overrideBrowserslist: ['Android 4.1', 'iOS 7.1', 'Chrome > 31', 'ff > 31', 'ie >= 8'],
      grid: true,
    }))
    .pipe(gulp.dest(devPath.buildPath))
    cb();
  }
  // 并列执行html,js和css三个任务,执行时间大幅缩短
  gulp.parallel(html,js,css)(cb)
})

以上第一个是html文件,第二个是gulpfile.js配置文件

任务执行成功后,html会变成

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <link rel="stylesheet" href="combine.css" />
    <title>title</title>
  </head>
  <body>
    <div>nothing</div>
    <script src="combine1.js"></script>
    <script src="combine2.js"></script>
  </body>
</html>

并且在与生成的html文件同级目录下,会看到 combine.csscombine1.jscombine2.js 这三个文件

guilefile.js注释: 为防止初学者不懂以上配置什么意思,这里特给出注释

const jsFilter = filter(['**/*.js', '!**/lib/**'])
const cssFilter = filter(['**/*.css', '!**/lib/**'])
const htmlFilter = filter("**/*.html")

以上三句代码通过gulp-filter来创建了三种不同的过滤器,分别可以过滤得到HTML文件,文件路径中不包括lib文件夹的CSS文件以及文件路径中不包括lib文件夹的JS文件。

gulp.src("./src/**/*.html", {base: './src'})

gulp.src 是 gulp读取文件的方式。需要注意的是我们应该指定base选项。 否则文件路径很可能出错

gulp.parallel(html,js,css)(cb)

gulp.taskgulp.parallel的回调函数别忘记cb的调用(具体参考上例)

注意事项

  1. 注释标签前后各有一个空格,请严格遵守<!--(这里有一个空格)/start:文件名/(这里有一个空格)--><!--(这里有一个空格)/end/(这里有一个空格)-->
  2. 理解base这个概念很重要,如果还不是很清楚的话,可以参考node和gulp的官方文档(这里先举一个简单的例子:当你书写诸如<link rel="stylesheet" href="/css/style1.css" /><script src="/js/test.js"></script>时,你的 / 指的是什么目录,那么base就是什么目录)

反馈

在插件使用过程中如遇到问题可向作者反馈([email protected])
如果觉得好用的话可向身边的人推广或给个星

许可证

MIT