详解如何将 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 文件

rush:js;"> app.use(require('connect-history-api-fallback')())

改成

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

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

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

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

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

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 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/*'],res) => {
res.send(adminHTML)
})

// 404 页面
app.get('*',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 开始愉快的写代码

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程之家。

相关文章

可以通过min-width属性来设置el-table-column的最小宽度。以...
yarn dev,当文件变动后,会自动重启。 yanr start不会自动重...
ref 用于创建一个对值的响应式引用。这个值可以是原始值(如...
通过修改 getWK005 函数来实现这一点。这里的 query 参数就是...
<el-form-item label="入库类型" ...
API 变动 样式类名变化: 一些组件的样式类名有所变动,可能需...