前端工程化-Webpack 基础-打包CSS

以下皆为拉勾教育课件内笔记

转换 CSS

例如,我们现在如果需要对 CSS 文件进行打包。我们就需要 CSS 对应的 loader (打包器)。一般来说有两个 loader:

  • css-loader 负责遍历 css 文件,将 CSS 转化为 CommonJS(将 CSS 输出到打包后的 JS 文件中)
  • style-loader 负责把包含 CSS 内容的 JS 代码,挂载到页面的 style 标签中。

需要安装才能使用上述 loader :npm i css-loader style-loader -D

CSS 打包逻辑

示例:

  • 声明 CSS
    html, body {
     margin: 0;
     padding: 0;
    }
    body { 
     /* background-color: #dbf; */
     background: url('../images/1.jpg') no-repeat;
    }
    
  • 在入口文件中,以模块的方式引入 CSS
    require('./header') 
    import data from './data.json' 
    import './css/main.css' // 引⼊ CSS 
    
    console.log('Hello Webpack', data)
    
  • 然后在 Webpack 的配置文件当中,添加 .css 文件的规则配置
    const { resolve } = require('path')
    
    module.exports = { 
      // 模式 
      mode: 'production', 
      // ⼊⼝ 
      entry: './src/index.js', 
      // 出⼝ 
      output: { 
        filename: 'bundle.js' 
        path: resolve(__dirname, 'output'), 
      },
    
      // loader 配置 
      module: { 
        // 配置⽂件类型规则,不同的规则使⽤不同的 loader 进⾏处理
        rules: [ 
          {
            // test 后跟随正则表达式,匹配⽂件类型
            test: /\.css$/,
            // use 表示使⽤什么 loader 来处理上述类型的⽂件
            use: [
              // 2. 将 JS 中的样式⽂件,嵌⼊到⻚⾯的 style 标签中
              'style-loader',
              // 1. css-loader 将样式⽂件转成 CommonJS 模块,加载到 JS 中
              'css-loader'
            ]
          }
        ]
      }, 
    
    注意:在处理 CSS 文件时,各个 loader 的使用,有先后顺序。例如,我们先用 css-loader 将 CSS 代码转成 JS 代码,再由 style-loader 将 JS 代码中的样式挂载到页面中。因此,需要先使用 css-loader,然后在使用 style-loader
    这里需要强调的是:use 数组中,loader 的加载顺序是从下往上(从右往左)的,即最后一个 loader 最先执行。因此,css-loader 在后,style-loader 在前。

转换 LESS

如果项目中除了 .css 文件之外,还有 .less 文件,我们还需要对 .less 文件进行打包。这里的打包顺序是:先将 .less 文件转成 .css 文件,然后再打包 .css 文件。
打包 .less 文件我们需要安装 less 和 less-loader:npm i less less-loader -D

less 打包逻辑

示例:

  • 声明 less 文件
    @body-bg: #dfb; 
    @body-color: blue; 
    body { 
      margin: 0 auto; 
      padding: 20px; 
      background: @body-bg; 
      color:@body-color; 
    } 
    p { 
      padding: 20px; 
      background: rgb(248, 200, 173); 
    } 
    .code { 
      user-select: none; 
    }
    
  • 引入 less 文件
    require('./header') 
    import data from './data.json' 
    import './css/main.css' // 引⼊ CSS 
    import './css/main.less' // 引⼊ less 
    console.log('Hello Webpack', data)
    
  • 然后再 webpack.config,js 中添加对应的 less 配置
    const path = require('path') 
    module.exports = { 
      mode: 'none', 
      entry: './src/index.js', 
      output: { 
        filename: 'bundle.js',
        path: path.join(__dirname, 'dist') 
      }, 
      module: { 
        rules: [ 
          { 
            test: /\.css$/, 
            use: [ 
              'style-loader', 
              'css-loader' 
            ] 
          }, 
          { 
            test: /\.less$/, 
            use: [ 
              'style-loader', 
              'css-loader', 
              'less-loader' 
            ] 
          } 
        ] 
      }
    }
    
    首先,我们在 rules 数组中,添加 .less 文件的规则匹配。然后,我们需要的执行顺序是 less-loader > css-loader > style-loader,所以 less-loader 放在 use 数组的最后。

将 CSS 打包成独立文件

此时我们需要 mini-css-extract-plugin 插件,安装:npm install mini-css-extract-plugin -D。使用:

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

module.exports = { 
  mode: 'none', 
  entry: './src/index.js', 
  output: { 
    filename: 'bundle.js', 
    path: path.join(__dirname, 'dist') 
  }, 
  module: { 
    rules: [ 
      { 
        test: /\.css$/, 
        use: [ 
          // 'style-loader', // 将 CSS 嵌⼊到 HTML 中(现在,不再需要 将 CSS 嵌⼊到 HTML 中) 
          MiniCssExtractPlugin.loader, // 将 CSS 打包到独⽴⽂件中 
          'css-loader' 
        ] 
      }, 
      { 
        test: /\.less$/, 
        use: [ 
          // 'style-loader', 
          MiniCssExtractPlugin.loader,
          'css-loader', 
          'less-loader' 
        ] 
      } 
    ] 
  }, 
  plugins: [ 
    new MiniCssExtractPlugin({ 
      // 指定输⼊位置和⽂件名称 
      filename: 'css/[name].css', 
    }), 
  ],
}

解决 CSS 中的图片引入问题

将 CSS 单独打包到独立文件时,往往会发生路径的变更,此时,CSS 中的背景图片地址可能需要更改,可以通过为 MiniCssExtractPlugin.loader 指定公共路径的方式解决路径变更的问题。

      { 
        test: /\.css$/, 
        use: [ 
          // 'style-loader', // 将 CSS 嵌⼊到 HTML 中(现在,不再需要 将 CSS 嵌⼊到 HTML 中) 
          // MiniCssExtractPlugin.loader // 将 CSS 打包到独⽴⽂件中 
          {
            loader: MiniCssExtractPlugin.loader,
            options: {
              publicPath: '../' // 为背景图⽚指定路径
            }
          },
          'css-loader' 
        ] 
      }, 

添加前缀

此时需要两个包

  • postcss-loader
  • autoprefixer

安装:npm install postcss-loader autoprefixer -D
使用:

  module: { 
    rules: [ 
      { 
        test: /\.css$/, 
        use: [ 
          MiniCssExtractPlugin.loader
          'css-loader' 
          'postcss-loader' // 添加这⼀⾏,注意添加的顺序
        ] 
      },
    ]
  }

此时运行 webpack 会报错:'No PostCSS Config found',原因是 PostCSS 需要一个配置,用来设置 autoprefixer 的设置标准(即需要兼容哪些浏览器)
解决:添加 PostCSS 的配置 - 在项目根目录下添加 postcss.config.js

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

指定兼容规则有两种指定方式,二选一即可【详情查看】

  1. 可以在 package.json 中指定(推荐)
"browserslist": [ 
  "last 1 version", // 最后的⼀个版本
  "> 1%" // 代表全球超过 1% 使⽤的浏览器
]
  1. 在项目根目录下创建 .browserslistrc
# Browsers that we support
last 1 version
> 1%

更多查询条件

  • > 5%: 基于全球使⽤率统计⽽选择的浏览器版本范围。>=,<,<=同样适⽤。> 5% in US : 同上,只是使 ⽤地区变为美国。⽀持两个字⺟的国家码来指定地区。

  • > 5% in alt-AS : 同上,只是使⽤地区变为亚洲所有国家。这⾥列举了所有的地区码。

  • > 5% in my stats : 使⽤定制的浏览器统计数据。

  • cover 99.5% : 使⽤率总和为99.5%的浏览器版本,前提是浏览器提供了使⽤覆盖率。

  • cover 99.5% in US : 同上,只是限制了地域,⽀持两个字⺟的国家码。

  • cover 99.5% in my stats :使⽤定制的浏览器统计数据。

  • maintained node versions :所有还被 node 基⾦会维护的 node 版本。

  • node 10 and node 10.4 : 最新的 node 10.x.x 或者10.4.x 版本。

  • current node :当前被 browserslist 使⽤的 node 版本。

  • extends browserslist-config-mycompany :来⾃browserslist-config-mycompany包的查询设置

  • ie 6-8 : 选择⼀个浏览器的版本范围。

  • Firefox > 20 : 版本⾼于20的所有⽕狐浏览器版本。>=,<,<=同样适⽤。

  • ios 7 :ios 7⾃带的浏览器。

  • Firefox ESR :最新的⽕狐 ESR(⻓期⽀持版) 版本的浏览器。

  • unreleased versions or unreleased Chrome versions : alpha 和 beta 版本。

  • last 2 major versions or last 2 ios major versions :最近的两个发⾏版,包括所有的次版本号和补 丁版本号变更的浏览器版本。

  • since 2015 or last 2 years :⾃某个时间以来更新的版本(也可以写的更具体since 2015-03或者 since 2015-03-10)

  • dead :通过last 2 versions筛选的浏览器版本中,全球使⽤率低于0.5%并且官⽅声明不在维护或者事 实上已经两年没有再更新的版本。⽬前符合条件的有 IE10,IE_Mob 10,BlackBerry 10,BlackBerry 7,OperaMobile 12.1。

  • last 2 versions :每个浏览器最近的两个版本。

  • last 2 Chrome versions :chrome 浏览器最近的两个版本。

  • defaults :默认配置 > 0.5%, last 2 versions, Firefox ESR, not dead。

  • not ie <= 8 : 浏览器范围的取反。 可以添加 not 在任和查询条件前⾯,表示取反


格式校验

每个程序员都有自己的编码习惯,最常见莫过于:

  • 有的人代码结尾必须加分号,有的人觉得不加分号更好看;
  • 有的人写字符串时,喜欢用双引号,而有的人喜欢用单引号;
  • 有的人代码缩进喜欢用 4 个空格,有的人喜欢用 2 个空格;

诸如此类,但是项目开发一般是多人协作,所以,不同的工程师,写的代码风格不同。一般写自己的代码怎么折腾都没关系,但整个项目有一个统一的编码规范。这样别看源码就能看得懂。在前端开发中,我们使用 StyleLint 插件来检测 CSS 代码。

官网:https://stylelint.io/
代码风格标准:https://github.com/stylelint/stylelint-config-standard

安装插件:npm i --g stylelint stylelint-config-standard ,stylelint 是运行工具,stylelint-config-standard 是 stylelint 的推荐配置。

在项目的根目录下创建 .stylelintrc.json 文件,添加以下配置:

{
  "extends": "stylelint-config-standard",
  "rules": {
     # 除了使⽤ stylelint-config-standard,我们还可以在 rules 字段中⾃定 义校验规则 
    "block-no-empty": true # 代码块不能为空
  }
}

运行 stylelint,检测 CSS 代码格式

# 注意:路径是写在双引号中的 
# 检测⼀个⽂件 
stylelint ⽂件路径/⽂件名.css
# 检测整个项⽬下,所有的 CSS ⽂件
stylelint **/*.css

Webpack 中使用 StyleLint

安装:npm i stylelint stylelint-config-standard stylelint-webpack-plugin -D

  • stylelint 校验样式文件的命令
  • stylelint-config-standard 校验样式文件的规则
  • stylelint-webpack-plugin 在 Webpack 中使用 stylelint 的插件

在 webpack.config.js 中配置 stylelint-webpack-plugin
配置详情:https://www.npmjs.com/package/stylelint-webpack-plugin

const StylelintPlugin = require('stylelint-webpack-plugin'); 
module.exports = {
  // ... 
  plugins: [
    // new StylelintPlugin(), // 使⽤默认值
    new StylelintPlugin({ 
      files: ['src/css/*.{css,less,sass,scss}'], // 匹配需要进⾏格式 校验的⽂件
      fix: true // 是否尽可能多地解决错误
    }) 
  ], 
  // ... 
};

在 package.json 中配置 stylelint-config-standard,使用 stylelint-config-standard 规则来检测代码。

"stylelint": { 
  "extends": "stylelint-config-standard", 
  // 后续为扩展配置(如果不需要⾃定义规则,可以忽略 rules) 
  "rules": { 
    "at-rule-no-unknown": [ 
      true,
      { 
        "ignoreAtRules": ["extends", "ignores"] 
      } 
    ],
    "indentation": "tab", 
    "number-leading-zero": "never", 
    "unit-whitelist": ["em", "rem", "s"]
  } 
}

指定规则配置有三种方式,按照加载的先后顺序,依次是:

  1. 在 package.json 中的 stylelint 属性指定规则
  2. 在 .stylelintrc 中指定规则
  3. 在 stylelint.config.js 中指定规则

压缩 CSS

压缩 CSS 我们可以使用 optimize-css-assets-webpack-plugin 进行。
详情查看:https://www.npmjs.com/package/optimize-css-assets-webpack-plugin

安装:npm install optimize-css-assets-webpack-plugin -D

使用:

const path = require('path')
var OptimizeCssAssetsPlugin = require('optimize-css-assets-webpac k-plugin'); 

module.exports = { 
  mode: 'none', 
  entry: './src/index.js', 
  output: { 
    filename: 'bundle.js', 
    path: path.join(__dirname, 'dist') 
  }, 
  module: { 
    rules: [ 
      { 
        test: /\.css$/, 
        use: [
          'style-loader', 
          'css-loader' 
        ] 
      }, 
      { 
        test: /\.less$/, 
        use: [ 
          'style-loader', 
          'css-loader', 
          'less-loader' 
        ] 
      } 
    ] 
  }, 
  plugins: [ 
    new OptimizeCssAssetsPlugin() 
  ] 
}
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容