
六、Vue-webpack基础打包
一、Vue 开发模式
目前我们使用 vue 的过程都是在 html 文件中,通过 template 编写自己的模板、脚本逻辑、样式等
但是随着项目越来越复杂,我们会采用组件化的方式来进行开发:这就意味着每个组件都会有自己的模板、脚本逻辑、样式等
当然我们依然可以把它们抽离到单独的 js、css 文件中,但是它们还是会分离开来;也包括我们的 script 是在一个全局的作用域下,很容易出现命名冲突的问题
并且我们的代码为了适配一些浏览器,必须使用 ES5 的语法
在我们编写代码完成之后,依然需要通过工具对代码进行构建、代码
所以在真实开发中,我们可以通过一个后缀名为 .vue 的 single-file components (单文件组件) 来解决,并且可以使用 webpack 或者 vite 或者 rollup 等构建工具来对其进行处理
单文件特点
代码的高亮
ES6、CommonJS 的模块化能力
组件作用域的 CSS
可以使用预处理器来构建更加丰富的组件,比如 TypeScript、Babel、Less、Sass 等
如何支持 SFC
方式一:使用 Vue CLI 来创建项目,项目会默认帮助我们配置好所有的配置选项,可以在其中直接使用.vue 文件
方式二:自己使用 webpack 或 rollup 或 vite 这类打包工具,对其进行打包处理
最终,无论是后期我们做项目,还是在公司进行开发,通常都会采用 Vue CLI 的方式来完成
二、webpack
随着前端的快速发展,目前前端的开发已经变的越来越复杂了:
- 比如开发过程中我们需要通过模块化的方式来开发
- 比如也会使用一些高级的特性来加快我们的开发效率或者安全性,比如通过 ES6+、TypeScript 开发脚本逻辑, 通过 sass、less 等方式来编写 css 样式代码
- 比如开发过程中,我们还希望实时的监听文件的变化来并且反映到浏览器上,提高开发的效率
- 比如开发完成后我们还需要将代码进行压缩、合并以及其他相关的优化
- 等等….
对于很多的前端开发者来说,并不需要思考这些问题,日常的开发中根本就没有面临这些问题:
- 这是因为目前前端开发我们通常都会直接使用三大框架来开发:Vue、React、Angular
- 但是事实上,这三大框架的创建过程我们都是借助于脚手架(CLI)的
- Vue-CLI、create-react-app、Angular-CLI 都是基于 webpack 来帮助我们支持模块化、less、 TypeScript、打包优化等的
webpack 是什么
webpack is a static module bundler for modern JavaScript applications.
webpack 是一个静态的模块化打包工具,为现代的 JavaScript 应用程序;
对上面的解释进行拆解:
- 打包 bundler:webpack 可以将帮助我们进行打包,所以它是一个打包工具
- 静态的 static:这样表述的原因是我们最终可以将代码打包成最终的静态资源(部署到静态服务器)
- 模块化 module:webpack 默认支持各种模块化开发,ES Module、CommonJS、AMD 等
- 现代的 modern:我们前端说过,正是因为现代前端开发面临各种各样的问题,才催生了 webpack 的出现和发展
webpack 安装
webpack 的安装目前分为两个:webpack、webpack-cli
那么它们是什么关系呢?
- 执行 webpack 命令,会执行 node_modules 下的.bin 目录下的 webpack
- webpack 在执行时是依赖 webpack-cli 的,如果没有安装就会报错
- 而 webpack-cli 中代码执行时,才是真正利用 webpack 进行编译和打包的过程
- 所以在安装 webpack 时,我们需要同时安装 webpack-cli(第三方的脚手架事实上是没有使用 webpack-cli 的,而是类似于自己的 vue-service-cli 的东西)
1 | npm install webpack webpack-cli –g # 全局安装 |
webpack 默认打包
我们可以通过 webpack 进行打包,之后运行打包之后的代码
- 在目录下直接执行 webpack 命令
- 生成一个 dist 文件夹,里面存放一个 main.js 的文件,就是我们打包之后的文件
- 这个文件中的代码被压缩和丑化了
- 暂时不关心他是如何做到的,后续讲 webpack 实现模块化原理时会再次讲到
- 另外发现代码中依然存在 ES6 的语法,比如箭头函数、const 等,这是因为默认情况下 webpack 并不清楚我 们打包后的文件是否需要转成 ES5 之前的语法,后续需要通过 babel 来进行转换和设置
我们发现是可以正常进行打包的,但是有一个问题
- webpack 是如何确定我们的入口的呢? 事实上,当我们运行 webpack 时,webpack 会查找当前目录下的 src/index.js 作为入口
- 所以,如果当前项目中没有存在 src/index.js 文件,那么会报错
当然,我们也可以通过配置来指定入口和出口 Webpack 的默认打包
- npx webpack –entry ./src/main.js –output-path ./build
局部 webpack
前面我们直接执行 webpack 命令使用的是全局的 webpack,
如果项目中使用的 webpack 版本和全局的不一样,就会产生冲突。
如果希望使用局部的可以按照下面的步骤来操作。
第一步:创建 package.json 文件,用于管理项目的信息、库依赖等
- npm init
第二步:安装局部的 webpack
- npm install webpack webpack-cli -D
第三步:使用局部的 webpack
- npx webpack
第四步:在 package.json 中创建 scripts 脚本,执行脚本打包即可创建局部的
1 | "scripts": { |
- npm run build
对 vue 代码的打包
npm i vue@next
1 | import { createApp } from 'vue'; // Vue代码 const app = createApp({ template: " |
因为使用的 vue 打包后的版本不对
vue 打包后不同版本解析
vue(.runtime).global(.prod).js:
- 通过浏览器中的 script 标签直接引用
- 之前通过 CDN 引入和下载的 Vue 版本就是这个版本
- 会暴露一个全局的 Vue 来使用
vue(.runtime).esm-browser(.prod).js:
- 用于通过原生 ES 模块导入使用 (在浏览器中通过
<script type=module>
来使用)
vue(.runtime).esm-bundler.js:
- 用于 webpack,rollup 和 parcel 等构建工具
- 构建工具中默认是 vue.runtime.esm-bundler.js
- 如果我们需要解析模板 template,那么需要手动指定 vue.esm-bundler.js
vue.cjs(.prod).js:
- 服务器端渲染使用
- 通过 require()在 Node.js 中使用
runtime 指的是运行时,不包含对 template 的编译
prod 是指生产环境,压缩后的代码
运行时+编译器 vs 仅运行时
在 Vue 的开发过程中我们有三种方式来编写 DOM 元素:
- 方式一:template 模板的方式(之前经常使用的方式)
- 方式二:render 函数的方式,使用 h 函数来编写渲染的内容
- 方式三:通过.vue 文件中的 template 来编写模板
它们的模板分别是如何处理的呢?
- 方式二中的 h 函数可以直接返回一个虚拟节点,也就是 Vnode 节点
- 方式一和方式三的 template 都需要有特定的代码来对其进行解析:
- 方式三.vue 文件中的 template 可以通过在 vue-loader 对其进行编译和处理
- 方式一种的 template 我们必须要通过源码中一部分代码来进行编译
所以,Vue 在让我们选择版本的时候分为
运行时+编译器
仅运行时
- 运行时+编译器包含了对 template 模板的编译代码,更加完整,但是也更大一些
- 仅运行时没有包含对 template 版本的编译代码,相对更小一些
1 | // 更改代码 指定版本即可正常显示 |
VSCode 对 SFC 文件的支持
插件一:Vetur,从 Vue2 开发就一直在使用的 VSCode 支持 Vue 的插件
插件二:Volar,官方推荐的插件(后续会基于 Volar 开发官方的 VSCode 插件)
编写 App.vue 代码
1 | <template> |
导入
1 | import { createApp } from 'vue/dist/vue.esm-bundler'; import App from |
App.vue 的打包过程
对代码打包会报错:我们需要合适的 Loader 来处理文件
- npm install vue-loader -D
在 webpack 的模板规则中进行配置:
1 | { |
打包依然会报错,这是因为我们必须添加@vue/compiler-sfc 来对 template 进行解析
- npm install @vue/compiler-sfc -D
另外我们需要配置对应的 Vue 插件
1 | const { VueLoaderPlugin } = require('vue-loader/dist/index'); |
重新打包即可支持 App.vue 的写法