从零搭建基于webpack的Electron-Vue3项目(1)——基于webpack的Vue3项目搭建

前言

本篇文章内容,主要是基于webpack的Vue3项目开发环境进行搭建,暂时还不涉及到Electron的整合。可以独立的当作一个内容来进行阅读。

项目创建

创建目录electron-vue3-webpack并进入执行npm init命令。设置了基础的项目信息后,我们开始本次的环境搭建之旅。

使用webpack

前置条件

基本熟悉webpack是什么以及它打包的运行处理过程。

环境准备

前端编写

项目根目录创建src\renderer目录,用于存放前端代码。向其中编写一个简单的前端页面以及JS:

  1. src\renderer\index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>It's Title</title>
</head>
<body>
</body>
</html>
  1. src\renderer\main.js
console.log(document.title); // 控制台输出html的title

webpack安装

命令行执行npm install -D webpack

HtmlWebpackPlugin插件安装

接下来安装webpack插件HtmlWebpackPlugin。该插件主要生成html,这里我们配置该插件template为上述index.html,配置方式见下文webpack插件配置部分。执行命令npm install --save-dev html-webpack-plugin

配置webpack

在项目根目录下创建webpack.config.js,内容如下:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/renderer/main.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
plugins: [
new HtmlWebpackPlugin({
template: './src/renderer/index.html' // 配置html模板文件
})
]
};

至此,一个webpack的基础环境配置完成:

打包运行

  1. 命令行执行npx webpack
  2. 完成编译检查dist目录;
  3. 使用浏览器打开dist/index.html,并检查控制台。

实际上,当你查看dist中的html的时候你会发现,webpack打包为我们引入了生成的js:

目前为止,我们完成了webpack的基础环境搭建以及试运行。接下来我们将引入Vue3,并以webpack打包的方式来进行Vue3的项目搭建。

使用Vue3

实际上,无论是Vue2还是Vue3,引入Vue并使用webpack来进行打包的原理都是一样的。

引入Vue3、Vue-Router以及Vuex组件

安装Vue3

# 最新稳定版
$ npm install vue@next -S

创建App.vue根组件

renderer目录下创建App.vue文件,内容如下:

<template>
<router-view/> <!-- router-view必须要引入Vue-Router组件,下文进行配置 -->
</template>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>

安装Vue-Router

$ npm install vue-router@next -S

创建Router实例

renderer目录下创建router目录,并增加index.js文件,其中内容如下:

import {createRouter, createWebHashHistory} from 'vue-router';

const routes = [ // 路由内容暂不配置
// {
// path: '/',
// name: 'Home',
// component: Home
// },
]; const router = createRouter({
history: createWebHashHistory(),
routes
}); export default router;

安装Vuex

$ npm install vuex@next -S

创建Vuex实例

renderer目录下创建store目录,并增加index.js文件,其中内容如下:

import {createStore} from 'vuex';

export default createStore({
state: {},
mutations: {},
actions: {},
modules: {}
});

编写main.js以及模板html

  1. src\renderer\index.html中的<body>标签中,添加<div id="app"></div>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>It's Title</title></head>
<body>
<div id="app"></div>
</body>
</html>
  1. 修改src\renderer\main.js代码:
import { createApp } from 'vue'
import App from './App.vue' // 引入上述
import router from './router' // 引入上述编写的router实例
import store from './store' // 引入上述vuex实例 createApp(App).use(store).use(router).mount('#app') // 链式加载,"#app"指代模板中<div id="app">

至此,目前的项目结构如下:

然而,当我们进行了上述一系列的配置以后,再次运行webpack却发现,报错了:

从报错信息可以看出,当webpack想要解析App.vue文件时候,报错提示我们:You may need an appropriate loader to handle this file type(你或许需要一个对应的loader来处理这种文件类型)。

了解到webpack打包机制的读者很容易知道,我们需要安装Vue对应的loader

安装Vue-Loader

较为熟悉的同学可能立马去官方的指引文件看文档了,其实官方文档也已经相当详细的说明了Vue-Loader的配置方式,详情见链接。(注意:截至2020/11/22文档还是Vue2版本下的配置,也许你在看的时候,已经正式替换为了Vue3的正确配置了)

  1. 安装vue-loader

  2. 修改webpack.config.js配置。

我也天真的以为Vue3的webpack也是这样的,然而最后吃了闭门羹。实际上,Vue3大不一样,接下来将有一系列的组件进行安装,在此之前我们先记录下当前的依赖:

  "devDependencies": {
"html-webpack-plugin": "^4.5.0",
"webpack": "^5.6.0",
"webpack-cli": "^4.2.0"
},
"dependencies": {
"vue": "^3.0.2",
"vue-router": "^4.0.0-rc.5",
"vuex": "^4.0.0-rc.1"
}

接着说Vue3的改变。事实上,Vue3的loader已经有了如下的变更:

  1. vue-loadernpm包为截至2020/11/22,版本为:v16.0.0-rc.2,该版本安装时需要指定版本
npm install -D vue-loader@v16.0.0-rc.2
  1. VueLoaderPlugin 的导入方式已经发生改变:
// 原先方式:
const VueLoaderPlugin = require('vue-loader/lib/plugin')
// 全新方式:
const { VueLoaderPlugin } = require('vue-loader')
  1. 移除vue-template-compiler,新增了@vue/compiler-sfc

vue-template-compiler在Vue2中是配合vue-loader组件,在Vue3中被移除了,取而代之的事@vue/compiler-sfc

npm install -D @vue/compiler-sfc

当然,为了让webpack处理.vue文件中的<style>块,以及各种css、图片等资源,我们添加一些常规的loader

npm install -D css-loader style-loader file-loader

至此,我们的package.json的依赖部分如下,大家自行对比:

  "devDependencies": {
"@vue/compiler-sfc": "^3.0.2",
"css-loader": "^5.0.1",
"file-loader": "^6.2.0",
"html-webpack-plugin": "^4.5.0",
"style-loader": "^2.0.0",
"vue-loader": "^16.0.0-rc.2",
"webpack": "^5.6.0",
"webpack-cli": "^4.2.0"
},
"dependencies": {
"vue": "^3.0.2",
"vue-router": "^4.0.0-rc.5",
"vuex": "^4.0.0-rc.1"
}

配置webpack

在上述步骤的基础上,我们终于可以进行webpack的配置编写,直接上配置:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const {VueLoaderPlugin} = require('vue-loader');
module.exports = {
entry: './src/renderer/main.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader'
},
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
},
{
test: /\.(png|jpg|gif|svg)$/,
use: [
{
loader: 'file-loader',
options: {
esModule: false, // esModule主要为了处理require图片报错的问题
}
}
],
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/renderer/index.html'
}), // 请确保引入这个插件来施展魔法
new VueLoaderPlugin()
]
};

这个配置的每一项的功能,不再赘述。不清楚的可以复习一下webpack配置,链接在此

webpack打包Vue3

迎来最后一步打包操作:npx webpack,输出对应成功结果,然后在dist目录下检查一下打包结果即可。

$ npx webpack

后续

当然,目前的demo没有任何实质的代码,还不能确保我们的工程有效。接下来的内容,我们继续编写Vue3的组件,完成一个简单的涵盖路由跳转的Example。

编写Example

编写一个Home页面、Plus页面的example,涵盖Vue3的一些新特性,API具体功能见官方网站。Example具体内容:

  • Home页面包含一个add按钮,以及可点击的卡片GO Plus Page
  • 当点击add按钮时,页面上数字+1,同时会调用VuexAPI来完成向store.number的提交+1操作;
  • 点击GO Plus Page卡片,调用Vue RouterAPI跳转到Plus页面;
  • Plus界面会显示store.number当前值,以及完成加载后会以50%概率随机加载2张(edge和chrome图标)图片的其中1张。

整体结构

Home、Plus页面

<!-- Home.vue -->
<template>
<div class="home">
<p>{{ 'number = ' + number }}</p>
<button @click="add">add</button>
<div class="card" @click="cardClick">
<p>GO Plug Page</p>
</div>
</div>
</template> <script>
// 从 vue 中引入 ref 函数
import {ref} from 'vue';
import {useRouter} from "vue-router";
import {useStore} from "vuex"; export default {
name: "Home",
setup() {
// 用 ref 函数包装一个响应式变量 number
let number = ref(0); let store = useStore(); let router = useRouter(); // 设定一个方法
function add() {
// number是被ref函数包装过了的,其值保存在.value中
number.value++;
// Vuex提交
store.commit('plus', {num: 1});
} // 定义卡片点击,进行路由跳转
function cardClick() {
router.push('/plus');
} // 将 成员 返回出去,供template中使用
return {number, add, cardClick};
}
};
</script>
<style scoped>
</style> <!-- Plus.vue -->
<template>
<div style="text-align: center">
<p>Refresh this page and you will see the icon change</p>
<div class="img-display">
<img :src="imgSrc" alt="">
</div>
<div class="number-display">
<p>{{ 'state.number = ' + state.number }}</p>
</div>
</div>
</template> <script>
import {useStore} from "vuex";
import {computed} from "vue"; export default {
name: "Plus",
setup() {
const state = useStore().state;
const imgSrc = computed(() => {
let randomBool = (Math.ceil(Math.random() * 10)) % 2 === 0;
if (randomBool) {
return require('../assets/img/edge.png');
} else {
return require('../assets/img/chrome.png');
}
}); // 计算属性
return {
state,
imgSrc
};
}
};
</script>
<style scoped>
</style>

Vuex、Router

// ---------------------------
// src/renderer/store/index.js
// ---------------------------
import {createStore} from 'vuex'; export default createStore({
state: {
number: 0,
},
mutations: {
plus(state, {num}) {
state.number += num;
}
},
actions: {},
modules: {}
}); // ----------------------------
// src/renderer/router/index.js
// ----------------------------
import {createRouter, createWebHashHistory} from 'vue-router';
// 定义路由组件, 注意,这里一定要使用 文件的全名(包含文件后缀名)
import Home from "../views/Home.vue";
import Plus from "../views/Plus.vue"; const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/plus',
name: 'Plus',
component: Plus
}
]; const router = createRouter({
history: createWebHashHistory(),
routes
}); export default router;

效果

PS:Plug页面刷新后,会清空state.number的内容所以归零。

再议webpack——热部署开发

上述进行开发的过程中,我们的流程始终的开发过程为:

  1. webpack配置;
  2. 项目编码;
  3. npx webpack
  4. 通过IDE查看页面结果,若需要修改,则回到步骤2。

实际开发中,我们会发现如下的一个问题:文件改动后,需要重新执行npx webpack命令完成编译,耗时麻烦。

watch参数

这个过程解决起来特别的简单,webpack实际上提供了运行参数watch,该参数简单来说就是在第一次调用以后并不会直接退出webpack,而会有一个单独的进程来监听webpack配置中指定入口代码执行以来整个依赖文件的变动,一旦发生了改变,则会立刻进行重新编译。关于watch参数详情,见此链接:Watch and WatchOptions | webpack

使用方式简单来说:

  • 启动 webpack 命令时,带上--watch参数
  • 配置 webpack.config.js 中设置 watch:true

这里我们使用前者

// package.json
...
"scripts": {
"build-vue3-with-webpack": "npx webpack --watch" // 添加watch参数
},
...

运行脚本后,你会看到控制台并不会在完成编译后退出,而是hold住的,且命令行最下方显示:

webpack 5.6.0 compiled successfully in 4621 ms
[webpack-cli] watching files for updates... // 监听文件更新

每当你修改了文件,你会发现命令行会有编译更新:

其实到了这一步后,开发效率已经有了很大的提升。然而有想法的开发人员会发现,倘若每次进行更新了文件,就要重新等待webpack进行编译,随着项目文件的越来越多,时间也会越来越就久,甚至到了后期,编译一次就要几分钟。其实webpack还有一个超级有用的开发者工具:webpack-dev-server

webpack-dev-server

使用webpack-dev-server的好处是修改了后不需要刷新浏览器,同时,该模块不会将文件编译输出为最终文件,而是放在内存中,转换起来很快。

安装

$ npm install webpack-dev-server -D // 请注意 —D 开发依赖

配置以及使用

webpack.config.js

需要在webpack配置文件中增加devServer节点,告知 dev server,从什么位置查找文件(但并不意味着会生成文件到该指定位置):

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const {VueLoaderPlugin} = require('vue-loader');
module.exports = {
entry: './src/renderer/main.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
devServer: { // 新增devServer节点
contentBase: './dist', // 告知dev server从什么位置查找
},
...
}
package.json/scripts

添加一个可以直接运行 dev server 的 script:

{
"name": "electron-vue3-webpack",
...
"scripts": {
"build-vue3-with-webpack": "npx webpack --watch",
"start": "webpack serve --open" // 新增脚本,启动webpack-dev-server
},
...
}

完成配置后,我们关闭之前的"npx webpack --watch",使用新的start脚本运行程序。然后进行开发:

这里和上面watch的区别在于:

  1. 没有实际的dist目录以及编译后的前端文件生成;
  2. 浏览器页面无需手动刷新页面,会自动进行;

关于webpack-dev-server的相关信息,可以进一步参考官方文档:开发环境 | webpack (docschina.org)

从零搭建基于webpack的Electron-Vue3项目(1)——基于webpack的Vue3项目搭建的更多相关文章

  1. Android零基础入门第35节:Android中基于回调的事件处理

    原文:Android零基础入门第35节:Android中基于回调的事件处理 通过前面两期掌握了Android中基于监听的事件处理的五种形式,那么本期一起来学习Android中基于回调的事件处理. 一. ...

  2. Android零基础入门第34节:Android中基于监听的事件处理

    原文:Android零基础入门第34节:Android中基于监听的事件处理 上一期我们学习了Android中的事件处理,也详细学习了Android中基于监听的事件处理,同时学会了匿名内部类形式,那么本 ...

  3. Vue3 企业级优雅实战 - 组件库框架 - 3 搭建组件库开发环境

    前文已经初始化了 workspace-root,从本文开始就需要依次搭建组件库.example.文档.cli.本文内容是搭建 组件库的开发环境. 1 packages 目录 前面在项目根目录下创建了 ...

  4. Vue3.0聊天室|vue3+vant3仿微信聊天实例|vue3.x仿微信app界面

    一.项目简介 基于Vue3.0+Vant3.x+Vuex4.x+Vue-router4+V3Popup等技术开发实现的仿微信手机App聊天实例项目Vue3-Chatroom.实现了发送图文表情消息/g ...

  5. 基于Vue+Vuex+Vue-Router+axios+mint-ui的移动端电商项目

    第一步:安装Node 1.打开NodeJS的官网,下载和自己系统相配的NodeJS的安装程序,包括32位还是64位一定要选择好,否则会出现安装问题. 下载地址:https://nodejs.org/e ...

  6. 使用Vite2+TypeScript4+Vue3技术栈,如何入手开发项目

    前言 今天,我们使用Vite2.0+Vue3+TS来试玩一下,开发一个demo项目.实战 我们,打开Vite官方网站(https://cn.vitejs.dev/). Vite (法语意为 " ...

  7. 【webpack】流行的前端模块化工具webpack初探

    从开发文件到生产文件   有一天我突然意识到一个问题,在使用react框架搭建应用时,我使用到了sass/less,JSX模版以及ES6的语法在编辑器下进行开发,使用这些写法是可以提高开发的效率.可是 ...

  8. 分享我们项目中基于EF事务机制的架构

    写在前面: 1. 本文中单元测试用到的数据库,在执行测试之前,会被清空,即使用空数据库. 2. 本文中的单元测试都是正确通过的. 要理解EF的事务机制,首先要理解这2个类:TransactionSco ...

  9. 分享我们项目中基于EF事务机制的架构 【转载】

    http://www.cnblogs.com/leotsai/p/how-to-use-entity-framework-transaction-scope.html 写在前面: 1. 本文中单元测试 ...

  10. webpack入门(二)what is webpack

    webpack is a module bundler.webpack是一个模块打包工具,为了解决上篇一提到的各种模块加载或者转换的问题. webpack takes modules with dep ...

随机推荐

  1. Jmeter HTML 报告、Jenkins 配置

    目录 Jmeter 生成 HTML 测试报告 Jenkins 配置 Jmeter 生成 HTML 测试报告 JMeter 支持生成 HTML 测试报告, 以便从测试计划中获得图表和统计信息. 以上定义 ...

  2. 实例说明C++的virtual function的作用以及内部工作机制初探

    C++为何要引入virtual function? 来看一个基类的实现: 1 class CBase 2 { 3 public: 4 CBase(int id) : m_nId(id), m_pBas ...

  3. lsyncd替代inotify+rsync实现实时同步

    因公司业务需要需要实时同步日志文件,刚一开始使用的是inotify+rsync来实现实时同步,但时间久而久之发现同步的速度越来越慢,往往延迟好几个小时.查了一下网上的inotify+rsync方案基本 ...

  4. JDK1.8源码(五)——java.util.Vector类

    JDK1.8源码(五)--java.lang. https://www.cnblogs.com/IT-CPC/p/10897559.html

  5. 板子题 Sol

    RT Cyber_Tree 出了一道板子题... 这题乍看之下貌似还不戳,但如果您做过类似的题,那么这就是一道板子题.... 首先明确要求的是什么,如果我们只考虑权值最大而不考虑最小距离,那么要求的显 ...

  6. TCP超时重传、序列号、滑动窗口简介

    文章目录 12 TCP:传输控制协议(初步) 12.1 引言 12.1.1 ARQ和重传 12.1.2 分组窗口和滑动窗口 12.1.3 变量窗口:流量控制和拥塞控制 12.1.4 变量窗口:设置重传 ...

  7. c# List集合类常用操作:二、增加

    所有操作基于以下类 class Employees { public int Id { get; set; } public string Name { get; set; } public stri ...

  8. 硕盟SM-T54(TYPE C转HDMI+VGA+USB3.0+PD3.0)

    硕盟SM-T54是一款TYPE C转HDMI+VGA+USB3.0+PD3.0四口扩展坞,您可以将含有USB 3.1协议的电脑主机,通过此产品连接到具有HDMI或VGA的显示器.电视机或其他显示设备. ...

  9. IDEA weblogic远程调试

    weblogic远程调试 这里我们使用vulhub的镜像作为初始构建镜像搭建漏洞环境 1. 搭建docker环境 新建一个目录,创建两个文件 DockerFile FROM vulhub/weblog ...

  10. 现在互联网好多bug 想到都烦

    我接触计算机十多年了,只是在15年前发布一篇给计算机有关的技术文章,后来就在也不发表了,今天在163博客写个备录,,写到一半结果误 关了,,浪费了好几个小时,还以为像以前那样,又要重写,,这也是我不爱 ...