vue-cli3单页构建大型项目方案

一、vue-cli3单页面构建方案

1、在目标文件夹内执行

vue ui ; 一个ui版界面,用于创建vue项目;

2、打开router文件夹内的index,看情况配置router的模式,是默认的hash还是history?ps:个人推介history模式,因为内嵌如app的H5页面的话,有可能某些app是不允许页面上带有'#'的,而hash会在url上利用#来做路由转发。ps:history模式在发布到服务器上需要nginx配置一下。详情请自行百度。

const router = new VueRouter({
 base: '/',
 mode: 'history', //还可设置为'hash'模式
 routes
})

3、在根目录新建vue.config.js,覆盖webpack配置,将如下内容copy到文件中,作为初始配置

// const webpack = require('webpack')

module.exports = {
  lintOnSave: false, // 禁止eslint
  devServer: {
    open: true, // 构建完成自动打开浏览器
  },

  configureWebpack: {
    plugins: [
      // 全局配置node_modules中的模块,使用时无需引入
      new webpack.ProvidePlugin({
        $: "jquery",
        jQuery: "jquery",
        "windows.jQuery": "jquery"
      })
    ]

  },

  // webpack 链接 API,用于生成和修改 webapck 配置
  chainWebpack: (config) => {
    // 取消 chunks,每个页面只对应一个单独的 JS / CSS
    config.optimization.splitChunks({
      cacheGroups: {}
    });

    // config
    //   .plugin('webpack-bundle-analyzer')
    //   .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin)
  },

  pluginOptions: {

  }
}

4、配置完这些后,npm run serve启动项目,会加载如下两个js

npm run serve

app.js:是所有单页面首次渲染都必须加载的js,内部合并了框架及js(如vue、vue-x、vue-router及非异步组件但引用了的node_modules中的模块),及所有页面公用的模块。about.js:是每个页面独立的js,这个跟router中引用模块的方式有关。

具体详解如下:

1、

import Home from '../views/Home.vue'

这种引用方式引用页面模版组件,就不会出现about.js文件,因为属于同步模块,当前件建的js会被打包进app.js。但是此种随着页面的增多,公用的app.js会越来越大。看情况在app.js大小接受的前提下权衡使用;2、

const routes = [
 {
  path: '/',
  name: 'Home',
  // component: Home
  component: () => import(/* webpackChunkName: "home" */ '../views/Home.vue') // webpack的魔法注释,将拆分出的js命名为home
 },
 {
  path: '/about',
  name: 'About',
  // route level code-splitting
  // this generates a separate chunk (about.[hash].js) for this route
  // which is lazy-loaded when the route is visited.
  component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
 }
]

这种引用方式就是异步引用模版组件,不会将当前组建的js打包进app.js,就不会出现1种的问题。因为只要没有加载到对应页面,就不会加载对应页面的js。对应页面的js会最为独立的js单独的动态引入,如同上图的about.js,在进入about页面时才会引入。

3、如果在main.js中引入的node_modules包,则会直接打包进app.js,这个逃不掉。

ps:最终结论,建议每个页面都异步引用页面模版。

5、每个页面如果引了node_mudules就会存在相对应的vendors-home.js,如果没引入node_mudules的话,每个页面按需组件就不会存在vendors-home.js这个文件,如下图:

6、区分本地、测试、线上环境

ps:官网提供一种方案,但是需要建立多个环境配置的配置文件,嫌麻烦,就不使用官方的方式,使用如下插件拆分环境:

cross-env:https://github.com/kentcdodds/cross-env

cnpm i cress-env --save-dev // 更改node环境变量插件

之后在package.json中加入如下三行配置,即可区分本地、测试、线上环境

"scripts": {
  "serve": "cross-env NODE_ENV=development vue-cli-service serve",
  "test": "cross-env NODE_ENV=test vue-cli-service build",
  "build": "cross-env NODE_ENV=production vue-cli-service build"
 },

在vue.config.js中执行如下代码即可打印出当前环境。

console.log(process.env.NODE_ENV)

在src目录下新建config目录,进入目录,新建gateway.config.js文件用于配置不同环境接口host,代码如下:gateway.config.js文件内容如下:

// 开发环境地址(npm run serve)
const devHost = {
 // 接口地址域名相关
 baseApi: 'https://abc.com',

}

// 测试环境地址(npm run test)
const testHost = {
 // 接口地址域名相关
 baseApi: 'https://abc.com',

}

// 线上环境地址(npm run build)
const proHost = {
 // 接口地址域名相关
 baseApi: 'https://abc1.com',

}

// 区分环境选择静态资源地址
const env = process.env.NODE_ENV

let exportConfig = ''
if (env === 'production') {
 exportConfig = proHost
} else if (env === 'test') {
 exportConfig = testHost
} else {
 exportConfig = devHost
}

export default exportConfig

结束:之后只需要在接口api的js文件中引入此文件即可。发布时区分环境打包。

7、浅谈项目引入第三方插件方案

ps:原则:移动端单个js大小不超过200k;pc端单个js不超过400k;

1.vue模块化引入node_modules包插件:

前提,各个页面都是异步加载,这样的好处是单个页面的js不会被打包进公共app.js中。之后在单个js中引入第三方库。但是据测试:这种模块化引入第三方插件,比cdn模式引入的js体积至少要大2呗,因为webpack内部对每个第三方库进行了二次处理,会增大js体积。权衡js大小使用。

2.cdn模式引入第三方插件:

提供这种方式,是因为有些库是不支持vue的,只支持cdn模式引入,而且比较轻量级,可以选择这种方案,异步cdn模式引入第三方插件,这些方式最下方脚手架示例中都有demo;

8、项目中常用的打包插件及第三方库

1.vue https://cn.vuejs.org
2.vue-router https://router.vuejs.org
3.vue-x https://vuex.vuejs.org
4.sass https://www.sass.hk
5.axios http://www.axios-js.com/
6.normalize.css http://necolas.github.io/normalize.css/
7.n-zepto https://npm.taobao.org/package/n-zepto
8.webpack-bundle-analyzer https://github.com/webpack-contrib/webpack-bundle-analyzer

下方是vue-cli3内置插件(直接在vue.config.js中配置):

如下插件可参考vue-cli3官网配置方法:

https://cli.vuejs.org/zh/config/#css-sourcemap

9.autoprefixer:自动添加浏览器前缀。(如:-webkit-等)
10.url-loader:改变静态资源引用路径

11.ProvidePlugin:全局配置node_modules中的模块

具体配置方法如下(比较全的vue.config.js配置):

const webpack = require('webpack')

const processEnv = process.env.VUE_APP_ENV; // 区分环境(值:production、development、test)
const isPro = processEnv === 'production'; // 判断production环境

const outputDir = 'dist'; // 输出文件目录(默认dist)
const assetsDir = ''; // 配置放置生成的静态资源 (js、css、img、fonts) 的 (相对于 outputDir 的) 目录

// 区分环境选择cdn地址
let publicPath = '' // 静态资源引用路径
let fontPublicPath = '' // 字体图标引用的cdn路径
let imgPublicPath = '' // css引用图片的cdn路径(c2c/static/img)
if (processEnv === 'production') {
  publicPath = 'https://abc.com/c2c/shop' // 正式环境静态资源css、js等cdn路径
  fontPublicPath = `https://abc.com/c2c/shop/${assetsDir ? assetsDir + '/' : '/'}fonts` // 正式环境字体图标引用的cdn路径
  imgPublicPath = `https://abc.com/c2c/shop/${assetsDir ? assetsDir + '/' : '/'}/img` // 正式环境css引用图片的cdn路径
} else if (processEnv === 'test') {
  // publicPath = './' // 正式环境静态资源css、js等cdn路径
  publicPath = 'https://bcd.com/c2c/shop/dist' // 测试环境静态资源css、js等cdn路径
  fontPublicPath = ''
  imgPublicPath = ''
} else {
  publicPath = '/'
  fontPublicPath = ''
  imgPublicPath = ''
}

const devServerHost = 'localhost';
const devServerPort = '8080'; // 端口号
const devServerOpen = true; // 热启动后自动打开浏览器

module.exports = {

  // 配置生成dist里面static的cdn资源路径(测试环境为./,正式环境走cdn路径)
  publicPath: publicPath,

  // 输出文件目录(默认dist)
  outputDir,

  // 配置放置生成的静态资源 (js、css、img、fonts) 的 (相对于 outputDir 的) 目录
  assetsDir,

  devServer: {
    host: devServerHost,
    port: devServerPort,
    open: devServerOpen, // 构建完成自动打开浏览器

    // eslint检测影响代码编译,注释调不会影响代码编译
    // overlay: {
    //   warnings: true,
    //   errors: true
    // }
  },
  lintOnSave: processEnv === 'development' ? true : false, // 开发环境开启eslint,测试和线上编辑代码禁止eslint

  // webpack 配置,键值对象时会合并配置,为方法时会改写配置
  configureWebpack: config => {
    // 扩展资源,不将部分资源js等打入包内引用cdn资源
    let externals = {
      // 'swiper': 'Swiper',
    };
    config.externals = externals;

    //警告 webpack 的性能提示
    config.performance = {
      hints: isPro ? 'warning' : false, // 本地开发不显示警告
      // 入口起点的最大体积
      maxEntrypointSize: 512000, // 500kib
      // 生成文件的最大体积
      maxAssetSize: 307200, // 300kib
      // 只给出 js 文件的性能提示
      assetFilter(assetFilename) {
        return assetFilename.endsWith('.js');
      }
    };
  },

  // webpack 链接 API,用于生成和修改 webapck 配置
  chainWebpack: (config) => {
    // 取消 chunks,每个页面只对应一个单独的 JS / CSS
    config.optimization.splitChunks({
      cacheGroups: {}
    });

    // 全局配置node_modules中的模块,使用时无需引入
    config.plugin('provide').use(webpack.ProvidePlugin, [{
      $: "n-zepto",
      Zepto: "n-zepto",
      "window.Zepto": "n-zepto"
    }]);

    config.module
      .rule('images')
      .use('url-loader')
      .loader('url-loader')
      .tap(options => Object.assign(options, {
        limit: 10240, // 小于10k,压缩图片 => base64
        // limit: 3000,
        publicPath: imgPublicPath,
        name: `[name].[hash:8].[ext]`
      }))

    // 设置fonts字体文件引用的路径
    config.module
      .rule('fonts')
      .test(/\.(woff2?|eot|ttf|otf)(\?.*)?$/i)
      .use('url-loader')
      .loader('file-loader')
      .tap(options => Object.assign(options, {
        limit: 5000,
        publicPath: fontPublicPath,
        name: '[name].[hash:8].[ext]'
      }))

    // npm run report;打印app.js的模块报告,查看各个模块;
    if (processEnv === 'report') {
      config
        .plugin('webpack-bundle-analyzer')
        .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin)
    }

  },

  // css配置处理
  css: {
    // 是否使用css分离插件 ExtractTextPlugin;true:页面css独立分割,false:页面css同一打包;
    extract: true,
    // 开启 CSS source maps(默认false)线上关闭,测试和本地开启
    sourceMap: isPro ? false : true,
    // css预设器配置项
    loaderOptions: {
      sass: {
        // sass的公共方法和变量,需要预编译;
        prependData: `
          @import "@/assets/css/global.scss";
          @import "@/assets/css/func.scss";
        `
      },
      postcss: {
        plugins: [
          // 浏览器自动加前缀
          require('autoprefixer')({
            overrideBrowserslist: [
              "Android 4.0",
              "iOS 7",
              "Chrome > 31",
              "ff > 31",
              "ie >= 8"
            ]
          }),
        ]
      }

    },
    // 启用 CSS modules for all css / pre-processor files.
    requireModuleExtension: false
  },

  // 构建时开启多进程处理 babel 编译
  parallel: require('os').cpus().length > 1,

  pwa: {
    iconPaths: {
      favicon32: 'favicon.ico',
      favicon16: 'favicon.ico',
      appleTouchIcon: 'favicon.ico',
      maskIcon: 'favicon.ico',
      msTileImage: 'favicon.ico'
    },

  },

  // 第三方插件配置
  pluginOptions: {
    // ...
  }
}

9、一个基础配置较为完善的基于vue-cli3的单页面项目方案脚手架:
项目脚手架集合project-init
其中的cli-start-spa文件夹,内部readme有项目细节。

到此这篇关于vue-cli3单页构建大型项目方案的文章就介绍到这了,更多相关vue-cli3单页构建 内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • vue-cli单页应用改成多页应用配置详解

    前言 从接触vue开始用的是vue-cli直接搭建单页应用,参考配合着vue-router开发起来简直爽到吊炸天,但是由于项目越来越复杂了,单页用起来可能有点力不从心,能不能弄成多页面呢,查了相关资料得到的结论是完全可以的,能多页面多入口,并且可以使用组件,还引入jQuery,这简直完美了,这个demo是从我已经改造完成的项目中摘出来的,现在演示下怎么把基于vue2的vue-cli单页模板改造成多页面,并且多入口的项目. 技术栈 vue: 2.0.1 vue-resource:1.0.3 vue

  • 详解vue-cli 快速搭建单页应用之遇到的问题及解决办法

    一.报错内容类似:Expected indentation of 0 spaces but found 4 将 build 文件下的 webpack.base.conf.js 文件里面的下面一段代码注释掉(eslint-loader内容),重新运行. 二.报错内容: Newline required at end of file but not found 只需要在 js css 等后面再加一行(空行)就可以了 或者将 build 文件下的 webpack.base.conf.js 文件里面的下

  • Vue-cli创建项目从单页面到多页面的方法

    对于某些项目来说,单页面不能很好的满足需求,所以需要将vue-cli创建的单页面项目改为多页面项目. 需要修改以下几个文件: 1.下载依赖glob $npm install glob --save-dev 2.修改build下的文件 (1)修改webpack.base.conf.js 添加以下代码: var glob = require('glob'): var entries = getEntry('./src/pages/**/*.js') 将module.exports中的 entry:

  • 手把手教你vue-cli单页到多页应用的方法

    vue-cli到多页应用 前言:我有一个cli创建的vue项目,但是我想做成多页应用,怎么办,废话不多说,直接开撸~ 约定:新增代码部分在//add和//end中间 删除(注释)代码部分在//del和//end中间,很多东西都写在注释里 第一步:cli一个vue项目 新建一个vue项目 官网 vue init webpack demo cli默认使用webpack的dev-server服务,这个服务是做不了单页的,需要手动建一个私服叫啥你随意 一般叫dev.server或者dev.client

  • vue-cli3单页构建大型项目方案

    一.vue-cli3单页面构建方案 1.在目标文件夹内执行 vue ui ; 一个ui版界面,用于创建vue项目: 2.打开router文件夹内的index,看情况配置router的模式,是默认的hash还是history?ps:个人推介history模式,因为内嵌如app的H5页面的话,有可能某些app是不允许页面上带有'#'的,而hash会在url上利用#来做路由转发.ps:history模式在发布到服务器上需要nginx配置一下.详情请自行百度. const router = new Vu

  • vue/react单页应用后退不刷新方案

    目录 引言 为什么麻烦 有坑的社区方案(以vue为例) 目前不错的方案 上效果图 vue中的实现 react中的实现 题外 该方案的优点 缺点 引言 前进刷新,后退不刷新,是一个类似app页面的特点,要在单页web应用中做后退不刷新,却并非一件易事. 为什么麻烦 spa的渲染原理(以vue为例):url的更改触发onHashChange/pushState/popState/replaceState,通过url中的pathName去匹配路由中定义的组件,加载进来并实例化渲染在项目的出口route

  • 详解Vue CLI3 多页应用实践和源码设计

    对于一个网站来说,即需要h5页面也同时需要web页面,而h5和web页面共用很多代码,不做响应式,只能拆分两个页面来写,一个h5,一个web.用vue cli3怎么配置h5与web的应用呢? 解决思路: 首先,需要产生多页面应用,用webpack配置成多页面应用,一个h5一个web,这个网上已经有很多教程了,下面会再整理一次,接着把所有公共的代码提到多页面目录外面. 我们看一下官网给的 multi-page 的配置:需要在 vue.config.js 配置 pages,示例如下: pages:

  • Vue SPA单页应用首屏优化实践

    1.代码压缩(gzip) 如果你用的是nginx服务器,请修改配置文件(其他web server 类似):sudo nano /etc/nginx/nginx.conf 在Gzip Settings里加入: gzip on; gzip_min_length 1k; gzip_buffers 4 16k; gzip_comp_level 5; gzip_types text/plain application/x-javascript text/css application/xml text/j

  • 详解VUE单页应用骨架屏方案

    什么是骨架屏? 简单的说,骨架屏就是在页面未渲染完成的时候,先用一些简单的图形大致勾勒出页面的基本轮廓,给用户造成页面正在加载的错觉,待页面渲染完成之后再用页面替换掉骨架屏,从而减少页面白屏的时间,给用户带来更好的体验. 分析VUE渲染过程 使用vue-cli3.0创建项目: vue create project 在生成的项目文件夹下的public文件夹下的index.html文件代码如下: <!DOCTYPE html> <html lang="en"> &l

  • 使用Vue.js和Flask来构建一个单页的App的示例

    在这个教程中,我们将讲解如何将vue.js单页应用与Flask后端进行连接. 一般来说,如果你只是想通过Flask模板使用vue.js库也是没有问题的.但是,实际上是一个很明显的问题那就是,Jinja(模板引擎)也和Vue.js一样采用双大括号用于渲染,但只是一个还算过的去的解决方案. 我想要一个不同的例子.如果我需要建立一个单页应用程序(应用程序使用单页组成, vue-router 在HTML5的History-mode以及其他更多好用的功能)用vue.js,由Flask提供Web服务?简单地

  • 使用 vue.js 构建大型单页应用

    前置条件: 熟悉使用 Javascript + HTML5 + css3. 理解 ES2015 Module 模块(export.import.export-default). 了解 nodejs 基础知识,npm 常用命令,以及 npm script 使用 (vue 项目中使用 npm 进行包管理). 了解 webpack 打包工具 (常用配置选项以及 loader 概念).(webpack webpack.github.io/ 是一个模块打包工具.它将一堆文件中的每个文件都作为一个模块,找出

  • Vue 2.0+Vue-router构建一个简单的单页应用(附源码)

    一.介绍 vue.js 是 目前 最火的前端框架,vue.js 兼具 angular.js 和 react.js 的优点,并剔除它们的缺点,并且提供了很多的周边配套工具 如vue-router .vue-resource .vuex等等 ,通过他们我们可以很轻松的构建一个大型单页应用. 目前Vue版本为:Vue2.0 官网地址:http://vuejs.org.cn/ 查看API文档:https://vuefe.cn/v2/api/ 对比其他框架:http://vuejs.org.cn/guid

  • 浅谈VUE单页应用首屏加载速度优化方案

    单页应用会随着项目越大,导致首屏加载速度很慢!!!以下给出在下知道的几种优化方案 使用CDN资源,减小服务器带宽压力 路由懒加载 将一些静态js css放到其他地方(如OSS),减小服务器压力 按需加载三方资源,如iview,建议按需引入iview中的组件 使用nginx开启gzip减小网络传输的流量大小 webpack开启gzip压缩 若首屏为登录页,可以做成多入口,登录页单独分离为一个入口 使用CDN资源,减小服务器带宽压力 在index.html中引入cdn资源 ... <body> &

  • 如何使用Vuex+Vue.js构建单页应用

    前言:在最近学习 Vue.js 的时候,看到国外一篇讲述了如何使用 Vue.js 和 Vuex 来构建一个简单笔记的单页应用的文章.感觉收获挺多,自己在它的例子的基础上进行了一些优化和自定义功能,在这里和大家分享下学习心得. 在这篇教程中我们将通过构建一个笔记应用来学习如何在我们的 Vue 项目中使用 Vuex.我们将大概的过一遍什么是 Vuex.js,在项目中什么时候使用它,和如何构建我们的 Vue 应用. 这里放一张我们项目的预览图片: 项目源码:vuex-notes-app:有需要的同学可

随机推荐