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


     简单介绍目前热门的JavaScript应用程序的静态模块打包工具webpack

    01、webpack介绍

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

    ■ 图1 webpack模块化示意图

    图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的版本

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

    ■ 图3 查看与更新npm

    2安装webpack

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

    ■ 图4 打开目录与Terminal控制台

    (1)初始化配置

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

    (2)安装webpack

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

    1. "devDependencies": {
    2. "webpack": "^5.17.0",
    3. }

    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所示,说明已成功安装。

     ■ 图5 成功安装webpack、webpack-dev-server和webpack-cli

    03、webpack配置文件

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

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

    1初始化配置

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

    1. const config = {
    2. }
    3. module.exports = config

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

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

    1. "scripts": {
    2. "build":"webpack -p",
    3. "test": "echo \"Error: no test specified\" && exit 1",
    4. "dev": "webpack-dev-server --open Chrome.exe --config webpack.config.js"
    5. }

    在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中进行入口和出口的配置:

    1. const pathrequire('path')
    2. const config = {
    3.     entry: {
    4.         main: './main'
    5.     },
    6.     output: {
    7.         path: path.resolve(__dirname, 'dist'),
    8.         publicPath: '/dist/',
    9.         filename: 'bundle.js'
    10. },
    11. //开发模式:development,将保留开发时的一些必要信息
    12. //生产模式:production,尽力压缩
    13. //none:只打包
    14. mode: 'development'
    15. }
    16. 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的入口程序:

    1. <div id="app">
    2. Hello Webpack!
    3. </div>
    4. <script type="text/javascript" src="/dist/bundle.js"></script>

    5在浏览器中打开webpack项目

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

    ■ 图6 在浏览器中打开webpack项目

    注意:执行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安装它们:

    1. npm install css-loader --save-dev
    2. npm install style-loader --save-dev

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

    1. rules:[
    2. {
    3. test: /\.css$/,
    4. //webpack的loader执行顺序是由右向左执行的,先执行css-loader后执行style-loader
    5. use: [
    6. 'style-loader',
    7. 'css-loader'
    8. ]
    9. }
    10. ]

     上述配置的意思是当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,内容如下:

    1. #app{
    2. font-size: 24px;
    3. color: #f50;
    4. }

    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配置如下:

    1. const path = require('path')
    2. //导入插件
    3. const MiniCssExtractPluginrequire('mini-css-extract-plugin')
    4. const config = {
    5.     entry: {
    6.         main:'./main.js'
    7.     },
    8.     output: {
    9.         path: path.resolve(__dirname, 'dist'),
    10.         publicPath'/dist/',
    11.         filename'bundle.js'
    12.     },
    13.     mode'development',
    14. plugins: [
    15. new MiniCssExtractPlugin({
    16.             filename'common.css'//导出的文件名
    17.         })
    18. ],
    19.      // 添加的module里面的rules
    20.     module:{
    21.         rules:[
    22.             {
    23.                 test/\.css$/i,
    24.                 use: [
    25.                     {
    26.                         loader: MiniCssExtractPlugin.loader,
    27.                         options: {
    28.                           publicPath'/dist/',
    29.                         },
    30.                       },
    31.                     'css-loader'
    32.                 ]
    33.             }
    34.         ]
    35.     }
    36. }
    37. module.exports = config

    (5)使用CSS

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

    1. <head>
    2.     <link rel="stylesheet" type="text/css" href="/dist/common.css">
    3. </head>
    4. <div id="app">
    5.     Hello Webpack!
    6. </div>
    7. <script type="text/javascript" src="/dist/bundle.js"></script>

    (6)测试插件

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

    ■ 图6使用CSS的结果

    从图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>,示例如下:

    1. <template>
    2. html
    3. </template>
    4. <style>
    5. css
    6. </style>
    7. <script>
    8. js
    9. </script>

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

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

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

    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目录按照以下命令安装依赖:

    1. npm install -D vue vue-loader vue-template-compiler
    2. npm install -D vue-style-loader
    3. npm install -D babel-loader @babel/core @babel/preset-env

    2修改配置文件

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

    1. const path = require('path')
    2. const MiniCssExtractPluginrequire('mini-css-extract-plugin')
    3. const VueLoaderPluginrequire('vue-loader/lib/plugin')
    4. const config = {
    5.     entry: {
    6.         main:'./main.js'
    7.     },
    8.     output: {
    9.         path: path.resolve(__dirname, 'dist'),
    10.         publicPath'/dist/',
    11.         filename'bundle.js'
    12.     },
    13.     mode'development',
    14.     module:{
    15.         rules:[
    16.             {
    17.                 test/\.vue$/,
    18.                 loader'vue-loader'
    19.             },
    20.             {
    21.                 test/\.css$/i,
    22.                 use: [
    23.                     //vue文件中的css
    24.                     'vue-style-loader',
    25.                     {
    26.                         loader: MiniCssExtractPlugin.loader,
    27.                         options: {
    28.                           publicPath'/dist/',
    29.                         },
    30.                       },
    31.                     'css-loader'
    32.                 ]
    33.             },
    34.             {
    35.                 test/\.m?js$/,
    36.                 exclude/node_modules/,
    37.                 use: {
    38.                   loader'babel-loader',
    39.                   options: {
    40.                     presets: ['@babel/preset-env']
    41.                   }
    42.                 }
    43.               }
    44.         ]
    45.     },
    46.     plugins: [
    47.         // 请确保引入该插件!
    48.         new VueLoaderPlugin(),
    49.         new MiniCssExtractPlugin({
    50.             filename'common.css'//导出的文件名
    51.         })
    52.     ]
    53. }
    54. module.exports = config

    3创建app.vue文件

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

    1. <template>
    2.     <div>你好,{{vname}}</div>
    3. </template>
    4. <script>
    5.     export default {
    6.         data(){
    7.             return {
    8.                 vname'Vue'
    9.             }
    10.         }
    11.     }
    12. </script>
    13. <!--因为本项目使用mini-css-extract-plugin插件打包css,加了scoped这部分样式只对当前组件(app.vue)有效-->
    14. <style  scoped>
    15.     div {
    16.          color: red;
    17.          font-size40pt;
    18.     }
    19. </style>

    4修改入口main.js

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

    1. import './css/style.css'
    2. //下面是Vue3的写法
    3. /*//导入Vue框架中的createApp方法,在Vue3中不能全局导入Vue
    4. import {createApp} from 'vue'
    5. //导入app.vue组件
    6. import App from './app.vue'
    7. //创建Vue根实例
    8. createApp(App).mount("#app")
    9. */
    10. //下面是Vue2的写法
    11. import Vue from 'vue'
    12. //导入app.vue组件
    13. import App from './app.vue'
    14. //创建Vue根实例
    15. const vm = new Vue({
    16.     //指定vm实例要控制的页面区域
    17.     el'#app',
    18.     //通过render函数,把指定的组件渲染到el区域中
    19.     renderh => h(App)
    20.     /**
    21.      * 相当于 render: function(h){
    22.      * return h(app)
    23.      * }
    24.      */
    25. })

    5运行测试

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

     

    ■ 图7 例3的运行结果

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

    1. <template>
    2.   <div>
    3.       <input v-model="uname">
    4.       <p>输入的用户名是:{{ uname }}</p>
    5.   </div>
    6. </template>
    7. <script>
    8. export default {
    9.   props: {
    10.       uname: {
    11.           typeString
    12.       }
    13.   }
    14. }
    15. </script>

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

    1. <template>
    2.     <div>
    3.         你好,{{vname}}
    4.         <!--使用子组件vInput渲染-->
    5.         <v-input></v-input>
    6.     </div>
    7. </template>
    8. <script>
    9.     import vInput from './input.vue'
    10.     export default {
    11.         data(){
    12.             return {
    13.                 vname'Vue'
    14.             }
    15.         },
    16.         components: {//vInput作为根组件的子组件
    17.             vInput
    18.         }
    19.     }
    20. </script>
    21. <style  scoped>
    22.     div {
    23.          color: red;
    24.          font-size40pt;
    25.     }
    26. </style>

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

    ■ 图8 渲染两个组件内容

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

     

  • 相关阅读:
    本地的git仓库和远程仓库
    一个.NET内置依赖注入的小型强化版
    Linux运维常用小总结
    构造函数_XMLHttpRequest
    从ReentrantReadWriteLock开始的独占锁与共享锁的源码分析
    CSS BFC
    UiPath实战(08) - 选取器(Selector)
    Python吴恩达深度学习作业19 -- 字符级语言模型
    vue2原理初探-数据代理和数据劫持
    物联网开发学习笔记——目录索引
  • 原文地址:https://blog.csdn.net/qq_41640218/article/details/125439755