详解如何将 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 相关文章推荐
jQuery防止click双击多次提交及传递动态函数或多参数
Apr 02 Javascript
解决Jquery向页面append新元素之后事件的绑定问题
Mar 16 Javascript
JavaScript中的call方法和apply方法使用对比
Aug 12 Javascript
Javascript中神奇的this
Jan 20 Javascript
利用AngularJs实现京东首页轮播图效果
Sep 08 Javascript
详解jQuery插件开发方式
Nov 22 Javascript
react-native DatePicker日期选择组件的实现代码
Sep 12 Javascript
async/await地狱该如何避免详解
May 10 Javascript
opencv 识别微信登录验证滑动块位置
Aug 07 Javascript
vue中的计算属性实例详解
Sep 19 Javascript
js模拟实现百度搜索
Jun 28 Javascript
JavaScript实现网页动态生成表格
Nov 25 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和XSL stylesheets转换XML文档
2006/10/09 PHP
使用Curl进行抓取远程内容时url中文编码问题示例探讨
2013/10/29 PHP
Yii获取当前url和域名的方法
2015/06/08 PHP
php判断当前操作系统类型
2015/10/28 PHP
php中使用GD库做验证码
2016/03/31 PHP
php之header的不同用法总结(实例讲解)
2017/11/28 PHP
PHP时间处理类操作示例
2018/09/05 PHP
jquery表格内容筛选实现思路及代码
2013/04/16 Javascript
js动态设置div的值下例子
2013/10/29 Javascript
JS实现横向与竖向两个选项卡Tab联动的方法
2015/09/27 Javascript
Boostrap实现的登录界面实例代码
2016/10/09 Javascript
jquery实现手机端单店铺购物车结算删除功能
2017/02/22 Javascript
JavaScript 中Date对象的格式化代码方法汇总
2017/09/06 Javascript
详解angular应用容器化部署
2018/08/14 Javascript
nuxt踩坑之Vuex状态树的模块方式使用详解
2019/09/06 Javascript
JS计算斐波拉切代码实例
2019/09/12 Javascript
Python语言实现机器学习的K-近邻算法
2015/06/11 Python
Python调用百度根据经纬度查询地址的示例代码
2019/07/07 Python
python中调试或排错的五种方法示例
2019/09/12 Python
python 链接sqlserver 写接口实例
2020/03/11 Python
python实现在列表中查找某个元素的下标示例
2020/11/16 Python
Python实现PS滤镜中的USM锐化效果
2020/12/04 Python
总结30个CSS3选择器
2017/04/13 HTML / CSS
金宝贝童装官网:Gymboree
2016/08/31 全球购物
英国现代绅士品牌:Hackett
2017/12/17 全球购物
YesBabyOnline美国:全球性的在线婚纱礼服工厂
2018/05/05 全球购物
自荐书格式
2013/12/01 职场文书
查环查孕证明
2014/01/10 职场文书
大家检讨书5000字
2014/02/03 职场文书
浪费资源的建议书
2014/03/12 职场文书
自主招生英文自荐信
2015/03/25 职场文书
十月围城观后感
2015/06/08 职场文书
社区志愿者服务心得体会
2016/01/22 职场文书
小学四年级作文之人物作文
2019/11/06 职场文书
抖音动画片,皮皮虾,《治愈系》动画在用这首REMIX作为背景音乐,Anak ,The last world with you完整版
2022/03/16 杂记
使用Apache Camel表达REST服务的方法
2022/06/10 Servers