webpack-vue
平时我们可以通过 Vue-cli 快速搭建 Vue 开发环境,但是要知道 Vue-cli 也是基于 webpack 构建的,那么如何使用 webpack 搭建 Vue 开发环境呢?
前面已经了解了 webpack 如何对 js、css、图片、字体等其他资源进行打包处理,而想要搭建 Vue 开发环境,主要就是对 .vue
文件进行处理。
准备
现在 Vue@3.x 已经发布了,因此需要安装 vue@next
。
npm install vue@next
在 src
文件夹下新增 vue
文件夹,新建 App.vue
文件,同时在 index.js
中导入:
project
webpack-demo
|- node_modules
|- package-lock.json
|- package.json
|- postcss.config.js
|- babel.config.js
|- webpack.config.js
|- /public
|- favicon.ico
|- index.html
|- /src
|- /css
|- style.css
|- title.less
|- /font
|- iconfont.css
|- iconfont.eot
|- iconfont.ttf
|- iconfont.woff
|- iconfont.woff2
|- /img
|- avatar.png
|- wallpaper.png
|- /js
|- format.js
|- math.js
+ |- /vue
+ |- App.vue
|- index.js
App.vue
<template>
<h2>我是Vue渲染出来的</h2>
<h2>{{title}}</h2>
</template>
<script>
export default {
data() {
return {
title: "Hello Vue"
}
}
}
</script>
<style>
</style>
index.js
+ import { createApp } from "vue";
import { sum } from "./js/math.js";
const { priceFormat } = require("./js/format");
+ import App from "./vue/App.vue";
import "./css/style.css";
import "./css/title.less";
import "./font/iconfont.css";
// 导入图片
import avatar from "./img/avatar.png";
console.log(sum(10, 20));
console.log(priceFormat());
const div = document.createElement("div");
div.className = "title";
div.innerHTML = "webpack-css";
// 方式一:设置 img 元素的 src
const imgEl = document.createElement("img");
imgEl.src = avatar;
// 方式二:设置背景图片
const bgEl = document.createElement("div");
bgEl.className = "image-bg";
// i元素
const iEl = document.createElement('i');
iEl.className = "iconfont icon-ashbin";
document.body.appendChild(div);
document.body.appendChild(imgEl);
document.body.appendChild(bgEl);
document.body.appendChild(iEl);
// babel
const messages = [1, 2, 3];
messages.map((n) => n + 1);
+ // vue
+ const app = createApp(App);
+ app.mount("#app");
配置 webpack
默认情况下 vue-loader
是对 Vue@2.x 准备的,而我们是 Vue@3.x,因此需要安装 vue-loader@next
,而 vue-loader
又依赖于 @vue/compiler-sfc
的,因此也需要安装。
npm install vue-loader@next @vue/compiler-sfc -D
修改 webpack.config.js
配置:
webpack.config.js
//...
+ const { VueLoaderPlugin } = require("vue-loader/dist/index");
//...
module.exports = {
module: {
rules: [
...
+ {
+ test: /\.vue$/,
+ loader: "vue-loader"
+ }
//...
]
}
plugins: [
...
+ new VueLoaderPlugin()
...
]
}
执行 npm run build
,打开浏览器可以看到渲染正常。但是浏览器控制台出现了一个警告:
runtime-core.esm-bundler.js:4432 Feature flags __VUE_OPTIONS_API__, __VUE_PROD_DEVTOOLS__ are not explicitly defined. You are running the esm-bundler build of Vue, which expects these compile-time feature flags to be globally injected via the bundler config in order to get better tree-shaking in the production bundle.
For more details, see https://link.vuejs.org/feature-flags.
这是因为从 3.0.0-rc.3 开始,Vue 希望我们手动设置全局标识,这样做的好处是可以对最终的打包代码进行 tree-shaking 优化。
全局标识有两个:
- __VUE_OPTIONS_API__(是否支持 Options API,默认为
true
) - __VUE_PROD_DEVTOOLS__(是否在生产环境中支持 devtools,默认为
false
)
为了在 webpack 中配置全局标识,可以使用 DefinePlugin
。
webpack.config.js
module.exports = {
plugins: [
...
new DefinePlugin({
BASE_URL: "'./'",
+ __VUE_OPTIONS_API__: true,
+ __VUE_PROD_DEVTOOLS__: false
}),
...
]
}
这时重新打包后,浏览器控制台的警告就会消除了。
总结
在这个案例中对 .vue 单文件进行了解析:安装 vue-loader
和 @vue/compiler-sfc
,同时配置 VueLoaderPlugin
,在重新打包后浏览器控制台会报一个全局标识的警告,通过配置 DefinePlugin
手动配置全局标识消除全局标识警告。