详解如何将 Vue-cli 改造成支持多页面的 history 模式


Posted in Javascript onNovember 20, 2017

标题可能描述不准确, 大概就是这么个需求:

用 Vue-cli 搭建一个多入口, 多页面的站点, 也就是通过html-webpack-plugin插件会生成多个 .html 文件, 在默认下, 是只有 index.html 这个入口可以用 history 模式, 如: http://www.xxx.com/xxx/xxx, 而其他的入口只能用 hash 模式, 如: http://www.xxx.com/admin.html#/xxx/xxx, 因为webpack-dev-middleware会将所有的路由都指向 index.html 文件, 假如线上的时候, 都需要 history 模式, 这样多少会造成麻烦.

真是太二了, 刚写完文章就发现connect-history-api-fallback这个插件就是做这个的...

方法更新如下:

修改 build/dev-server.js 文件

app.use(require('connect-history-api-fallback')())

改成

var history = require('connect-history-api-fallback')
app.use(history({
  rewrites: [
    { from: 'index', to: '/index.html'}, // 默认入口
    { from: /\/backend/, to: '/backend.html'}, // 其他入口
    { from: /^\/backend\/.*$/, to: '/backend.html'},
  ]
}))

具体规则就参考: https://github.com/bripkens/connect-history-api-fallback

-------------- 以下代码请无视 --------------

下面我们就来改造下, 让所有入口都支持 history 模式:

1. 首先, 我们在 build 目录下建立个 setup-dev-server.js 文件, 里面代码如下:

const path = require('path')
const webpack = require('webpack')
const clientConfig = require('./webpack.dev.conf') // 引入开发环境下的 webpack 配置文件

module.exports = function setupDevServer(app, opts) {
  const clientCompiler = webpack(clientConfig)
  // 加载 webpack-dev-middleware 插件
  const devMiddleware = require('webpack-dev-middleware')(clientCompiler, {
    publicPath: clientConfig.output.publicPath,
    stats: {
      colors: true,
      chunks: false
    }
  })
  app.use(devMiddleware)
  // 关键代码开始
  // 因为开发环境下, 所有的文件都在内存里, 包括由 html-webpack-plugin 生成的 .html 文件, 所以我们需要用 webpack-dev-middleware 提供的 api 从内存里读取
  clientCompiler.plugin('done', () => {
    const fs = devMiddleware.fileSystem // 访问内存
    const filePath = path.join(clientConfig.output.path, 'index.html') // 读取的文件, 文件名和 html-webpack-plugin 生成的文件名要求一致
    if (fs.existsSync(filePath)) { // 判断下文件是否存在
      const index = fs.readFileSync(filePath, 'utf-8') // 从内存里取出
      opts.indexUpdated(index) // 将取出的文件通过 indexUpdated 函数返回, 这个函数怎么来的, 后面会说明
    }
    const adminPath = path.join(clientConfig.output.path, 'backend.html') // 同上, 这是第二个入口生成的 .html 文件, 如果还有其他入口, 这个多复制几份
    if (fs.existsSync(adminPath)) {
      const admin = fs.readFileSync(adminPath, 'utf-8')
      opts.adminUpdated(admin)
    }
  })

  // 加载热重载模块
  app.use(require('webpack-hot-middleware')(clientCompiler))
  var hotMiddleware = require('webpack-hot-middleware')(clientCompiler)
  // 当修改 html-webpack-plugin 模版时, 自动刷新整个页面
  clientCompiler.plugin('compilation', function(compilation) {
    compilation.plugin('html-webpack-plugin-after-emit', function(data, cb) {
      hotMiddleware.publish({
        action: 'reload'
      })
      cb()
    })
  })
}

2. 修改 build/dev-server.js 文件

主要修改文件中var app = express()到module.exports = app.listen(port, function (err) {之间的代码

var app = express()

var indexHTML
var adminHTML

// 引用前面创建的文件, 并将两个保存内容的函数传过去, 这里保存内容的变量写成对象或者数组也可以, 还可以少点代码
require('../config/setup-dev-server')(app, {
  indexUpdated: index => {
    indexHTML = index
  },
  adminUpdated: index => {
    adminHTML = index
  },
})

// 加载反向代理
Object.keys(proxyTable).forEach(function(context) {
  var options = proxyTable[context]
  if (typeof options === 'string') {
    options = {
      target: options
    }
  }
  app.use(proxyMiddleware(context, options))
})
// 设置静态文件夹路由
var staticPath = path.posix.join(config.assetsPublicPath, config.assetsSubDirectory)
app.use(staticPath, express.static('./static'))

// 入口1路由
app.get(['/', '/category/:id'], (req, res) => {
  res.send(indexHTML)
})

// 入口2路由
app.get(['/backend', '/backend/*'], (req, res) => {
  res.send(adminHTML)
})

// 404 页面
app.get('*', (req, res) => {
  res.send('HTTP STATUS: 404')
})

app.use(function(req, res, next) {
  var err = new Error('Not Found')
  err.status = 404
  next(err)
})

app.use(function(err, req, res) {
  res.status(err.status || 500)
  res.send(err.message)
})

module.exports = app.listen(port, function(err) {

3. npm run dev 开始愉快的写代码吧

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript.The.Good.Parts阅读笔记(一)假值与===运算符
Nov 16 Javascript
将HTML的左右尖括号等转义成实体形式的两种实现方式
May 04 Javascript
Javascript堆排序算法详解
Dec 03 Javascript
Node.js中child_process实现多进程
Feb 03 Javascript
浏览器兼容性问题大汇总
Dec 17 Javascript
js querySelector() 使用方法
Dec 21 Javascript
javascriptvoid(0)含义以及与"#"的区别讲解
Jan 19 Javascript
浅谈Vue.js组件(二)
Apr 09 Javascript
vue input标签通用指令校验的实现
Nov 05 Javascript
JavaScript实现简单计算器功能
Dec 19 Javascript
vue 监听 Treeselect 选择项的改变操作
Aug 31 Javascript
Vue中强制组件重新渲染的正确方法
Jan 03 Vue.js
详解Vue2 SSR 缓存 Api 数据
Nov 20 #Javascript
Three.js开发实现3D地图的实践过程总结
Nov 20 #Javascript
jquery ztree实现右键收藏功能
Nov 20 #jQuery
深入理解vuex2.0 之 modules
Nov 20 #Javascript
three.js中文文档学习之如何本地运行详解
Nov 20 #Javascript
AngularJS实现自定义指令及指令配置项的方法
Nov 20 #Javascript
详解webpack + react + react-router 如何实现懒加载
Nov 20 #Javascript
You might like
在“咖啡之国”感受咖啡文化
2021/03/03 咖啡文化
php 字符串压缩方法比较示例
2014/01/23 PHP
php实现根据url自动生成缩略图的方法
2014/09/23 PHP
PHP类相关知识点实例总结
2016/09/28 PHP
日期 时间js控件
2009/05/07 Javascript
javascript检测浏览器flash版本的实现代码
2011/12/06 Javascript
关于JS字符串函数String.replace()
2013/04/07 Javascript
javascript 获取模态窗口的滚动位置代码
2013/08/06 Javascript
js动画效果制件让图片组成动画代码分享
2014/01/14 Javascript
JS创建自定义表格具体实现
2014/02/11 Javascript
JavaScript中0和""比较引发的问题
2016/05/26 Javascript
AngularJS入门教程中SQL实例详解
2016/07/27 Javascript
详解vue express启动数据服务
2017/07/05 Javascript
javascript  数组排序与对象排序的实例
2017/07/17 Javascript
详解Web使用webpack构建前端项目
2017/09/23 Javascript
使用JS获取SessionStorage的值
2018/01/12 Javascript
JS实现基于拖拽改变物体大小的方法
2018/01/23 Javascript
vue使用el-upload上传文件及Feign服务间传递文件的方法
2019/03/15 Javascript
微信小程序手动添加收货地址省市区联动
2020/05/18 Javascript
解决Vue的项目使用Element ui 走马灯无法实现的问题
2020/08/03 Javascript
JavaScript实现商品评价五星好评
2020/11/30 Javascript
[01:26]神话结束了,却也刚刚开始——DOTA2新英雄玛尔斯驾临战场
2019/03/10 DOTA
Python的Asyncore异步Socket模块及实现端口转发的例子
2016/06/14 Python
Python面向对象程序设计OOP深入分析【构造函数,组合类,工具类等】
2019/01/05 Python
Django 允许局域网中的机器访问你的主机操作
2020/05/13 Python
无惧面试,带你搞懂python 装饰器
2020/08/17 Python
使用CSS3来绘制一个月食图案
2015/07/18 HTML / CSS
HTML5 window/iframe跨域传递消息 API介绍
2013/08/26 HTML / CSS
美国专业级皮肤病和spa品质护肤品的高级零售网站:SkinCareRx
2017/02/06 全球购物
大学生职业生涯规划书范文
2014/01/04 职场文书
财务会计专业个人求职信范本
2014/01/08 职场文书
2014旅游局领导班子四风问题对照检查材料思想汇报
2014/09/19 职场文书
法院干警四风问题个人对照检查材料思想汇报
2014/10/07 职场文书
银行开户授权委托书格式
2014/10/10 职场文书
谢师宴邀请函
2015/02/02 职场文书
学雷锋感言
2015/08/03 职场文书