前端工程化-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() 
  ] 
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
禁止转载,如需转载请通过简信或评论联系作者。

推荐阅读更多精彩内容