gulp搭建h5项目

227 阅读4分钟

「这是我参与2022首次更文挑战的第1天,活动详情查看:2022首次更文挑战」。

写在前面的话

在上个周突然接到一个新需求,公司有一个新项目,需要做一套H5出来,不能使用vue,原因是需要做成服务端渲染的,直接交由后端同学套模板,后端同学不会vue,我又没太多时间帮他对接口,我手里还有好几个人任务排队呢,那直能给他们来一套静态页面了,由于我也是从后端转向前端的,除了vue我也不会其他的东西呀,没办法,学呗,找博客,看看有没有轮子可以用,最开始想着用webpack,可是我不会呀,感觉又很复杂,配置了两小时。后来放弃了,继续百度看到了gulp,然后看看官网,看了一下介绍,再看看github,这不就是我想要的吗,所以就他了,搭建花费了一两个小时,之后就挺顺利的,很不错,虽然才是浅入了一下,但是成长感觉挺不错的,下次再深入一下,多用一些插件再减少人力,提高质量。

gulp

gulp 将开发流程中让人痛苦或耗时的任务自动化,从而减少你所浪费的时间、创造更大价值。

gulp是一个JavaScript工具包,用作前端Web开发中的流构建系统,基于Node.js和npm的任务运行器,用于自动化Web开发中涉及的耗时和重复性任务,gulp 使用代码配置方法来定义其任务,并依赖于其小型的单用途插件来实现它们。gulp 生态系统包括 4,298 多个这样的插件。

1. 安装引入

  1. 安装
npm install --global gulp-cli
  1. 创建项目目录
mkdir h5
  1. 进入目录
cd h5
  1. 初始化npm
npm init
  1. 安装gulp
npm install --save-dev gulp
  1. 检查版本
gulp --version

2. 开发前的准备

重点加难点

  1. 安装必要相关插件

    插件你只需要知道怎么使用 是用来干啥的就行了,没必要每个插件都特别熟悉,了解,使用多了就自然熟悉了。

    • 自动加载gulp插件的库 gulp-load-plugins
    • 编译sass 为 css gulp-sass
    • 省时的浏览器同步工具,热加载 browser-sync
    • 模板工具 art-template
    • 处理CSS前缀问题的神器 autoprefixer
    • 将px单位转换为视口单位的 (vw, vh, vmin, vmax) 的 PostCSS 插件. postcss-px-to-viewport
    • 删除生成目录 del
    • 图片压缩 gulp-imagemin
    • js压缩 gulp-uglify
    • 代理 http-proxy-middleware
  2. 创建对应的文件存放目录

├─src
│  ├─assets
│  │  ├─css
│  │  │  ├─components
│  │  │  └─mine
│  │  ├─images
│  │  │  ├─icons
│  │  ├─js
│  │  │  └─mine
│  │  └─lib
│  │      ├─swiper
│  │      ├─vant
│  │      └─vue
│  ├─layout
│  │  ├─components
│  │  └─dailog
│  └─views
│      └─mine

  • src 为根目录
  • assets 主要存放资源文件
  • layout 存放公共模板
  • views 存放html视图文件
  • 尽量css、js目录对应html文件,方便查找

3. 创建gulpfile配置文件

这里我使用的 官网组合任务

  1. 创建gulpfile.js配置文件

前期大部分时间都是花在这里,也是劝退很多人的一个地方,我都差一点点退缩了,配置一直不正确,对传统前端新人不友好。

  1. 引入插件
const {src, dest, parallel, series, watch} = require('gulp');

// 省时的浏览器同步工具
const browserSync = require('browser-sync');
const bs = browserSync.create();
// 自动加载gulp*插件
const loadPlugins = require('gulp-load-plugins');
const plugins = loadPlugins();

// 模板渲染
const artTemplate = require('art-template');
// css前缀
const autoprefixer = require('autoprefixer');
// 将px单位转换为视口单位的 (vw, vh, vmin, vmax) 的 PostCSS 插件.
const pxtoviewport = require('postcss-px-to-viewport');

// 删除生成目录
const clean = () => {
  const del = require('del');
  return del(['dist', 'temp']);
};
  1. css处理

因为是h5端,是要适配不同的屏幕,就使用postcss的插件来开发

// css处理
const css = () => {
  return src(['src/assets/css/**'], {base: 'src'})
    .pipe(plugins.if(/\.scss$/, plugins.sass()))
    .pipe(
      plugins.postcss([
        autoprefixer({
          browers: ['last 2 versions', 'ie >= 9', '> 5% in CN'],
          cascade: false,
          remove: false,
        }),
        // h5 px转vw
        pxtoviewport({
          // 设计稿的视口宽度
          viewportWidth: 1080,
          viewportHeight: 1732,
          // 单位转换后保留的精度
          unitPrecision: 6,
          //  媒体查询里的单位是否需要转换单位
          mediaQuery: true,
          // 设置最小的转换数值
          minPixelValue: 1,
          // 忽略某些文件夹下的文件或特定文件
          exclude: [/node_modules/i],
          // selectorBlackList (Array) 需要忽略的CSS选择器
          selectorBlackList: ['.ignore', '.hairlines', /\.van-loading__text/, /\.van-(?!loading)/],
        }),
      ])
    )
    .pipe(dest('temp'))
    .pipe(bs.reload({stream: true})); // 编译完成后刷新
};
  1. js 处理

没有特殊处理,也没有压缩

const js = () => {
  return src('src/assets/js/**/*.js', {base: 'src'})
    .pipe(plugins.babel({presets: ['@babel/preset-env']}))
    .pipe(dest('temp'))
    .pipe(bs.reload({stream: true}));
};
  1. html 处理

配置时出现问题最多的地方,文件找不到了,模板语法不对了,特费神,刚上手差点就被这里劝退了,把路径控制对就没问题了

const html = () => {
  // 原始语法的界定符规则,art-template 官网的
  artTemplate.defaults.rules[0].test = /<%(#?)((?:==|=#|[=-])?)[ \t]*([\w\W]*?)[ \t]*(-?)%>/;
  // 标准语法的界定符规则,art-template 官网的
  artTemplate.defaults.rules[1].test = /<\?([@#]?)[ \t]*(\/?)([\w\W]*?)[ \t]*\?>/;
  // src/views/**/*.html 渲染的html文件路径
  return src('src/views/**/*.html', {base: 'src'})
    .pipe(
      plugins.htmlTpl({
        tag: 'tpl', // 勿使用这个标签<tpl>
        paths: ['./src/views'], // html文件目录
        engine: function (template, data) {
          return (
            template &&
            artTemplate.compile(template, {
              cache: false,
              // 是否开启压缩  HTML、JS、CSS
              minimize: false,
              root: './src', // 根目录
            })(data)
          );
        }
      })
    )
    .pipe(dest('temp'))
    .pipe(bs.reload({stream: true}));
};
  1. 资源文件处理,可以添加文件压缩等方式处理一下,我这里没有做过多处理
// 资源文件处理
const image = () => {
  return src('src/assets/images/**', {base: 'src'})
    .pipe(dest('temp'))
    .pipe(bs.reload({stream: true}));
};
// 字体处理
const font = () => {
  return src('src/assets/fonts/**', {base: 'src'})
    .pipe(dest('temp'))
    .pipe(bs.reload({stream: true}));
};

// lib不处理
const lib = () => {
  return src('src/assets/lib/**', {base: 'src'})
    .pipe(dest('temp'))
    .pipe(bs.reload({stream: true}));
};
// 不处理根目录下的public目录
const extra = () => {
  return src('public/**', {base: 'public'})
    .pipe(dest('dist'))
    .pipe(bs.reload({stream: true}));
};
  1. 开发环境配置

配置开发监听刚才创建的处理任务

// 开发环境
const serve = () => {
  watch('src/assets/css/**', css);
  watch('src/assets/js/**', js);
  watch('src/**/*.html', html);
  watch('src/assets/lib/**', lib);
  watch('src/assets/images/**', image);
  watch('src/assets/fonts/**', font);
  watch('public/**', extra);

  bs.init({
    notify: false,
    port: 2080,
    server: {
      baseDir: ['temp', 'dist', 'src', 'public'], // 基本目录(资源文件搜索入口)
      index: 'views/index.html',
      // URL匹配
      routes: {
        '/node_modules': 'node_modules',
      },
    },
  });
};
  1. 进行创建打包和调试的命令
// 使用useref处理HTML build打包合并的文件:包含js css html压缩处理
const useref = () => {
  return src('temp/*.html', {base: 'temp'})
    .pipe(
      plugins.useref({
        searchPath: ['dist', 'temp', '.'], // 匹配html中需要build的资源的路径
      })
    )
    .pipe(plugins.if(/\.js$/, plugins.uglify()))
    .pipe(plugins.if(/\.css$/, plugins.cleanCss()))
    .pipe(
      plugins.if(
        /\.html$/,
        plugins.htmlmin({
          minifyCSS: true, // 压缩css
          minifyJS: true, // 压缩js
          removeComments: true, // 清除HTML注释
        })
      )
    )
    .pipe(dest('dist'));
};

// 编译文件: 需要对文件进行处理的
const compile = parallel(css, js, html);

// 打包
const build = series(clean, lib, parallel(series(compile, useref), image, font, extra));

// 调试
const dev = series(clean, compile, serve);

module.exports = {
  clean,
  build,
  dev,
};

  1. 在package.json中创建脚本命令
{
    "name": "gulp-demo",
    "version": "0.1.0",
    "license": "MIT",
    "scripts": {
        "clean": "gulp clean",
        "build": "gulp build",
        "dev": "gulp dev"
    }
}
  1. 配置完成
  2. 创建公共头部、底部、组件,就可以像Django前后端不分离那样进行开发,接下来就是用模板形式开发减少代码重复量
<header class="search-header">
  <% if ($data != 'mine') { %>
  <a href="javascript:history.go(-1)" class="back-icon">
    <img src="/assets/images/icons/icon23.png" alt="">
  </a>
  <strong class="title"><% print($data) %></strong>
  <% } else  { %>
    <strong class="title">&nbsp;</strong>
  <% } %>

  <a href="javascript:">
    <img src="/assets/images/icons/icon8.png" alt="">
  </a>
</header>
  1. view中的文件引入公共文件
<% include('./layout/header.html', 'index') %>

结语

我是幸福部长,我在学gulp了,已经使用gulp完成了一个h5项目,总的来说除了刚开始搭建项目时,配置有一点困难,其他的都还好,速度很快。