自己动手 webpack 打包 vue 单文件组件

1. 为什么要了解这些

vue 的脚手架集成了 webpack,并进行了大量的默认配置

我们只需要按照框架的要求编写代码,打包就好了

慢慢的我们就成了傻瓜,不知道这其中到底发生了什么,一旦遇到问题,不知道该如何思考,因为你可能都不清楚它的运作原理

更何况,看尤大的思路,将来很可能使用脚手架创建项目时,打包工具不再是默认的,而是让你 webpack 和 vite 二选一

所以,我们就更需要对打包过程有一个大概的了解

下面我们就手动实现这一点

2. 动手实践

SPA 和组件化密不可分,组件化让SPA成为可能,SPA促使组件化编程的落地

vue 的单文件组件就是具体的体现

2.1 搭建目录结构

创建项目文件夹 webpack-demo

运行如下命令进行初始化

npm init -y

根目录下新建 src 目录

src 目录下新建 index.html,main.js

index.html 代码





  
  
  
  Document



  
  • id=app 的div 是将来 vue 实例的挂载点
  • bundle.js 是打包生成的文件,先不同管它

src 目录下新建 Home.vue



当前目录结构如下

自己动手 webpack 打包 vue 单文件组件_第1张图片

 

2.3 安装和配置webpack

安装 webpack

npm i webpack webpack-cli -D

根目录下新建 webpack.config.js,配置打包模式、入口和出口文件

const path = require('path')
module.exports = {
  mode: 'development',
  entry: path.join(__dirname, 'src', 'main.js'), // 打包的入口文件
  output: {
    path: path.join(__dirname, 'dist'),
    filename: 'bundle.js'
  }  
}

package.json 中添加打包命令

自己动手 webpack 打包 vue 单文件组件_第2张图片

2.4 编写打包入口文件

在 src/main.js 中编写代码

import Vue from 'vue'
import Home from './Home.vue'

let vm = new Vue({
  el: '#app', // 指定当前vue实例的挂载点,也就是将index.html 中的id=app 的dom作为挂载点
  // 将 Home 组件中的模板和样式渲染到 index.html 页面中,具体来说,
  // 就是用模板中的内容替换 index.html 中的 id=app 的元素,也会将 css 放到页面中
  render: h => h(Home)
})

运行打包命令

npm run dev

报错

错误解决见下一节

2.5 安装相关加载器(loader)

上面错误原因在于 webpack 默认只能打包 js 文件,对于 .vue 文件不认识

所以需要安装能够处理 vue 文件的 loader

这个 loader 不能在 webpack 文档中找,因为 webpack 与 vue 本身是没有关系的

webpack 只是一个打包工具,默认可以处理 js 文件,并且提供了一些通用的 laoder,比如

  • css-loader 处理 css 文件的打包工作
  • url-loader 处理图片字体等静态资源文件的打包工作

所以,vue 官方提供了能够处理 vue 文件的加载器

https://vue-loader.vuejs.org/zh/

安装

npm install -D vue-loader vue-template-compiler

在webpack 中配置

 

自己动手 webpack 打包 vue 单文件组件_第3张图片

 

错误信息

自己动手 webpack 打包 vue 单文件组件_第4张图片

上面错误是因为组件中有 css 代码,需要对应的 loader

安装 loader

npm i style-loader css-loader -D

配置规则

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

重新运行 

npm run dev

打包成功

运行 index.html

自己动手 webpack 打包 vue 单文件组件_第5张图片

2.6 多组件如何切换

src 目录下新建 About.vue



希望运行 index.html 的时候展示 About 组件的内容,怎么办?

可以修改 main.js

自己动手 webpack 打包 vue 单文件组件_第6张图片

重新打包 

npm run dev

index.html

 

自己动手 webpack 打包 vue 单文件组件_第7张图片

虽然实现了,但很显然,这种实现方案是不现实的

2.7 使用路由实现组件切换

其实,组件切换的逻辑应该是这样的

  • 首先,我们是一个 SPA 应用,只有一个 index.html 作为应用入口
  • 传统开发模式中的多页面,此时以多组件的方式实现。不严谨的说,就是传统模式下的一个页面对应这里的一个组件,当然我们这里组件的粒度更精细
  • 通过地址栏中的 hash 值的变化,寻找对应的组件在页面中显示

我们都知道,页面实际运行中,其实就是将 vue 实例中 render 属性指定的组件内容替换掉 index.html 中的 id=app 的元素

我们新建一个根组件,将根组件的内容显示到 index.html 中的 id=app 的元素上

当组件发生切换时,改变根组件中的内容,也就是将其他组件的内容显示到跟组件上,而根组件又渲染到 index.html 中,所以最终 html 页面也会变化

引入 vue 的官方路由 vue-router,来实现这一点

 

 

安装vue-router

npm install vue-router

 

创建根组件

src 目录下创建 App.vue



其中 router-view 作为匹配到路由规则的组件的展示区域

修改打包入口文件

main,js 中引入 vue-router,并编写路由规则,并向 vue 实例注册 router 实例

自己动手 webpack 打包 vue 单文件组件_第8张图片

还要注意,上面 render 函数中将组件名称改成了 App 组件

重新打包

通过修改地址栏中的 hash 值,可以看到对应的组件内容

自己动手 webpack 打包 vue 单文件组件_第9张图片

自己动手 webpack 打包 vue 单文件组件_第10张图片

 

 

2.8 公共组件如何处理

我们不能要求用户通过修改地址栏来切换不同的组件

必须要提供一个导航

而且这个导航,无论 Home 还是 About 组件都需要

所以不能分别在两个组件中定义一份,否则随着项目的扩大,维护成本会越来越高

解决方案:提取一个公共导航

src 目录下新建 NavBar.vue



修改 App.vue,引入上面的组件,并在 router-view 上面使用

自己动手 webpack 打包 vue 单文件组件_第11张图片

重新打包,然后运行 index.html

 

自己动手 webpack 打包 vue 单文件组件_第12张图片

 

现在我们可以通过点击连接切换组件了

至此,一个简单的 SPA 应用就完成了

2.9 项目目录调整

随着项目变大,组件会越来越多,全部都放在 src 目录下,不便于管理

另外,随着组件的增多,路由规则也会越来越多,我们当前将所有路由规则写在 入口文件 main.js 中,会让文件越来越臃肿,另外入口文件的作用应该是告诉webpack 哪些文件应该打包,而不应该放路由处理这种逻辑代码,所以应该也提取出来

具体操作

  • 新建 views 目录,存放页面级组件,如 Home.vue,About.vue
  • 新建 components 目录,存放局部组件,如 NavBar.vue
  • 新建 router 目录,其下新建 index.js,将路由处理相关代码放在这里

自己动手 webpack 打包 vue 单文件组件_第13张图片

router/index.js 中代码如下

import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
import About from '../views/About.vue'

// 安装路由功能:
Vue.use(VueRouter)
/**
 * 创建路由规则
 * 当用户请求不同的hash值时,显示不同的组件(将不同的组件内容显示在 )
 */
const routes = [
  { path: '/home', component: Home },
  { path: '/about', component: About }
]

// 创建 router 实例,然后传 `routes` 配置
const router = new VueRouter({
  routes
})
export default router

 

main.js 中代码修改如下

import Vue from 'vue'
import router from './router' // 可以省略 index.js
import App from './App.vue'

let vm = new Vue({
  el: '#app', // 指定当前vue实例的挂载点,也就是将index.html 中的id=app 的dom作为挂载点
  // 将 Home 组件中的模板和样式渲染到 index.html 页面中,具体来说,
  // 就是用模板中的内容替换 index.html 中的 id=app 的元素,也会将 css 放到页面中
  render: h => h(App),
  router
})

运行命令,重新打包,发现程序能够正常运行

npm run dev

3. 总结

经过一系列的步骤,我们手动创建的第一个单页面应用已经成功

仔细对比一下,发现与使用 vue 脚手架创建项目,目录结构基本一致了

你可能感兴趣的:(前端,Vue,webpack,webpack,单文件组件)