日期:2024年5月19日

打包工具

Node.js的出现使js得以在服务器中运行,模块化的引入使js在编写大型应用时更加的得心应手。但是我们毕竟还是前端工程师,主战场还是位于浏览器,换句话说,我们要回来写网页了!

习惯了npm包管理器,我们便不再愿意去四处寻找下载js文件。习惯了模块化,我们也不想在使用script标签去引入外部脚本。正所谓曾经沧海难为水!但是node是编写服务器代码的,npm也是作为它配套的包管理器而存在的!要怎么样才能将它用到前端项目中呢?

要想达到这个目的,我们便需要一个新的东西 —— 打包工具。打包工具,顾名思义就是一个用来对代码打包的工具。那么为什么要对代码进行打包呢?在ES模块化标准刚刚产生时,支持标准的浏览器不够多,如果使用ES模块化会导致项目的兼容性奇差,但是我们这些程序员依然想要使用ES的模块化标准,怎么办呢?打包工具帮助你!打包工具可以对代码进行编译,将ES模块化的语法转换为可以实现同样的功能的旧版的语法。我们想在前端使用npm来管理依赖怎么办?没关系直接使用!打包工具可以帮助你将npm中的包导入到前端页面中!总的来说,打包工具可以帮助我们对代码“打包”,有了打包工具后我们可以直接以node工程的形式去管理应用,打包工具会自动将你的代码打包为可以直接运行在浏览器中的项目!

说到这里,有的同学可能会产生疑问。ES模块刚刚产生时兼容性不好,但是15年到现在已经很久了啊!现在应该没有什么太大的兼容问题了吧!确实如此!现在来讲我们完全可以直接在浏览器中使用ES模块化去编写前端代码!但是前端的模块化先天就有一个缺陷,就是模块中的代码需要通过网络去加载,这样就带来一个很严重的问题,前端中的每个模块都需要浏览器发送请求来加载。10个模块就要发10次请求,100个模块就要发100次请求,所以即使支持ES模块规范,我们依然不建议在浏览器中直接使用。

与直接使用模块规范不同,打包工具在打包代码时,会对所有代码进行解析。会将所有的代码统一打包为一个(或多个)文件,并且打包时会对代码进行检查,只将使用到的模块打包到最终文件中。这样一来减少了文件的数量,同时也减少了文件的大小,使代码的加载速度更快,用户体验也更好。

Webpack

Webpack就是这样一款打包工具。在它的官网是这样描述的:

本质上,webpack 是一个用于现代 JavaScript 应用程序的 静态模块打包工具。当 webpack 处理应用程序时,它会在内部从一个或多个入口点构建一个 依赖图(dependency graph),然后将你项目中所需的每一个模块组合成一个或多个 bundles,它们均为静态资源,用于展示你的内容。

webpack是静态模块打包工具,它可以将使用ES模块化规范(动态模块)编写的代码转换为静态的模块代码。webpack在打包时,根据指定的入口文件(一个或多个)构建依赖图,所谓的依赖指的就是入口文件在执行时所需要的资源(js、css、图片等)。依赖图生成后,webpack会将图中所需的依赖打包到一个文件中。

使用webpack

现在我们来使用一个简单的案例来演示webpack的使用,创建项目:

  1. 创建my-webpack目录
  2. 调用npm init -yyarn init -y初始化项目
  3. 在目录下创建子目录src和dist
  4. 在项目中安装开发依赖webpack和webpack-cli(yarn add webpack webpack-cli -D 或 npm i webpack webpack-cli -D)

webpack目录下必须要包含两个目录src和dist,src用来存放源码,dist用来存放打包后的代码。编写项目时,所有的代码都要编写到src目录下,编码完毕后使用webpack对代码进行打包,webpack会将打包后的代码放入到dist目录中。换句话说,最终要运行的是打包后的也就是dist目录中的代码。

webpack-cli包是webpack的命令行工具,安装后可以在命令行中调用webpack的打包指令。webpack包是webpack的核心代码,所有打包的逻辑都在核心代码中编写。

编写代码:

  1. 安装jQuery(yarn add jquery 或 npm i jquery)
  2. 在src下创建index.js
  3. 在dist下创建index.html

src/index.js:

import $ from "jquery"

$("body").append("<h1>你好!Webpack</h1>")

dist/index.html:

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script defer src="./main.js"></script>
</head>
<body>
    
</body>
</html>

webpack默认会将src下的index.js打包到dist目录下,并重命名为main.js,所以我们将index.html直接定义到了dist目录中,同时通过src标签引入了打包后的main.js文件。

代码编写完毕后,执行命令来打包项目:

yarn webpack

npx webpack

也可以将webpack添加到package.json的scripts中:

"scripts": {
  "build":"webpack"
}

这样就可以通过yarn buildnpm run build来执行打包。

webpack.config.js

默认配置下,webpack仅仅将src下的index.js打包为dist下的main.js,显然这样还不够灵活。在项目中可以创建一个webpack.config.js来定制webpack的打包行为。这个文件大概长成这个样子:

webpack.config.js

const path = require('path');

module.exports = {
  mode: ...,
  entry: ...,
  output: ...,
  module: ...,
  plugins: ...,

};

mode,打包模式,可选值(”production”,”development”,”none”)

entry,打包的入口文件,配置方式:

entry: './path/to/my/entry/file.js'

entry: {
  main: './path/to/my/entry/file.js',
}

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

entry: {
  app: './src/app.js',
  adminApp: './src/adminApp.js',
}

output,打包后文件输出位置,配置方式:

output: {
  filename: 'bundle.js',
}

output: {
  filename: '[name].js',
  path: __dirname + '/dist',
}

module,配置webpack的loader,配置方式:

module: {
  rules: [
    { test: /\.css$/, use: 'css-loader' },
    { test: /\.ts$/, use: 'ts-loader' },
  ],
}


module: {
  rules: [
    {
      test: /\.css$/,
      use: [
        { loader: 'style-loader' },
        {
          loader: 'css-loader',
          options: {
            modules: true,
          },
        },
        { loader: 'sass-loader' },
      ],
    },
  ],
}

plugins,配置webpack的plugin(插件),配置方式:

plugins: [
  new webpack.ProgressPlugin(),
  new HtmlWebpackPlugin({ template: './src/index.html' }),
]

loader(加载器)

webpack本身仅仅能处理js文件,但是在实际开发中除了js文件外,还有一些其他类型的文件我们也希望可以一起打包,这就需要使用到loader。通过loader可以对webpack进行扩展使其具备处理某种类型文件的能力。

部分loader

  • 样式相关的:
    1. style-loader
    2. css-loader
    3. less-loader
    4. sass-loader
    5. postcss-loader
    6. stylus-loader
  • 编译相关的:
    1. babel-loader
    2. ts-loader

示例:

处理CSS:

安装:

npm install style-loader css-loader -D

配置:

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

加载图片:

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

处理Less:

安装:

npm install less less-loader -D

配置:

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

babel:

安装:

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

配置:

module: {
  rules: [
    {
      test: /\.m?js$/,
      exclude: /(node_modules|bower_components)/,
      use: {
        loader: 'babel-loader',
        options: {
          presets: ['@babel/preset-env']
        }
      }
    }
  ]
}

plugin(插件)

插件同样可以扩展webpack的功能,它可以处理一下loader无法完成的工作。

HtmlWebpackPlugin

安装:

npm install html-webpack-plugin -D

配置:

plugins: [
    new HtmlWebpackPlugin({
        title: "Output Management"
    })
]

开发服务器

安装:

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

配置:

devServer: {
    static: './dist',
}

启动:

npx webpack serve --open

Vite

除了Webpack外,还有一些其他的打包工具,在众多的打包工具中Vite是Webpack的有力竞争者。打包工具的左右都是相同的,不同点就在于打包的性能。Webpack的打包工作比较简单,在开发环境和生成环境中都会简单的直接将所有模块直接打包。直接打包速度比较慢,导致开发大型项目时每次重构都需要等待很长的时间。

Vite另辟蹊径,在开发环境中不再使用传统的模式对项目进行打包,而是采用ES模块化来引入模块,这样便大大的加快了开发时的重构速度。而在生成环境中,为了提高访问速度依然会正常的对项目进行进行打包工作。

创建项目

npm create vite@latest
yarn create vite
pnpm create vite

这行命令后,根据提示来选择项目的配置,并在项目中安装依赖。依赖安装后可以通过yarn dev来启动开发服务器。开发完毕使用yarn build来对项目进行打包。

相较于Webpack,Vite更易于使用,在Vite中直接开启了各种常用功能,如CSS、CSS预处理器、资源加载器等都已经默认支持,我们需要在做单独配置,只需根据需要安装依赖即可。同时,vite也可以通过配置文件来做一些特殊的配置或引入插件等,但是本课重点主要在于打包工具的介绍,故而不再对打包工具做更多的介绍。

5 10 投票数
文章评分
订阅评论
提醒
guest

3 评论
最旧
最新 最多投票
内联反馈
查看所有评论
lifei
lifei
1 年 前

老师,这个课目前有没有视频呢?

zyl
zyl
1 年 前

老师,有没有react18+ts+vite的可以写进简历的项目的课程呀

coder
coder
1 年 前

,666

3
0
希望看到您的想法,请您发表评论x