【记录】webpack的使用

134 阅读5分钟

一、概述

1.1 webpack的作用

提供友好的前端模块化开发支持,以及代码混淆、处理浏览器短JavaScript的兼容性、性能优化等强大的功能。

1.2 使用webpack的好处

重心可以放在实现具体的功能上,兼容问题可以不考虑交给webpack处理,提高前端开发的效率和可维护性。

1.3 举例

例如现在有有个项目使用es6的语法,在js中使用import语句导入了第三方的包。直接在浏览器中运行是会报错的。这个时候webpack就会派上用场了!


二、webpack的使用初体验

2.1 安装

先初始化一个空项目

npm init -y

npm install  npm i webpack@5.5.1 webpack-cli@4.5.0 -D

然后在根目录下创建webpack.config.js配置文件:

module.exports = {
  mode: 'development'
}
// development: 开发环境、不会对打包环境生成进行代码压缩和性能优化、打包速度快、适合开发阶段使用。  
// production: 会压缩、会优化,打包速度慢,适合发布阶段使用。 

再在package.json中配置运行命令:

"dev": "webpack" // dev这个命名是可以随便取

运行该命令后会在根目录中多出一个dist文件夹,其中有main.js就是编译后的js代码。可以在index.html中直接使用,不会有兼容性问题。

2.2 webpack.config.js配置文件

这个文件用于设置如何打包工程。
默认约定
默认入口文件是src->index.js | 默认的输出文件路径为dist-> main.js

const path = require('path')
module.exports = {
  mode: 'development',
  // mode: 'production'
  entry: path.join(__dirname, './src/index.js'), // 入口文件
  output: {
    path: path.join(__dirname, './dist'), // 输出文件名称
    filename: 'bundle.js' // 输出文件的名称 
  }
}

可以通过devServer节点来设置更多的配置项,如修改项目端口。

module.exports = {
  devServer: {
    open: true, // 自动打开浏览器
    host: '127.0.0.1', // 实时打包使用的主机地址 
    port: 80, // 端口号
  }
}

三、 webpack插件

3.1 插件的作用

让webpack使用起来更方便,举例两个常用的插件:

  • webpack-dev-server: 类似于node.js的nodemon工具,每次修改源码后就会自动打包。
  • html-webpack-plugin:自定制index.html页面的内容

3.2 安装插件

安装webpack-dev-server:

npm i webpack-dev-server@3.11.0 -D

配置装webpack-dev-server

修改package.josn文件
"dev": "webpack serve"

如果执行命令后出现报错,看看是否是webpack-cli版本不对应。
打包成功后会在本地起一个8080端口的服务器,但是直接访问这个端口不会显示index.html页面,因此就引出了html-webpack-plugin,将index.html复制一份到根目录,这样就可以直接访问到index.html。

tip: 不配置webpack-dev-server,打包后的文件会存放在实际的物理磁盘上。 配置了则存放在内存上(在根目录,但是不可见),即不会实时更新。

安装html-webpack-plugin

npm i html-webpack-plugin@4.5.0 -D

配置html-webpack-plugin

// 导入构造函数
const HtmlPlugin = require('html-webpack-plugin')
// 实例化对象
const htmlplugin = new HtmlPlugin({
  template: './src/index.html', // 模板文件
  filename: './index.html' // 存放路径
})

module.exports = {
  mode: 'development',
  plugins: [htmlplugin], // 挂载插件实例对象
}

该插件也是复制到项目的根目录中的index.html页面,也被放到了内存中,且会在复制的index.html 页面底部 自动注入打包好的bundle.js文件。


四、webpack中的loader

webpack默认只能打包处理.js结尾的模块,其他非.js后缀名结尾的模块,webpack默认是处理不了的,需要调用loader加载器才可以正常打包,否则会报错。

loader的作用: 协助webpack打包处理特定的文件模块:

  • css-loader打包处理.css相关的文件
  • less-loader打包处理.less相关的文件
  • babel-loader打包处理webpack无法处理的高级JS语法

4.1 打包处理css文件

新建一个css文件夹,并在该文件夹下创建一个index.css样式。在index.js导入(一切皆模块化,也可以导入css)

image.png

import './css/index.css'

// 安装两个
npm i style-loader@2.0.0 css-loader@5.0.1

安装完成后需要进行配置,在webpack.config.js的module->rules, 添加loader规则:

module.exports = {
  module: { // 所有巅峰文件模块的匹配规则
    rules: [ // 文件后缀名的匹配规则,test表示匹配的文件类型,use表示对应的调用的loader
      {test: /.css$/, use: ['style-loader', 'css-loader']}
    ]
  }
}

注意: use数组中指定的loader顺序是固定的; 多个loader的调用顺序是从后往前调用

4.2 打包处理less

npm i less-loader@7.1.0 less@3.12.2 -D

{test: /.less$/, use: ['style-loader','css-loader','less-loader']}

4.3 打包处理样式表中于url路径相关的文件

如果样式中存在背景图引入了图片等资源, webpack默认是处理不了这些的。

#box {
  width: 400px;
  height: 120px;
  background-color: red;
  background: url("../img/new_head.jpg");
}
// 安装对应的加载器
npm i url-loader@4.1.1 file-loader@6.2.0 -D

// 配置
      {
        test: /\.jpg|png|gif$/,
        use: ['url-loader?limit=22229']
      }
      
// limit: 这个参数是用于指定图片大小的,单位是字节byte。只要小于等于limit大小的图片,才会被转为base64格式的图片。

4.4 loader的另一种配置方式

     {
        test: /\.jpg|png|gif$/,
        use: {
          loader: 'url-loader', // 指定要调用的loader
          options: { // 指定参数项
            limit: 22229 
          }
        }
      }

4.5 babel处理高级语法

例如class类,static等关键字,这些webpack默认是处理不了的。此时就需要安装babel。

image.png

// 安装
npm i babel-loader@8.2.1 @babel/core@7.12.3 @babel/plugin-proposal-class-properties@7.12.1 -D

// 配置
     {
        test: /\.js$/,
        // exclude表示排除,不处理第三方的库
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options:{
            // 声明一个插件用于转化class中的高级语法
            plugins: ['@babel/plugin-proposal-class-properties']
          }
        }
      }

五、打包发布

开发环境下,打包生成的文件是存放在内存中的,无法获取到最终打包成的文件。且在开发环境下,打包的文件不会进行代码的压缩和性能优化。

5.1 整理打包后的文件

// 在package.json新增build命令
// mode用于指定打包模式
"build":"webpack --mode production" 

但是,这么打包出来的文件是比较杂乱的。整理dist打包文件需要进行额外的配置:

// 1. js文件统一放到js文件夹下
entry: path.join(__dirname, './src/index.js'), // 入口文件
  output: {
    path: path.join(__dirname, './dist'), // 输出文件名称
    filename: 'js/bundle.js' // 输出文件的名称 
  },
  
 // 在url-loader插件中配置
 {
        test: /\.jpg|png|gif$/,
        use: {
          loader: 'url-loader', // 指定要调用的loader
          options: { // 指定参数项
            limit: 22229 ,
            outputPath: 'image'
          }
        }
}

5.2 自动清理dist目录下的旧文件

为了在每次打包发布是自动清理掉dist目录中的旧文件,可以安装并配置clean-webpack-plugin插件。

npm i clean-webpack-plugin@3.0.0 -D

// 在入口文件index.js使用
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const cleanPlugin = new CleanWebpackPlugin()

plugins: [cleanPlugin]

5.3 Source Map

开发环境下webpack默认开启了Source Map功能。默认生成的Source Map在程序运行出错时,记录的是生成后的代码位置。导致运行时报错的位置和源代码的行数不一致。

// webpack.config.js中再添加一项配置即可
devtool: 'eval-source-map'

可以直接在控制台提示错误行的位置(仅限在开发模式中使用),并定位到具体的源代码。
在生产环境下,如果省略了dev'tool选项,则最终生成的文件中不包含Source Map。这能防止源代码通过Sorce Map的形式暴露给他人。但这不方便定位到错误代码位置,可以只定位行数不暴露源码。

devtool: 'nosources-source-map', // 只定位行数,不暴露源码
devtool: 'source-map', // 定位行数并暴露源码

六、总结

实际开发中不需要自己配置webpack,有现成的脚手架 CLI 可以一键生成webpack项目,开箱即用。但是需要webpack的基本概念。