详解vue-cli3多页应用改造


Posted in Javascript onJune 04, 2019

需求

一个平台P,包含产品a、b、c、d、e。各产品UI样式风格统一,且会用到公共配置(HOST、是否添加埋点js)、组件(头部导航、表格、搜索框)、方法(请求拦截、生成UUID)。

现状:由于历史遗留原因,各产品为独立SPA、各自维护,配置、组件也都自成一体,只是大概样式上保持了一致,但细节(比如同一面包屑样式,左边距5px、8px都有)都不一致。
这种情况下,改组件、改配置都得一改改多个地方,且有些项目是vue-cli2、有些是vue-cli3,项目间依赖包的版本也不一致,维护起来非常不友好。

目标:整合各产品单页应用为MPA,提取公共文件(主题、配置、组件、方法),减少规范性东西的维护成本。

目录结构对比

整合前

详解vue-cli3多页应用改造

bds-bank-fe
│  README.md
│
│// 静态资源输出目录
│
└───dist
│  └───index.html + static // 平台首页
│  └───label // 产品a
│  │  └───index.html + static
│  └───metrics // 产品b
│  └───service // 产品c
│  └───help // 产品d
│
│// 项目路径
│
└───help-center // 产品d
└───portal-page // 平台首页
└───service-doc // 产品c
└───unify-label // 产品a
└───unify-metrics // 产品b
│  └───build
│  └───config
│  └───src

整合后

详解vue-cli3多页应用改造

│// 静态资源输出目录
│
└───dist
│  └───index.html
│  └───label.html
│  └───metric.html
│  └───service.html
│  └───stocktake.html
│  └───css
│  └───js
│  └───img
├── public
│  └───favicon.ico
│  └───index.html
│
│// 项目路径
│
├── src
│   └── assets
│   └── components
│   ├── pages
│     ├── index
│     ├── label
│     ├── metric
│     ├── service
│     ├── stocktake

实现

vue-cli 3.0官方支持多页,重点在于vue.config.js文件中pages这个配置项,每个页面单独配置entry、template、filename等。pages配置说明

// 官网示例如下
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'
 }
}

Step1: 创建新项目

选择需要的Babel、Router、Vuex、eslint...

具体步骤参考官网:创建一个项目

Step2: 修改配置文件vue.config.js

在根目录下新建public文件夹,包含favicon.ico和index.html两个文件。

详解vue-cli3多页应用改造

index文件内容如下:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width,initial-scale=1.0">
  <link rel="icon" href="<%= BASE_URL %>favicon.ico" rel="external nofollow" >
  <title>P-公共服务平台</title>
</head>
<body>
<noscript>
  <strong>
    We're sorry but page doesn't work properly without JavaScript enabled. Please enable it to continue.
  </strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

然后,在根目录下新建vue.config.js

const glob = require('glob')
const path = require('path')
const resolve = (dir) => path.join(__dirname, dir)

const PAGES_PATH = './src/pages/*/*.js'

module.exports = {
 pages: setPages(),
 // TODO:以下内容非生成多页应用必须配置
 lintOnSave: true,
 productionSourceMap: false,
 chainWebpack: config => {
  /**
   * 自动化导入文件
   */
  const types = ['vue-modules', 'vue', 'normal-modules', 'normal']
  types.forEach(
   type => addStyleResource(config.module.rule('less').oneOf(type)))
  /**
   * 添加别名
   */
  config.resolve.alias
   .set('@index', resolve('src/pages/index'))
   .set('@label', resolve('src/pages/label'))
   .set('@metrics', resolve('src/pages/metric'))
   .set('@service', resolve('src/pages/service'))
   .set('@stocktake', resolve('src/pages/stocktake'))
  /**
   * 菜单icon处理为svg-sprite
   */
  config.module
   .rule('svg')
   .exclude
   .add(resolve('src/assets/icons/menus'))
   .end()
  config.module
   .rule('svg-sprite-loader')
   .test(/\.svg$/)
   .include
   .add(resolve('src/assets/icons/menus')) // 处理目录
   .end()
   .use('svg-sprite-loader')
   .loader('svg-sprite-loader')
   .options({
    symbolId: 'icon-[name]'
   })
 }
}

/**
 * 组装页面
 */
function setPages () {
 let pages = {}
 glob.sync(PAGES_PATH).forEach(filepath => {
  let fileList = filepath.split('/')
  let fileName = fileList[fileList.length - 2]

  pages[fileName] = {
   entry: filepath,
   template: 'public/index.html',
   filename: `${fileName}.html`,
   // title:
   chunks: ['chunk-vendors', 'chunk-common', fileName]
  }
 })
 return pages
}

/**
 * 注入公共less
 * @param rule
 */
function addStyleResource (rule) {
 rule.use('style-resource')
  .loader('style-resources-loader')
  .options({
   patterns: [
    path.resolve(__dirname, 'src/assets/styles/variable.less')
   ]
  })
}

Step3: 拷贝原项目src目录至pages下,大概长这样

详解vue-cli3多页应用改造

Step4: 各产品原项目下package.json依赖包都挪到根目录下package.json,重新安装

PS:由于依赖向上升级,某些老版本依赖包可能会存在升级引发的问题,需要细心走查一遍。这里由于业务不一样,就不详细赘述了

然后npm start,完美启动~

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
两种WEB下的模态对话框 (asp.net或js的分别实现)
Dec 02 Javascript
Zero Clipboard js+swf实现的复制功能使用方法
Mar 07 Javascript
JavaScrip单线程引擎工作原理分析
Sep 04 Javascript
jQuery实现右侧显示可向左滑动展示的深色QQ客服效果代码
Oct 23 Javascript
Angular.js与Bootstrap相结合实现表格分页代码
Apr 12 Javascript
Angular2内置指令NgFor和NgIf详解
Aug 03 Javascript
详解vue.js+UEditor集成 [前后端分离项目]
Jul 07 Javascript
es7学习教程之fetch解决异步嵌套问题的方法示例
Jul 21 Javascript
一篇文章让你彻底弄懂JS的事件冒泡和事件捕获
Aug 14 Javascript
基于JavaScript实现每日签到打卡轨迹功能
Nov 29 Javascript
jquery+ajax实现上传图片并显示上传进度功能【附php后台接收】
Jun 06 jQuery
解决webpack多页面内存溢出的方法示例
Oct 08 Javascript
javascript异步处理与Jquery deferred对象用法总结
Jun 04 #jQuery
浅谈react-router@4.0 使用方法和源码分析
Jun 04 #Javascript
vue axios post发送复杂对象问题
Jun 04 #Javascript
vue 2.5.1 源码学习 之Vue.extend 和 data的合并策略
Jun 04 #Javascript
vue实现分环境打包步骤(给不同的环境配置相对应的打包命令)
Jun 04 #Javascript
JavaScript实现页面中录音功能的方法
Jun 04 #Javascript
vue elementUI 表单校验功能之数组多层嵌套
Jun 04 #Javascript
You might like
一周学会PHP(视频)Http下载
2006/12/12 PHP
php file_exists 检查文件或目录是否存在的函数
2010/05/10 PHP
php数组函数序列之each() - 获取数组当前内部指针所指向元素的键名和键值,并将指针移到下一位
2011/10/31 PHP
PHP获取数组中某元素的位置及array_keys函数应用
2013/01/29 PHP
PHP源码分析之变量的存储过程分解
2014/07/03 PHP
PHP命令行脚本接收传入参数的三种方式
2014/08/20 PHP
PHP中exec与system用法区别分析
2014/09/22 PHP
ThinkPHP查询语句与关联查询用法实例
2014/11/01 PHP
PHP解压ZIP文件到指定文件夹的方法
2016/11/17 PHP
PHP 7.1新特性的汇总介绍
2016/12/16 PHP
PHP基于Closure类创建匿名函数的方法详解
2017/08/17 PHP
jquery选择器(常用选择器说明)
2010/09/28 Javascript
百度地图api应用标注地理位置信息(js版)
2013/02/01 Javascript
使用jquery菜单插件HoverTree仿京东无限级菜单
2014/12/18 Javascript
AngularJS基础知识
2014/12/21 Javascript
基于JavaScript操作DOM常用的API小结
2015/12/01 Javascript
Bootstrap入门书籍之(四)菜单、按钮及导航
2016/02/17 Javascript
jQuery插件之validation插件
2017/03/29 jQuery
深入理解基于vue-cli的vuex配置
2017/07/24 Javascript
Angular4 Select选择改变事件的方法
2018/10/09 Javascript
简单说说angular.json文件的使用
2018/10/29 Javascript
JS根据Unix时间戳显示发布时间是多久前【项目实测】
2019/07/10 Javascript
vue-cli3访问public文件夹静态资源报错的解决方式
2020/09/02 Javascript
Python中对象的引用与复制代码示例
2017/12/04 Python
python:按行读入,排序然后输出的方法
2019/07/20 Python
解决Python3下map函数的显示问题
2019/12/04 Python
Python爬虫谷歌Chrome F12抓包过程原理解析
2020/06/04 Python
websocket+sockjs+stompjs详解及实例代码
2018/11/30 HTML / CSS
世界上最悠久的自行车制造商:Ribble Cycles
2017/03/18 全球购物
The Beach People美国:澳洲海滨奢华品牌
2018/07/05 全球购物
商务邀请函范文
2014/01/14 职场文书
春风行动实施方案
2014/03/28 职场文书
大学生撤销处分思想汇报
2014/09/12 职场文书
2014年图书馆工作总结
2014/11/25 职场文书
《水浒传》读后感3篇(范文)
2019/09/19 职场文书
小程序与后端Java接口交互实现HelloWorld入门
2021/07/09 Java/Android