Уровень проекта, многостраничная конфигурация Vue-cli3+node + оптимизация производительности

Vue.js
Уровень проекта, многостраничная конфигурация Vue-cli3+node + оптимизация производительности

предисловие

Про многостраничную конфигурацию vue можно сказать, что cli2-cli3 это процесс от 0 до 1. Думать о cli2 невыносимо, cli3 ничуть не сладко, хотя сам cli3 обеспечивает входную конфигурацию многостраничных страниц, но хотите гибко адаптироваться к структуре в соответствии с конфигурацией, некоторые операции все же необходимы, чтобы избежать постоянных модификаций на более позднем этапе; эта статья будет сотрудничать с узлом, чтобы сделать гибкую конфигурацию и установить некоторые только что необходимые конфигурации плюс оптимизация производительности.

Создать проект

  • Метод работы

    vue create xxx
    ... ...
    选择配置(非路由模式)
    ... ...
    创建完成
    
  • Структура проекта

Проанализируйте vue.config.js

  • исходный код

    module.exports = {
    lintOnSave: false
    }
    
  • Код многостраничной конфигурации официального сайта

    module.exports = {
    pages: {
     index: {
     // page 的入口
     entry: 'src/index/main.js',
     // 模板来源
     template: 'public/index.html',
     // 在 dist/index.html 的输出
     filename: 'index.html',
     // 当使用 title 选项时,
     // template 中的 title 标签需要是 <title><%= htmlWebpackPlugin.options.title %></title>
     title: 'Index Page',
     // 在这个页面中包含的块,默认情况下会包含
     // 提取出来的通用 chunk 和 vendor chunk。
     chunks: ['chunk-vendors', 'chunk-common', 'index']
     },
     // 当使用只有入口的字符串格式时,
     // 模板会被推导为 `public/subpage.html`
     // 并且如果找不到的话,就回退到 `public/index.html`。
     // 输出文件名会被推导为 `subpage.html`。
     subpage: 'src/subpage/main.js'
     }
    }
    

Анализ перед модификацией

  • Во-первых, делаем вывод из кода, представленного на официальном сайте, то есть несколько страниц фактически являются единым входным списком, поэтому при возникновении потребности в новых страницах, чтобы вручную не изменять данные информации о добавлен список, нам нужно поставить этот кусок скрипта;
  • Во-вторых, с первой точки зрения, многостраничная структура несовместима с инициализированной структурой, поэтому наш первый шаг — модифицировать структуру рендеринга всего шаблона, делать добавления и удаления.Конечно, удаление не просто необходимо , но избыточные структуры будут бессмысленными;

Изменить - настроить структуру

 1.可清空public文件夹、删除main.js和app.vue等其他非核心冗余文件
 2.src增加模板入口文件夹,名字随意,本来是用pages为入口文件夹,结构如下

Изменить — написать многостраничную конфигурационную логику

Вышеупомянутая структура построена, дальше будем настраивать логику, в первую очередь зададим шаги;

  第一步,怎么灵活?方案:将list用脚本读取配置;
  第二部,怎么读取?方案:利用node的fs读取文件夹信息作为入口配置信息

С планом мы скорректируем его непосредственно ниже;

  // -----------------------------pages config----------------------------------
  const fs = require('fs')
  let pages = {}
  const _configPages = async function () {
    await fs.readdirSync('./src/pages/').forEach((val) => {
     pages[val] = {
     // page entry
     entry: `src/pages/${val}/index.js`,
     // 模板来源
     template: `src/pages/${val}/index.html`,
     // 在 dist/index.html 的输出
    filename: `${val}.html`
     }
   })
  }
   _configPages('./src/pages/') // readdirSync
   module.exports = {
     pages: pages // more pages config
   }

Примечание: после окончания работы все заметили, что единственным ключом является название каждой папки шаблона, имя файла в ней менять не нужно, поэтому каждый раз при добавлении страницы нужно только перезапускать ее~

gzip-оптимизация для оптимизации производительности

  首先说明一点的事,开启gzip,在最直观的感觉中,会占用服务端的带宽资源,但是相对于大文件的损耗,还是很值得的,而且目前主流的云cdn,默认开启gzip,所以提前gzip,往往是提高性能的最佳方式。
  
  走一个configureWebpack,简单暴力
  compression-webpack-plugin
  
  const CompressionWebpackPlugin = require('compression-webpack-plugin')
  const gzipSourceList = ['css', 'js']
  module.exports = {
    configureWebpack: config => { // open gzip
       if (process.env.NODE_ENV === 'production') {
       config.optimization.minimizer[0].options.terserOptions.compress.drop_console = true
       return {
         plugins: [
         new CompressionWebpackPlugin({
          filename: '[path].gz[query]', // 目标资源文件名称
          algorithm: 'gzip',
          test: new RegExp(
          '\\.(' + gzipSourceList.join('|') + ')$'
           ), // 匹配所有对应的文件
          threshold: 10240, // 多少kb 配置10kb
          minRatio: 0.8, // 压缩比例
         deleteOriginalAssets: false // 是否删除原始资源
          })
       ]
       }
     }
    }
  }

Остальное нужно только настроить

  module.exports = {
    publicPath: '/[name]/', // 根目录 | “/” 建议制定
    outputDir: './dist/[name]/', // build path 打包输出路径
    productionSourceMap: false, // don·t use map 不要把源暴露出去
    devServer: {
     port: 1314, // port
     open: true, // default browser 主动打开默认浏览器
     overlay: { // 报错展示
      warnings: true, // eslint show warnings
      errors: true // eslint show errors
     }
   }
 }

Структурное расширение

Чтобы сделать разработку очень гибкой, некоторые области выборки и общедоступных файлов по-прежнему необходимо зарезервировать.Структура выглядит следующим образом~

  • запись индекса выборки

    import axios from 'axios'
      import qs from 'qs'
      
      function fetch (type, prefix, url, params, status) {
        return new Promise((resolve, reject) => {
          let postParams = {}
          const instance = axios.create({
            timeout: 100000
          })
          postParams = params
          let fetchData = {
            method: type,
            url: `${prefix}${url}`,
            data: qs.stringify(postParams)
          }
          if (type === 'get' || type === 'GET') {
          }
          instance(fetchData).then(response => {
            const res = response.data
            if (res.code === status) {
              resolve(res)
            } else {
              resolve(res)
            }
          }).catch(error => {
            reject(error)
          })
        })
      }
      
      export {
        fetch
      }
    
  • fetch-api

    import {
        fetch
      } from './index'
      import {
        API_ROOT_CODE
      } from '../config/config' // 域名配置区域
      export default {
        getDemo (params) {
          // demo
          return fetch('get', API_ROOT_CODE, '/test/', params, 0)
        }
      }
    

... и так далее (здесь опущено, пожалуйста, обратитесь к исходному коду для других структурных деталей)

инструменты отладки

 <script>
  var _hmt = _hmt || [];
  (function () {
    // 这里使用的是 eruda, vconsole也不错,根据个人习惯(两种都是拦截了请求资源,所以遇到一些奇葩的请求问题,不妨注释一下)
    const domains = [] // 正式服域名配置 根据域名自动判断是否开启
    const hostname = window.location.hostname
    if (domains.indexOf(hostname) === -1) {
      var src = '//cdn.bootcss.com/eruda/1.2.4/eruda.min.js';
      document.write('<scr' + 'ipt src="' + src + '"></scr' + 'ipt>');
      document.write('<scr' + 'ipt>eruda.init();</scr' + 'ipt>');
    }
  })();
</script>
... ... 

Эпилог

本文基于cli拓展优化,基本适用于目前绝大多数项目级多页面开发,欢迎大家多提一些宝贵意见和见解,欢迎指正~

исходный код GIT,через поезд