基于vue-cli配置多页面应用程序

543 阅读5分钟

一、准备工作---安装环境

1. 安装node环境: https://nodejs.org/en/download/

2. 安装vue-cli脚手架: npm install vue-cli -g

二、初始化项目以及安装相关的第三方模块

初始化项目:vue init webpack vue-multipage-template

安装glob: npm install glob -save-dev --registry=https://registry.npm.taobao.org


三、 项目目录展示以及需要调整的文件

    1. 项目目录展示

     

    

    2. 需要调整的文件

     在修改webpack配置的时候,需要对创建好的一些文件做对应的调整。其中主要是调整build文件夹下的一些文件。如图:

    

    除此之外,还需要对src文件夹做一些小小的调整。如图:在src文件夹下新建pages目录,里面放置多页面的html模块以及入口文件。

    

 index/App.vue的代码:

<template>  
    <div id="app">   
         this is index  
    </div>
</template>

<script>
export default {  
    name: 'App'
}
/script>

<style>
</style>

index/index.html代码:

<!DOCTYPE html><html lang="en">  <head>    <meta charset="UTF-8">    <meta name="viewport" content="width=device-width, initial-scale=1.0">    <meta http-equiv="X-UA-Compatible" content="ie=edge">    <title>index</title>  </head>  <body>    <div id="app"></div>    <!-- built files will be auto injected -->  </body></html>

 index/index.js入口文件的代码:

// The Vue build version to load with the `import` command// (runtime-only or standalone) has been set in webpack.base.conf with an alias.import Vue from 'vue'import App from './App'Vue.config.productionTip = false/* eslint-disable no-new */new Vue({  el: '#app',  components: { App },  template: '<App/>'})


    以上就是基本的项目目录展示,接下来的部分就是对webpack配置的修改,以满足多页面应用程序开发的需要。主要是对build文件夹下的utils.js、webpack.base.conf.js、webpack.dev.conf.js、webpack.prod.conf.js这四个文件的修改。

四、webpack配置文件的修改

    因为配置文件的内容都很多,我只是把主要代码展示,把需要新增的代码或是需要调整的部分做好标注,以减少文章篇幅。

    1. build/utils.js

'use strict'const path = require('path')const config = require('../config')const ExtractTextPlugin = require('extract-text-webpack-plugin')const packageConfig = require('../package.json')exports.assetsPath = function (_path) {  ...}exports.cssLoaders = function (options) {  ...}// Generate loaders for standalone style files (outside of .vue)exports.styleLoaders = function (options) {  ...}/** * 多页面配置-----新增的内容
 * 新增entries方法,配置多入口文件
 * 新增htmlPlugin方法,配置多页面的HTML模板 */const glob = require('glob')const HtmlWebpackPlugin = require('html-webpack-plugin')const PAGES_PATH = path.resolve(__dirname, '../src/pages')const merge = require('webpack-merge')//多入口配置// 通过glob模块读取pages文件夹下的每个文件夹下的js后缀文件,作为入口处理exports.entries = function () {  var entryFiles = glob.sync(PAGES_PATH + '/*/*.js')  var entryArr = {}  entryFiles.forEach((filePath) => {      var filename = filePath.substring(filePath.lastIndexOf('\/') + 1, filePath.lastIndexOf('.'))      entryArr[filename] = filePath  })  return entryArr}//html-webpack-plugin多页面配置exports.htmlPlugin = function () {  let entryHtml = glob.sync(PAGES_PATH + '/*/*.html')  let arr = []  entryHtml.forEach((filePath) => {    let filename = filePath.substring(filePath.lastIndexOf('\/') + 1, filePath.lastIndexOf('.'))    let conf = {        // 模板来源        template: filePath,        // 文件名称        filename: filename + '.html',        // 页面模板需要加对应的js脚本,如果不加这行则每个页面都会引入所有的js脚本        chunks: ['manifest', 'vendor', filename],        inject: true    }    if (process.env.NODE_ENV === 'production') {        conf = merge(conf, {            minify: {                removeComments: true,                collapseWhitespace: true,                removeAttributeQuotes: true            },            chunksSortMode: 'dependency'        })    }    arr.push(new HtmlWebpackPlugin(conf))  })  return arr}
exports.createNotifierCallback = () => {  ...}

2. build/webpack.base.conf.js

'use strict'const path = require('path')const utils = require('./utils')const config = require('../config')const vueLoaderConfig = require('./vue-loader.conf')function resolve (dir) {  return path.join(__dirname, '..', dir)}module.exports = {  context: path.resolve(__dirname, '../'),

  //需要把entry的配置调整,其他部分的代码不变  entry: utils.entries(), //使用utils.js导出的entries()  output: {    ....  },  resolve: {    ...  },  module: {    rules: [      ...    ]  },  node: {     ...
  }}

3.  build/webpack.dev.conf.js。 这个文件主要是对plugins这部分的配置做修改。需要把plugins配置里的new HtmlWebpackPlugin()给注释或者删除。然后使用utils.js导出的htmlPlugi()

'use strict'const utils = require('./utils')const webpack = require('webpack')const config = require('../config')const merge = require('webpack-merge')const path = require('path')const baseWebpackConfig = require('./webpack.base.conf')const CopyWebpackPlugin = require('copy-webpack-plugin')const HtmlWebpackPlugin = require('html-webpack-plugin')const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')const portfinder = require('portfinder')const HOST = process.env.HOSTconst PORT = process.env.PORT && Number(process.env.PORT)const devWebpackConfig = merge(baseWebpackConfig, {  module: {    rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })  },  // cheap-module-eval-source-map is faster for development  devtool: config.dev.devtool,  // these devServer options should be customized in /config/index.js  devServer: {    clientLogLevel: 'warning',    historyApiFallback: {      rewrites: [        { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },      ],    },    hot: true,    contentBase: false, // since we use CopyWebpackPlugin.    compress: true,    host: HOST || config.dev.host,    port: PORT || config.dev.port,    open: config.dev.autoOpenBrowser,    overlay: config.dev.errorOverlay      ? { warnings: false, errors: true }      : false,    publicPath: config.dev.assetsPublicPath,    proxy: config.dev.proxyTable,    quiet: true, // necessary for FriendlyErrorsPlugin    watchOptions: {      poll: config.dev.poll,    }  },  plugins: [    new webpack.DefinePlugin({      'process.env': require('../config/dev.env')    }),    new webpack.HotModuleReplacementPlugin(),    new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.    new webpack.NoEmitOnErrorsPlugin(),    // https://github.com/ampedandwired/html-webpack-plugin    /*    =================注释掉单页面的配置====================    new HtmlWebpackPlugin({      filename: 'index.html',      template: 'index.html',      inject: true    }),    =================注释掉单页面的配置====================    */    // copy custom static assets    new CopyWebpackPlugin([      {        from: path.resolve(__dirname, '../static'),        to: config.dev.assetsSubDirectory,        ignore: ['.*']      }    ])  ].concat(utils.htmlPlugin())   //==================合并多页面html模板=-=======================})module.exports = new Promise((resolve, reject) => {  portfinder.basePort = process.env.PORT || config.dev.port  portfinder.getPort((err, port) => {    if (err) {      reject(err)    } else {      // publish the new Port, necessary for e2e tests      process.env.PORT = port      // add port to devServer config      devWebpackConfig.devServer.port = port      // Add FriendlyErrorsPlugin      devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({        compilationSuccessInfo: {          messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`],        },        onErrors: config.dev.notifyOnErrors        ? utils.createNotifierCallback()        : undefined      }))      resolve(devWebpackConfig)    }  })})

4. build/webpack.prod.conf.js。这部分跟build/webpack.dev.conf.js修改的地方一样。

'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 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: ['.*']      }    ])  ].concat(utils.htmlPlugin())   //==================合并多页面html模板=-=======================})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


至此,需要做出调整的文件以及全部修改完了。

通过 npm run dev重新启动项目,

在浏览器localhost:8080/index.html,localhost:8080/detail.html就可以访问对应的页面了。


通过 npm run build打包项目,文件也可以正常打包到dist目录了。



参考:

    https://blog.csdn.net/qq_38111015/article/details/89147144