vue-cli3脚手架配合express搭建devserver

我的最新博客地址:我的最新博客

目录

写在前面

说说旧版的vue-cli搭建devserver

webpack-dev-middleware

webpack-hot-middleware

http-proxy-middleware

旧版的vue-cli结合express所构建的devserver

新版的@vue/cli构建devserver

新版脚手架的devserver配置(重要)


写在前面

近期本人在github上自己用最新的vue-cli3脚手架初始化了一个移动端的项目,因为项目中要访问某大厂的后端接口,而他们的接口又设置某些头部跨域验证,所以,不得不在本地起一个devserver,用作接口代理转发。

说说旧版的vue-cli搭建devserver

在说新版的脚手架之前,先来看一看以前的vue脚手架怎么配合express来搭建devserver。

我们在使用第三方框架例如vue,react在进行开发时,其代码是不能直接运行在浏览器上的,原因是浏览器不认识那些语法,这时我们会使用webpack进行编译打包转换为浏览器可执行的代码。但是试想我们在进行开发时,没写一行代码就要进行编译打包,然后再在浏览器里运行查看效果,这无疑大大降低了我们的开发效率,所以我们能不能让工具自己检测到代码变化然后自己自动的编译打包,然后我们便可以实时的查看到页面效果了。

首先,我们需要了解构建自己的devserver所需要用到的最基本的几个插件:webpack-dev-middlewarewebpack-hot-middlewarehttp-proxy-middleware

webpack-dev-middleware

webpack-dev-middleware插件,该插件对文件进行监听,当检测到代码变化时会主动对代码进行重新的编译,正如官网所介绍的,使用此插件的几个好处:

1.No files are written to disk, rather it handles files in memory.(编译后的文件会存在于内存中,而不是在磁盘中)

2.If files changed in watch mode, the middleware delays requests until compiling has completed.(如果文件的变化处于watch模式下,该中间件会在编译完成之后再进行资源的请求)

3.Supports hot module reload (HMR).(支持模块热加载技术)

具体使用,我就不多介绍了,请去看官网 webpack-dev-middleware的用法(传送门)

webpack-hot-middleware

webpack-hot-middleware是用来进行页面的热重载的,刷新浏览器 一般和 webpack-dev-middleware 配合使用,实现热加载功能。它的核心功能就是实现浏览器端的热重载,和webpack-dev-server达到类似的功能。关于它的使用,总结为以下几点:

1.在webpack的配置文件的plugins中增加HotModuleReplacementPlugin();

2.在webpack的配置文件entry中新增webpack-hot-middleware/client入口,比如下面这样:

//  webpack.config.js
const path = require('path')
module.exports = {
    entry: ['webpack-hot-middleware/client?reload=true', path.resolve(__dirname, './src/main.js'))]
    ......
}

3.在server文件中,express中加入中间件webpack-hot-middleware,如下这样:

const express = require('express');
const webpack = require('webpack');
const webpackConfig = require('./webpack.config');

const compiler = webpack(webpackConfig);

const app = express();

app.use(require('webpack-hot-middleware')(compiler));

4.在入口文件处添加如下代码:

    if (module.hot) {
      module.hot.accept()
    }

该插件的详细使用请查看官网:webpack-hot-middleware详细介绍(传送门)

http-proxy-middleware

http-proxy-middleware用于将请求转发给其它服务器,常用于本地开发服务器的接口代理。

这个插件使用比较简单,这里不再赘述了,详细使用请查看官网:传送门

旧版的vue-cli结合express所构建的devserver

通过我们上面的分析,我们大致有了构建devserver的方向,话不多说,直接上code:

先来看node入口文件server.js:

var path = require('path')
var express = require('express')
var webpack = require('webpack')
var proxyMiddleware = require('http-proxy-middleware')
var webpackConfig = require('./webpack.dev.conf')

var proxyTable = config.dev.proxyTable

var app = express()

var compiler = webpack(webpackConfig)

var devMiddleware = require('webpack-dev-middleware')(compiler, {
  publicPath: webpackConfig.output.publicPath,
  quiet: true
})

var hotMiddleware = require('webpack-hot-middleware')(compiler, {
  log: info => console.log(info)
})

Object.keys(proxyTable).forEach(function (context) {
  var options = proxyTable[context]
  if (typeof options === 'string') {
    options = { target: options }
  }
  app.use(proxyMiddleware(options.filter || context, options))
})

// handle fallback for HTML5 history API
app.use(require('connect-history-api-fallback')())

app.use(devMiddleware)

app.use(hotMiddleware)

app.listen(3000)

然后webpack的配置文件入口处添加 'webpack-hot-middleware/client?reload=true' ,plugins中添加new webpack.HotModuleReplacementPlugin()。还有项目主入口文件记得添加接受模块热更新的逻辑代码即可。

以上就是旧版的vue-cli脚手架结合express及其中间件所构建的devserver。

下面,我们来看最新的vue-cli3(即@vue/cli)怎么构建devserver呢?

新版的@vue/cli构建devserver

众所周知,使用最新版的vue脚手架@vue/cli的时候,其配置文件不再是webpack.config.js,而变成了vue.config.js文件,我们阅读过它的文档都知道,它的配置和原始的webpack配置并不相同,而是内部做了一些封装。关于vue.config.js的详细配置请查看@vue/cli配置文件文档

下面最关键的部分来了:我会写出我思考的全部过程,会写的很细,如何从零到有。

我刚开始分析使用最新版vue脚手架进行构建devserver的时候,想到只要能够通过vue.config.js经过转换之后得到最原始的webpack.config.js的配置内容即可,那接下来就可以使用旧版的那一套。思路确定了之后,首先明确,既然脚手架的作者让我们遵循它所制定的一套规则(即@vue/cli官方文档)配置vue.config.js,那么其内部肯定是写了如何把这个vue.config.js解析为最原始的webpack.config.js的配置文件。

明确了第一个目标后,我先去看了项目的package.json:

众所周知,这个serve命令是我们在启动本地开发环境时的命令。由这个指令我去看了node_modules里面的@vue包下面的cli-service包:

然后,先看此包的package.json文件(即node_modules/@vue/cli-service/package.json):

可以看到main和bin的配置,然后知道此包对外暴漏的入口文件为lib/Service.js文件,而根项目目录所执行的serve命令中的vue-cli-service其实就是此包(即node_modules/@vue/cli-service)下的bin文件夹下的vue-cli-service.js文件,我们打开bin文件夹和lib文件夹,果不其然:

然后,我先去仔细阅读了执行vue-cli-service命令的文件,即bin/vue-cli-service.js文件,代码量并不大:

#!/usr/bin/env node

const semver = require('semver')
const { error } = require('@vue/cli-shared-utils')
const requiredVersion = require('../package.json').engines.node

if (!semver.satisfies(process.version, requiredVersion)) {
  error(
    `You are using Node ${process.version}, but vue-cli-service ` +
    `requires Node ${requiredVersion}.\nPlease upgrade your Node version.`
  )
  process.exit(1)
}

const Service = require('../lib/Service')
const service = new Service(process.env.VUE_CLI_CONTEXT || process.cwd())

const rawArgv = process.argv.slice(2)
const args = require('minimist')(rawArgv, {
  boolean: [
    // build
    'modern',
    'report',
    'report-json',
    'watch',
    // serve
    'open',
    'copy',
    'https',
    // inspect
    'verbose'
  ]
})
const command = args._[0]

service.run(command, args, rawArgv).catch(err => {
  error(err)
  process.exit(1)
})

可以看到 new Service创建了一个Service的实例,变量command为我们所执行的命令的环境标志(即若我们执行的是“vue-cli-service serve”命令,那command即为serve),最后执行了实例的run方法,很明显run的是command命令。

然后再去看看lib/Service.js主入口文件(代码量有点大,就不在此复制粘贴了),我们挑重要的看:

module.exports = class Service {
    constructor() {...}
    
    resolvePkg() {...}

    init() {...}

    loadEnv() {...}

    resolvePlugins() {...}

    async run() {...}    

    resolveChainableWebpackConfig() {...}

    resolveWebpackConfig() {...}

    loadUserOptions() {...}

}

经过一番分析之后得知,每个方法的用意,比如 init 方法,它就是初始化配置的,把一些vue.config.js里面的一些配置加入到实例属性上(比如chainWebpack,configureWebpack),以便于以后的解析。resolveChainableWebpackConfig方法就是解析vue.config.js中的chainWebpack配置,将其转化为原始的webpack配置。resolveWebpackConfig方法就是将配置转化为原始的webpack配置的方法,只要调用Service实例的resolveWebpackConfig,即可将vue.config.js配置转换为webpack.config.js(笔者还去读了里边很多的文件,过程太复杂就不再这里一一赘述了)。

然后发现此包中的webpack.config.js文件:

// this file is for cases where we need to access the
// webpack config as a file when using CLI commands.

let service = process.VUE_CLI_SERVICE

if (!service || process.env.VUE_CLI_API_MODE) {
  const Service = require('./lib/Service')
  service = new Service(process.env.VUE_CLI_CONTEXT || process.cwd())
  service.init(process.env.VUE_CLI_MODE || process.env.NODE_ENV)
}

module.exports = service.resolveWebpackConfig()

看到最后的module.exports = service.resolveWebpackConfig(),我就知道我找到我所想要的东西了,原来此文件就是将vue.config.js转换为最原始的webpack的配置文件,再加上此js文件最开头的那两行注释:this file is for cases where we need to access the webpack config as a file when using CLI commands.(此文件用于在使用CLI命令时需要将webpack配置文件作为文件访问的情况。)这两行注释更加明确了我的寻找是正确的。(其实,笔者一开始没注意到这个文件,直到看到lib/commands/serve.js文件时才去看了webpack.config.js,才发现原来众里寻他千百度,那文件却在手边眼前处......)

新版脚手架的devserver配置(重要)

由此,我们已经找到了我们想要的把vue.config.js转换为最原始的webpack配置文件,所以,我们想要构建devserver变得异常容易,只需要将webpack的配置文件引入的地方改成下面的引入方式即可:

const webpackConfig = require('@vue/cli-service/webpack.config.js')

由此,我们就已经完成了我们的目标:利用@vue/cli脚手架搭配express搭建devserver。

纯属个人理解,如有异议,欢迎大家留言来一起探讨。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值