likes
comments
collection
share

Webpack使用(入门篇)

作者站长头像
站长
· 阅读数 17

Webpack是什么

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

静态模块:指的是编写代码过程中的,html,css,js,图片等固定内容的文件

Webpack使用(入门篇)

注意: 只有和入口有直接/间接的引入关系的模块,才会被打包

webpack 主要是用于前端工程化。主要功能是:把静态模块内容压缩、整合和转义等。例如,把 less / sass 转成 css 代码,把 ES6+ 降级成 ES5,支持多种模块文件类型,多种模块标准语法。目前很多项目依旧基于 webpack 进行构建,webpack 目前仍是前端工程师必须掌握的工具之一

本文将通过一个简单的示例介绍Webpack的五大核心模块:

  1. entry (入口):入口提示webpack以哪个文件为起点开始打包,分析构建内部依赖图
  2. output (出口):输出提示webpack打包后的资源输出到哪,以及如何命名
  3. module (loader加载器):让webpack能够处理非 JS 文件(webpack自身只能理解js/json,不能处理css/img等其他资源)
  4. plugin (插件):插件可以用于执行范围更广的任务。插件范围包括:从打包优化到压缩,一直到重新定义环境中的变量等
  5. mode (模式):
    • 开发模式:能让代码本地调试的环境 process.env.NODE_NEV = development
    • 生产模式:能让代码优化上线运行的环境 process.env.NODE_NEV = production

Webpack初使用

我们用一个实际例子来体会 webpack 使用全过程:

  • 封装 utils 包,校验用户名和密码长度,在 index.js 中使用,使用 Webpack 打包

步骤:

  • 新建项目文件夹,初始化包环境

    npm init -y
    # 注意,项目文件夹不能为中文,只能为小写字母和小横杠(-)
    

    在新文件夹中输入cmd打开终端(当然,也可以使用 vscode 自带的终端):

    Webpack使用(入门篇)

    初始化后,项目结构如下:

    Webpack使用(入门篇)

  • 新建 src 源代码文件夹(书写代码)包括 utils/check.js 封装用户名和密码长度函数,引入到 src/index.js 进行使用

    项目结构如下:

    Webpack使用(入门篇)

    JavaScript 文件的引入使用 ES6 语法:

    • export default {} import 变量名 from '模块名或路径'
    • export 修饰定义语句import {同名变量} from '模块名或路径'
  • 下载 webpack webpack-cli 到项目(版本独立)

    npm i webpack webpack-cli --save-dev
    # 此处的 --save-dev 等同于 -D 开发时的依赖。里面的模块是开发时用的,发布时用不到它
    

    注意:虽然 webpack 是全局软件包,封装的是命令工具,但是为了保证项目之间版本分别独立,推荐使用局部安装。因为每个项目使用的 webpack 版本可能不一致,所以全局安装会导致之前项目用的老版本webpack 被覆盖掉

    Webpack使用(入门篇)

    随后把 webpack 命令配置到 package.json 中的 scripts 自定义命令,作为局部命令使用

    Webpack使用(入门篇)

  • 项目中运行工具命令,采用自定义命令的方式(局部命令)

    npm run build
    

    npm run 自定义命令名字

    注意:实际上在终端运行的是 build 右侧的具体命名

    如图所示,即为打包成功:

    Webpack使用(入门篇)

  • 自动产生 dist 分发文件夹(压缩和优化后,用于最终运行的代码)

    打包后项目结构如下:

    Webpack使用(入门篇)

    Webpack 默认入口和出口分别为:src/index.jsdist/main.js

整个过程如下图所示:

Webpack使用(入门篇)

Webpack出入口修改

入口(entry ) 属性指示 webpack 应该使用哪个模块,来作为构建其内部 依赖图(dependency graph) 的开始。进入入口起点后,webpack 会找出有哪些模块和库是入口起点(直接和间接)依赖的。默认值是 ./src/index.js,但你可以通过在 webpack configuration 中配置 entry 属性,来指定一个(或多个)不同的入口起点

出口(output) 属性告诉 webpack 在哪里输出它所创建的 bundle,以及如何命名这些文件。主要输出文件的默认值是 ./dist/main.js,其他生成文件默认放置在 ./dist 文件夹中。你可以通过在配置中指定一个 output 字段,来配置这些处理过程

path.join 方法将多个路径片段拼接在一起,并根据操作系统的规则生成正确的路径

path.resolve 方法根据参数生成一个绝对路径。如果传入的路径是绝对路径,则直接返回该路径;如果传入的是相对路径,则根据当前工作目录生成绝对路径

操作步骤:

  • 在项目根目录,新建 Webpack.config.js 配置文件。此处建议使用 vscode-icon/Material Icon Theme 插件,此插件能让项目结构更加清晰

  • 导出配置对象,配置入口,出口文件路径

    const path = require('path')
    module.exports = {
      // 入口: 可以使用相对路径
      entry: './src/main.js',
      // entry: path.resolve(__dirname, 'src/main.js'), // 入口
      // 出口
      output: {
        // 路径必须是绝对路径
        path: path.join(__dirname, 'dist'),
        // 在该路径下输出什么文件名
        filename: 'app.js',
        clean: true // 先清空 dist,然后再输出最新内容
      },
    }
    

    打包前的项目结构如下图所示:

    Webpack使用(入门篇)

  • 重新打包观察

    注意:此时由于我们更改了入口为main.js,因此我们要把index.js重命名为main.js,或者新建一个main.js文件也可,这里我们采用重命名的形式

    打包后项目结构如下(此时的出入口已经更改成功):

    Webpack使用(入门篇)

webpack打包出入口更多配置项请查阅官网:webpack中文文档

Webpack自动生成html文件

webpack本身是不能自动生成html文件的,但我们可以使用 webpack 的 html-webpack-plugin 插件,该插件主要作用是在 Webpack 打包时生成 html 文件,并引入其他打包后的资源

该插件安装步骤如下:

  • 下载 html-webpack-plugin 本地软件包到项目中

    npm i html-webpack-plugin --save-dev
    

    与上文一样,此处的 --save-dev 等同于 -D 开发时的依赖。里面的模块是开发时用的,发布时用不到它。webpack插件都应该带上 -D,只有开发时才用到

  • 配置 webpack.config.js 让 Webpack 拥有插件功能

    // ...
    const HtmlWebpackPlugin = require('html-webpack-plugin');
    
    module.exports = {
      // ...
      plugins: [ // 插件列表
        new HtmlWebpackPlugin({
          // 以指定的 html 文件作为生成模板
          template: path.resolve(__dirname, 'public/index.html') 
        })
      ]
    };
    

    此插件指定以 public/index.html 为模板复制到 dist/index.html,并自动引入其他打包后资源

    如果设置后打包时报错,很有可能是plugins中的p大写了,建议直接官网复制,避免不必要的麻烦

    此处指定 public 文件夹下的 index.html文件,我们在项目中新建该文件夹,并引入 index.html 文件:

    Webpack使用(入门篇)

    <!-- index.html网页骨架 -->
    <div class="img-wrap">
      <img class="logo-img" src="" alt="">
    </div>
    <div class="login-wrap">
      <form action="javascript:;">
        <div class="form-item">
          <span>用户名:</span>
          <input type="text" class="username">
        </div>
        <div class="form-item">
          <span>密码:</span>
          <input type="password" class="password">
        </div>
        <div class="form-item">
          <button class="login-btn">注 册</button>
        </div>
      </form>
    </div>
    
  • 运行打包命令,观察打包后 dist 文件夹下内容(js 逻辑写到 main.js 中)

    项目结构如下:

    Webpack使用(入门篇)

    成功在 dist 文件夹中生成了压缩后的 index.html 文件,并且会自动把输出的 js 文件自动引入到 html 中

Webpack打包css代码

webpack 默认只识别 JS 和 JSON 文件内容,所以想要让 webpack 识别更多不同内容,需要使用加载器。 webpack 支持使用 loader 对文件进行预处理。你可以构建包括 JavaScript 在内的任何静态资源。并且可以使用 Node.js 轻松编写自己的 loader

webpack 需要两个加载器来辅助才能打包 css 代码:

使用步骤如下:

  • 准备 css 文件引入到 src/main.js 中(压缩转译处理等)

    import './css/index.css'
    

    注意:这里只是引入代码内容让 Webpack 处理,不需定义变量接收在 JS 代码中继续使用,所以没有定义变量接收。引入 css 模块后,webpack 会帮我们去加载 css 文件并解析

  • 下载 css-loader 和 style-loader 本地软件包

    npm i css-loader style-loader --save-dev
    
  • 配置 webpack.config.js 让 Webpack 拥有该加载器功能

    // ...
    module.exports = {
      // ...
      module: { // 加载器
      // 匹配规则, 遇到什么文件, 用什么 loader 加载, webpack 没有加载各种文件的能力, 它只能交给不同的loader 去帮忙加载
        rules: [
          {
            test: /\.css$/i, // 匹配 .css 结尾的文件
            // 交给两个 loader 帮忙解析
            // loader 的执行顺序是从右到左的
            // webpack 先读取了 css 文件, 交给 css-loader 帮忙解析 css 语法, 解析完毕后交给 style-loader, 帮忙将解析完毕的 css 插入到网页的 style 标签中
            use: ['style-loader', 'css-loader'], 
          }
        ]
      }
    };
    
  • 打包后运行 dist/index.html 观察效果,看看准备好的样式是否作用在网页上

    项目结构如下:

    Webpack使用(入门篇)

    配置好重新打包后,css 样式被合并到了 app.js 中,此时样式已经引入到 html 页面中

Webpack打包less代码

加载器 less-loader:把 less 代码编译为 css 代码,还需要依赖 less 软件包。与 css 加载器功能类似,让 Webpack 拥有打包 less 代码功能

使用步骤如下:

  • 准备 less 样式引入到 src/main.js 中

    import './less/index.less'
    
  • 下载 less 和 less-loader 本地软件包

    npm i less less-loader --save-dev
    
  • 配置 webpack.config.js 让 Webpack 拥有功能

    // ...
    module.exports = {
      // ...
      module: { // 加载器
        rules: [ // 规则列表
          // ...
           { // 打包 less 需要安装 less 和 less-loader 两个包, 其他配置和 css-loader 差不多
            test: /\.less$/i,
            use: [
              // compiles Less to CSS
              'style-loader',
              'css-loader',
              'less-loader',
            ],
          },
        ]
      }
    };
    
  • 打包后运行 dist/index.html 观察效果,此处与 css 类似,不再赘述。此外,最好是把 easy less 插件禁用或者卸载,以免引起不必要的麻烦

Webpack打包图片

资源模块:Webpack 内置了资源模块的打包,无需下载额外 loader

使用步骤:

  • 准备图片素材到 src/assets 中(存放资源模块 - 图片/字体图标等)

    项目结构如下:

Webpack使用(入门篇)

  • 在 index.less 中给 body 添加背景图

    body{
      background: url(../assets/background.png) no-repeat center center;
    }
    
  • 在 main.js 中给 img 标签添加 logo 图片

    /**
     目标:要给 img 标签设置一个 logo 图片
     注意:再赋予给 img 的 src 属性图片的时候,需要把图片数据对象引入过来
    */
    import imgObj from './assets/logo.png'
    document.querySelector('.logo-img').src = imgObj
    
  • 配置 webpack.config.js 让 Webpack 拥有打包图片功能

    // ...
    module.exports = {
      // ...
      module: { // 加载器
        rules: [ // 规则列表
          // ...
          { // 针对资源模块(图片,字体文件,图标文件等)处理
            test: /\.(png|jpg|jpeg|gif)$/i,
            type: 'asset', 
            // 根据文件大小(8KB)小于:把文件转成 base64 打包进 js 文件中(减少网络请求次数)大于:文件复制到输出的目录下
            // webpack 的 asset 类型, 自动帮我们区分图片大小来决定是否要转换成 BASE64 格式的字符串
            // 8KB 是判断标准, 超过了就不转, 没超过就转换成 BASE64
    
            // 转 BASE64 
            // 好处: 少发一次请求
            // 坏处: 文件体积会增大 33.4%
            generator: { // 输出文件时,路径 + 名字
              // [] 内置变量
              // [hash] 自动生成随机的唯一字符串, 避免冲突
              // [ext] 后缀名
              filename: 'assets/[hash][ext]'
            }
          }
        ]
      }
    };
    
  • 打包后运行 dist/index.html 观察效果

注意:

  • 小于 8KB 文件会被转成 data URI(base64 字符串)打包进 JS 文件中(好处:可以减少网络请求次数,缺点:增加 30% 体积)
  • 大于 8KB 文件会被复制到 dist 下,自动替换使用代码的图片名字

Webpack集成 babel 编译器

babel 定义:是一个 JavaScript 语法编译器,将采用 ECMAScript 2015+ 语法编写的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中

babel-loader:让 Webpack 可以使用 babel 转译 JavaScript 代码

使用步骤:

  • 下载 babel babel-loader core 本地软件包

    npm i babel-loader @babel/core @babel/preset-env -D
    
  • 配置 webpack.config.js 让 Webpack 拥有功能

    // ...
    module.exports = {
      // ...
      module: { // 加载器
        rules: [ // 规则列表
          // ...
          {
            test: /\.m?js$/,
            exclude: /(node_modules|bower_components)/, // 排除指定目录里的 js (不进行编译降级)
            use: {
              loader: 'babel-loader',// 使用 babel-loader 来加载文件
              options: {
                presets: ['@babel/preset-env'] // 预设规则
              }
            }
          }
        ],
      }
    };
    
  • 打包运行 dist/index.html 观察效果

各个软件包的作用表格:

模块作用
@babel/coreJs 编译器,分析代码
@babel/preset-envbabel 预设,规则
babel-loader让 webpack 翻译 js 代码

Webpack开发服务器

每次改动代码,都要重新打包,十分不便,所以这里给项目集成 webpack-dev-server 开发服务器

作用:启动 Web 服务,打包输出源码在内存,并会自动检测代码变化热更新到网页

使用步骤:

  • 下载 webpack-dev-server 软件包到当前项目

    npm i webpack-dev-server --save-dev
    
  • 配置自定义命令,并设置打包的模式为开发模式

    "scripts": {
      // ...
      "dev": "webpack serve --mode=development"
    },
    
  • 使用 npm run dev 来启动开发服务器,访问提示的域名+端口号,在浏览器访问打包后的项目网页,修改代码后,试一试热更新效果

    Webpack使用(入门篇)

    可以使用 http://localhost:8080/ 或者 http://192.168.80.94:8080/ 访问。在 js / css 文件中修改代码保存后,会实时反馈到浏览器

Webpack打包模式

打包模式:提供 mode 配置选项,告知 Webpack 使用相应模式的内置优化

分类:

模式名称模式名字特点
开发模式development调试代码,实时加载,模块热替换等
生产模式production压缩代码,资源优化,更轻量等

如何设置影响 Webpack

  • 方式1:在 webpack.config.js 配置文件设置 mode 选项

    // ...
    
    module.exports = {
      // ...
      mode: 'production'
    }
    
  • 方式2:在 package.json 命令行设置 mode 参数

    "scripts": {
      "build": "webpack --mode=production",
      "dev": "webpack serve --mode=development"
    },
    

注意:命令行设置的优先级高于配置文件中的,推荐用命令行设置

Webpack开发环境调错source map

代码被压缩和混淆,无法正确定位源代码位置(行数和列数),source map 为我们解决了这个问题。source map 可以准确追踪 error 和 warning 在原始代码的位置

设置:webpack.config.js 配置 devtool 选项

// ...
module.exports = {
  // ...
  devtool: 'inline-source-map'
}
//inline-source-map 选项:把源码的位置信息一起打包在 JS 文件内

注意:source map 适用于开发环境,不要在生产环境使用(防止被轻易查看源码位置)

Webpack设置解析别名路径

设置 Webpack 如何设置路径别名,方便我们引入目标模块。解析别名:配置模块如何解析,创建 import 或 require 的别名,来确保模块引入变得更简单

例如:

  • 原来路径如下:

    import { checkUsername,  checkPassword } from '../src/utils/check.js'
    
  • 配置解析别名:在 webpack.config.js 中设置

    // ...
    
    module.exports = {
      // ...
      resolve: {
        alias: {
          MyUtils: path.resolve(__dirname, 'src/utils'),
          '@': path.resolve(__dirname, 'src')
        }
      }
    }
    
  • 这样我们以后,引入目标模块写的路径就更简单了

    import { checkUsername,  checkPassword } from 'MyUtils/check.js'
    import { checkUsername,  checkPassword } from '@/utils/check.js'
    
转载自:https://juejin.cn/post/7276281005743390761
评论
请登录