vue预渲染 render-spa-plugin
- 
全局安装 1npm install -g @vue/cli-init
- 
创建vebpack项目 
 vue init webpack . // 在当前文件夹下创建项目 1
 2
 3
 4
 5
 6
 7
 8
 9
 10? Generate project in current directory? Yes
 ? Project name prerender-spa
 ? Project description A Vue.js project
 ? Author dxc1996 <[email protected]>
 ? Vue build standalone
 ? Install vue-router? Yes
 ? Use ESLint to lint your code? No
 ? Set up unit tests No
 ? Setup e2e tests with Nightwatch? No
 ? Should we run `npm install` for you after the project has been created? (recommended) npm
- 
安装插件 1npm/cnpm i prerender-spa-plugin -D
- 
路由模式要为 history 1
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16import Vue from 'vue'
 import Router from 'vue-router'
 import Home from '@/components/Home'
 import About from '@/components/About'
 import Test from '@/components/Test'
 
 Vue.use(Router)
 
 export default new Router({<!-- -->
 mode:'history',
 routes: [
 {<!-- -->path: '/',name: 'Home',component: Home},
 {<!-- -->path: '/about',name: 'About',component: About},
 {<!-- -->path: '/test',name: 'Test',component: Test}
 ]
 })这是我的目录结构 
  
- 
在webpack.prod.config.js下配置 1
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20const PrerenderSPAPlugin = require('prerender-spa-plugin');
 // 调用渲染器
 const Renderer = PrerenderSPAPlugin.PuppeteerRenderer
 plugins:[
 ...
 //调用渲染器
 new PrerenderSPAPlugin({<!-- -->
 staticDir: path.join(__dirname, '../dist'),
 // Required - Routes to render.
 routes: [ '/', '/about'],
 renderer: new Renderer({<!-- -->
 inject: {<!-- -->
 foo: 'bar'
 },
 headless: false,
 // 在项目的入口使用document.dispatchEvent(new Event('render-event'))
 renderAfterDocumentEvent: 'render-event',
 })
 })
 ]整体来说是这样的 1
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171'use strict'
 const path = require('path')
 const utils = require('./utils')
 const webpack = require('webpack')
 const config = require('../config')
 const merge = require('webpack-merge')
 const baseWebpackConfig = require('./webpack.base.conf')
 const CopyWebpackPlugin = require('copy-webpack-plugin')
 const HtmlWebpackPlugin = require('html-webpack-plugin')
 const ExtractTextPlugin = require('extract-text-webpack-plugin')
 const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
 const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
 const PrerenderSPAPlugin = require('prerender-spa-plugin');
 // 调用渲染器
 const Renderer = PrerenderSPAPlugin.PuppeteerRenderer
 
 const env = require('../config/prod.env')
 
 const webpackConfig = merge(baseWebpackConfig, {<!-- -->
 module: {<!-- -->
 rules: utils.styleLoaders({<!-- -->
 sourceMap: config.build.productionSourceMap,
 extract: true,
 usePostCSS: true
 })
 },
 devtool: config.build.productionSourceMap ? config.build.devtool : false,
 output: {<!-- -->
 path: config.build.assetsRoot,
 filename: utils.assetsPath('js/[name].[chunkhash].js'),
 chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
 },
 plugins: [
 // http://vuejs.github.io/vue-loader/en/workflow/production.html
 new webpack.DefinePlugin({<!-- -->
 'process.env': env
 }),
 new UglifyJsPlugin({<!-- -->
 uglifyOptions: {<!-- -->
 compress: {<!-- -->
 warnings: false
 }
 },
 sourceMap: config.build.productionSourceMap,
 parallel: true
 }),
 // extract css into its own file
 new ExtractTextPlugin({<!-- -->
 filename: utils.assetsPath('css/[name].[contenthash].css'),
 // Setting the following option to `false` will not extract CSS from codesplit chunks.
 // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.
 // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`,
 // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
 allChunks: true,
 }),
 // Compress extracted CSS. We are using this plugin so that possible
 // duplicated CSS from different components can be deduped.
 new OptimizeCSSPlugin({<!-- -->
 cssProcessorOptions: config.build.productionSourceMap
 ? {<!-- --> safe: true, map: {<!-- --> inline: false } }
 : {<!-- --> safe: true }
 }),
 // generate dist index.html with correct asset hash for caching.
 // you can customize output by editing /index.html
 // see https://github.com/ampedandwired/html-webpack-plugin
 new HtmlWebpackPlugin({<!-- -->
 filename: config.build.index,
 template: 'index.html',
 inject: true,
 minify: {<!-- -->
 removeComments: true,
 collapseWhitespace: true,
 removeAttributeQuotes: true
 // more options:
 // https://github.com/kangax/html-minifier#options-quick-reference
 },
 // necessary to consistently work with multiple chunks via CommonsChunkPlugin
 chunksSortMode: 'dependency'
 }),
 // keep module.id stable when vendor modules does not change
 new webpack.HashedModuleIdsPlugin(),
 // enable scope hoisting
 new webpack.optimize.ModuleConcatenationPlugin(),
 // split vendor js into its own file
 new webpack.optimize.CommonsChunkPlugin({<!-- -->
 name: 'vendor',
 minChunks (module) {<!-- -->
 // any required modules inside node_modules are extracted to vendor
 return (
 module.resource &&
 /\.js$/.test(module.resource) &&
 module.resource.indexOf(
 path.join(__dirname, '../node_modules')
 ) === 0
 )
 }
 }),
 // extract webpack runtime and module manifest to its own file in order to
 // prevent vendor hash from being updated whenever app bundle is updated
 new webpack.optimize.CommonsChunkPlugin({<!-- -->
 name: 'manifest',
 minChunks: Infinity
 }),
 // This instance extracts shared chunks from code splitted chunks and bundles them
 // in a separate chunk, similar to the vendor chunk
 // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
 new webpack.optimize.CommonsChunkPlugin({<!-- -->
 name: 'app',
 async: 'vendor-async',
 children: true,
 minChunks: 3
 }),
 
 // copy custom static assets
 new CopyWebpackPlugin([
 {<!-- -->
 from: path.resolve(__dirname, '../static'),
 to: config.build.assetsSubDirectory,
 ignore: ['.*']
 }
 ]),
 //调用渲染器
 new PrerenderSPAPlugin({<!-- -->
 // Required - The path to the webpack-outputted app to prerender.
 staticDir: path.join(__dirname, '../dist'),
 // Required - Routes to render.
 routes: [ '/', '/about'],
 
 renderer: new Renderer({<!-- -->
 // Optional - Any values you'd like your app to have access to via `window.injectProperty`.
 inject: {<!-- -->
 foo: 'bar'
 },
 // Other puppeteer options.
 // (See here: https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#puppeteerlaunchoptions)
 headless: false, // Display the browser window when rendering. Useful for debugging.
 
 // Optional - Wait to render until the specified event is dispatched on the document.
 // eg, with `document.dispatchEvent(new Event('custom-render-trigger'))`
 // 在项目的入口使用document.dispatchEvent(new Event('render-event'))
 renderAfterDocumentEvent: 'render-event',
 
 })
 })
 ]
 })
 
 if (config.build.productionGzip) {<!-- -->
 const CompressionWebpackPlugin = require('compression-webpack-plugin')
 
 webpackConfig.plugins.push(
 new CompressionWebpackPlugin({<!-- -->
 asset: '[path].gz[query]',
 algorithm: 'gzip',
 test: new RegExp(
 '\\.(' +
 config.build.productionGzipExtensions.join('|') +
 ')$'
 ),
 threshold: 10240,
 minRatio: 0.8
 })
 )
 }
 
 if (config.build.bundleAnalyzerReport) {<!-- -->
 const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
 webpackConfig.plugins.push(new BundleAnalyzerPlugin())
 }
 
 module.exports = webpackConfig
- 
配置main.js 1
 2
 3
 4
 5
 6
 7
 8
 9new Vue({<!-- -->
 el: '#app',
 router,
 components: {<!-- --> App },
 template: '<App/>',
 mounted(){<!-- -->
 document.dispatchEvent(new Event('render-event'))
 }
 })
- 
打包后的文件 
  
  
 如有雷同,请联系删除


