CSS系列(18)-- 工程化实践详解
前端技术探索系列:CSS 工程化实践详解 🏗️
致读者:探索 CSS 工程化之路 👋
前端开发者们,
今天我们将深入探讨 CSS 工程化实践,学习如何在大型项目中管理 CSS。
工程化配置 🚀
项目结构
src/├── styles/│ ├── base/│ │ ├── _reset.scss│ │ ├── _typography.scss│ │ └── _variables.scss│ ├── components/│ │ ├── _button.scss│ │ ├── _card.scss│ │ └── _form.scss│ ├── layouts/│ │ ├── _grid.scss│ │ ├── _header.scss│ │ └── _footer.scss│ ├── utils/│ │ ├── _mixins.scss│ │ └── _functions.scss│ └── main.scss
构建配置
// webpack.config.js
module.exports = {module: {rules: [{test: /\.scss$/,use: [MiniCssExtractPlugin.loader,{loader: 'css-loader',options: {modules: true,importLoaders: 2}},'postcss-loader','sass-loader']}]},plugins: [new MiniCssExtractPlugin({filename: '[name].[contenthash].css'}),new PurgeCSSPlugin({paths: glob.sync(`${PATHS.src}/**/*`, { nodir: true })})]
};
模块化管理 🎯
CSS Modules
// Button.module.scss
.button {padding: 0.5em 1em;border-radius: 4px;&.primary {background: var(--primary-color);color: white;}&.secondary {background: var(--secondary-color);color: white;}
}// 使用
import styles from './Button.module.scss';const Button = () => (<button className={styles.button}>Click me</button>
);
样式组织
// _variables.scss
:root {// 颜色系统--primary-color: #007bff;--secondary-color: #6c757d;--success-color: #28a745;// 间距系统--spacing-unit: 8px;--spacing-small: calc(var(--spacing-unit) * 1);--spacing-medium: calc(var(--spacing-unit) * 2);--spacing-large: calc(var(--spacing-unit) * 3);// 字体系统--font-family-base: system-ui, -apple-system, sans-serif;--font-size-base: 16px;--line-height-base: 1.5;
}// _mixins.scss
@mixin responsive($breakpoint) {@if $breakpoint == tablet {@media (min-width: 768px) { @content; }} @else if $breakpoint == desktop {@media (min-width: 1024px) { @content; }}
}@mixin flex-center {display: flex;justify-content: center;align-items: center;
}
质量控制 💫
Stylelint 配置
// .stylelintrc.js
module.exports = {extends: ['stylelint-config-standard','stylelint-config-prettier'],plugins: ['stylelint-scss','stylelint-order'],rules: {'order/properties-alphabetical-order': true,'at-rule-no-unknown': null,'scss/at-rule-no-unknown': true,'selector-class-pattern': '^[a-z][a-zA-Z0-9]+$','max-nesting-depth': 3}
};
Git Hooks
// package.json
{"husky": {"hooks": {"pre-commit": "lint-staged"}},"lint-staged": {"*.scss": ["stylelint --fix","prettier --write"]}
}
工程化工具 🛠️
class CSSEngineering {constructor(options = {}) {this.options = {entry: 'src/styles',output: 'dist/css',modules: true,purge: true,...options};this.init();}init() {this.setupBuildSystem();this.setupLinting();this.setupOptimization();this.setupModules();}setupBuildSystem() {const webpack = require('webpack');const config = this.generateWebpackConfig();this.compiler = webpack(config);this.setupWatcher();}generateWebpackConfig() {return {entry: this.options.entry,output: {path: this.options.output,filename: '[name].[contenthash].css'},module: {rules: this.generateLoaderRules()},plugins: this.generatePlugins()};}setupLinting() {const stylelint = require('stylelint');// 设置 Stylelintthis.linter = stylelint.createLinter({config: require('./.stylelintrc.js')});// 设置 Git Hooksif (this.options.gitHooks) {this.setupGitHooks();}}setupOptimization() {if (this.options.purge) {this.setupPurgeCss();}this.setupMinification();this.setupCacheOptimization();}setupModules() {if (this.options.modules) {this.enableCSSModules();}this.setupDependencyManagement();}setupPurgeCss() {const PurgeCSSPlugin = require('purgecss-webpack-plugin');const glob = require('glob');this.plugins.push(new PurgeCSSPlugin({paths: glob.sync(`${this.options.entry}/**/*`)}));}setupMinification() {const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');this.plugins.push(new CssMinimizerPlugin({minimizerOptions: {preset: ['default', {discardComments: { removeAll: true }}]}}));}setupDependencyManagement() {// 依赖图分析this.analyzeDependencies();// 循环依赖检测this.detectCircularDependencies();// 未使用代码检测this.detectUnusedCode();}analyzeDependencies() {const madge = require('madge');madge(this.options.entry).then(res => {console.log('依赖图:', res.obj());this.checkDependencies(res);});}detectCircularDependencies() {const madge = require('madge');madge(this.options.entry).then(res => {const circular = res.circular();if (circular.length) {console.warn('检测到循环依赖:', circular);}});}detectUnusedCode() {// 使用 PurgeCSS 检测未使用的 CSSconst PurgeCSS = require('purgecss');new PurgeCSS().purge({content: ['**/*.html', '**/*.js', '**/*.jsx'],css: [`${this.options.entry}/**/*.css`]}).then(result => {console.log('未使用的 CSS:', result);});}
}
最佳实践建议 💡
-
工程化流程
- 统一构建流程
- 自动化部署
- 版本控制
- 持续集成
-
代码组织
- 模块化管理
- 组件封装
- 样式复用
- 依赖管理
-
质量控制
- 代码规范
- 自动检查
- 测试覆盖
- 性能监控
-
优化策略
- 代码压缩
- 依赖优化
- 按需加载
- 缓存策略
写在最后 🌟
CSS 工程化是大型项目必不可少的环节,良好的工程化实践可以显著提升开发效率和代码质量。
进一步学习资源 📚
- 工程化工具文档
- 最佳实践指南
- 性能优化策略
- 案例研究分析
如果你觉得这篇文章有帮助,欢迎点赞收藏,也期待在评论区看到你的想法和建议!👇
终身学习,共同成长。
咱们下一期见
💻
相关文章:

CSS系列(18)-- 工程化实践详解
前端技术探索系列:CSS 工程化实践详解 🏗️ 致读者:探索 CSS 工程化之路 👋 前端开发者们, 今天我们将深入探讨 CSS 工程化实践,学习如何在大型项目中管理 CSS。 工程化配置 🚀 项目结构 …...

日拱一卒(18)——leetcode学习记录:二叉树中的伪回文路径
一、题目 给你一棵二叉树,每个节点的值为 1 到 9 。我们称二叉树中的一条路径是 「伪回文」的,当它满足:路径经过的所有节点值的排列中,存在一个回文序列。 请你返回从根到叶子节点的所有路径中 伪回文 路径的数目。 二、思路 …...

hive—炸裂函数explode/posexplode
1、Explode炸裂函数 将hive某列一行中复杂的 array 或 map 结构拆分成多行(只能输入array或map) 语法: select explode(字段) as 字段命名 from 表名; 举例: 1)explode(array)使得结果中将array列表里的每个元素生…...

SpringBoot 新特性
优质博文:IT-BLOG-CN 2.1.0新特性最低支持jdk8,支持tomcat9 对响应式编程的支持,spring-boot-starter-webflux starter POM可以快速开始使用Spring WebFlux,它由嵌入式Netty服务器支持 1.5.8 2.1.0/2.7.0/3.0.0 Configuration propertie…...

鸿蒙app封装 axios post请求失败问题
这个问题是我的一个疏忽大意,在这里记录一下。如果有相同问题的朋友,可以借鉴。 当我 ohpm install ohos/axios 后,进行简单post请求验证,可以请求成功。 然后,我对axios 进行了封装。对axios 添加请求拦截器/添加响…...

消息队列 Kafka 架构组件及其特性
Kafka 人们通常有时会将 Kafka 中的 Topic 比作队列; 在 Kafka 中,数据是以主题(Topic)的形式组织的,每个 Topic 可以被分为多个分区(Partition)。每个 Partition 是一个有序的、不可变的消息…...

网络攻击与防范
目录 选填 第一章 1、三种网络模式 2、几种创建网络拓扑结构 NAT模式 VPN模式 软路由模式1 软路由模式2 3、Linux网络配置常用指令 4、常见网络服务配置 DHCP DNS Web服务与FTP服务 FTP用户隔离 第二章 DNS信息收集(dnsenum、dnsmap) 路…...

文献研读|基于像素语义层面图像重建的AI生成图像检测
前言:本篇文章主要对基于重建的AI生成图像检测的四篇相关工作进行介绍,分别为基于像素层面重建的检测方法 DIRE 和 Aeroblade,以及基于语义层面重建的检测方法 SimGIR 和 Zerofake;并对相应方法进行比较。 相关文章:论…...

【操作系统】为什么需要架构裁剪?
为什么需要架构裁剪? 原因 减小核心大小提高架构初始化速度降低内存占用提高系统性能移除不需要的功能,增加安全性 裁剪方法 初始化配置设置功能模块化移除不需要的驱动底层 一般裁剪对象(以操作系统为例) 文件系统的支持网…...

LSTM长短期记忆网络
LSTM(长短期记忆网络)数学原理 LSTM(Long Short-Term Memory)是一种特殊的递归神经网络(RNN),解决了标准RNN中存在的梯度消失(Vanishing Gradient) 和**梯度爆炸&#x…...

基于前端技术UniApp和后端技术Node.js的电影购票系统
文章目录 摘要Abstruct第一章 绪论1.1 研究背景与意义1.2 国内外研究现状 第二章 需求分析2.1 功能需求分析2.2 非功能性需求分析 第二章系统设计3.1 系统架构设计3.1.1 总体架构3.1.2 技术选型 3.2 功能架构 第四章 系统实现4.1 用户端系统实现4.1.1 用户认证模块实现4.1.2 电…...

数据结构与算法:稀疏数组
前言 此文以整型元素的二维数组为例,阐述稀疏数组的思想。其他类型或许有更适合压缩算法或者其他结构的稀疏数组,此文暂不扩展。 稀疏数组的定义 在一个二维数据数组里,由于大量的元素的值为同一个值,比如 0或者其他已知的默认值…...

Meta重磅发布Llama 3.3 70B:开源AI模型的新里程碑
在人工智能领域,Meta的最新动作再次引起了全球的关注。今天,我们见证了Meta发布的Llama 3.3 70B模型,这是一个开源的人工智能模型,它不仅令人印象深刻,而且在性能上达到了一个新的高度。 一,技术突破&#…...

VSCode中的Black Formatter没有生效的解决办法
说明 如果正常按照配置进行的话,理论上是可以生效的。 "[python]": {"editor.defaultFormatter": "ms-python.black-formatter","editor.formatOnSave": true }但我在一种情况下发现不能生效,应为其本身的bug…...

【潜意识Java】蓝桥杯算法有关的动态规划求解背包问题
目录 背包问题简介 问题描述 输入: 输出: 动态规划解法 动态规划状态转移 代码实现 代码解释 动态规划的时间复杂度 例子解析 输出: 总结 作者我蓝桥杯:2023第十四届蓝桥杯国赛C/C大学B组一等奖,所以请听我…...

Odoo:免费开源ERP的AI技术赋能出海企业电子商务应用介绍
概述 伴随电子商务的持续演进,客户对于便利性、速度以及个性化服务的期许急剧攀升。企业务必要探寻创新之途径,以强化自身运营,并优化购物体验。达成此目标的最为行之有效的方式之一,便是将 AI 呼叫助手融入您的电子商务平台。我们…...

微信小程序苹果手机自带的数字键盘老是弹出收起,影响用户体验,100%解决
文章目录 1、index.wxml2、index.js3、index.wxss1、index.wxml <!--index.wxml--> <view class="container"><view class="code-input-container"><view class="code-input-boxes"><!-- <block wx:for="{{…...

sql中case when若条件重复 执行的顺序
sql case when若条件重复 执行的顺序 在 SQL 中,如果你在 CASE 表达式中定义了多个 WHEN 子句,并且这些条件有重叠,那么 CASE 表达式的执行顺序遵循以下规则: (1)从上到下:SQL 引擎会按照 CASE …...

压力测试Jmeter简介
前提条件:要安装JDK 若不需要了解,请直接定位到左侧目录的安装环节。 1.引言 在现代软件开发中,性能和稳定性是衡量系统质量的重要指标。为了确保应用程序在高负载情况下仍能正常运行,压力测试变得尤为重要。Apache JMeter 是一…...

cesium 与 threejs 对比
Cesium 和 Three.js 都是用于在 Web 浏览器中创建和渲染 3D 图形的强大 JavaScript 库,但它们有显著的不同之处,主要体现在应用领域、功能集和使用场景上。 以下是两者之间的对比: 1. 应用场景 Three.js: 适用于广泛的 3D 图形应用ÿ…...

探索QScreen的信号与槽:动态响应屏幕变化
在处理屏幕显示和多显示器环境时,QScreen 提供了一些特有的信号,这些信号可以在屏幕的变化时通知应用程序,帮助我们动态地适配和响应显示设备的变化。今天,我们将深入探讨如何使用 QScreen 的信号与槽,并展示适用的使用…...

vLLM项目加入PyTorch生态系统,引领LLM推理新纪元
近日,vLLM项目宣布正式成为PyTorch生态系统的一部分,标志着该项目与PyTorch的合作进入了一个全新的阶段。本文将从以下几个方面进行介绍,特别提醒:安装方案在第四个部分,可选择性阅读。 vLLM项目概述 vLLM的成就与实际…...

索引-介绍结构语法
一.概述: 1.当给某个字段创建索引后,就会把字段生成二叉排序树进行查找,大大增加了查找效率,比不创建索引时用的全表扫描好得多。 2.二叉排序树:小的在左边,大的在右边(查找和存放都遵循这个原则)。 3.注…...

SpringBoot整合JDBC
讲到这里,基本上我们就可以使用SpringBoot来开发Web项目视图显示和业务逻辑代码,但是要做一个完成案例,我们还差一点点,就是怎么访问数据库,获取数据,接下来我们就看怎么用SpringBoot整合我们前面已经讲过的…...

XXE靶场
XXE-lab 靶场 靶场网址:http://172.16.0.87/ 第一步我们看到网站有登录框我们试着用 bp 去抓一下包 将抓到的包发到重放器中 然后我们构建palody <!DOCTYPE foo [ <!ENTITY xxe SYSTEM "php://filter/readconvert.base64-encode/resourceC:/flag/fla…...

Elasticsearch:使用 Open Crawler 和 semantic text 进行语义搜索
作者:来自 Elastic Jeff Vestal 了解如何使用开放爬虫与 semantic text 字段结合来轻松抓取网站并使其可进行语义搜索。 Elastic Open Crawler 演练 我们在这里要做什么? Elastic Open Crawler 是 Elastic 托管爬虫的后继者。 Semantic text 是 Elasti…...

Facebook的隐私保护政策:用户数据如何在平台上被管理?
在当今数字化世界,社交平台如何管理用户数据并保护隐私成为了一个热点话题。作为全球最大的社交网络,Facebook(现Meta)在数据隐私方面的政策备受关注。本文将简要介绍Facebook的隐私保护措施,以及用户数据如何在平台上…...

【ETCD】【源码阅读】深入解析 EtcdServer.applySnapshot方法
今天我们来一步步分析ETCD中applySnapshot函数 一、函数完整代码 函数的完整代码如下: func (s *EtcdServer) applySnapshot(ep *etcdProgress, apply *apply) {if raft.IsEmptySnap(apply.snapshot) {return}applySnapshotInProgress.Inc()lg : s.Logger()lg.In…...

HBase是什么,HBase介绍
官方网站:Apache HBase – Apache HBase Home HBase是一个分布式的、面向列的NoSQL数据库,主要用于存储和处理海量数据。它起源于Google的BigTable论文,是Apache Hadoop项目的子项目。HBase设计用于高可靠性、高性能和可伸…...

【Rust自学】3.3. 数据类型:复合类型
3.3.0. 写在正文之前 欢迎来到Rust自学的第三章,一共有6个小节,分别是: 变量与可变性数据类型:标量类型数据类型:复合类型(本文)函数和注释控制流:if else控制流:循环 通过第二章…...