「这是我参与11月更文挑战的第21天,活动详情查看:2021最后一次更文挑战」
先来做下准备工作:
-
删除
webpack_babel
目录下的build
、dist
和node_modules
文件夹; -
拷贝一份
webpack_babel
目录,并重命名为webpack_vue
; -
打开
VS Code
的终端,切换目录到webpack_vue
下,运行npm install
安装当前项目(webpack_vue
)所需依赖,安装完成后,项目目录如下:
前面我们已经讲了 Webpack
可以对 js
、css
、font
和 img
等资源进行打包,而下面要讲的我们自己编写的 Vue
的代码事实上也是 JavaScript
代码,所以我们可以看下 Webpack
对我们编写的 Vue
的代码的打包。
我们打开 ./src/main.js
文件,将其中的内容修改如下:
import { sum } from './js/math.js';
import { createApp } from 'vue'; // 以模块的方式引入 Vue 中的 createApp 函数
const { formatPrice } = require('./js/format.js');
import './js/element';
console.log(sum(10, 20));
console.log(formatPrice(100));
复制代码
这次我们使用 Vue
的方式和之前不同了,之前我们使用 Vue
时,要么是通过 CDN
引入:
<script src="https://unpkg.com/vue@next"></script>
复制代码
要么是通过下载到本地的 Vue
源码文件进行引入:
<script src="../js/vue.js"></script>
复制代码
这次我们是这样引入 Vue
的:
import { createApp } from 'vue';
复制代码
这种在 js
代码中引入 Vue
的方式,意思是把 vue
当做一个模块,然后从这个模块中导入 createApp
这个函数,以便后续使用。而既然要将 vue
当成一个模块来使用,就必须在当前项目中有这个模块(即当前项目依赖 vue
),也就意味着在当前项目的 node_modules
目录下要有这个模块,因此,以这种方式使用 Vue
就需要我们先来安装这个 vue
模块:
npm install vue@next
复制代码
注意:
- 当前(
2021-11-21
)Vue
官方还没有把Vue
的版本默认切换到3.x
,所以我们安装Vue3.x
还需要在vue
后面带上@next
。否则,直接npm install vue
安装的还是Vue2.x
。- 这里的命令不需要也不应该添加
-D
(虽然加上也不会报错,但建议按照规范来),因为Vue
除了开发阶段,在生产阶段(我们把打包出来的包部署到静态服务器上后,用户访问时会将其下载下来,而下载下来的代码中也应该包含Vue
的核心代码)也是需要使用的。
安装完成后,我们从 vue
模块中导入 createApp
函数就没有问题了。下面,我们就可以像之前一样使用这个 createApp
函数创建 Vue
的应用了:
import { sum } from './js/math.js';
import { createApp } from 'vue';
const { formatPrice } = require('./js/format.js');
import './js/element';
console.log(sum(10, 20));
console.log(formatPrice(100));
// 编写 Vue 相关的代码
const app = createApp({
template: '<h2>我是 Vue 渲染出来的</h2>',
data() {
return {
title: '你好'
}
}
});
app.mount('#app');
复制代码
上面代码中,我们将创建出来的 Vue
应用挂载到了 id
为 app
的 HTML
元素上,这个元素其实在当前项目下 public
文件夹下的 index.html
这个模板文件中已经有了:
那么现在如果我们对项目进行打包,然后在浏览器上运行的话,刚才编写的这段 Vue
的代码应该是能渲染出对应的内容(template
选项中的内容)的,因为 Vue
的代码本质上也是 JavaScript
代码,而 Webpack
默认是可以对 JavaScript
代码进行打包的,所以 Webpack
应该是能对我们刚才编写的这段 Vue
的代码进行打包的。那我们来运行 npm run build
命令打包看下效果(打包过程可能会慢一点点,因为 Vue
的源代码稍微有点多):
可以看到,打包过程没有问题,再来用 Live Server
插件在浏览器中打开 ./build/index.html
文件看下页面效果:
你会发现,页面上并没有显示 template
选项中的内容,那为什么没有显示对应的内容呢?打包的过程没问题,但把打包后的代码运行在浏览器上时,对应的内容却没有显示,那我们打开浏览器的控制台看下有没有给我们相关的信息:
你会发现,控制台打印了两条警告信息,上面那条我们暂时可以忽略,我们来看下面那条警告(这条警告可能称之为错误会更好)。这条警告中提到:Component provided template option but runtime compilation is not supported in this build of Vue.
,意思是:组件提供了 template
选项,但在当前这个 Vue
构建版本中是不支持运行时编译的。
这里说的“组件”指的就是我们给 createApp
函数传入的第一个参数对象,它是一个根组件。在这个根组件里我们确实写了 template
选项,那这个 template
到时候一定是会被 Vue
的源代码解析的,但事实上,Vue
的源代码有很多版本,这些版本又可以分为两大类:
Runtime + Compiler
:即“运行时 + 编译器”版本,如果需要在客户端上编译模板(例如,将一个字符串传递给template
选项,或者使用元素的DOM
内HTML
作为模板挂载到某个元素上),这时就需要编译器,因此就需要这个完整的构建版本,即Runtime + Compiler
版本;Runtime-only
:即”仅运行时“版本,如果不需要在客户端上编译模板,用这个版本即可。
也就是说,如果在代码中没有使用 template
选项(你可能会问,没有 template
选项,那到时候还怎么渲染相应的内容呢?其实我们还有其它方式渲染内容,比如说使用 render
函数或者写成 .vue
文件,.vue
文件的解析会有相应的办法,具体后面会讲),就可以不要编译器,使用仅运行时版本即可。
但是,如果我们写了 template
选项,那就必须使用 Runtime + Compiler
版本了,因为这个版本中包含了 Compiler
的功能,而 Compiler
最主要的功能就是用来对 template
进行编译的。
而 Vue
模块默认使用的是 Runtime-only
版本的构建版本(vue.runtime.esm-bundler.js
),这就意味着它不包含对 template
这部分代码的编译功能。也就是说我们现在用的是默认的仅运行时版本,因此我们在编写的组件中使用的 template
最终相当于没有编译成功,所以在浏览器页面中就没有对应的效果。
正因如此,控制台中才出现了 Vue
提供给我们的那个警告信息,当然,它这里建议我们去给 vue
起别名(alias
),这个我们后面再讲。现在,我们需要明确的是,当前我们引用的 Vue
的版本是默认的“仅运行时”版本,不满足我们的需求,我们需要引入 Vue
的“运行时 + 编译器”版本。