详解如何将 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 相关文章推荐
最简单的js图片切换效果实现代码
Sep 24 Javascript
用函数模板,写一个简单高效的 JSON 查询器的方法介绍
Apr 17 Javascript
js调用图片隐藏&显示实现代码
Sep 13 Javascript
jquery购物车实时结算特效实现思路
Sep 23 Javascript
Js保留小数点的4种效果实现代码分享
Apr 12 Javascript
禁用页面部分JavaScript不是全部而是部分
Sep 03 Javascript
js实现常用排序算法
Aug 09 Javascript
SelecT下拉框选中和取值的解决方法
Nov 22 Javascript
详解为Angular.js内置$http服务添加拦截器的方法
Dec 20 Javascript
jquery树形插件zTree高级使用详解
Aug 16 jQuery
小程序接入腾讯位置服务的详细流程
Mar 03 Javascript
js函数柯里化的方法和作用实例分析
Apr 11 Javascript
详解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
php.ini 中文版
2006/10/28 PHP
php设计模式 Chain Of Responsibility (职责链模式)
2011/06/26 PHP
浅析php单例模式
2014/11/25 PHP
如何用PHP做到页面注册审核
2017/03/02 PHP
Laravel 5.2 文档 数据库 ―― 起步介绍
2019/10/21 PHP
JS实现图片横向滚动效果示例代码
2013/09/04 Javascript
Jquery图片延迟加载插件jquery.lazyload.js的使用方法
2014/05/21 Javascript
extjs 如何给column 加上提示
2014/07/29 Javascript
jQuery实现点击图片翻页展示效果的方法
2015/02/16 Javascript
JS自定义选项卡函数及用法实例分析
2015/09/02 Javascript
JS实现针对给定时间的倒计时功能示例
2017/04/11 Javascript
实例讲解DataTables固定表格宽度(设置横向滚动条)
2017/07/11 Javascript
Javascript中弹窗confirm与prompt的区别
2018/10/26 Javascript
在layui中select更改后生效的方法
2019/09/05 Javascript
JavaScript 浏览器对象模型BOM原理与常见用法实例分析
2019/12/16 Javascript
Python自动连接ssh的方法
2015/03/07 Python
Python实现字符串与数组相互转换功能示例
2017/09/22 Python
python2.7安装图文教程
2018/03/13 Python
使用PyInstaller将python转成可执行文件exe笔记
2018/05/26 Python
Python基于BeautifulSoup和requests实现的爬虫功能示例
2019/08/02 Python
python 动态迁移solr数据过程解析
2019/09/04 Python
Python 合并拼接字符串的方法
2020/07/28 Python
Python 如何反方向迭代一个序列
2020/07/28 Python
解锁canvas导出图片跨域的N种姿势小结
2019/01/24 HTML / CSS
HTML5 图片悬停放大的实现代码示例
2019/12/04 HTML / CSS
Nisbets爱尔兰:英国最大的厨房和餐饮设备供应商
2019/01/26 全球购物
四年的个人工作自我评价
2013/12/10 职场文书
外贸业务员求职信范文
2013/12/12 职场文书
人事行政主管岗位职责
2013/12/22 职场文书
实习单位接收函模板
2014/01/10 职场文书
党员剖析材料范文
2014/09/30 职场文书
社区四风存在问题及整改措施
2014/10/26 职场文书
财政局个人年终总结
2015/03/03 职场文书
2015年法务工作总结范文
2015/05/23 职场文书
python可视化大屏库big_screen示例详解
2021/11/23 Python
在windows server 2012 r2中安装mysql的详细步骤
2022/07/23 Servers