Skip to content

Webpack 使用

TIP

Webpack 是一个用于现代 JavaScript 应用程序的静态模块打包工具。当 webpack 处理应用程序时,它会在内部构建一个 依赖图(dependency graph),此依赖图对应映射到项目所需的每个模块,并生成一个或多个 bundle

一 安装

1 安装

sh
npm init -y

npm i webpack webpack-cli -D

mkdir webpack.config.js

2 入口

  • 入口起点(entry point)指示 webpack 构建的入口起点
  • 默认值是 ./src/index.js,可以配置一个或多个
js
module.exports = {
  entry: "./src/index.js",
};

3 出口

  • output 属性告诉 webpack 构建的 bundle,输出存放的目录
  • 主要输出文件的默认值是 ./dist/main.js,其他生成文件默认放置在 ./dist 文件夹中
js
const { resolve } = require("path");

module.exports = {
  // 入口
  entry: "./src/index.js",
  // 出口
  output: {
    path: resolve(__dirname, "dist"),
    filename: "main.js",
  },
};

4 loader

  • loader 让 webpack 能把其他非 JS 和 JSON 模块转化为 JS 模块,以便 webpack 能识别和处理
  • loader 有 test 和 use 两个属性,前者表示匹配某个文件,后者表示如何转化
sh
npm i raw-loader -D
js
// 例如,读取.txt文件的loader配置如下
const { resolve } = require("path");

module.exports = {
  entry: "./src/index.js",
  output: {
    path: resolve(__dirname, "dist"),
    filename: "main.js",
  },
  module: {
    rules: [
      // 解析 .txt
      { test: /\.txt$/, use: "raw-loader" },
    ],
  },
};

5 插件

  • 插件用于 打包优化,资源管理,注入环境变量
bash
npm i html-webpack-plugin -D
js
const { resolve } = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin"); // 引入插件

module.exports = {
  entry: "./src/index.js",
  output: {
    path: resolve(__dirname, "dist"),
    filename: "main.js",
  },
  module: {
    rules: [
      // 解析 .txt
      { test: /\.txt$/, use: "raw-loader" },
    ],
  },
  plugins: [
    // 使用插件
    new HtmlWebpackPlugin({
      template: "./src/index.html",
    }),
  ],
};

6 模式

  • mode 模式用于区分构建环境,通常为开发环境和生产环境
  • mode 取值 development,production 具体见mode
js
module.exports = {
  mode: "development", // 当前模式为开发环境
};
  • 模式配置方式
js
// 1 没有任何配置,webpack的mode默认为production,webpack serve的mode默认为development

// package.json的执行命令配置
"scripts": {
  "build": "webpack",
  "start": "webpack serve"
},

// index.js程序中读取
console.log(process.env.NODE_ENV); // development | production

// webpack.config.js配置文件中读取
console.log('NODE_ENV',process.env.NODE_ENV); // undefined
js
// 1 命令行加 --mode用来设置模块内的process.env.NODE_ENV,配置文件读取不了

// package.json的执行命令配置
"scripts": {
  "build": "webpack --mode=production",
  "start": "webpack --mode=development serve"
},

// index.js程序中读取
console.log(process.env.NODE_ENV); // development | production

// webpack.config.js配置文件中读取
console.log('NODE_ENV',process.env.NODE_ENV); // undefined
js
// 2 命令行加 --env用来设置webpack配置文件的函数参数,模块内读取不了

// package.json的执行命令配置
"scripts": {
  "build": "webpack --mode=production",
  "start": "webpack --mode=development serve"
},

// index.js程序中读取
console.log(process.env.NODE_ENV); // development | production

// webpack.config.js配置文件中读取
console.log('NODE_ENV',process.env.NODE_ENV); // undefined

二 开发环境

1 开发服务器

sh
npm i webpack-dev-server -D
  • 配置文件
js
// webpack.config.js
module.exports = {
  // 配置静态服务器
  devServer: {
    contentBase: resolve(__dirname, "static"), // 提供静态资源目录
    writeToDisk: true, // 打包文件写入硬盘,以便于调试
    compress: true, // 是否开启gzip压缩
    port: 3000, // 端口号
    open: true, // 自动打开浏览器
  },
};
  • 启动文件
json
"scripts": {
	"start": "webpack serve"
}

2 处理 CSS

sh
npm i style-loader css-loader -D
  • 配置文件
js
// webpack.config.js
module.exports = {
  // loader
  module: {
    rules: [
      { test: /\.css$/, use: ["style-loader", "css-loader"] }, // 解析css
    ],
  },
};

3 处理 Less

sh
npm i less less-loader -D
  • 配置文件
js
// webpack.config.js
module.exports = {
  // loader
  module: {
    rules: [
      { test: /\.less$/, use: ["style-loader", "css-loader", "less-loader"] }, // 解析less
    ],
  },
};

4 处理 Sass

sh
npm i node-sass sass-loader -D
  • 配置文件
js
// webpack.config.js
module.exports = {
  // loader
  module: {
    rules: [
      { test: /\.scss$/, use: ["style-loader", "css-loader", "sass-loader"] }, // 解析sass
    ],
  },
};

5 处理图片

  • file-loader 解决 CSS 等文件中的引入图片路径问题
  • url-loader 是对 file-loader 的增强,可以配置 limit 限制图片大小,做对应处理
  • html-loader 解决 html 中引入图片路径问题
  • 安装命令
sh
npm i file-loader url-loader html-loader -D
  • 配置文件
js
// webpack.config.js
module.exports = {
  // loader
  module: {
    rules: [
      // 解析css中带有url中的图片
      {
        test: /\.(jpg|png|bmp|gif|svg)$/,
        use: [
          {
            loader: "url-loader",
            options: {
              name: "[hash:10].[ext]",
              limit: 8192, // 图片小于limit就转为base64内嵌,大于就保持原样引入
            },
          },
        ],
      },
      // 解析html中的src图片
      { test: /\.html$/, use: ["html-loader"] },
    ],
  },
};

6 babel 处理 ES6+

sh
npm i babel-loader @babel/core @babel/preset-env -D
  • 配置文件
js
// webpack.config.js
module.exports = {
  // loader
  module: {
    rules: [
      // 解析es6
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: [
          {
            loader: "babel-loader",
            options: {
              presets: [
                [
                  "@babel/preset-env",
                  // false 不对polyfill做操作,直接引入所有的polyfill 代价非常多非常大
                  /* {
										useBuiltIns: 'usage', // 按需加载polyfill
										// debug: true,
										corejs: { version: 3 }, // 指定corejs的版本号 2或者3 polyfill
										targets: { // 指定要兼容哪些浏览器
											chrome: '60',
										},
									}, */
                ],
              ],
            },
          },
        ],
      },
    ],
  },
};

7 babel 处理装饰器

  • @babel/plugin-proposal-decorators 把类和对象装饰器编译成 ES5
  • @babel/plugin-proposal-class-properties 转换静态类属性以及使用属性初始值化语法声明的属性
  • 安装命令
sh
npm i @babel/plugin-proposal-decorators @babel/plugin-proposal-class-properties -D
  • 配置文件
js
// webpack.config.js
module.exports = {
  // loader
  module: {
    rules: [
      // 解析es6
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: [
          {
            loader: "babel-loader",
            options: {
              presets: [["@babel/preset-env"]],
              // 插件-装饰器
              plugins: [
                ["@babel/plugin-proposal-decorators", { legacy: true }],
                ["@babel/plugin-proposal-class-properties", { loose: true }],
              ],
            },
          },
        ],
      },
    ],
  },
};

8 babel 处理 polyfill

sh
npm i babel-loader @babel/core @babel/preset-env -D
  • 配置文件
js
// webpack.config.js
module.exports = {
  // loader
  module: {
    rules: [
      // 解析es6
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: [
          {
            loader: "babel-loader",
            options: {
              presets: [
                [
                  "@babel/preset-env",
                  // false 不对polyfill做操作,直接引入所有的polyfill 代价非常多非常大
                  /* {
										useBuiltIns: 'usage', // 按需加载polyfill
										// debug: true,
										corejs: { version: 3 }, // 指定corejs的版本号 2或者3 polyfill
										targets: { // 指定要兼容哪些浏览器
											chrome: '60',
										},
									}, */
                ],
              ],
            },
          },
        ],
      },
    ],
  },
};

polyfill 解决方案

  • polyfill.io
  • polyfill.io 自动化的 JavaScript Polyfill 服务
  • polyfill.io 通过分析请求头信息中的 UserAgent 实现自动加载浏览器所需的 polyfills
js
// 页面头部引入js,会根据不同的浏览器下载对应兼容性polyfills
<script src="https://polyfill.io/v3/polyfill.min.js"></script>

9 处理 Eslint

sh
npm i babel-loader @babel/core @babel/preset-env -D
  • 配置文件
js
// webpack.config.js
module.exports = {
  // loader
  module: {
    rules: [
      // 解析es6
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: [
          {
            loader: "babel-loader",
            options: {
              presets: [
                [
                  "@babel/preset-env",
                  // false 不对polyfill做操作,直接引入所有的polyfill 代价非常多非常大
                  /* {
										useBuiltIns: 'usage', // 按需加载polyfill
										// debug: true,
										corejs: { version: 3 }, // 指定corejs的版本号 2或者3 polyfill
										targets: { // 指定要兼容哪些浏览器
											chrome: '60',
										},
									}, */
                ],
              ],
            },
          },
        ],
      },
    ],
  },
};
bash

# eslint
npm i eslint eslint-loader babel-eslint -D

# 第三方类库

第三方插件

npm i lodash -S

Released under the MIT License.