写点什么

全栈开发实战|Vue 进阶——使用静态模块打包工具 webpack

作者:TiAmo
  • 2023-04-24
    江苏
  • 本文字数:6744 字

    阅读完需:约 22 分钟

全栈开发实战|Vue进阶——使用静态模块打包工具webpack

简介: 全栈开发实战|Vue 进阶——使用静态模块打包工具 webpack

01、webpack 介绍


webpack 根据模块的依赖关系进行静态分析,然后将这些模块按照指定的规则生成对应的静态资源。图 1 是来自 webpack 官方网网站(https://webpack.js.org/)的模块化示意图。



图 1 的左边是业务中编写的各种类型文件,例如 typescript、jpg、less、css。这些类型的文件通过特定的加载器(Loader)编译后,最终统一生成.js、.css、.jpg、.png 等静态资源文件。在 webpack 中,一张图片、一个 css 文件等都被称为模块,并彼此存在依赖关系。使用 webpack 的目的就是处理模块间的依赖关系,并将它们进行打包。


webpack 的主要适用场景是单页面应用(SPA),SPA 通常是由一个 html 文件和一堆按需加载的 js 文件组成。接下来学习 webpack 的安装与使用。


02、安装 webpack 与 webpack-dev-server


我们使用 npm 安装 webpack,而 npm 是集成在 Node.js 中的,所以需要首先安装 Node.js。


1●安装 Node.js 和 NPM

通过访问官网https://nodejs.org/en/即可下载对应版本的 Node.js


下载完成后运行安装包 node-v14.15.4-x64.msi,一直下一步即可完成安装。然后在命令行窗口中输入命令 node -v,检查是否安装成功。如图 2 所示。



如图 2 所示,出现了版本号,说明 Node.js 已安装成功。同时,npm 包也已经安装成功,可以输入 npm -v 查看版本号。输入 npm -g install npm 命令,将 npm 更新至最新版本。如图 3 所示。



2●安装 webpack

首先,创建一个目录,例如 C:\webpack-firstdemo,使用 VSCode 打开该目录,并进入 Terminal 控制台,如图 4 所示。



(1)初始化配置


在图 4 中输入命令 npm init 初始化配置,该命令执行后,将有一系列选项,可以按回车快速确认,结束后将在 webpack-firstdemo 目录下生成一个 package.json 文件。


(2)安装 webpack


初始化配置后,接着在图 4 中输入命令 npm install webpack --save-dev 在本地局部(项目中)安装 webpack。--save-dev 将作为开发依赖来安装 webpack。安装成功后,在 package.json 文件中将多一项配置:

"devDependencies": {    "webpack": "^5.17.0",}
复制代码

3●安装 webpack-dev-server

接着安装 webpack-dev-server,它可以在开发环境中提供很多服务,例如启动一个服务器、热更新、接口代理等。在图 4 中输入命令 npm install webpack-dev-server --save-dev 在本地局部安装 webpack-dev-server。


4●安装 webpack-cli

在 webpack 4 以前,不用安装 webpack-cli 即可使用。在 webpack 4 以后,它将 webpack 和 webpack-cli 分开处理,需要安装 webpack-cli。在图 4 中输入命令 npm install webpack-cli --save-dev 在本地局部安装 webpack-cli。


如果在 package.json 文件的 devDependencies 中包含 webpack、webpack-dev-server 和 webpack-cli,如图 5 所示,说明已成功安装。



03、webpack 配置文件


webpack 配置文件是一个名为 webpack.config.js 的.js 文件,架构的好坏都体现在该配置文件中。下面我们由浅,完成配置。


【1】完成 webpack 的基本配置。具体步骤如下:


1●初始化配置

在 webpack-firstdemo 目录下创建一个名为 webpack.config.js 的.js 文件,并初始化配置内容:

const config = {}module.exports = config
复制代码

2●添加快速启动 webpack-dev-server 脚本

在 package.json 的 scripts 里面添加一个快速启动 webpack-dev-server 服务的脚本:

"scripts": {"build":"webpack -p",    "test": "echo \"Error: no test specified\" && exit 1",    "dev": "webpack-dev-server --open Chrome.exe --config webpack.config.js"}
复制代码

在 Terminal 终端执行 npm run build 命令时,将执行 webpack -p 命令进行打包。


在 Terminal 终端执行 npm run dev 命令时,将执行 webpack-dev-server –open Chrome.exe --config webpack.config.js 命令,其中--config 是指向 webpack-dev-server 读取配置文件的路径,这里指向上面步骤中创建的 webpack.config.js 文件。--open 将在执行命令时自动使用谷歌浏览器打开页面(如果 open 后面没有指定浏览器,则使用默认浏览器打开),默认地址是 127.0.0.1:8080,但 IP 和端口号可以修改,示例如下:

"dev": "webpack-dev-server --host 128.11.11.11 --port 9999 --open --config webpack.config.js"
复制代码

3●配置入口和出口

在 webpack 配置中,最重要的也是必选的两项是入口(entry)和出口(output)。入口的作用是告诉 webpack 从哪里开始寻找依赖并编译;出口的作用是配置编译后的文件存储位置和文件名。


在 webpack-firstdemo 目录下创建一个名为 main.js 空文件作为入口的文件,然后在 webpack.config.js 中进行入口和出口的配置:

const path = require('path')const config = {    entry: {        main: './main'    },    output: {        path: path.resolve(__dirname, 'dist'),        publicPath: '/dist/',        filename: 'bundle.js'},//开发模式:development,将保留开发时的一些必要信息//生产模式:production,尽力压缩//none:只打包mode: 'development'}module.exports = config
复制代码


上述配置 entry 中的 main 就是配置的入口,webpack 将从 main.js 文件开始工作。output 中 path 选项用来存放打包后文件的输出目录,是必填项。publicPath 指定资源文件引用的目录,如果资源存放在 CDN 上,这里可以填 CDN 的网址。filename 用于指定输出文件的名称。所以这里配置的 output 意为打包后的文件将存储在 webpack-firstdemo/dist/bundle.js 文件,在 html 中引入它即可。


4●创建 index.html 文件

在 webpack-firstdemo 目录下,新建一个名为 index.html 文件,作为 SPA 的入口程序:

<div id="app">    Hello Webpack!</div><script type="text/javascript" src="/dist/bundle.js"></script>
复制代码

5●在浏览器中打开 webpack 项目

在 Terminal 终端执行 npm run dev 命令,将会自动在浏览器中打开页面,如图 6 所示。



注意:执行 npm run dev 命令时,可能会报如下错误:

Cannot find module 'webpack-cli/bin/config-yargs'
复制代码

出现上述错误的原因是 webpack-cli 的新版本与 webpack-dev-server 兼容性的问题,解决办法是:首先,执行 npm uninstall -g webpack-cli 命令,卸载 webpack-cli。然后,执行 npm install webpack-cli@3.3.12 --save-dev 命令,安装低版本的 webpack-cli。最后,执行 npm run dev 命令,将会自动在浏览器中打开页面。


04、加载器 Loaders 与插件 Plugins


1●加载器 Loaders

在 webpack 中,一切皆模块,例如.css、.js、.html、.jpg 等。对于不同的模块,需要使用不同的加载器(Loaders)来处理。Loaders 是 webpack 最强大的功能之一。webpack 通过使用不同的 Loader,处理不同格式的文件,例如处理 CSS 样式文件,需要使用 style-loader 和 css-loader。下面通过 NPM 安装它们:

npm install css-loader --save-devnpm install style-loader --save-dev
复制代码

Loaders 安装后,需要在 webpack.config.js 的 module 对象的 rules 属性中配置。rules 是一个数组配置规则,可以指定一系列 Loaders,每个 Loader 都必须包含 test 和 use 两个选项。配置规则告诉 webpack 符合 test 规定格式的文件,使用 use 后面的 Loader 处理。配置 style-loader 和 css-loader 示例代码如下:

rules:[      {          test: /\.css$/,          //webpack的loader执行顺序是由右向左执行的,先执行css-loader后执行style-loader          use: [             'style-loader',             'css-loader'            ]       }]
复制代码

上述配置的意思是当 webpack 编译过程中遇到 require()或 import 语句导入后缀名.css 的文件时,先将.css 文件通过 css-loader 转换,再通过 style-loader 转换,然后继续打包。配置 style-loader 和 css-loader 完成后,就可以在配置的入口文件 main.js 中使用 require()或 import 语句导入.css 文件了。


webpack 有许多功能强大的加载器,大家可以访问https://webpack.js.org/loaders/进行学习。


2●插件 Plugins

插件 Plugins 是实现 webpack 的自定义功能,可实现 Loaders 不能实现的复杂功能。使用 Plugins 丰富的自定义 API 以及生命周期事件,可以控制 webpack 打包流程的每个环节。现在我们用一个 mini-css-extract-plugin 插件将散落在 webpack-firstdemo 中的 css 提取出来,并生成一个 common.css 文件,最终在 index.html 中通过的形式加载它。下面在【例 1】的基础上实现该插件。


【例 2】实现 CSS 导出插件。具体实现过程如下:


(1)创建.css 文件

在 C:\webpack-firstdemo 目录中创建 css 文件夹,并在该文件夹中创建 style.css,内容如下:

#app{    font-size: 24px;    color: #f50;}
复制代码

2)导入.css 文件

配置 style-loader 和 css-loader 的前提下,在配置的入口文件 main.js 中使用 import 语句导入.css 文件,具体如下:

import './css/style.css'
复制代码

(3)安装 mini-css-extract-plugin 插件

通过 npm install --save-dev mini-css-extract-plugin 命令安装 mini-css-extract-plugin 插件。


(4)配置插件

在配置文件 webpack.config.js 中配置插件,完整的 webpack.config.js 配置如下:

const path = require('path')//导入插件const MiniCssExtractPlugin = require('mini-css-extract-plugin')const config = {    entry: {        main:'./main.js'    },    output: {        path: path.resolve(__dirname, 'dist'),        publicPath: '/dist/',        filename: 'bundle.js'    },    mode: 'development',plugins: [new MiniCssExtractPlugin({            filename: 'common.css'//导出的文件名        })],     // 添加的module里面的rules    module:{        rules:[            {                test: /\.css$/i,                use: [                    {                        loader: MiniCssExtractPlugin.loader,                        options: {                          publicPath: '/dist/',                        },                      },                    'css-loader'                ]            }        ]    }}module.exports = config
复制代码

(5)使用 CSS

在 index.html 中,使用元素引用 common.css,具体代码如下:

<head>    <link rel="stylesheet" type="text/css" href="/dist/common.css"></head><div id="app">    Hello Webpack!</div><script type="text/javascript" src="/dist/bundle.js"></script>
复制代码

(6)测试插件

在 Terminal 终端执行 npm run dev 命令,将会自动在浏览器中打开页面,如图 6 所示。



从图 6 可以看出,导出 CSS 的插件已生效。


Webpack 看似复杂,但它只不过是一个 js 配置文件,只要明白入口、出口、加载器和插件这 4 个概念,使用起来就不会那么困难。


05、单文件组件与 vue-loader


Vue.js 是一个渐进式的 JavaScript 框架,在使用 webpack 构建 Vue 应用时,可以使用一种新的构建模式:.vue 单文件组件。


.vue 是 Vue.js 自定义的一种文件格式,一个.vue 文件就是一个单独的组件,在文件内封装了组件相关的代码:html、css、js。


.vue 文件由三部分组成<template>、<style>、<script>,示例如下:

<template>        html    </template>    <style>        css    </style>    <script>        js    </script>
复制代码

可是,浏览器本身并不识别.vue 文件,所以必须对.vue 文件进行加载解析,此时需要 webpack 的 vue-loader 加载器。下面通过一个实例讲解如何使用 vue-loader 实现单文件组件。

【例 9】使用 vue-loader 实现单文件组件。

在【例 8】的基础上完成【例 9】。具体实现过程如下:

1安装开发依赖

使用 vue-loader 加载解析.vue 文件时,需要使用 vue-template-compiler 编译器对模板内容预编译为 JavaScript 渲染函数。安装 Vue、vue-loader 以及 vue-template-compiler 依赖时,保证版本一致(编写本书时,还没有对应 Vue 3 的 vue-template-compiler,因此本节使用的是 Vue 2)。另外,还需要安装 babel-loader 加载器解析 ES 语法。进入 webpack-firstdemo 目录按照以下命令安装依赖:

npm install -D vue vue-loader vue-template-compilernpm install -D vue-style-loadernpm install -D babel-loader @babel/core @babel/preset-env
复制代码

2修改配置文件

在配置文件 webpack.config.js 中,添加 vue-loader 和 babel-loader 的配置。修改后的配置文件内容如下:

const path = require('path')const MiniCssExtractPlugin = require('mini-css-extract-plugin')const VueLoaderPlugin = require('vue-loader/lib/plugin')const config = {    entry: {        main:'./main.js'    },    output: {        path: path.resolve(__dirname, 'dist'),        publicPath: '/dist/',        filename: 'bundle.js'    },    mode: 'development',    module:{        rules:[            {                test: /\.vue$/,                loader: 'vue-loader'            },            {                test: /\.css$/i,                use: [                    //vue文件中的css                    'vue-style-loader',                    {                        loader: MiniCssExtractPlugin.loader,                        options: {                          publicPath: '/dist/',                        },                      },                    'css-loader'                ]            },            {                test: /\.m?js$/,                exclude: /node_modules/,                use: {                  loader: 'babel-loader',                  options: {                    presets: ['@babel/preset-env']                  }                }              }        ]    },    plugins: [        // 请确保引入该插件!        new VueLoaderPlugin(),        new MiniCssExtractPlugin({            filename: 'common.css'//导出的文件名        })    ]}module.exports = config
复制代码

3创建 app.vue 文件

在 webpack-firstdemo 目录下新建一个 app.vue 文件作为根实例组件,具体内容如下:

<template>    <div>你好,{{vname}}</div></template><script>    export default {        data(){            return {                vname: 'Vue'            }        }    }</script><!--因为本项目使用mini-css-extract-plugin插件打包css,加了scoped这部分样式只对当前组件(app.vue)有效--><style  scoped>    div {         color: red;         font-size: 40pt;    }</style>
复制代码

4修改入口 main.js

.vue 是没有名称的组件,在父组件中使用时可以对它自定义。现在需要在 main.js 中使用它。修改后的 main.js 内容如下:

import './css/style.css'//下面是Vue3的写法/*//导入Vue框架中的createApp方法,在Vue3中不能全局导入Vueimport {createApp} from 'vue'//导入app.vue组件import App from './app.vue'//创建Vue根实例createApp(App).mount("#app")*///下面是Vue2的写法import Vue from 'vue'//导入app.vue组件import App from './app.vue'//创建Vue根实例const vm = new Vue({    //指定vm实例要控制的页面区域    el: '#app',    //通过render函数,把指定的组件渲染到el区域中    render: h => h(App)    /**     * 相当于 render: function(h){     * return h(app)     * }     */})
复制代码

5运行测试

执行命令 npm run dev,运行结果如图 8 所示。


■ 图 8 例 9 的运行结果

下面在 webpack-firstdemo 目录中再新建一个.vue 文件 input.vue,具体代码如下:

<template>  <div>      <input v-model="uname">      <p>输入的用户名是:{{ uname }}</p>  </div></template><script>export default {  props: {      uname: {          type: String      }  }}</script>
复制代码

在根实例 app.vue 组件中,导入 input.vue 组件,修改后的 app.vue 代码如下:

<template>    <div>        你好,{{vname}}        <!--使用子组件vInput渲染-->        <v-input></v-input>    </div></template><script>    import vInput from './input.vue'    export default {        data(){            return {                vname: 'Vue'            }        },        components: {//vInput作为根组件的子组件            vInput        }    }</script><style  scoped>    div {         color: red;         font-size: 40pt;    }</style>
复制代码

执行命令 npm run dev,运行结果如图 9 所示。

■ 图 9 渲染两个组件内容

从图 15.9 可以看出,我们在 index.html 中渲染了多个组件内容,这就是一个简单的单页面应用,即仅有 index.html 页面。

webpack-firstdemo 目录是本节(15.3 节)的代码,大家可在目录下执行 npm install 命令将自动安装所有的依赖,然后执行 npm run dev 命令启动服务。

发布于: 刚刚阅读数: 3
用户头像

TiAmo

关注

有能力爱自己,有余力爱别人! 2022-06-16 加入

CSDN全栈领域优质创作者,万粉博主;阿里云专家博主、星级博主、技术博主、阿里云问答官,阿里云MVP;华为云享专家;华为Iot专家;亚马逊人工智能自动驾驶(大众组)吉尼斯世界纪录获得者

评论

发布
暂无评论
全栈开发实战|Vue进阶——使用静态模块打包工具webpack_Vue_TiAmo_InfoQ写作社区