:::info 💡 通常css为了兼容各个浏览器,不得已会添加样式前缀,如兼容低版本chrome需加前缀-webkit-,浏览器之多兼容起来极为麻烦,并且还有可能遗漏某些兼容,导致未知的问题潜伏,所以可以通过webpack统一,标准的帮我们做这些工作。 :::

问题1:怎么设定需要兼容那些浏览器呢?

比如有一个项目要求兼容IE8,要怎么去设置让webpack来知道css要兼容到IE8。

1.caniuse.com

这里就要用到一个网站:caniuse.com ,在该网站找到 Browser usage table 进入,就可以看到各大浏览器所占市场份额。
image.png
通过该网站可以看到IE8的市场占有率为0.04%,chrome98市场占有率为15.53%。

2.不要担心这是某个野鸡网站,webpack兼容浏览器的标准就是从这里获得的。

在我们安装webpack之后,会自动安装一个browserslist,可以在项目的node_modules/browserslist/index.js找到关联caniuse网站的相关内容。下面在进行一下测试。

image.png

3.知道我们要兼容的浏览器所占市场份额之后,开始配置要兼容的浏览器

Browserslist的配置可以写在package.json的browserslist字段里也可以写在browserslistrc文件里。
package.json示例:

  1. {
  2. + "browserslist": [
  3. + "> 1%",//大于1%市场份额的浏览器
  4. + "last 2 versions"//最新的2个chrome版本
  5. + "not dead"//没有死掉的 24个月不更新为死掉的
  6. + ]
  7. }

browserslistrc文件示例:

  1. webpacktest
  2. |- /node_modules
  3. |- /src
  4. |- index.js
  5. + |- .browserslistrc
  6. |- package-lock.json
  7. |- package.json
  8. |- webpack.config.js
  1. + > 1% //大于1%市场份额的浏览器
  2. + last 2 versions //最新的2个chrome版本
  3. + not dead //没有死掉的 24个月不更新为死掉的

配置文件内容说明

例子 说明
> 1% 全球超过1%人使用的浏览器
> 5% in US 指定国家使用率覆盖
last 2 versions 所有浏览器兼容到最后两个版本根CanIUse.com追踪的版本
Firefox ESR 火狐最新版本
Firefox > 20 指定浏览器的版本范围
not ie <=8 方向排除部分版本
Firefox 12.1 指定浏览器的兼容到指定版本
unreleased versions 所有浏览器的beta测试版本
unreleased Chrome versions 指定浏览器的测试版本
since 2013 2013年之后发布的所有版本

注意:.browserslistrc文件和package.json中browserslist的两者不可同时存在,报错信息:

image.png

4.测试一下

  1. npx browserslist

NPX
结果为:
image.png
结果有点多,让我们修改一下.browserslistrc文件或者pakeage.json中的配置,以.browserslistrc文件举例。

  1. - > 1%
  2. - last 2
  3. - not dead
  4. + last 2 chrome versions
  1. npx browserslist

image.png
浏览器返回数量减少,只有chrome最新的两个版本,测试没问题,这样我们就可以按需要去兼容你想兼容的浏览器了。

问题2:设定要兼容那些浏览器之后,webpack要怎么去做配置。

:::info 当设置好要兼容那些浏览器之后,让webpack开始做兼容工作
webpack处理兼容用到了postcss-loader,其内部使用到了postcss,postcss-preset-env是postcss常用功能性的集合。 :::

1.下载

  1. npm install postcss-loader postcss postcss-preset-env --save-dev

2.配置

  1. const path = require('path');
  2. module.exports = {
  3. entry: './src/index.js',
  4. output: {
  5. filename: 'index.js',
  6. path: path.resolve(__dirname, 'dist'),
  7. },
  8. module: {
  9. rules: [
  10. {
  11. test: /\.css$/,
  12. use: [
  13. 'style-loader',
  14. 'css-loader',
  15. + {
  16. + loader: 'postcss-loader',
  17. + options: {
  18. + postcssOptions: {
  19. + plugins:[
  20. + require('postcss-preset-env')
  21. + ]
  22. + }
  23. + }
  24. + }
  25. ]
  26. },
  27. {
  28. test: /\.less$/,
  29. use: [
  30. 'style-loader',
  31. 'css-loader',
  32. + {
  33. + loader: 'postcss-loader',
  34. + options: {
  35. + postcssOptions: {
  36. + plugins:[
  37. + require('postcss-preset-env')
  38. + ]
  39. + }
  40. + }
  41. + },
  42. 'less-loader'
  43. ]
  44. }
  45. ]
  46. }
  47. };

注意点:
1.postcss-loader处理的是css文件,如果使用到了css预编译器,less举例,应在less-loader将.less文件处理成.css文件之后,在执行postcss-loader,代码书写顺序如上。
2.css文件中使用到@import时候,被引入的文件没有经过postcss-loader处理,这时候可以给css-loader设置importLoader:1 表示希望在css-loader编译时遇到 @import 语法时,将会往后退几个loader重新处理,这里表示一个也就是要经过postcss-loader的处理

  1. const path = require('path');
  2. module.exports = {
  3. entry: './src/index.js',
  4. output: {
  5. filename: 'index.js',
  6. path: path.resolve(__dirname, 'dist'),
  7. },
  8. module: {
  9. rules: [
  10. {
  11. test: /\.css$/,
  12. use: [
  13. 'style-loader',
  14. - 'css-loader',
  15. + {
  16. + loader: 'css-loader',
  17. + importLoader: 1
  18. + },
  19. {
  20. loader: 'postcss-loader',
  21. options: {
  22. postcssOptions: {
  23. plugins:[
  24. require('postcss-preset-env')
  25. ]
  26. }
  27. }
  28. }
  29. ]
  30. },
  31. {
  32. test: /\.less$/,
  33. use: [
  34. 'style-loader',
  35. - 'css-loader',
  36. + {
  37. + loader: 'css-loader',
  38. + importLoader: 1
  39. + },
  40. {
  41. loader: 'postcss-loader',
  42. options: {
  43. postcssOptions: {
  44. plugins:[
  45. require('postcss-preset-env')
  46. ]
  47. }
  48. }
  49. },
  50. 'less-loader'
  51. ]
  52. }
  53. ]
  54. }
  55. };

3.打包

  1. npm run build

4.查看

在浏览器中打开引用打包后js文件的html,打开控制台,在element的head中找到style-loader添加的style。
image.png
如果没有出现兼容的css样式,请在.browserslist中降低要兼容的浏览器版本。

  1. - > 1%
  2. + > 0.001%

5.优化

:::tips 可以看到第二步 ‘配置’ 添加两个相同的代码块,事实上我们可以封装起来,使用PostCSS 本身的 配置文件。postcss.config.js :::

  1. webpacktest
  2. |- /node_modules
  3. |- /src
  4. |- index.js
  5. |- .browserslistrc
  6. |- package-lock.json
  7. |- package.json
  8. + |- postcss.config.js
  9. |- webpack.config.js
  1. + module.exports = {
  2. + plugins: [
  3. + [
  4. + 'postcss-preset-env',
  5. + {
  6. + // 其他选项
  7. + },
  8. + ],
  9. + ],
  10. + };

有了postcss.config.js文件,我们去优化原有的webpack.config.js

  1. const path = require('path');
  2. module.exports = {
  3. entry: './src/index.js',
  4. output: {
  5. filename: 'index.js',
  6. path: path.resolve(__dirname, 'dist'),
  7. },
  8. module: {
  9. rules: [
  10. {
  11. test: /\.css$/,
  12. use: [
  13. 'style-loader',
  14. 'css-loader',
  15. - {
  16. - loader: 'postcss-loader',
  17. - options: {
  18. - postcssOptions: {
  19. - plugins:[
  20. - require('postcss-preset-env')
  21. - ]
  22. - }
  23. - }
  24. - }
  25. + 'postcss-loader'
  26. ]
  27. },
  28. {
  29. test: /\.less$/,
  30. use: [
  31. 'style-loader',
  32. 'css-loader',
  33. - {
  34. - loader: 'postcss-loader',
  35. - options: {
  36. - postcssOptions: {
  37. - plugins:[
  38. - require('postcss-preset-env')
  39. - ]
  40. - }
  41. - }
  42. - },
  43. + 'postcss-loader'
  44. 'less-loader'
  45. ]
  46. }
  47. ]
  48. }
  49. };

Loader 将会在打包时自动搜索postcss.config.js配置文件。
ok,postcss的公共配置文件就设置好了。再次打包。

扩展

也可以通过webpack.config.js中的target来设置打包后的最终运行环境

文档:
target概念:https://webpack.docschina.org/concepts/targets/
target选项:https://webpack.docschina.org/configuration/target#browserslist