简体   繁体   中英

get List of routes via axios in Vue Webpack Cli

I'm using prerender-spa-plugin in my Vue Webpack Cli project. Like from the documentation i'm registering the Plugin in webpack.prod.conf.js like this

...
plugins: [
  ...
  new PrerenderSpaPlugin(
    path.join(__dirname, '../dist'),
    ['/', '/about', '/contact'],
    {
      captureAfterTime: 5000
    }
  )
]

I'm wondering if it would be possible to get the list of routes array via an axios call. I tried the following without success:

var routes = axios.get('http://myapi.com/api').then(function (response) {
  return response.map(function (response) {
    return '/base/' + response.slug
  })
})

plugins: [
  ...
  new PrerenderSpaPlugin(
    path.join(__dirname, '../dist'),
    routes,
    {
      captureAfterTime: 5000
    }
  )
]

Since my Javascript knowledge is poor I'm not able to solve this. Thankfull for any hints.

Best regards

This currently won't work (or at least work reliably) because Webpack assumes your configuration is synchronous by default. To get around this is to use Webpack's support for asynchronous configuration and return a promise that is resolved after your route request.

If you are in an environment that supports async/await (node 8+) then it's as simple as exporting an async function. Otherwise, return a new Promise :

// webpack.conf.js
module.exports = async function () {
  const response = await axios.get('http://myapi.com/api')
  const routes = response.map((response) => {
    return '/base/' + response.slug
  })

  return {
    plugins: [
      // ...
      new PrerenderSpaPlugin(
        path.join(__dirname, '../dist'),
        routes,
        {
          captureAfterTime: 5000
        }
      )
    ]
  }
}

If that isn't an option, you can always have a task that makes this request, writes it to a json file, and then require('./route-response.json') in your config.

I had a similar requirement - to get the list of routes from my API. I ended up creating a prebuild script - prebuild.js

const fs = require('fs')
const axios = require('axios')

// Fetch data from API
axios.get('http://myapi.com/api.php')
  .then(function(response) {
    const data = response.data
    try {
      // Save the route list to local file
      fs.writeFileSync('./route-response.js', data)
    } catch(err) {
      console.log(err)
    }
  })
  .catch(function(err) {
    console.log(err)
  })

My API sends the data of the route-response.js file, ready to be directly saved and consumed by npm. You could handle this formatting in Node instead. Sample format:

module.exports = {
  theList: [
    '/',
    '/about',
    '/contact',
    '/login',
    '/register'
  ]
}

The above file is fetched in webpack.prod.conf.js as below:

...
const routeList = require('./route-response.js')
...
const webpackConfig = merge(baseWebpackConfig, {
  ...
  plugins: [
    ...
    new PrerenderSPAPlugin({
      staticDir: path.resolve(__dirname, '../dist'),
      routes: routeList.theList,
      renderer: new PuppeteerRenderer()
    })
    ...
  ]
  ...
})

and finally, add the prebuild script to the package.json

  • prebuild: runs before the build step.
  • postbuild: runs after the build step.

Here's a sample

...
"scripts": {
  "dev": "node build/dev-server.js",
  "prebuild": "node build/prebuild.js",
  "build": "node build/build.js"
},
"dependencies": {
...

This way, I only have to run npm run build

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM