前端工具 | Webpack (构建工具)

140 阅读5分钟

Webpack

存在的问题

  1. 兼容性问题:浏览器可能无法解析 ESM 模块化代码。
  2. 模块过多的加载问题: 一个模块对浏览器来说就是一个文件,模块太多则需要频繁向服务器发送请求。

构建工具: 将多个模块打包成一个文件,可以将使用 ESM 规范编写的代码转换为旧的 JS 语法,解决了上面两个问题。

基本使用

  1. 初始化项目 npm int -y

  2. 安装依赖 webpack、webpack-cil(支持命令行使用)

    • npm add -D webpack webpack-cil
    • -D:表示我安装的是一个开发依赖(devDependencies) ,webpack 并非项目运行刚需,而是只在项目开发阶段有用。
  3. 在目录下创建子目录 src 和 dist,在 src 里编写代码

  4. 打包项目 npm webpack,打包后的文件会放到 dist 目录

  5. 做如下配置后,npm build 就相当于 npm webpack

注: webpack 是按需打包的,引入了但没有执行的东西也不会打包进去。

webpack.config

//webpack.config.js 
//...
module.exports = {
  mode:"development" //生产or开发模式
  entry: ...,//入口文件
  output: ...,//输出文件
  module: ...,//loader
  plugins: ...,//插件
};

(1)mode:production生产模式,development开发模式,none

一般都不改的,约定优于配置

(2)entry:打包的主文件(入口文件)

entry: './src/file_1.js'

entry: { //这里的main和adminMain用于output里的[name]
  main: './src/file_1.js',
  adminMain:'./src/file_2.js'
}

entry: ['./src/file_1.js', './src/file_2.js']

(3)output:打包后文件输出位置

output: {
  filename: 'bundle.js',//打包后的文件名
  clean:true, //先把打包目录清空再打包
}

output: {
  filename: '[name].js',//[name]是entry里的main和adminMain
  path: __dirname + '/dist',//指定打包的目录(绝对路径),默认是dist
}

(4)module:配置webpack的loader

Loader(加载器)

webpack 本身仅能处理 js 文件. 通过 loader 可以对 webpack 进行扩展使其具备编译其他类型文件的能力。

  • 样式相关的:style-loader 、css-loader、less-loader、sass-loader、postcss-loader、stylus-loader
  • 编译相关的:babel-loader、ts-loader

css-loader

npm install style-loader css-loader -D

module: {
    rules: [
      {
        test: /.css$/i,
        use: ["style-loader", "css-loader"],
      },
    ],
  }

css-loader 将 css 代码转成 JS(CSS 对象),style-loader 则负责将 CSS 对象转换为可插入 HTML 中的 style 标签。所以二者的顺序不能反

处理图片

不需要安装 loader,直接配置

{
  test: /.(png|svg|jpg|jpeg|gif)$/i,
	type: "asset/resource"
}

less-loader

npm install less less-loader -D

module: {
  rules: [
    {
      test: /.less$/i,
      use: [
        "style-loader",
        "css-loader",
        "less-loader",
      ],
    },
  ],
    }

babel-loader

兼容性问题,比如老掉牙的浏览器不支持 ES6 新特性语法。

通过 babel 编译器把新特性代码转成旧特性代码。

在 webpack 打包时使用 babel,就要用 babel-loader。

1、安装

npm install -D babel-loader @babel/core @babel/preset-env

@babel/core:babel 的核心库

@babel/preset-env:bebel 的预设,在 babel 内部,针对于不同的转换也会有不同的插件,例如普通函数和箭头函数需要一个 babel 插件,let 和 var 需要一个插件......babel/preset 把常用的 babel 插件都给我们准备好了。

2、配置 loader

module: {
  rules: [
    {
      test: /.m?js$/,
      exclude: /(node_modules|bower_components)/,  //这几个目录的文件不予处理
      use: {
        loader: 'babel-loader',
        options: {
          presets: ['@babel/preset-env']
        }
      }
    }
  ]
}

3、配置 babel

在 package.json 中设置兼容列表(大部分情况下不用管)

...
"script":{...},
"dependencies":{...},
"browserslist":[
  "default",
  "ie 6-8"
]

Plugin(插件)

插件同样可以扩展webpack的功能(loader 只负责处理编译相关的问题)。

HtmlWebpackPlugin:在构建项目时帮我在打包目录自动生成 html 网页

npm install html-webpack-plugin -D

//webpack.config.js 
const HtmlWebpackPlugin = reuire("html-webpack-plugin")

module.exports = {
  //......
	modeules{...},	
	plugins: [
    new HtmlWebpackPlugin({
      title: "html的title",//指定生成的html文件的title
      template:"./src/index.html" //生成的html以这个页面为模板
    })
	]
}

实时自动 build

方法一:npm webpack --watch

可在配置文件里配置 "script":{...,"watch":"webpack --watch"},那么直接 npm watch

方法二:webpack 开发服务器

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

启动:npm webpack serve --open

--open:启动后自动在浏览器上打开

可在 package.json 配置文件里配置命令后,直接 npm dev

//package.json
//...
"script":{
  "build":"webpack",
  "watch":"webpack --watch",
  "dev":"webpack serve --open",  
}

注意:使用 webpack 服务器的时候,服务器是可以自动更新实时显示,但是本地打包目录里的文件还是死的,所以开发完毕后要部署了,记得要手动 build 一下。

sourceMap

项目部署运行的是打包后的代码的。但是若想在浏览器命令行中调试代码,打包后的代码由于被极度压缩精简,几乎没有可读性。

sourceMap 将源码和编译后的代码做了一个映射,那么我们在浏览器调试的时候就可以看到源码的结构

module.exports = {
  //......
  modeules:{...},	
  plugins: [...],
  devtool:"inline-source-map"
}

Vite

vite 和 webpack

相较于Webpack,Vite 更快。

  1. 在开发环境中,webpack先编译构建再启动,Vite直接先给你用 原生 ES 模块(ESM) 的方式启动(冷启动快),再按需编译(热更新快,只有修改的模块才会被重新编译)。
  2. 在项目部署时,依然会正常的对项目进行打包工作。

相较于Webpack,Vite更易于使用。

  1. 开箱即用,在Vite中直接开启了各种常用功能,如CSS、CSS预处理器、资源加载器等都已经默认支持,我们无需再做单独配置,只需根据需要安装依赖即可。
  2. 同时,vite也可以通过配置文件来做一些特殊的配置或引入插件等。

安装使用

自动创建项目并安装 Vite:npm create vite@latest

这行命令后,根据提示来选择项目的配置,它会给你生成好 package.json 等配置文件。

## 1.创建命令
npm create vue@latest

## 2.具体配置
## 配置项目名称
√ Project name: vue3_test
## 是否添加TypeScript支持
√ Add TypeScript?  Yes
## 是否添加JSX支持
√ Add JSX Support?  No
## 是否添加路由环境
√ Add Vue Router for Single Page Application development?  No
## 是否添加pinia环境
√ Add Pinia for state management?  No
## 是否添加单元测试
√ Add Vitest for Unit Testing?  No
## 是否添加端到端测试方案
√ Add an End-to-End Testing Solution? » No
## 是否添加ESLint语法检查
√ Add ESLint for code quality?  Yes
## 是否添加Prettiert代码格式化
√ Add Prettier for code formatting?  No

手动 npm install 安装依赖

npm vite 启动开发服务器

npm vite build 打包

注意,Vite 打包也是以 ESM 模块化的形式打包的,而这种形式打包的代码只能在服务器上运行,所以本地无法预览。

可以通过 npm vite preview 预览打包后的代码

script 命令

{
  "scripts": {
    "dev": "vite", // 启动开发服务器,别名:`vite dev`,`vite serve`
    "build": "vite build", // 为生产环境构建产物
    "preview": "vite preview" // 本地预览生产构建产物
  }
}

script 中配置好命令后,就可以通过 npm dev 来启动开发服务器,开发完毕使用 npm build 来对项目进行打包。

vite.config

兼容性处理插件npm add -D @vitejs/plugin-legacy

// vite.config.js
import legacy from '@vitejs/plugin-legacy'
import { defineConfig } from 'vite'
//defineConfig要不要都行,但是把配置写里面的话就会有提示
export default defineConfig({
  plugins: [
    legacy({
      targets: ['defaults', 'not IE 11'],
    }),
  ],
})

和 webpack 不同,vite 需要用 es6 的模块化规范向外暴露。

在兼容性处理上,webpack 只打包一个兼容处理后的文件,而 vite 打包两个文件,一个是源码文件,一个是兼容处理后的文件。如果浏览器支持模块化代码,则引入源码文件,反之则引入兼容处理后的文件。