用 gulp 4 把 less 文件编译成 css 文件

中文文档: https://www.gulpjs.com.cn/docs/getting-started/quick-start/

当下编译 less 的方式有很多如:

  1. 利用代码编辑器插件编译, 如vscode编辑器 等, 这种适合人数少的团队, 通过简单约定
  2. 利用项目所使用的框架, 如项目中用到了 webpack / rollup / vite 这些工具, 可以直接配置使用
  3. 如果项目没有用到webpack vite 等大型打包工具, 可以使用 gulp 这种轻量的工具 编译 less

gulp 利用 gulp-less 插件编译 less 文件到 css , 需要用到 nodejs 的支持,
如果没有 nodejs 请先去安装nodejs

本文依据 node 版本如下:

$ node -v
v14.17.0

项目基本目录结构示意

项目
| public
|----| less
|----|----|common.less
|----|----|page
|----|----|----|home.less
|----| css
|----|----|common.css
|----|----|home.css
| gulpfile.js
| package.json
| package-lock.json

初始化package.json

在项目根目录, 寻找有没有 package.json 文件
如果没有这个文件, 则使用 npm init 生成 package.json 文件

安装依赖包

执行如下命令,安装依赖包,
如果已经安装了部分依赖, 可以不安装

npm install  gulp gulp-clean gulp-clean-css gulp-less gulp-rename  less-plugin-autoprefix  -D

本文安装依赖版本如下:

"devDependencies": {
    "gulp": "^4.0.2",
    "gulp-clean": "^0.4.0",
    "gulp-clean-css": "^4.3.0",
    "gulp-less": "^5.0.0",
    "gulp-rename": "^2.0.0"
    "less-plugin-autoprefix": "^2.0.0"
},
"gulp-clean":  用来清空文件夹

“gulp-clean-css”: 压缩css文件
“gulp-less”: 编译less文件
“gulp-rename”: 重命名输出文件
“less-plugin-autoprefix”: 为css自动添加兼容写法

添加 npm 命令

在项目根目录, 可以直接执行 gulp XXX ,
但是为了方便记忆, 和 使用, 我选择放到 scripts 中,

"scripts": {
    "watch": "gulp",
    "build": "gulp build",
    "clean": "gulp clean"
  },

创建 gulp 配置文件

在项目根目录, 创建 gulpfile.js 文件, 用来编写gulp配置文件.

配置项

ROOT_DIR Less 和 css 的共同目录 public
OUTPUT_LESS Less 文件输出目录
INPUT_LESS Less 文件输入目录, 这个是一个数组
SOURCEMAPS 是否开启 sourcemaps

// 配置
const ROOT_DIR = "./public"; 
// Less 文件输出目录
const OUTPUT_LESS = `${ROOT_DIR}/css/`; 
// Less 文件输入目录
const INPUT_LESS = [
  `${ROOT_DIR}/less/`,
  `${ROOT_DIR}/less/page/`,
]
// 是否开启 sourcemaps
const SOURCEMAPS = true;

gulpfile.js 全部内容

const fs = require('fs');
const { src,dest, watch, series, parallel } = require('gulp');
const less = require('gulp-less');
const minifycss = require('gulp-clean-css')
const clean = require('gulp-clean')
const rename = require('gulp-rename')
const LessAutoprefix = require('less-plugin-autoprefix');
const autoprefix = new LessAutoprefix({ browsers: ['last 2 versions'] });
// const path = require('path');
 
// 配置
const ROOT_DIR = "./public"; 
// Less 文件输出目录
const OUTPUT_LESS = `${ROOT_DIR}/css/`; 
// Less 文件输入目录
const INPUT_LESS = [
  `${ROOT_DIR}/less/`,
  `${ROOT_DIR}/less/page/`,
]
// 是否开启 sourcemaps
const SOURCEMAPS = true;

function existsDir(file){
  file = file.replace(/\/$/,"");
  const stats = fs.statSync(file);
  if(!stats.isDirectory()) {
    throw new Error(`${file} 不是一个文件夹`)
  };
}

// 检验输出文件夹是否存在
existsDir(OUTPUT_LESS)

// 清空输出文件夹
function cleanTasks(cb) {
  src(`${OUTPUT_LESS}`, {read: false})
  .pipe(clean());
  cb();
}

// less 编译流程
function lessTask(srcpath, cb) {
  console.log(srcpath)
  src(srcpath, { sourcemaps: SOURCEMAPS })
  .pipe(less({ plugins: [autoprefix] }))
  .pipe(rename(function (path) {
    const dirname = OUTPUT_LESS.replace(new RegExp(ROOT_DIR + '\/' ),'');
    return {
      dirname: dirname,
      basename: path.basename,
      extname: ".css"
    };
  }))
  .pipe(minifycss())
  .pipe(dest(`${ROOT_DIR}`, { sourcemaps: SOURCEMAPS }));

  cb && cb();
}

function doneTask(cb) {
  console.log(`任务完成`);
  cb();
}

// 获取less目录下所有less文件
function getLessFile(rootPath){
  let files = []
  try {
    const fileList = fs.readdirSync(rootPath) || [];

    fileList.forEach(function(file){
      const filePath = rootPath + file

      const stats = fs.statSync(filePath)
      if(stats.isDirectory()) return;

      if(/\.less$/.test(file)) {
        files.push(filePath);
      }

    })
  } catch (error) {
    console.log("读取文件目录失败:",error)
  }
  return files
}

// 每一个less 文件生成一个less编译任务, 目的是所有less文件,异步编译, 提高编译速度
function lessParallelTasks(){
  const fileList = INPUT_LESS.reduce((files,dir) => files.concat(getLessFile(dir)), []);

  return fileList.map(function(filePath){
    return cb => lessTask(filePath, cb);
  });
}

// 观察指定文件的变化, 然后编译这个文件
function watchTasks() {
  const lessList = INPUT_LESS.map(dir => `${dir}*.less`);

  watch(lessList).on('all', function(eventName, stats) {
    lessTask(stats)
    console.log(`[${eventName}] ${stats} 编译完成`);
  });
  
  // 其他一些基础less, 修改这些需要全部编译一次 
  watch([`${ROOT_DIR}/less/lib/*.less`], series( parallel(lessParallelTasks()), doneTask));
}

exports.build = series(cleanTasks, parallel(lessParallelTasks()), doneTask);
exports.clean = series(cleanTasks);
exports.watch = watchTasks;
exports.default = watchTasks;


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

了 义

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值