「Webpack 基础」常用配置解读

1,162 阅读5分钟

作为一个大前端开发,离不开webpack打包,熟悉甚至精通webpack打包是必须的。由于webpack比较重要,内容比较多,我准备写一个webpack系列的文章进行解读,本篇主要是解读常用的基础配置,其他系列文章:

安装 webpack

### 安装最新版本
npm install --save-dev webpack

### 安装指定版本
npm install --save-dev webpack@<version>

如果使用 webpack 4+ 版本,还需要安装webpack-cli

npm install --save-dev webpack-cli

package.json 添加一个 npm 脚本(npm script)

"scripts": {
   "build": "webpack"
}

常用配置项

1. mode

设置打包环境,production为生产环境,development为开发环境。可以在不同环境配置不同打包需求,如在生产环境中,尽量提升打包速度,减少包体积等,在开发环境增加必要的调试信息。

module.exports = {
  mode: process.env.NODE_ENV === 'production' ? 'production' : 'development',
};

2. devtool

  • 为了更容易地追踪错误和警告,JavaScript 提供了 source map 功能,将编译后的代码映射回原始源代码。

  • 根据不同环境配置不同的source map。对于开发环境,通常希望更快速的 source map,需要添加到 bundle 中以增加体积为代价,但是对于生产环境,则希望更精准的 source map,需要从 bundle 中分离并独立存在。具体可以参看 devtool

3. entry

打包的入口文件,可以是字符串/对象/数组

  • 字符串形式,项目中只有一个打包入口文件时,使用这种形式,如:
module.exports = {
  entry: './src/index.js',
};
  • 对象形式,项目中有多个打包入口文件时,使用这种形式,入口文件随意命名,如:
module.exports = {
  entry: {
    a: './src/entry-a',
    b: ['./src/entry-b1', './src/entry-b2'],
  },
};
  • 数组形式
module.exports = {
  entry: ['./src/entry1', './src/entry2'],
};

4. output

  • path

path.resolve(__dirname, 'dist')表示绝对路径

  • fileName

出口文件动态变化: [name].bundle.js

module.exports = {
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].bundle.js',
  },
};

5. module

webpack 可以使用 loader 来预处理文件。这允许你打包除 JavaScript 之外的任何静态资源。可以使用 Node.js 来很简单地编写自己的 loader。

5.1 加载 js 资源

  • 使用 babel-loader 加载 ES2015+ 代码,然后使用 Babel 转译为 ES5,React 项目中,还需要安装@babel/preset-react
npm install --save-dev babel-loader @babel/core @babel/preset-env @babel/preset-react

在 webpack 配置对象中,需要添加 babel-loader 到 module 的 loaders 列表中,像下面这样:

module.exports = {
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /(node_modules)/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env', '@babel/preset-react'],
            plugins: ['@babel/plugin-proposal-class-properties'],
          },
        },
      },
    ],
  },
};

5.2 加载样式

为了从 JavaScript 模块中 import 一个 CSS 文件,你需要在 module 配置中 安装并添加 style-loadercss-loaderpostcss-loader(css 自动加上兼容性前缀)

  • 安装style-loadercss-loaderpostcss-loaderpx2rem-loader
npm install --save-dev style-loader css-loader postcss-loader px2rem-loader

webpack.config.js中添加配置

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          'style-loader',
          'css-loader',
          'postcss-loader',
          {
            loader: 'px2rem-loader', // 进行移动端适配
            options: {
              remUni: 75, // 按设计稿750的十分之一计算
              remPrecision: 8, // 计算的精确度到小数点后8位
            },
          },
        ],
      },
    ],
  },
};

webpack 根据正则表达式,来确定应该查找哪些文件,并将其提供给指定的 loader。在这种情况下,以 .css 结尾的全部文件,都将被提供给 style-loader 和 css-loader。

关于打包css样式的,可以详见我的另一片文章: Webpack打包配置解读- CSS 样式篇

5.3 加载图片

假想,现在我们正在下载 CSS,但是我们的背景和图标这些图片,要如何处理呢?使用 file-loader或者url-loader(url-loader 在文件大小(单位 byte)低于指定的限制时,可以返回一个 DataURL) ,我们可以轻松地将这些内容混合到 CSS 中:

npm install --save-dev file-loader

webpack.config.js中配置file-loader

module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|svg|jpg|gif)$/,
        use: ['file-loader'],
      },
    ],
  },
};
  • 当你 import MyImage from './my-image.png',该图像将被处理并添加到 output 目录,并且 MyImage 变量将包含该图像在处理后的最终 url。
  • 当使用 css-loader 时,如上所示,你的 CSS 中的 url('./my-image.png') 会使用类似的过程去处理。loader 会识别这是一个本地文件,并将 './my-image.png' 路径,替换为输出目录中图像的最终路径。
  • html-loader 以相同的方式处理 <img src="./my-image.png" />

5.4 加载字体

file-loaderurl-loader 可以接收并加载任何文件,然后将其输出到构建目录

调整webpack.config.js文件

module.exports = {
  module: {
    rules: [
      {
        test: /\.(woff|woff2|eot|ttf|otf)$/,
        use: ['file-loader'],
      },
    ],
  },
};

5.5 按需加载 js 资源

bundle-loader

参考 React-router4 使用 bundle-loader 实现按需加载(code-splitting)

6. plugins

plugins 选项用于以各种方式自定义 webpack 构建过程。webpack 附带了各种内置插件,可以通过 webpack.[plugin-name] 访问这些插件。请查看这个页面获取插件列表和对应文档,但请注意这只是其中一部分,社区中还有许多插件。

6.1 设定 HtmlWebpackPlugin

HtmlWebpackPlugin简化了 HTML 文件的创建,以便为你的 webpack 包提供服务。这对于在文件名中包含每次会随着编译而发生变化哈希的 webpack bundle 尤其有用。

安装:

npm install --save-dev html-webpack-plugin

调整webpack.config.js文件

const HtmlWebpackPlugin = require('html-webpack-plugin');
 module.exports = {
    plugins: [
      new HtmlWebpackPlugin({
        template: path.join(__dirname, './public/index.html'),
        projectName: require('./package.json').name, // 项目名
      }),
    ];
 }

HtmlWebpackPlugin会默认生成 index.html 文件,把我们的原来的替换

6.2 清理 /dist 文件夹

通常,在每次构建前清理 /dist 文件夹,是比较推荐的做法,因此只会生成用到的文件。clean-webpack-plugin

安装clean-webpack-plugin

npm install --save-dev clean-webpack-plugin
const CleanWebpackPlugin = require('clean-webpack-plugin');
 module.exports = {
    plugins: [
       new CleanWebpackPlugin(path.resolve(__dirname,'dist')),
    ];
 }

6.3 Split CSS

MiniCssExtractPlugin将 CSS 提取为独立的文件的插件,对每个包含 css 的 js 文件都会创建一个 CSS 文件,支持按需加载 css 和 sourceMap

只能用在 webpack4 中,对比另一个插件 ExtractTextPlugin优点:

  • 异步加载
  • 不重复编译,性能更好
  • 更容易使用
  • 只针对 CSS

安装

npm install --save-dev mini-css-extract-plugin

修改webpack.config.js的配置

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

module.exports = {
  plugins: [
    new MiniCssExtractPlugin({
      // 类似 webpackOptions.output里面的配置 可以忽略
      filename: '[name].css',
      chunkFilename: '[id].css',
    }),
  ],
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
            options: {
              // 这里可以指定一个 publicPath
              // 默认使用 webpackOptions.output中的publicPath
              publicPath: '../',
            },
          },
          'css-loader',
        ],
      },
    ],
  },
};

7. devServer

配置地本服务器,webpack-dev-server是一个轻量级的服务器,开发环境中使用,可以实现热重载

安装webpack-dev-server

npm install webpack-dev-server --save-dev

启动webpack-dev-server

npm run webpack-dev-server

修改webpack.config.js的配置

module.exports = {
  devServer: {
    open: true,
    port: 5168, // 设置端口号,默认8080
  },
};

结语

如果你也是一个对投资理财感兴趣的程序员,欢迎关注我的公众号「谷底飞龙」,一起成为技术界的投资大佬吧。