解析ElementPlus打包源码(四、打包主题)

buildThemeChalk

scss 复制代码
withTaskName('buildThemeChalk', () =>
  run('pnpm run -C packages/theme-chalk build')
)

这个打包任务需要执行packages/theme-chalk下的build命令

对应的命令是"build": "gulp --require @esbuild-kit/cjs-loader"

我们去看对应的gulpfile.ts

javascript 复制代码
import path from 'path'
import { Transform } from 'stream'
import chalk from 'chalk'
import { type TaskFunction, dest, parallel, series, src } from 'gulp'
import gulpSass from 'gulp-sass'
import dartSass from 'sass'
import autoprefixer from 'gulp-autoprefixer'
import rename from 'gulp-rename'
import consola from 'consola'
import postcss from 'postcss'
import cssnano from 'cssnano'
import { epOutput } from '@element-plus/build-utils'
import type Vinly from 'vinyl'

const distFolder = path.resolve(__dirname, 'dist')
const distBundle = path.resolve(epOutput, 'theme-chalk')

/**
 * using `postcss` and `cssnano` to compress CSS
 * @returns
 */
function compressWithCssnano() {
  const processor = postcss([
    cssnano({
      preset: [
        'default',
        {
          // avoid color transform
          colormin: false,
          // avoid font transform
          minifyFontValues: false,
        },
      ],
    }),
  ])
  return new Transform({
    objectMode: true,
    transform(chunk, _encoding, callback) {
      const file = chunk as Vinly
      if (file.isNull()) {
        callback(null, file)
        return
      }
      if (file.isStream()) {
        callback(new Error('Streaming not supported'))
        return
      }
      const cssString = file.contents!.toString()
      processor.process(cssString, { from: file.path }).then((result) => {
        const name = path.basename(file.path)
        file.contents = Buffer.from(result.css)
        consola.success(
          `${chalk.cyan(name)}: ${chalk.yellow(
            cssString.length / 1000
          )} KB -> ${chalk.green(result.css.length / 1000)} KB`
        )
        callback(null, file)
      })
    },
  })
}

/**
 * compile theme-chalk scss & minify
 * not use sass.sync().on('error', sass.logError) to throw exception
 * @returns
 */
function buildThemeChalk() {
  const sass = gulpSass(dartSass)
  const noElPrefixFile = /(index|base|display)/
  return src(path.resolve(__dirname, 'src/*.scss'))
    .pipe(sass.sync())
    .pipe(autoprefixer({ cascade: false }))
    .pipe(compressWithCssnano())
    .pipe(
      rename((path) => {
        if (!noElPrefixFile.test(path.basename)) {
          path.basename = `el-${path.basename}`
        }
      })
    )
    .pipe(dest(distFolder))
}

/**
 * Build dark Css Vars
 * @returns
 */
function buildDarkCssVars() {
  const sass = gulpSass(dartSass)
  return src(path.resolve(__dirname, 'src/dark/css-vars.scss'))
    .pipe(sass.sync())
    .pipe(autoprefixer({ cascade: false }))
    .pipe(compressWithCssnano())
    .pipe(dest(`${distFolder}/dark`))
}

/**
 * copy from packages/theme-chalk/dist to dist/element-plus/theme-chalk
 */
export function copyThemeChalkBundle() {
  return src(`${distFolder}/**`).pipe(dest(distBundle))
}

/**
 * copy source file to packages
 */

export function copyThemeChalkSource() {
  return src(path.resolve(__dirname, 'src/**')).pipe(
    dest(path.resolve(distBundle, 'src'))
  )
}

export const build: TaskFunction = parallel(
  copyThemeChalkSource,
  series(buildThemeChalk, buildDarkCssVars, copyThemeChalkBundle)
)

export default build

copyThemeChalkSource

我们直接运行pnpm run -C packages/theme-chalk build

可以看到这个把src下的文件,直接复制到了const distBundle = path.resolve(epOutput, 'theme-chalk')这个路径下

series(buildThemeChalk, buildDarkCssVars, copyThemeChalkBundle)

按顺序执行了 buildThemeChalk, buildDarkCssVars, copyThemeChalkBundle 这几个任务

javascript 复制代码
function buildThemeChalk() {
  const sass = gulpSass(dartSass)
  const noElPrefixFile = /(index|base|display)/
  return src(path.resolve(__dirname, 'src/*.scss'))
    .pipe(sass.sync())
    .pipe(autoprefixer({ cascade: false }))
    .pipe(compressWithCssnano())
    .pipe(
      rename((path) => {
        if (!noElPrefixFile.test(path.basename)) {
          path.basename = `el-${path.basename}`
        }
      })
    )
    .pipe(dest(distFolder))
}
  • gulp-sass:是gulp的sass插件,可以点击链接查看相关文档说明
  • sass.sync():是同步编译scss成css。调用 sass()(用于异步渲染 CSS),调用 sass.sync()(用于同步渲染 CSS)
  • gulp-autoprefixergulp-autoprefixer 是一个基于 Gulp 的插件,用于自动为 CSS 代码添加浏览器兼容前缀,从而解决不同浏览器对 CSS 属性支持差异的问题。也可以点击链接查看相关文档说明
  • compressWithCssnano():
    • 通过 PostCSS 结合 cssnano 对 CSS 内容进行压缩优化。colormin: false禁用颜色压缩(避免如 #ffffff 被转为 white,或 rgba 被简化)。minifyFontValues: false:禁用字体值压缩,可见minifyFontValues的文档说明。
    • 函数返回了一个 Transform 流
      • objectMode: true,Gulp 处理的是文件对象而非二进制流,需开启对象模式
      • file.isNull()是边界判断,空文件直接返回
      • file.isStream()也是边界判断,流式文件直接报错
      • 然后 使用 PostCSS 处理器处理 CSS 字符串,
  • rename:使用gulp-rename插件对文件进行重命名

对于 buildDarkCssVars,就是针对暗色主题变量进行打包

对于 copyThemeChalkBundle,把主题打包的相关css文件复制到最终的打包目录const distBundle = path.resolve(epOutput, 'theme-chalk')

copyFullStyle

该任务把打包后的theme-chalk下的index.css复制到了如图这里

相关推荐
kyriewen5 分钟前
我扒了 10,221 条 JD:腾讯技术岗 75% 在要 AI
前端·人工智能·ai编程
郑州光合科技余经理1 小时前
同城外卖小程序开发:下单成功后,后台导出能不能对上用户端状态
开发语言·前端·git·后端·uni-app·php·ai编程
+VX:Fegn08951 小时前
计算机毕业设计|基于springboot + vue旅游管理系统(源码+数据库+文档)
java·开发语言·vue.js·spring boot·课程设计
雪芽蓝域zzs1 小时前
第 7 章:双 Y 轴组合图(柱状 + 折线,看板高频场景)
vue.js·echars
IT_陈寒2 小时前
Vue的响应式让我熬到凌晨三点,原来漏了这个小细节
前端·人工智能·后端
一 乐2 小时前
二手交易平台|基于springboot + vue二手交易平台(源码+数据库+文档)
java·数据库·vue.js·spring boot·小程序
Blanche15002 小时前
利用 RAG 为答疑机器人扩展知识范围
前端
天若有情6732 小时前
【纯前端小工具】公历生日转农历,批量查询每年农历生日对应的公历日期(GitHub Pages在线直接用)
前端·javascript·github pages·农历转换·lunisolar·网页小工具
SoonITer2 小时前
怎样构建一个 Agent-friendly 的网站
前端·agent
颜进强2 小时前
01 · NestJS 是什么:用途、解决什么问题、与热门框架对比
前端·后端·ai编程