解析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复制到了如图这里

相关推荐
大橙子额1 小时前
【解决报错】Cannot assign to read only property ‘exports‘ of object ‘#<Object>‘
前端·javascript·vue.js
WooaiJava2 小时前
AI 智能助手项目面试技术要点总结(前端部分)
javascript·大模型·html5
LYFlied2 小时前
从 Vue 到 React,再到 React Native:资深前端开发者的平滑过渡指南
vue.js·react native·react.js
爱喝白开水a2 小时前
前端AI自动化测试:brower-use调研让大模型帮你做网页交互与测试
前端·人工智能·大模型·prompt·交互·agent·rag
Never_Satisfied2 小时前
在JavaScript / HTML中,关于querySelectorAll方法
开发语言·javascript·html
董世昌412 小时前
深度解析ES6 Set与Map:相同点、核心差异及实战选型
前端·javascript·es6
B站_计算机毕业设计之家3 小时前
豆瓣电影数据采集分析推荐系统 | Python Vue Flask框架 LSTM Echarts多技术融合开发 毕业设计源码 计算机
vue.js·python·机器学习·flask·echarts·lstm·推荐算法
WeiXiao_Hyy3 小时前
成为 Top 1% 的工程师
java·开发语言·javascript·经验分享·后端
吃杠碰小鸡4 小时前
高中数学-数列-导数证明
前端·数学·算法
kingwebo'sZone4 小时前
C#使用Aspose.Words把 word转成图片
前端·c#·word