悟夕导航

Sass 与工程化:Webpack、Vite、GitHub Actions 三连击

75 0 0

——让 .scss 从本地骚到云端,提交即部署,咖啡还没凉,全球用户已换新皮肤

警告:本章全程高能,操作不当下一个 npm install 就能把电脑变成电磁炉。
目标:把 Sass 塞进现代化流水线,实现“git push → 自动编译 → 压缩 → 部署”,老板看你都像看 CI/CD 小精灵。

第一回:项目初始化——先搭个“骚”基地

# 1. 开新坑
mkdir sass-ci-workflow && cd $_
npm init -y

# 2. 一键三连依赖
npm i -D sass concurrently prettier eslint-config-standard sass-lint-autofix

# 3. 目录规矩先行
mkdir -p scss/{base,components,utils} public/css
touch scss/main.scss public/index.html

目录范例:

sass-ci-workflow/
├─ .github/workflows/ci.yml   ← 稍后上锅
├─ scss/
│  ├─ base/
│  │  └─ _reset.scss
│  ├─ components/
│  │  └─ _button.scss
│  ├─ utils/
│  │  └─ _variables.scss
│  └─ main.scss
├─ public/
│  ├─ index.html
│  └─ css/         ← 编译后自动产出,不手写
└─ package.json

第二回:脚本命令——让 npm 替你打工

package.json 里加几行“骚”脚本:

"scripts": {
  "dev": "concurrently \"npm run scss:watch\" \"npm run serve\"",
  "scss:watch": "sass --watch scss:public/css --style=expanded --source-map",
  "scss:build": "sass scss:public/css --style=compressed --no-source-map",
  "serve": "python -m http.server 3000 -d public", // 没 Python 用 `npx serve public`
  "lint:scss": "sass-lint scss/**/*.scss -v",
  "lint:scss:fix": "sass-lint-auto-fix",
  "predeploy": "npm run lint:scss && npm run scss:build",
  "deploy": "gh-pages -d public"   // 稍后装 gh-pages
}

一句话解释:

  • dev:本地开发,一边写 Sass、一边热刷新。
  • predeploy:上线前先 lint + 压缩,防止把 2MB 的 CSS 推到用户脸上。

第三回:Webpack 5 方案——“老大哥”依旧稳

嫌原生 sass CLI 功能少?上 Webpack:

npm i -D webpack webpack-cli webpack-dev-server html-webpack-plugin css-loader mini-css-extract-plugin sass-loader

webpack.config.js 核心片段:

const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = (env, argv) => {
  const isProd = argv.mode === 'production';

  return {
    entry: './scss/main.scss', // 把 Sass 当入口
    module: {
      rules: [{
        test: /\.s[ac]ss$/,
        use: [
          isProd ? MiniCssExtractPlugin.loader : 'style-loader',
          'css-loader',
          'sass-loader'
        ]
      }]
    },
    plugins: isProd
      ? [new MiniCssExtractPlugin({ filename: 'css/[name].[contenthash:8].css' })]
      : [],
    devServer: { static: './public', port: 3000, open: true }
  };
};

开发:

npx webpack serve --mode development

生产:

npx webpack --mode production

Webpack 会帮你:

  • 自动加浏览器前缀(再配 postcss-loader + autoprefixer
  • 文件名加哈希,永久缓存,用户永不迷路。

第四回:Vite 方案——“秒开”界扛把子

Webpack 热更新 3 秒?Vite 300ms 搞定:

npm create vite@latest sass-vite --template vanilla
cd sass-vite
npm i -D sass

vite.config.js 加一行:

import { defineConfig } from 'vite';
export default defineConfig({
  css: { devSourcemap: true } // 调试 Sass 直达原行号
});

.scss 文件当 ES Module 导入:

import './style/main.scss';

开发:

npm run dev

生产:

npm run build   // 自动压缩、哈希、拆包

Vite 默认用 esbuild 编译 Sass,大型项目 1 万行也能 1 秒内完事,老板看你都像看光纤本身。


第五回:Lint & Format——让代码像钢琴键一样整齐

  1. 统一团队风格

    npm i -D prettier eslint-config-prettier eslint-plugin-prettier

    .prettierrc

{
  "semi": true,
  "singleQuote": true,
  "tabWidth": 2
}
  1. Sass 专用 linter

    npm i -D sass-lint-config-standard

    .sass-lint.yml

options:
  formatter: stylish
files:
  include: 'scss/**/*.scss'
rules:
  # 禁止裸写数字 0
  no-zero-units: 1
  # 强制变量命名用 kebab-case
  variable-name-format: 1
  1. Git Hooks 保底

    npx mrm lint-staged

    package.json 补充:

"lint-staged": {
  "*.scss": ["sass-lint --fix", "prettier --write"],
  "*.{js,html}": ["prettier --write"]
}

从此 git commit 前自动格式化,谁再提交 tab 与空格混编,直接打回重写。


第六回:GitHub Actions 流水线——push 即部署

目标:

  • main 分支收到 push → 安装依赖 → lint → 编译 Sass → 部署到 GitHub Pages → 评论里甩访问链接。

.github/workflows/ci.yml

name: Sass-CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest

    steps:
      - name: 拉代码
        uses: actions/checkout@v3

      - name: 装 Node
        uses: actions/setup-node@v3
        with:
          node-version: 18
          cache: 'npm'

      - name: 装依赖
        run: npm ci

      - name: Lint SCSS
        run: npm run lint:scss

      - name: 编译 & 压缩
        run: npm run scss:build

      - name: 部署到 GitHub Pages
        if: github.ref == 'refs/heads/main'
        uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./public
          cname: sass-demo.yourname.com   # 有域名就写,没有可删

提交代码后,打开 Actions 面板看小绿灯一路狂闪,5 分钟后访问 https://yourname.github.io/sass-ci-workflow,CSS 已是最新压缩版,妈妈再也不用担心我手动 FTP。


第七回:性能加速锦囊——让包更小、跑得更快

  1. sass --embedded 多线程编译,大型项目速度 +60%。
  2. cssnano 二次压缩,删除无用浏览器前缀、合并相同规则,再省 15%。
  3. 雪碧图过时?用 vite-plugin-svg-icons 把图标打包成 symbol, Sass 直接 background: url('~@/assets/icons.svg#arrow')
  4. 分割主题包:白天/黑夜两套变量拆成 theme-light.scsstheme-dark.scss,用户按钮切换时按需加载,首屏不额外加 1KB。
  5. 浏览器缓存策略:

    • CSS 文件名带 [contenthash],内容不变永久 304。
    • 服务器开 gzip + brotli,再压 70%,手机 3G 也能秒开。

第八回:常见翻车现场 & 急救指南

翻车现象原因一键急救
本地样式正常,线上 404路径大小写 & Git 默认忽略大小写git config core.ignorecase false
Actions 绿灯但页面空白忘记把 public/css 目录提交.gitignore 白名单 !public/css
热更新把 CPU 跑满node_modules 被无意监听watchOptions.ignored: /node_modules/
压缩后颜色变了postcss-colormin 把 #ff6b6b 转成 hsl关闭对应规则或锁定 cssnano 配置

终极命令速查表(建议打印贴墙)

目的命令
本地开发npm run dev
一次性编译npm run scss:build
检查+修复npm run lint:scss:fix
部署 Pagesnpm run deploy
Webpack 开发npx webpack serve --mode development
Vite 生产npm run build
清空缓存npx rimraf node_modules/.cache

毕业彩蛋:把徽章穿在身上

README.md 贴上骚气小徽章:

![Sass-CI](https://github.com/yourname/sass-ci-workflow/workflows/Sass-CI/badge.svg)
![license](https://img.shields.io/badge/license-MIT-f06292)
![size](https://img-badge.herokuapp.com/size/github/yourname/sass-ci-workflow/main/public/css/app.min.css?color=ff6b6b)

绿牌一亮,招聘官直接关键词“CI/CD”搜到你,offer 率 +50%。


下下回(真的终章)

《Sass 到 PostCSS 与未来:CSS @layer、@container、@scope 的梦幻联动》
——当新原生特性席卷而来,Sass 如何优雅退居幕后,与 PostCSS 联手继续“骚”到 2030。

最后的最后:
把 Sass 写好是手艺,把 Sass 塞进流水线是工程;
手艺让人尊敬,工程让人敬畏。
愿你在键盘上敲下的每一行 @mixin,都能通过光纤,变成用户眼里 0.1 毫秒的惊艳。
0
快来点个赞吧

发表评论

隐私评论

评论列表

来写一个评论吧