工程化相关(二)(css工程应用 & js 兼容性)

243 阅读5分钟

📃 前言:demo-webpack5代码地址:

🔗 gitee:code for demo-webpack@5

🔗 github:demo-webpack@5

demo-webpack.png

一、css 工程化

  随着业务量及项目体量的增加,传统的 css 样式书写会使代码变得非常臃肿不便于维护和扩展,且极易产生样式冲突,于是 css 工程化应运而生,其实际上是一套方法论,使用不同的手段解决不同的问题。

  • 预处理器:如 Sassless 等编程式的 css 语言,提供了增强语法,使得代码变得简洁且结构清晰,最终能编译为普通的 css 代码,以便浏览器能够解析

  • 🎨 后处理器:如 postcss,可以在编译后的 css 代码上执行各种操作,如添加浏览器前缀、转换现代 css 功能以兼容旧浏览器等


  • css module:webpack 中使用的 css-loader,开启 module 配置后,能将样式类名转换为 hash值,解决类名冲突问题

  • 其它:如提供大量预定义 css 类的框架 tailwindcss

⏳ 【预处理器】
1、安装和使用
  • 构建工具为 webpack

  pnpm 或者 npm、yarn 安装均可,示例中推荐使用 pnpm

# Sass
pnpm add -D node-sass sass-loader css-loader

# less
pnpm add -D less less-loader

# 如果不将 css 单独构建成独立模块,而是直接注入页面,可以再下载 style-loader
pnpm add -D style-loader
# 若要单独构建生成独立 css 文件(具体配置:后处理器 中再提)
pnpm add -D mini-css-extract-plugin

  webpack.config.js 文件配置,sassless 保留其一即可,下面 css-loader 未开启 module 模式,开启可见本文【后处理器】

// ... 其它配置导入模块

module.exports = {
    // ... 其它配置
    module:{
        rules:[
            // less 配置
            {
                test:/\.less$/,
                use:['style-loder','css-loader','less-loader']
            },
            // sass 配置
            {
                test:/\.scss$/,
                use:['style-loder','css-loader','sass-loader']
            }
        ]
    }
}

  • 构建工具为 vite

   vite.config.js 文件配置,预处理器后缀名为配置的键名,具体配置选项见官网

   🔗 less 配置选项    🔗 sass 配置选项

import { defineConfig } from 'vite'

// 不用 jsdoc 注解也可以获取类型提示
export default defineConfig({ 
    // ... 
    css: { 
        preprocessorOptions: { 
           less: { 
                math: 'parens-division'
           },
           scss: { 
               api: 'modern-compiler', // 或 "modern","legacy" 
               importers: [ 
                   // ... 
               ]
           }
       }
   }
})

2、语法层面

🔗 less 官网

🔗 sass & less 语法区别,推荐其他掘友文章

🎨 【后处理器】
1、postcss 作用

📜 postcss 的作用是:类似于 webpack 处理思路,做样式代码分析,抽象语法树分析,将分析结果交给插件,代码转换由插件完成

🔎 识别后缀名 .css.pcss.postcss

2020-02-04-14-37-51.png

2、postcss 使用
  • 构建工具为 webpack( postcss 配置文件见下面)
# 核心
pnpm add -D postcss postcss-loader

# 预设插件 和 打包后将 css 抽离为独立文件的插件
pnpm add -D postcss-preset-env mini-css-extract-plugin

# css-loader 将编译生成的 css 文件转换成 js 文件
pnpm add -D css-loader

mini-css-extract-plugin 迷你-css-提取-插件

  使用 css-loader 后,css 最后是编译为了 js 文件,如果要抽离成 css 文件,则需要用到插件 mini-css-extract-plugin,该插件提供了一个 loader 和 插件

 🚚  loader 负责记录 CSS 内容,同时导出开启 css-module 的样式对象

 🎮  plugin 负责生成文件,默认情况一个 chunk 对应一个 css 文件

 🎯  style-loader 引入样式是通过 js 生成 style 标签,而 MiniCssExtractPlugin.loader 是通过 link 标签引入资源文件

  webpack.config.js 文件配置

 💡 注意:loader 的执行顺序是自下而上,同一层级从右到左

// css 记录并提取生成独立文件的插件
const MiniCssExtractPlugin = require('mini-css-extract-plugin')

module.exports = {
    module:{
        rules:[
            {
                test:/\.(p)?css&/,
                use: [
                    // 'style-loader',
                    MiniCssExtractPlugin.loader,//替代 style-loader
                    {
                       loader:'css-loader',
                       options:{
                           modules:{
                               // 这里 css-loader 开启了 module 模式,将生成的样式类名拼接hash值,避免样式重名冲突
                               localIdentName:'[local]_[hash:base64]'
                           }
                       }
                     },
                    'postcss-loader'
                 ]
            },
            // ... sass 或 less 预处理器的配置
        ],
        plugins:[
            new MiniCssExtractPlugin({ filename:'css/' }) // 生成 css 文件
        ]
    }
}

  • 构建工具为 vite

vite 内部使用 postcss-load-config 自动加载 postcss 的配置文件 postcss.config.cjspackage.json 中指定了 "type" : "module" 否则使用 .js 后缀),因此无需单独配置,只要确保该配置文件在根目录即可

# postcss 插件预设 postcss-preset-env
# 其中内置了很多常用插件,如 autoprefixer,自动添加浏览器厂商前缀

pnpm add -D postcss postcss-preset-env

   postcss.config.cjs 文件配置

module.exports = {
   map: false,
   plugins: {
      'postcss-preset-env': {
         // 哪怕是草案阶段的语法,也需要转换
         stage: 0,
         // 编译后,新语法不可见,比如 color:var(--color) 编译后不可见,仅展示 color:颜色
         preserve: false 
       }
   }
};
3、调整浏览器兼容范围

方式1:在 postcss-preset-env 配置中加入配置 browsers

// postcss.config.cjs

module.exports = {
   plugins: {
      "postcss-preset-env": {
          browsers: [
             "last 2 version",// 最近两个版本
             "> 1%", // 支持全球市场份额超过 1% 的浏览器
             "not dead" // 排除那些不再更新和使用的浏览器(没有市场份额或过时)
          ]
      } 
  }
}

【方式2 - 推荐 ✨】:使用配置文件 .browserslistrc

last 2 version
> 1%
not dead

【方式3 - 推荐 ✨】:在 package.json 配置文件中配置 browserslist

{
   "browserslist": [
       "last 2 version",
       "> 1%",
       "not dead"
   ]
}
🧩 【css module】

  webpack 中使用 scc-loader,识别css 模块内容并转换,当开启 modules 配置后,能解决样式命名冲突问题,编译后的样式类名会变为 hash 值(可配置拼接)

  若结合 style-loader 能将编译后的样式放入页面 head>style 标签中,除此之外在 js 模块中能简化导入的 css 模块信息,只保留 { 原类名1: hash 值类名1,..., 原类名nhash 值类名n }

二、js 兼容性 - babel

 babel 通过各类插件,对 js 代码进行转换,以兼容不同浏览器、浏览器不同版本对 js 语法的支持

 🎉 @babel/core 含 babel 操作 js 的 api

1、webpack 结合 babel
# 安装 aip 和 loader
pnpm add -D @babel/core babel-loader

# 安装预设
pnpm add -D @babel/preset-env

# 安装 core-js ,如果需要,可以安装 regenerator-runtime (生成器 function* 的转换和 async await 的转换)
pnpm add -D core-js regenerator-runtime

  webpack.config.js 文件配置

// babel-loader 要在 postcss-loader、css-loader 等之前执行,因它们生成的 js 文件无需转换

module.exports = {
    module:{
        rules:[
            // ... postcss
            // ... sass 或 less 预处理器的配置
            {
                test: /\.js$/,
                use: 'babel-loader',
                exclude: /node_modules/
            }
        ]
    }
}

2、babel 配置文件

 配置文件为@6.x *.babelrc,@7.x babel.config.js( package.json 指定 type为 module )

 📝 使用预设(插件集合)和 插件实现代码转换,以解决兼容问题

 🖇 转换时,plugins 正序执行,再倒序执行 presets

export default {
    // 预设
   presets: [
       ["@babel/preset-env", {
           // 默认为 false ,设置为 usage 后,会根据使用情况,编译结果中导入 api ,如 Promise ,避免浏览器本身不支持
           "useBuiltIns": "usage",
           "corejs": 3
       }]
   ],
   // 插件
   plugins: []  
}

📃 写在最后:推荐我的日常 demo 地址,涉及 jstsvuereact,欢迎访问 🎉🎉 ⭐

🔗 getee:daily_demo

🔗 github:daily_demo

image.png