Skip to content

webpack 基本配置

基本配置,主要包含:

  • 拆分配置和 merge
  • 启动本地服务
  • 处理 ES6
  • 处理样式
  • 处理图片
  • (模块化)

公共配置文件 webpack.common.js

js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { srcPath, distPath } = require('./paths');
module.exports = {
  entry: path.join(srcPath, 'index'),
  module: {
    rules: [
      {
        // 处理 ES6 等
        test: /\.js$/,
        loader: ['babel-loader'],
        include: srcPath,
        exclude: /node_modules/,
      },
      // {
      //     test: /\.vue$/,
      //     loader: ['vue-loader'],
      //     include: srcPath
      // },
      // {
      //     test: /\.css$/,
      //     // loader 的执行顺序是:从后往前(知识点)
      //     loader: ['style-loader', 'css-loader']
      // },
      {
        test: /\.css$/,
        // loader 的执行顺序是:从后往前
        loader: ['style-loader', 'css-loader', 'postcss-loader'], // 加了 postcss
      },
      {
        test: /\.less$/,
        // 增加 'less-loader' ,注意顺序
        loader: ['style-loader', 'css-loader', 'less-loader'],
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: path.join(srcPath, 'index.html'),
      filename: 'index.html',
    }),
  ],
};

开发环境配置 webpack.dev.js

js
const path = require('path');
const webpack = require('webpack');
const webpackCommonConf = require('./webpack.common.js');
const { smart } = require('webpack-merge');
const { srcPath, distPath } = require('./paths');
module.exports = smart(webpackCommonConf, {
  mode: 'development',
  module: {
    rules: [
      // 直接引入图片 url
      {
        test: /\.(png|jpg|jpeg|gif)$/,
        use: 'file-loader',
      },
    ],
  },
  plugins: [
    new webpack.DefinePlugin({
      // window.ENV = 'development'
      ENV: JSON.stringify('development'),
    }),
  ],
  devServer: {
    port: 8080,
    progress: true, // 显示打包的进度条
    contentBase: distPath, // 根目录
    open: true, // 自动打开浏览器
    compress: true, // 启动 gzip 压缩
    // 设置代理
    proxy: {
      // 将本地 /api/xxx 代理到 localhost:3000/api/xxx
      '/api': 'http://localhost:3000',
      // 将本地 /api2/xxx 代理到 localhost:3000/xxx
      '/api2': {
        target: 'http://localhost:3000',
        pathRewrite: {
          '/api2': '',
        },
      },
    },
  },
});

生成环境配置 webpack.prod.js

js
const path = require('path');
const webpack = require('webpack');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const webpackCommonConf = require('./webpack.common.js');
const { smart } = require('webpack-merge');
const { srcPath, distPath } = require('./paths');
module.exports = smart(webpackCommonConf, {
  mode: 'production',
  output: {
    filename: 'bundle.[contentHash:8].js', // 打包代码时,加上 hash 戳
    path: distPath,
    // publicPath: 'http://cdn.abc.com'  // 修改所有静态文件 url 的前缀(如 cdn 域名),这里暂时用不到
  },
  module: {
    rules: [
      // 图片 - 考虑 base64 编码的情况
      {
        test: /\.(png|jpg|jpeg|gif)$/,
        use: {
          loader: 'url-loader',
          options: {
            // 小于 5kb 的图片用 base64 格式产出
            // 否则,依然延用 file-loader 的形式,产出 url 格式
            limit: 5 * 1024,
            // 打包到 img 目录下
            outputPath: '/img1/',
            // 设置图片的 cdn 地址(也可以统一在外面的 output 中设置,那将作用于所有静态资源)
            // publicPath: 'http://cdn.abc.com'
          },
        },
      },
    ],
  },
  plugins: [
    new CleanWebpackPlugin(), // 会默认清空 output.path 文件夹
    new webpack.DefinePlugin({
      // window.ENV = 'production'
      ENV: JSON.stringify('production'),
    }),
  ],
});

配置文件还引入了一个 paths.js 的文件

js
const path = require('path');
const srcPath = path.join(__dirname, '..', 'src');
const distPath = path.join(__dirname, '..', 'dist');
module.exports = {
  srcPath,
  distPath,
};

想要使用 babel 功能,还需要在根目录增加 .babelrc 文件

js
{
    "presets": ["@babel/preset-env"],
    "plugins": []
}

当处理 css 时,为了保持兼容性,自动前缀,引入 postcss-loader 模块启用 autoprefixer 功能,在根目录新增 postcss.config.js 文件

js
module.exports = {
  plugins: [require('autoprefixer')],
};

最后,看下完整的 package.json 配置

js
{
  "name": "webpack-demo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "devBuild": "webpack --config build-base-conf/webpack.dev.js",
    "dev": "webpack-dev-server --config build-base-conf/webpack.dev.js",
    "build": "webpack --config build-base-conf/webpack.prod.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@babel/core": "^7.7.4",
    "@babel/preset-env": "^7.7.4",
    "autoprefixer": "^9.7.3",
    "babel-loader": "^8.0.6",
    "clean-webpack-plugin": "^3.0.0",
    "css-loader": "^3.2.1",
    "file-loader": "^5.0.2",
    "happypack": "^5.0.1",
    "html-webpack-plugin": "^3.2.0",
    "less": "^3.10.3",
    "less-loader": "^5.0.0",
    "mini-css-extract-plugin": "^0.8.0",
    "optimize-css-assets-webpack-plugin": "^5.0.3",
    "postcss-loader": "^3.0.0",
    "style-loader": "^1.0.1",
    "terser-webpack-plugin": "^2.2.2",
    "url-loader": "^3.0.0",
    "webpack": "^4.41.2",
    "webpack-cli": "^3.3.10",
    "webpack-dev-server": "^3.9.0",
    "webpack-merge": "^4.2.2",
    "webpack-parallel-uglify-plugin": "^1.1.2"
  },
  "dependencies": {
    "lodash": "^4.17.15",
    "moment": "^2.24.0"
  }
}

基于 MIT 许可发布