WebPack 再入门(1)基础

263 阅读1分钟

五个核心概念

概念说明
Entry代码打包的入口
Output代码产物输出
Loader处理 js 中引入的各种资源
Plugins处理额外各种的事情,比如压缩代码等等,可以扩展各种强大的能力
Mode区别开发模式生产模式

基本使用

目的方法
处理样式文件使用 style-loader/css-loader,如果是 less 还需要 less-loader
处理 html使用 HtmlWebpackPlugin
处理图片css 中引用了图片使用 url-loader,html 中引用了图片使用 html-loader
处理其他资源file-loader

loader

loaderoptions
url-loader/.(jpg|png|gif)$/
limit: base64 处理的大小限制
esModule: 是否以 ES 模块方式处理
name: 图片产物命名方法
file-loader

devServer

方便开发,监听文件变更,自动编译,自动打开刷新页面

npx webpack-dev-server

Mode

development production

process.env.NODE_ENV

提取 CSS 成单独文件

使用插件 mini-css-extract-plugin 并使用 MiniCssExtractPlugin.loader 替换 style-loader

CSS 兼容性处理

使用 postcss-loader、postcss-preset-env

postcss-preset-env 的作用是帮助 postcss-loader 根据 package.json 中的 browerslist 配置转换成具有兼容性的 css 代码

postcss-loader 示例

{
  loader: 'postcss-loader',
  options: {
    ident: 'postcss',
    plugins: () => [
      require('postcss-preset-env')()
    ]
  }
}

browserslist 示例

{
  "browserslist": {
     "production"[
       "last 1 chrome version",
       "last 1 firefox version",
       "last 1 safari version"
     ],
     "development": [
       ">0.2%",
       "not dead",
       "not op_mini all"
     ]
  }
}

压缩 css

使用插件 optimize-css-assets-webpack-plugin

new OptimizeCssAssetsWebpackPlugin()

js 语法检查

使用 eslint eslint-loader eslint-config-arbnb-base eslint-plugin-import

package.json 配置

{
  "eslintConfig": {
    "extends": "airbnb-base"
  }
}

loader 配置

test: /\.js$/,
exclude: /node_modules/,
loader: 'eslint-loader',
options: {
  fix: true
}

使规则失效

// eslint-disable-next-line

js 兼容性处理

使用 babel-loader babel @babel/core @babel/preset-env

loader: 'babel-loader',
options: {
  presets: ['@babel/preset-env']
}

一: @babel/preset-env 基本的语法转换 二: @babel/polyfill 全量兼容语法

import '@babel/polyfill'

三: core-js 按需使用兼用处理

presets: [
  '@babel/preset-env',
  {
    useBuileIns: 'usage',
    corejs: {
      version: 3
    },
    targets: {
      chrome: '60',
      firefox: '60',
      ie: '9',
      safari: '10',
      edge: '17'
    }
  }
]

html 和 js 代码压缩

mode: production 生产环境下自动压缩 js 代码,原理是生产环境会自动加载一些 plugins

html 压缩

new HtmlWebpackPlugin({
  template: 'xxx.html',
  // 压缩配置
  minify: {
    // 移除空格
    collapseWhitespace: true,
    // 移除注释
    removeComments: true
  }
})

完整配置示例

const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCssAssetsWebpackPlugin = require("optimize-css-assets-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");

const commonCssLoader = [
  MiniCssExtractPlugin.loader,
  "css-loader",
  {
    loader: "postcss-loader",
    options: {
      ident: "postcss",
      plugins: () => [require("postcss-preset-env")()],
    },
  },
];

module.exports = {
  entry: "./src/index.js",
  output: {
    filename: "bundle.js",
    path: resolve(__dirname, "build"),
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [...commonCssLoader],
      },
      {
        test: /\.less$/,
        use: [...commonCssLoader, "less-loader"],
      },
      {
        test: /\.js$/,
        exclude: /node_modules/,
        enforce: "pre", // 优先执行
        loader: "eslint-loader",
        options: {
          fix: true,
        },
      },
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel-loader",
        options: {
          presets: [
            [
              "@babel/preset-env",
              {
                useBuiltIns: "usage",
                corejs: { version: 3 },
                targets: {
                  chrome: "60",
                },
              },
            ],
          ],
        },
      },
      {
        test: /\.(jpg|png|gif)$/,
        loader: "url-loader",
        options: {
          limit: 8 * 1024,
          name: "[hash:10].[ext]",
          outputPath: "image",
          esModule: false,
        },
      },
      {
        test: /\.html$/,
        loader: "html-loader",
      },
      {
        exclude: /\.(js|css|less|html|jpg|png|gif)/,
        loader: "file-loader",
        options: {
          outputPath: "assets",
        },
      },
    ],
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: "css/build.css",
    }),
    new OptimizeCssAssetsWebpackPlugin(),
    new HtmlWebpackPlugin({
      template: "./src/index.html",
      minify: {
        collapseWhitespace: true,
        removeComments: true,
      },
    }),
  ],
  devServer: {
    contentBase: resolve(__dirname, 'build'),
    compress: true,
    port: 3000,
    open: true,
  }
};