18.工程化-灵析社区

懒人学前端

一、对比 Less、Sass、Stylus、PostCSS?

Less、Sass 和 Stylus 是 CSS 预处理器,PostCSS 是转换 CSS 工具的平台

  • Less

变量:$标识符变量,使用{}插值

嵌套:支持{ }大括号嵌套

混入器:支持 选择器 混入 或 使用.selector(@param)创建纯混入器

扩展 / 继承 / 运算符 / @import:支持

流程:支持if条件判断,支持when递归模拟循环

映射:支持@声明和使用 Map

特有:提供 Less.js,直接在浏览器使用 Less

  • SaSS

变量:支持$标识符变量,使用#{}插值

嵌套:SCSS 支持{ }大括号嵌套 SASS 支持缩进嵌套

混入器:@mixin创建@include使用

扩展 / 继承 / 运算符 / @import:支持

流程:支持if else条件判断,支持for while each循环

映射:支持$()声明 Map,提供map-get(map, key) map-keys(map) map-values(map)等一系列方法操作 Map,支持遍历 Map

特有:支持 compass ,内含 自动私有前缀 等一系列有用SASS模块,支持压缩输出

  • Stylus

变量:支持$标识符变量 和 赋值表达式变量,使用{}插值

嵌套:支持{ }大括号嵌套 和 缩进嵌套

混入器:像函数一样创建和使用

扩展 / 继承 / 运算符 / @import:支持

流程:支持if else unless三元 条件判断,支持for循环

映射:像 JS 一样创建和使用对象

特有:支持中间件,自动分配函数变量,提供 JS API。支持压缩输出

  • PostCSS

接受 CSS 文件,把 CSS 规则转换为抽象语法树

提供 API 供插件调用,对 CSS 处理

插件:支持 Autoprefixer 自动添加私有前缀、css-modules CSS 模块 stylelint CSS 语法检查等插件,PostCSSS 是工具的工具

二、Webpack 处理 SASS 文件时,sass-loader, css-loader,style

作用

  • sass-loader

将 SASS / SCSS 文件编译成 CSS

调用node-sass,支持options选项向node-sass传参

  • css-loader

支持读取 CSS 文件,在 JS 中将 CSS 作为模块导入

支持 CSS 模块 @规则@import @import url()

  • style-loader

将 CSS 以<style>标签的方式,插入 DOM

配置顺序

Webpack中 loader 的加载顺序是从后往前

在处理 SASS / SCSS 文件时,三者的配置顺序 style-loader css-loader sass-loader

可以用插件 ExtractTextWebpackPlugin 替换 style-loader,生成新的 CSS 文件

三、如何压缩 CSS 大小,如何去除无用的 CSS?

压缩 CSS ,简单可分为 3 步骤:

① 去除 CSS 中的换行和空格

② 去除 每个选择器,最后一个属性值后的分号;

② 去除 注释,正则/*[^*] [^/][^*]**+)*/

此外,包括使用 缩写属性,z-index值的重新排序,也可以减少代码量。但通过工具进行时,结果不一定总是安全

常用的 CSS 压缩工具有:

  • YUI Compressor

基于 Java , 本来是 JS 压缩,也兼容 CSS 压缩,配置较少,但保障压缩安全

  • clean-css

基于 NodeJS , 可以根据 浏览器版本、具体的 CSS 标准模块,详细配置兼容性

  • cssnano

基于 PostCSS ,是 Webpack5 推荐的 CssMinimizerWebpackPlugin 默认的 CSS 压缩工具

如何去除无用的 CSS :

  • Chrome 开发者工具 Lighthouse

打开 http / https 网址,勾选 Performance 选项,在性能报告中,会列出 unused CSS,可以人工去除

  • UnCSS

通过 jsdom 加载 HTML 并执行 JS

通过 PostCSS 解析样式

通过document.querySelector查找 HTML 中不存在的 CSS 选择器

返回 剩余样式

  • PurgeCSS

可以对 HTML JS 和 VUE 等框架中 CSS 使用情况分析,并删除无用 CSS

提供 Webpack Gulp Grunt 等工程化工具的插件

  • cssnano

提供discardUnused选项,用于删除与当前 CSS 无关的规则

不支持内容分析

同样支持工程化工具

四、什么是 CSS 模块化,有哪几种实现方式?

什么是 CSS 模块化?

CSS 模块化是将 CSS 规则 拆分成相对独立的模块,便于开发者在项目中更有效率地组织 CSS:

  • 管理层叠关系
  • 避免命名冲突
  • 提高复用度,减少冗余
  • 便于维护或扩展

CSS 模块化的方式:

  • 基于文件拆分
  • 不拆分但设置作用域
  • CSS in JS
  • 内联样式、Shadow DOM 等

无论哪种方式,核心都是通过 保证CSS类命名唯一,或者 避免命名使用内联样式,来模拟出CSS模块作用域的效果

基于文件的 CSS 模块的加载

  • <link>

将不同模块的 CSS 分文件存放,通过<link>标签按需引入

  • @import

@规则,将其它 CSS 嵌入当前 CSS

除现代浏览器外,也得到了 CSS 预处理器 Less、Sass 和 Stylus 的支持

  • import

在 Webpack 中,将 CSS 作为资源引入,并可以通过 CSS Modules 为 CSS 生成独一无二的类名

CSS 模块化的实现方式

  • 分层拆分

将 CSS规则 分层存放,并约束不同层次间的命名规则

SMACSS:按功能分成 Base Layout Module State Theme 五层

ITCSS:按从通用到具体分成 Settings Tools Generic Base Objects Components 七层

  • 分块拆分

将页面中视觉可复用的块独立出来,仅使用类选择器,并确保类名唯一

OOCSS

将盒模型规则与颜色、背景等主题规则拆分

将视觉可复用的块类名与页面结构解耦

BEM

将页面按 Block Element Modifier 划分

类名规则 block-name__element-name--modifier-name

  • 原子化拆分

每个选择器只包含1个或少量属性,通过组合选择器定义复杂样式

ACSS:属性名像函数,属性值像函数参数,像写内联样式一样组合类名

Utility-First CSS:提供一套可配置的 CSS 实用类库,使用时按需编译

  • CSS in JS

CSS Modules

将 CSS 作为资源引入

根据内容的哈希字符串,计算出独一无二的类名,CSS 规则 只对该类名下的元素生效

styled-components Aphrodite Emotion 等

通过 JS 创建包含属性定义的组件

生成独一无二的类名

Radium 等

通过 JS 创建包含属性定义的组件

生成内联样式

  • Shadow DOM

通过attachShadow给元素的影子DOM,附加<style>标签,其中规则不会影响外部元素。代表的框架有 Ionic 等

五、如何自动压缩图片?

  • 使用或调用软件

使用 PhotoShop 自动批处理功能

  • 录制动作:打开文件,调整大小,另存为调整品质,关闭文件

  • 文件菜单,自动,批处理,选择 源文件夹,批量执行动作

  • 使用 开源图片处理软件 XnViewr,工具,批量转换功能

XnConVenter 提供更复杂的图片批量处理功能

  • 使用 命令行工具,包括 NConvert ImageMagic 等以及类似 img2webp 的专门格式的转换工具
  • 工程化配置图片压缩

这里以Webpack为例

CSS 内联图片

配置url-loader小于指定尺寸图片转 base64,减少请求

module: {
  rules: [{
    test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
    loader: 'url-loader',
    options: {
    limit: 10, // 小于10KB图片,转base64编码
  }
}]}
  • 图片模块

import / require 到 .js 或 .html 以及 require({图片路径}) 的图片

这些图片被打包器看作是资源模块引入

配置file-loader+image-webpack-loader调节品质

rules: [{
  test: /\.png$/i, // 以png为例
  use: [
    'file-loader',
    {
      loader: 'image-webpack-loader',
      options: {
        pngquant: {
          quality: [0.65, 0.90] // 设置png的品质区间
        },
      }
    },
  ],
}]
  • 图片目录

图片以静态资源附件的形式,放置在同一目录下

通过CopyPlugin将图片从源目录(src)复制到发布目录(dist)

可以安装imagemin-webpack-plugin,在复制时,批量调整图片尺寸

npm i imagemin-webpack-plugin -D
plugins: [
  new CopyPlugin({
  patterns: [{
    from: resolve('src-es6/images'),
    to: resolve('dist/images'),
  }]
  }),
  new ImageminPlugin({ // 在 CopyPlugin 之后。如果是 merge 多配置文件,CopyPlugin 放 common 被合并的配置里
    test: /\.(png|jpe?g)$/i,
    pngquant: {
      quality: '70-75' // 设置 png 的品质区间
    },
    plugins: [ // 可以引入其它图片压缩插件
      ImageminMozjpeg({
        quality: 70, // 设置 jpeg / jpg 的品质
        progressive: true // 渐进式:true:由模糊到清晰加载 false:从上到下加载
      })
    ]
  }),
]

代码中使用的ImageminMozjpeg需要额外安装,您也可以安装其它压缩插件

npm i imagemin-mozjpeg -D
  • 使用反向代理

部分CDN服务商,提供一键 图片瘦身,自动转 webp 等能压缩图片服务

您可以自建反向代理节点,将图片缓存在节点上,根据客户端接受的MIME文件类型列表,如支持 image/webp 的客户端,将图片转成 webp 格式。根据用户 UserAgent,调节品质、尺寸后,再返回给客户端

需要提醒的是,避免使用 defalte gzip 和 br 等压缩算法,再次压缩图片,这样带来的性能损耗通常高于传输收益

六、如何自动添加浏览器私有前缀属性?

  • 使用 SASS

自定义添加浏览器私有前缀的Mixins,不能适应所有属性

@mixin autoPrefix($propertyName, $propertyValue, $prefixs: ()) {
    @each $prefix in $prefixs {
      -#{$prefix}-#{$propertyName}: $propertyValue;
    }
    #{$propertyName}: $propertyValue;
  }
div {
  @include autoPrefix(box-shadow, 0 0 1px black, ('webkit', 'moz'))
}
转换为 CSS
div {
  -webkit-box-shadow: 0 0 1px black;
  -moz-box-shadow: 0 0 1px black;
  box-shadow: 0 0 1px black;
}
  • 搭配compass或Bourbon
@import "compass/css3";
div {
  @include box-shadow(0 0 1px black);
}  
  • 使用 Less,搭配 LESS Elements
@import "elements.less";
div {
  .box-shadow(0 0 1px black);
}
  • 使用 Autoprefixer

支持补全属性值,支持按浏览器兼容情况精确补全

VsCode

安装 Extensions:Autoprefixer

进入 Vscode Perferences Settings 搜索 Autoprefixer

配置支持的浏览器版本

 "autoprefixer.options": {
  "browsers": [
    "ie >= 6",
    "firefox >= 8",
    "chrome >= 24",
    "Opera >= 10"
  ]
}

F1 后,Run Autoprefixer,自动补全

  • Webpack

安装并添加 postcss-loader

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ["css-loader", "postcss-loader"]
      }
    ]
  }
}

创建 postcss.config.js

module.exports = {
  plugins: [
    require('autoprefixer')
  ]
}

创建 .browserslistrc

ie >= 6
firefox >= 8
chrome >= 24
Opera >= 10

或在 package.json 添加 browserslist 属性

 {
  "browserslist": [
    "ie >= 6",
    "firefox >= 8",
    "chrome >= 24",
    "Opera >= 10"
  ]
}

七·、对比媒体查询与按需引入 CSS?

  • 媒体查询

允许我们通过设备、屏幕、使用场景、用户偏好来解析符合条件的 CSS,忽略不符合条件的 CSS

即使通过 Link 标签附加媒体查询条件引入的 CSS,不符合条件时依然会被下载

  • 按需引入

按需引入,可以避免冗余下载的问题,允许我们按照目标环境引入CSS

但条件没有媒体查询丰富,多数时,无法及时对运行环境的变化作出响应

  • IE 浏览器中,可以通过 HTML 注释,附加 if 条件,阻止其中的 HTML 被解析,相应的 CSS 也不会被下载
<!--[if lt IE 9]><link rel="stylesheet" href="ielt9.css" /><![endif]-->
  • 工程化及ES6等模块化环境中,我们可以通过import或require只引入需要的css,通过PurgeCSS和cssnano去除未被使用的CSS
  • 在webpack配置DefinePlugin自定义环境变量,在uni-app中 使用条件注释等利用打包工具提供的 条件编译 功能

阅读量:2024

点赞量:0

收藏量:0