详解如何将 Vue-cli 改造成支持多页面的 history 模式
标题可能描述不准确, 大概就是这么个需求:
用 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'}, ] }))
具体规则就参考:
-------------- 以下代码请无视 --------------
下面我们就来改造下, 让所有入口都支持 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 开始愉快的写代码吧
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: vue.js项目中实用的小技巧汇总
下一篇: 深入理解Vue官方文档梳理之全局API