记一次基于vue-cli的多页面应用配置

初始环境

  • vue-cli生成的单页应用

配置原则

尽可能不修改原有的配置文件和目录结构,作到增量配置html

目录结构

├── README.md
├── build                   # build 脚本
├── config                  # prod/dev build config 文件
├── index.html              # 主网页
├── package.json
├── src                     # Vue.js 核心业务
│   ├── App.vue             # App Root Component
│   ├── api                 # 接入后端服务的基础 API
│   ├── assets              # 静态文件
│   ├── components          # 组件
│   ├── main.js             # Vue 主入口文件
│   ├── router              # 路由
│   ├── service             # 服务
│   ├── pages               # 多页面
│   ├── store               # Vuex 状态管理
│   ├── util                # 通用 utility
│   └── view                # 各个页面
├── static                  # 静态文件
└── test                    # 测试
复制代码

具体配置

修改文件

├── build                   # build 脚本
    ├── utils.js
    ├── webpack.base.conf.js
    ├── webpack.dev.conf.js
    ├── webpack.prod.conf.js
├── package.json
├── src
    ├── pages               # 多页面
        ├── scan # 例如增长一个scan的页面
            ├── scan.html
            ├── scan.js
            ├── scan.vue
复制代码

配置代码

  • package.json:glob模块vue

    "glob": "^7.1.2",
    复制代码
  • utils.jsnode

    ...
    /* +++++++++++++++ 增长 ++++++++++++++++++++ */
    const glob = require('glob')
    const HtmlWebpackPlugin = require('html-webpack-plugin')
    const merge = require('webpack-merge')
    /* +++++++++++++++++++ 增长 +++++++++++++++ */
    
    ...
    
    /* +++++++++++++++ 增长 ++++++++++++++++++++ */
    const PAGE_PATH = path.resolve(__dirname, '../src/pages')
    exports.entries = function (){
      const entrys = glob.sync(PAGE_PATH + '/*/*.js')
    
      const entrysMap = {}
      entrys.forEach((filePath)=>{
        const fileName = filePath.substring(filePath.lastIndexOf('\/') + 1, filePath.lastIndexOf('.js'))
        entrysMap[fileName] = filePath
      })
      return entrysMap
    }
    
    exports.htmlPlugins = function (){
      const entryHtmls = glob.sync(PAGE_PATH + '/*/*.html')
    
      const htmlsArray = []
      entryHtmls.forEach((filePath)=>{
        const fileName = filePath.substring(filePath.lastIndexOf('\/') + 1, filePath.lastIndexOf('.html'))
    
        let HtmlWebpackPluginConf =  new HtmlWebpackPlugin({
          filename: fileName + '.html',
          template: filePath,
          chunks: ['manifest', 'vendor', fileName],
          inject: true
        })
    
        if(process.env.NODE_ENV === 'production'){
          HtmlWebpackPluginConf = merge(HtmlWebpackPluginConf, {
            minify: {
              removeComments: true,
              collapseWhitespace: true,
              removeAttributeQuotes: true
            },
            chunksSortMode: 'dependency'
          })
        }
    
        htmlsArray.push(HtmlWebpackPluginConf)
      })
      return htmlsArray
    }
    /* +++++++++++++++ 增长 ++++++++++++++++++++ */
    
    复制代码
  • webpack.base.conf.jswebpack

    ...
    module.exports = {
      context: path.resolve(__dirname, '../'),
      entry: {
        /* +++++++++++++++ 增长 ++++++++++++++++++++ */
        ...(utils.entries()),
        /* +++++++++++++++ 增长 ++++++++++++++++++++ */
        app: ["babel-polyfill", "./src/main.js"]
      },
    ...
    复制代码
  • webpack.dev.conf.jsnginx

    ...
      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',
          /* +++++++++++++++ 增长 ++++++++++++++++++++ */
          chunks: ['manifest', 'vendor', 'app'],
          /* +++++++++++++++ 增长 ++++++++++++++++++++ */
          inject: true
        }),
        // copy custom static assets
        new CopyWebpackPlugin([
          {
            from: path.resolve(__dirname, '../static'),
            to: config.dev.assetsSubDirectory,
            ignore: ['.*']
          }
        ])
    /* +++++++++++++++ 增长 ++++++++++++++++++++ */
      ].concat(utils.htmlPlugins())
    /* +++++++++++++++ 增长 ++++++++++++++++++++ */
    })
    ...
    复制代码
  • webpack.prod.confgit

...
    new HtmlWebpackPlugin({
      filename: process.env.NODE_ENV === 'testing'
        ? 'index.html'
        : config.build.index,
      template: 'index.html',
      /* +++++++++++++++ 增长 ++++++++++++++++++++ */
      chunks: ['manifest', 'vendor', 'app'],
      /* +++++++++++++++ 增长 ++++++++++++++++++++ */
      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'
    }),
    ...
  /* +++++++++++++++ 增长 ++++++++++++++++++++ */
  ].concat(utils.htmlPlugins())
  /* +++++++++++++++ 增长 ++++++++++++++++++++ */
})
...

复制代码

nginx 配置

location = /scan {
    rewrite (\/scan).* /scan.html/ redirct
}
复制代码

参考