vue单页到多页的配置

作者: xurna | 来源:发表于2019-07-19 15:13 被阅读2次

    前言

    vue如果改成多页,可以减少每次渲染的包大小,每个页面也可以成为一个新的单页,可以更合理划分业务内容。分别写了html及pug两个模板引擎的多页模板,仓库地址如下:

    vue单页改成多页步骤

    • 此步骤是基于上一篇vue单页项目模板搭建的,并且使用的是html模板,有不清楚的webpack配置可以去该仓库查询
    • 修改目录结构:将app目录下的pages下的页面结构修改成如下,文件夹名-js文件名-html文件名需要一致,且定义的页面路由开头也需要与文件名一致,页面内容不详讲。
      .
      ├── README.md
      ├── app // 前端目录
      │   ├── assets
      │   │   ├── images
      │   │   ├── js
      │   │   └── less
      │   ├── components
      │   └── pages
      │       ├── home
      │       │   ├── detail.vue
      │       │   ├── home.html
      │       │   ├── home.js
      │       │   └── main.vue
      │       └── user
      │           ├── main.vue
      │           ├── user.html
      │           └── user.js
      ├── back-end  // 后端服务
      ├── build  // webpack配置
      │   ├── build.js
      │   ├── utils.js
      │   ├── webpack.common.conf.js
      │   ├── webpack.dev.conf.js
      │   └── webpack.prod.conf.js
      ├── dist // 打包文件
      ├── package.json
      ├── test
      ├── webpack.config.js
      
    • 修改webpack配置
      • 修改入口配置

        // 新建文件 utils.js
        const path = require('path')
        // `glob`: 匹配文件, 该模块允许你使用 * 等符号, 例如lib/*.js就是获取lib文件夹下的所有js后缀名的文件
        const glob = require('glob')
        const PAGE_PATH = path.resolve(__dirname, '../app/pages')
        
        //多入口配置:通过js文件名
        exports.entries = function () {
          // 通过glob模块读取pages文件夹下的所有对应文件夹下的js后缀文件
          var entryFiles = glob.sync(PAGE_PATH + '/*/*.js')
          var map = {}
          entryFiles.forEach((filePath) => {
            // 获取文件名
            var filename = filePath.substring(filePath.lastIndexOf('\/') + 1, filePath.lastIndexOf('.'))
            map[filename] = filePath
          })
          return map
        }
        

        修改入口:

          entry: utils.entries(),
        
      • 修改html生成配置

        • webpack.dev.conf.js:注释掉原来定义的HtmlWebpackPlugin,并改成下面的
          plugins: [
            // new HtmlWebpackPlugin({
            //   filename: 'index.html',
            //   title: '',
            //   template: path.join(appDir, 'index.html'),
            //   inject: true,
            //   chunks: ['app']
            // })
          ],
          
          const glob = require('glob')
          const PAGE_PATH = path.resolve(__dirname, '../app/pages')
          
          let entryHtml = glob.sync(PAGE_PATH + '/*/*.html')
          entryHtml.forEach((filePath) => {
            let filename = filePath.substring(filePath.lastIndexOf('\/') + 1, filePath.lastIndexOf('.'))
            let conf = {
              filename: filename + '.html',
              template: filePath,
              inject: true,
              chunks: [filename], // 页面模板需要加对应的js脚本,如果不加这行则每个页面都会引入所有的js脚本
            }
            config.plugins.push(new HtmlWebpackPlugin(conf))
          })
          
        • webpack.prod.conf.js:注释掉原来定义的HtmlWebpackPlugin,并改成下面的
         plugins: [
           // new HtmlWebpackPlugin({
           //   filename: 'index.html', 
           //   template: path.join(appDir, 'index.html'),
           //   title: '',
           //   inject: true,
           //   minify: {
           //     removeComments: true,
           //     collapseWhitespace: true,
           //     removeAttributeQuotes: true,
           //     conservativeCollapse: true
           //   },
           //   chunks: ['manifest', 'vendors', 'app']
           // }),
           new webpack.HashedModuleIdsPlugin(),
           // new InlineManifestWebpackPlugin('manifest') 
         ],
        
        const glob = require('glob')
        const PAGE_PATH = path.resolve(__dirname, '../app/pages')
        
        let entryHtml = glob.sync(PAGE_PATH + '/*/*.html')
        entryHtml.forEach((filePath) => {
          let filename = filePath.substring(filePath.lastIndexOf('\/') + 1, filePath.lastIndexOf('.'))
          let conf = {
            filename: filename + '.html', 
            template: filePath,
            minify: {
              removeComments: true,
              collapseWhitespace: true,
              removeAttributeQuotes: true,
              conservativeCollapse: true
            },
            inject: true,
            chunksSortMode: 'dependency',
            chunks: ['manifest', 'vendors', filename],
          }
          config.plugins.push(new HtmlWebpackPlugin(conf))
        })
        // 需放在HtmlWebpackPlugin下面
        config.plugins.push(new InlineManifestWebpackPlugin('manifest'))
        
      • 到这步,已经可以正常执行打包npm run build,但是开发调试的时候npm run dev,发现页面输入的页面路由http://xxxx:9001/home直接404了,解决办法是,需要在devServer中配置重写操作指定页面,不然都是直接默认查找index.html页面的。

          // utils.js
          exports.rewrites = function () {
            const entries = exports.entries();
            const rewrites = [];
            Object.keys(entries).forEach((name) => {
              const reg = new RegExp(`^\/${name}`);
              rewrites.push({ from: reg, to: `\/${name}.html` });
            });
            console.log(rewrites);
            return rewrites;
          };
        
        // webpack.dev.conf.js
        devServer: {
         ...
          historyApiFallback: {
            rewrites: utils.rewrites() // 重要!路由匹配html页面,不配置则通过路由找不到页面
          }, 
          ...
        },
        
        

        配置完后就可以正常按照路由打开页面了。

      • 由于vue-router我使用了history模式的路由,打包后的页面需要在服务器端配置路由,通过后端render才可打开页面(或者你可以采用hash模式的路由,就可以直接打开html页面),我写了一个back-end的简单服务器端,到目录下执行npm run dev,,打开http://localhost:3000/home即可看到对应打包页面内容。因为,上线前,需要后端配置前端的页面路由指定的html页面。

    使用pug模板引擎

    • 安装依赖
      npm install -save-dev pug pug-loader
      
    • 修改webpack配置
      • webpack.common.conf.js,增加pug-loader
        module: {
          rules: [
            ...
            {
              test: /\.pug$/,
              loader: 'pug-loader'
            },
          ]
        },
        
      • webpack.dev.conf.js & webpack.prod.conf.js,修改入口文件后缀
        - let entryHtml = glob.sync(PAGE_PATH + '/*/*.html')
        + let entryHtml = glob.sync(PAGE_PATH + '/*/*.pug')
        
    • 修改页面模板
      .
      ├── README.md
      ├── app // 前端目录
           ├── assets
           │   ├── images
           │   ├── js
           │   ├── layout
           │   │     └── base.pug // 新增公共pug
           │   └── less
           ├── components
           └── pages
               ├── home
               │   ├── detail.vue
               │   ├── home.pug  // 修改文件后缀及内容
               │   ├── home.js
               │   └── main.vue
               └── user
                   ├── main.vue
                   ├── user.pug  // 修改文件后缀及内容
                   └── user.js
      
      

    参考文章

    相关文章

      网友评论

        本文标题:vue单页到多页的配置

        本文链接:https://www.haomeiwen.com/subject/wwxrlctx.html