详解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 相关文章推荐
jQuery-ui中自动完成实现方法
Jun 10 Javascript
js focus不起作用的解决方法(主要是因为dom元素是否加载完成)
Nov 05 Javascript
js判断undefined类型示例代码
Feb 10 Javascript
用js判断输入是否为中文的函数
Mar 10 Javascript
javascript限制用户只能输汉字中文的方法
Nov 20 Javascript
Bootstrap每天必学之按钮(一)
Nov 24 Javascript
深入探究JavaScript中for循环的效率问题及相关优化
Mar 13 Javascript
Javascript中绑定click事件的四种方式介绍
Oct 26 Javascript
微信小程序HTTP接口请求封装代码实例
Sep 05 Javascript
小程序使用wxs解决wxml保留2位小数问题
Dec 13 Javascript
使用jquery实现轮播图效果
Jan 02 jQuery
详解Vue.js 可拖放文本框组件的使用
Mar 03 Vue.js
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 sprintf()函数用例解析
2011/05/18 PHP
JS对URL字符串进行编码/解码分析
2008/10/25 Javascript
javascript 日期时间函数(经典+完善+实用)
2009/05/27 Javascript
再谈javascript 动态添加样式规则 W3C校检
2009/12/25 Javascript
jQuery的实现原理的模拟代码 -5 Ajax
2010/08/07 Javascript
jquery 取子节点及当前节点属性值的方法
2014/08/24 Javascript
详解JavaScript中的自定义事件编写
2016/05/10 Javascript
vue项目如何刷新当前页面的方法
2018/05/18 Javascript
小程序清理本地缓存的方法
2018/08/17 Javascript
Vue2.0点击切换类名改变样式的方法
2018/08/22 Javascript
CSS3 动画卡顿性能优化的完美解决方案
2018/09/20 Javascript
在vue中更换字体,本地存储字体非引用在线字体库的方法
2018/09/28 Javascript
mockjs+vue页面直接展示数据的方法
2018/12/19 Javascript
angular4应用中输入的最小值和最大值的方法
2019/05/17 Javascript
python批量提取word内信息
2015/08/09 Python
python脚本实现xls(xlsx)转成csv
2016/04/10 Python
Python生成密码库功能示例
2017/05/23 Python
Python处理CSV与List的转换方法
2018/04/19 Python
python中使用iterrows()对dataframe进行遍历的实例
2018/06/09 Python
Python for循环生成列表的实例
2018/06/15 Python
Django 中间键和上下文处理器的使用
2019/03/17 Python
简单了解python filter、map、reduce的区别
2020/01/14 Python
python数据预处理 :数据抽样解析
2020/02/24 Python
django实现更改数据库某个字段以及字段段内数据
2020/03/31 Python
Django返回HTML文件的实现方法
2020/09/17 Python
Betsey Johnson官网:妖娆可爱的连衣裙及鞋子、手袋和配件
2016/12/30 全球购物
澳大利亚网上书店:QBD
2021/01/09 全球购物
最新党员思想汇报
2014/01/01 职场文书
大学毕业自我鉴定范文
2014/02/03 职场文书
流动人口婚育证明范本
2014/09/26 职场文书
中学生检讨书1000字
2014/10/28 职场文书
2014年部门工作总结
2014/11/12 职场文书
爱心助学感谢信
2015/01/21 职场文书
校友回访母校寄语
2015/02/26 职场文书
幼儿园教师心得体会范文
2016/01/21 职场文书
Python 如何将integer转化为罗马数(3999以内)
2021/06/05 Python