从零配置webpack 5 + React脚手架(三)

1,017 阅读3分钟

配置 PostCSS

postcss 一种对 css 编译的工具,类似 babel 对 js 的处理。

CSS 规则添加特定厂商的前缀。 Autoprefixer 自动获取浏览器的流行度和能够支持的属性,并根据这些数据帮你自动为 CSS 规则添加前缀。 postcss 只是一个工具,本身不会对 css 一顿操作,它通过插件实现功能,autoprefixer 就是其一。

安装 postcss

npm install postcss postcss-loader autoprefixer --save-dev

project

  my-project
  |- config
    |- webpack.common.config.js
    |- webpack.dev.config.js
    |- webpack.prod.config.js
  |- node_modules
  |- public
    |- index.html
  |- src
    |- app.js
  |- package.json
+ |- postcss.config.js

配置 postcss.config.js

module.exports = {
  plugins: [
    require('autoprefixer')({
      overrideBrowserslist: [
        'Android 4.1',
        'iOS 7.1',
        'Chrome > 31',
        'ff > 31',
        'ie >= 8',
      ],
    }),
  ],
};

webpack.dev.config.js

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

src/app.less

.box {
  .box1 {
    display: flex;
    justify-content: center;
    background-color: #ccc;
  }
  .box2 {
    background-color: #ff0;
  }
}

执行 npm start 控制台看 css 样式,是否加上了浏览器前缀 image.png webpack.prod.config.js

  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          MiniCssExtractPlugin.loader,
          "css-loader",
          'postcss-loader',
        ]
      },
      {
        test: /\.less$/,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
          'postcss-loader',
          'less-loader'
        ]
      },
      {
        test: /\.(sass|scss)$/,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
          'postcss-loader',
          'sass-loader'
        ]
      }
    ]
  },

执行 npm run build 浏览器打开 dist 目录下的 index.html,控制台看 css 样式,是否加上了浏览器前缀

添加图片的 loader

url-loader 功能类似于 file-loader, 但是在文件大小(单位为字节)低于指定的限制时,可以返回一个 DataURL。

安装 url-loader

注意:url-loader 依赖于 file-loader,所以两个 loder 都要安装

npm install file-loader url-loader --save-dev

webpack.common.config.js

module: {
  rules: [
    {
      test: /\.(png|jpe?g|gif)$/i,
      loader: 'url-loader',
      options: {
        name: '[name].[ext]',
        outputPath: 'images',
        limit: 8192,
      },
    },
  ],
},
  • 后缀为 jpg,png,gif 的文件,使用 url-loader 进行预处理;
  • options 中的[name].[ext]表示,输出的文件名为 原来的文件名;
  • outputPath 是输出到 dist 目录下的路径,即 dist/images;
  • limit: 8192,指定文件的最大体积(以字节为单位)。 如果文件体积等于或大于限制,默认情况下将使用 file-loader 并将所有参数传递给它。若是小于了 8kb,将图片打包成 base64 的图片格式插入到 bundle.js 文件中,这样做的好处是,减少了 http 请求,但是如果文件过大,js 文件也会过大,得不偿失,这是为什么有 limit 的原因。(但是,DataURL 形式的图片不会被浏览器缓存,这是另外一个话题了下次聊)

project

  my-project
  |- src
+   |- images
+     |- 01.png

src/app.js

import React, { Component } from 'react';
import './app.less';
import BJImage from './images/01.png';

class App extends Component {
  componentDidMount() {
    let element = document.getElementById('box2');
    let myImage = new Image();
    myImage.src = BJImage;
    element.appendChild(myImage);
  }
  render() {
    return (
      <>
        <div className="box">
          <div className="box1">my-project!!!----1</div>
          <div id="box2"></div>
        </div>
      </>
    );
  }
}

export default App;

执行 npm start 图片是不是展示出来了。

配置 source-map

配置 source-map 便于开发调试。选择一种 source map 格式来增强调试过程。不同的值会明显影响到构建(build)和重新构建(rebuild)的速度。

webpack.dev.config.js

module.exports = merge(common, {
  devtool: 'eval-cheap-module-source-map',
})

你可以打个console.log试试, image.png image.png

配置 resolve.alias

webpack.common.config.js

module.exports = {
  resolve: {
    extensions: ['.js', '.jsx', '.json', '.less', '.scss'],
    modules: [ path.resolve(__dirname, '../src'), 'node_modules' ],
    alias: {
      _components: path.join(__dirname, '../src/components'),
      _images: path.join(__dirname, '../src/images'),
      _pages: path.join(__dirname, '../src/pages'),
      _util: path.join(__dirname, '../src/util'),
      _mock: path.join(__dirname, '../src/mock'),
    }
  },
}
  • extensions: 如果有多个文件有相同的名字,但后缀名不同,webpack 会解析列在数组首位的后缀的文件 并跳过其余的后缀。使用此选项会 覆盖默认数组,这就意味着 webpack 将不再尝试使用默认扩展来解析模块。
  • modules: 如果你想要添加一个目录到模块搜索目录,此目录优先于 node_modules/ 搜索。
  • alias: 创建 import 或 require 的别名,来确保模块引入变得更简单。例如,一些位于 src/ 文件夹下的常用模块

配置好后,例如images文件就可以如下形式引入了。

src/app.js

import React, { Component } from 'react';
import './app.less';
- import BJImage from './images/01.png';
+ import BJImage from '_images/01.png';

class App extends Component {
  componentDidMount() {
    let element = document.getElementById('box2');
    let myImage = new Image();
    myImage.src = BJImage;
    element.appendChild(myImage);
  }
  render() {
    return (
      <>
        <div className="box">
          <div className="box1">my-project!!!----1</div>
          <div id="box2"></div>
        </div>
      </>
    );
  }
}

export default App;

这一系列文章就算是结束了,其实webpack还有很多配置,大家可以按照自己的开发需求参考webpack官网可自行配置,这个系列文章主要进行了一些简单的配置。

完整的配置代码