视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
详解如何将 Vue-cli 改造成支持多页面的 history 模式
2020-11-27 22:25:18 责编:小采
文档


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

用 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 开始愉快的写代码吧

下载本文
显示全文
专题