Skip to content

Latest commit

 

History

History
526 lines (418 loc) · 15.6 KB

2.config_css.md

File metadata and controls

526 lines (418 loc) · 15.6 KB

配置和css处理

配置文件

  • 默认在终端执行 webpack 命令的时候,会在当前目录下找 ./src/index.js 这个文件作为入口文件,然后进行打包。

如果我们想指定入口文件和打包输出目录的话,就可以在终端输入

npx webpack --entry ./src/main.js --output-path ./build
// 入口文件为 ./src/main.js 打包输出目录为 ./build

命令行还可以添加哪些参数请到官方文档这里查阅。

  • 通过命令行的方式添加这些 webpack 的配置参数可读性差,也很麻烦,所以最常见的方式是在项目根目录下新建 webpack.config.js 文件,然后在其中用 commonjs 的方式导出一个对象即可。
// webpack.config.js
const path = require('path')

module.exports = {
    entry: './src/main.js', // 入口文件
    output: { // 输出
        filename: 'bundle.js',
        path: path.resolve(__dirname, './build') // 必须是绝对路径
    }
}

指定配置文件名字

终端执行 webpack 命令的时候,默认会去找项目目录下的 webpack.config.js ,如果想要指定配置文件的名字,可以提供命令行参数:

webpack --config wk.config.js

webpack 依赖图

  • 事实上webpack在处理应用程序时,它会根据命令或者配置文件找到入口文件
  • 从入口开始,会生成一个依赖关系图,这个依赖关系图会包含应用程序中所需的所有模块(比如.js文件、css文件、图片、字体等)
  • 然后遍历图结构,打包一个个模块(根据文件的不同使用不同的loader来解析)

css-loader

当在 js 文件中引入了 css 文件后,使用 webpack 打包就会报错,这就是由于缺少 loader 去解析 css 文件。

  • loader 可以用于对模块的源代码进行转换
  • 我们可以将css文件也看成是一个模块,我们是通过import来加载这个模块
  • 在加载这个模块时,webpack其实并不知道如何对其进行加载,我们必须制定对应的loader来完成这个功能
  • css-loader 可以读取 css 文件

但是安装完 css-loader 打包后会报错,因为没有告诉 webpack 怎么去将 css-loader 和 css 文件去做关联。

css-loader 的使用方式有三种:

  • 内联方式

内联方式使用较少,因为不方便管理;在引入的样式前加上使用的loader,并且使用!分割;

import 'css-loader!../css/style.css'
  • cli 方式(webpack 5 已经不再支持)

  • 配置文件方式。

    • module.rules中允许我们配置多个loader(因为我们也会继续使用其他的loader,来完成其他文件的加载);
    • 这种方式可以更好的表示loader的配置,也方便后期的维护,同时也让你对各个Loader有一个全局的概览

    module.rules的配置如下:

    • rules属性对应的值是一个数组 [rule]
    • 数组中存放的是一个个的Rule,Rule是一个对象,对象中可以设置多个属性:
      • test属性:用于对 resource(资源)进行匹配的,通常会设置成正则表达式;
      • use属性:对应的值时一个数组:[UseEntry]
        • UseEntry是一个对象,可以通过对象的属性来设置一些其他属性
          • loader:必须有一个 loader属性,对应的值是一个字符串;
          • options:可选的属性,值是一个字符串或者对象,值会被传入到loader中;
          • query:目前已经使用options来替代
        • 传递字符串(如:use: [ 'style-loader' ])是 loader 属性的简写方式(如:use: [ { loader: 'style-loader'} ])
      • loader属性: Rule.use: [ { loader } ] 的简写。
module: {
    rules: [
      {
        // 规则使用正则表达式
        test: /\.css$/, // 匹配资源
        use: [
          // { loader: "css-loader" },
          // 注意: 编写顺序(从下往上, 从右往做, 从后往前)
          "style-loader", 
          {
            loader: "css-loader",
            options: {
              importLoaders: 1
            }
          },
          "postcss-loader"
        ],
        // loader: "css-loader"
      }
    ]
  }

下面看看三种写 loader 的方式:

// 最完整的写法
module: {
  rules: [
    {
      test: /\.css$/,
      use: [
        {
          loader: 'css-loader'
        }
      ]
    }
  ]
}

// 简写法
module: {
  rules: [
    {
      test: /\.css$/,
      use: [
        "css-loader"
      ]
    }
  ]
}

// 简写法
module: {
  rules: [
    {
      test: /\.css$/,
      loader: "css-loader"
    }
  ]
}

style-loader

css-loader 处理 css 后打包不报错了,但是发现打包后的代码并没有使 css 生效,因为 css-loader 只解析 css 文件,并不会将 css 插入页面。想要插入样式,需要用到 style-loader。

预处理器

如果使用了 css 预处理器编写样式,例如 less,就需要先按照 less 工具,然后安装 less-loader,less-loader 会调用 less 工具先将 less 文件编译成 css 文件,然后再执行后续 css-loader 和 style-loader 的操作。

module: {
  rules: [
    {
      test: /\.less$/,
      use: [
        'style-loader',
        'css-loader',
        'less-loader'
      ]
    }
  ]
}

浏览器兼容性

针对不同浏览器对 css 和 js 支持不同特性的情况,我们需要做兼容性处理。

浏览器市场占有率

浏览器市场占有率是在https://www.caniuse.com/usage-table这里查的。

browserslist

我们需要为项目配置 browserslist,来告诉各种工具需要匹配哪些版本的浏览器。

Browserslist是什么?Browserslist是一个在不同的前端工具之间,共享目标浏览器和Node.js版本的配置:

  • Autoprefixer
  • Babel
  • postcss-preset-env
  • eslint-plugin-compat
  • stylelint-no-unsupported-browser-features
  • postcss-normalize
  • obsolete-webpack-plugin
> 1%
last 2 versions
not dead

类似这样的配置使用的是caniuse-lite的工具来查询匹配的浏览器的,这个工具的数据来自于caniuse的网站上。

browserslist 编写规则

  • defaults:Browserslist的默认浏览器(> 0.5%, last 2 versions, Firefox ESR, not dead)。

  • 5%:通过全局使用情况统计信息选择的浏览器版本。>=,<和<=工作过。

    • 5% in US:使用美国使用情况统计信息。它接受两个字母的国家/地区代码。
    • > 5% in alt-AS:使用亚洲地区使用情况统计信息。有关所有区域代码的列表,请参见caniuse-lite/data/regions
    • > 5% in my stats:使用自定义用法数据。
    • > 5% in browserslist-config-mycompany stats:使用来自的自定义使用情况数据browserslist-config-mycompany/browserslist-stats.json。
    • cover 99.5%:提供覆盖率的最受欢迎的浏览器。
    • cover 99.5% in US:与上述相同,但国家/地区代码由两个字母组成。
    • cover 99.5% in my stats:使用自定义用法数据。
  • dead:24个月内没有官方支持或更新的浏览器。现在是IE 10,IE_Mob 11,BlackBerry 10,BlackBerry 7, Samsung 4和OperaMobile 12.1。

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

    • last 2 Chrome versions:最近2个版本的Chrome浏览器。
    • last 2 major versions或last 2 iOS major versions:最近2个主要版本的所有次要/补丁版本。
  • node 10和node 10.4:选择最新的Node.js10.x.x 或10.4.x版本。

  • current node:Browserslist现在使用的Node.js版本。

  • maintained node versions:所有Node.js版本,仍由Node.js Foundation维护。

  • iOS 7:直接使用iOS浏览器版本7。

    • Firefox > 20:Firefox的版本高于20 >=,<并且<=也可以使用。它也可以与Node.js一起使用。
    • ie 6-8:选择一个包含范围的版本。
    • Firefox ESR:最新的[Firefox ESR]版本。
    • PhantomJS 2.1和PhantomJS 1.9:选择类似于PhantomJS运行时的Safari版本。
  • extends browserslist-config-mycompany:从browserslist-config-mycompanynpm包中查询。

  • supports es6-module:支持特定功能的浏览器。es6-module这是“我可以使用” 页面feat的URL上的参数。有关所有可用功能的列表,请参见。caniuselite/ data/features

  • browserslist config:在Browserslist配置中定义的浏览器。在差异服务中很有用,可用于修改用户的配置,例如browserslist config and supports es6-module。

  • since 2015或last 2 years:自2015年以来发布的所有版本(since 2015-03以及since 2015-03-10)。

  • unreleased versions或unreleased Chrome versions:Alpha和Beta版本。

  • not ie <= 8:排除先前查询选择的浏览器。

browserslist 命令行

可以使用命令行查询某些条件对应的浏览器版本

npx browserslist ">1%, last 2 version, not dead"
and_chr 89
and_ff 86
and_qq 10.4
and_uc 12.12
android 89
baidu 7.12
chrome 89
chrome 88
edge 89
edge 88
firefox 87
firefox 86
ie 11
ios_saf 14.0-14.5
ios_saf 13.4-13.7
kaios 2.5
op_mini all
op_mob 62
opera 73
opera 72
safari 14
safari 13.1
samsung 13.0
samsung 12.0

配置 browserslist

有两种方法配置 browserslist

  1. 在 package.json 中配置
browserslist: [
  '> 1%',
  'last 2 versions',
  'not dead',
]
  1. 在 browserslistrc 文件中配置
> 1%
last 2 versions
not dead

如果没有配置,会有一个默认配置:

> 0.5%,
last 2 versions,
Firefox ESR,
not dead

每一行规则之间是 or 或 的关系,如果要使用 and 关系,就写到一行里使用 and 连接。not 取反。

> 0.5% and last 2 versions
not dead

postcss

  • 什么是PostCSS呢?
    • PostCSS是一个通过JavaScript来转换样式的工具;
    • 这个工具可以帮助我们进行一些CSS的转换和适配,比如自动添加浏览器前缀、css样式的重置;
    • 但是实现这些工具,我们需要借助于PostCSS对应的插件;
  • 如何使用PostCSS呢?主要就是两个步骤:
    • 第一步:查找PostCSS在构建工具中的扩展,比如webpack中的postcss-loader;
    • 第二步:选择可以添加你需要的PostCSS相关的插件;

命令行使用 postcss

当然,我们能不能也直接在终端使用PostCSS呢?也是可以的,但是我们需要单独安装一个工具postcss-cli;

  • 我们可以安装一下它们:postcss、postcss-cli
      npm install postcss postcss-cli -D
  • 我们编写一个需要添加前缀的css:
.content {
  /* 十六进制通常是写几位 */
  color: #12345678;
}

:fullscreen {

}

.content {
  user-select: none;
  transition: all 2s ease;
}
  • 因为我们需要添加前缀,所以要安装autoprefixer:
npm install autoprefixer -D
  • 直接使用使用postcss工具,并且制定使用autoprefixer
npx postcss --use autoprefixer -o end.css ./src/css/style.css

转化之后的css样式如下:

.content {
  /* 十六进制通常是写几位 */
  color: #12345678;
}

:-webkit-full-screen {
  color: red;
}

:-ms-fullscreen {
  color: red;
}

:fullscreen {
  color: red;
}

.content {
  -webkit-user-select: none;
     -moz-user-select: none;
      -ms-user-select: none;
          user-select: none;
  transition: all 2s ease;
}



/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNyYy9jc3MvdGVzdC5jc3MiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7RUFDRSxlQUFlO0VBQ2YsZ0JBQWdCO0FBQ2xCOztBQUVBO0VBQ0UsVUFBVTtBQUNaOztBQUZBO0VBQ0UsVUFBVTtBQUNaOztBQUZBO0VBQ0UsVUFBVTtBQUNaOztBQUVBO0VBQ0UseUJBQWlCO0tBQWpCLHNCQUFpQjtNQUFqQixxQkFBaUI7VUFBakIsaUJBQWlCO0VBQ2pCLHVCQUF1QjtBQUN6QiIsImZpbGUiOiJlbmQuY3NzIiwic291cmNlc0NvbnRlbnQiOlsiLmNvbnRlbnQge1xyXG4gIC8qIOWNgeWFrei/m+WItumAmuW4uOaYr+WGmeWHoOS9jSAqL1xyXG4gIGNvbG9yOiAjMTIzNDU2Nzg7XHJcbn1cclxuXHJcbjpmdWxsc2NyZWVuIHtcclxuICBjb2xvcjogcmVkO1xyXG59XHJcblxyXG4uY29udGVudCB7XHJcbiAgdXNlci1zZWxlY3Q6IG5vbmU7XHJcbiAgdHJhbnNpdGlvbjogYWxsIDJzIGVhc2U7XHJcbn1cclxuXHJcblxyXG4iXX0= */

postcss-loader

因为postcss需要有对应的插件才会起效果,所以我们需要配置它的plugin

  module: {
    rules: [
      {
        // 规则使用正则表达式
        test: /\.css$/, // 匹配资源
        use: [
          // { loader: "css-loader" },
          // 注意: 编写顺序(从下往上, 从右往做, 从后往前)
          "style-loader",
          "css-loader",
          {
            loader: "postcss-loader",
            options: {
              postcssOptions: {
                plugins: [
                  require('autoprefixer')
                ]
              }
            }
          }
        ],
        // loader: "css-loader"
      },
    ]
  }

postcss-preset-env

事实上,在配置postcss-loader时,我们配置插件并不需要使用autoprefixer。我们可以使用另外一个插件:postcss-preset-env。postcss-preset-env也是一个postcss的插件;它可以帮助我们将一些现代的CSS特性,转成大多数浏览器认识的CSS,并且会根据目标浏览器或者运行时环境添加所需的polyfill;也包括会自动帮助我们添加autoprefixer(所以相当于已经内置了autoprefixer);

举一个例子:

  • 我们这里在使用十六进制的颜色时设置了8位;
  • 但是某些浏览器可能不认识这种语法,我们最好可以转成RGBA的形式;
  • 但是autoprefixer是不会帮助我们转换的;
  • 而postcss-preset-env就可以完成这样的功能;
npm install postcss-preset-env -D

使用 postcss-preset-env 插件来处理:

  module: {
    rules: [
      {
        // 规则使用正则表达式
        test: /\.css$/, // 匹配资源
        use: [
          // { loader: "css-loader" },
          // 注意: 编写顺序(从下往上, 从右往做, 从后往前)
          "style-loader",
          "css-loader",
          {
            loader: "postcss-loader",
            options: {
              postcssOptions: {
                plugins: [
                  require('postcss-preset-env'),
                  // 'postcss-preset-env' 简写
                ]
              }
            }
          }
        ],
        // loader: "css-loader"
      },
    ]
  }

如果 /\.css$//\.less$/ 都需要设置同样的 postcss 设置,那么可以提取成根目录文件 postcss.config.js

module.exports = {
  plugins: [
    'postcss-preset-env'
  ]
}

使用 postcss-preset-env 后, css 被做了兼容性处理:

.content {
  /* 十六进制通常是写几位 */
  color: rgba(18,52,86,0.47059);
}

:-webkit-full-screen {
  color: red;
}

:-ms-fullscreen {
  color: red;
}

:fullscreen {
  color: red;
}

.content {
  -webkit-user-select: none;
     -moz-user-select: none;
      -ms-user-select: none;
          user-select: none;
  transition: all 2s ease;
}

postcss-preset-env 是含有 autoprefixer 的效果的,所以就不需要 autoprefixer 了。

注意:当使用 @import 语法在一个 css 文件中引入另外一个 css 文件时,如果首先由 postcss-loader 处理了第一个文件,当走到 @import 引入的文件时,默认将不再使用 postcss-loader 处理,而继续使用之后的 loader 处理,如果碰到 @import 时想让 loader 处理从头再来一次,需要像下面这样写:

use: [
  // { loader: "css-loader" },
  // 注意: 编写顺序(从下往上, 从右往做, 从后往前)
  "style-loader", 
  {
    loader: "css-loader",
    options: {
      importLoaders: 1
    }
  },
  "postcss-loader"
],

importLoaders 是 css-loader 的一个属性, 用于配置 css-loader 作用于 @import 的资源之前有多少个 loader 。