vue2开发过程问题总结

本文首发于我的博客

前言

慢慢地也用vue2+webpack2重构了一整个项目,期间自己踩过的坑和思考记录下来,既让自己复盘一遍也方便以后查找相关的问题

项目构建

因为vue-cli实在是太友好了,并且也是打算做单页应用,所以直接用vue-cli构建基于webpack2的模板。

整体技术栈使用vue2+webpack2+vuex+Axios+vue-router

项目总体结构↓


|-- build                            // 项目构建webpack相关代码
|-- config                           // 项目开发环境配置
|-- node-moudles                     //node依赖包(自动生成的)
|-- src                              // 源码目录(此文件内基本就是开发者主要编写代码存放资源的地方)
     |--router                            //路由文件
     |--vuex                              //vuex文件
     |--style                             //公共样式文件
     |--assets                            //静态资源(大多都是放一些样式类文件,如css、scss等,不知道为啥,当时我没有用)
     |--components                        //组件文件
|-- static                           // 静态文件,比如一些图片,json数据等(打包成生产环境时,会将这个文件直接打包进去)
|-- .babelrc                         // ES6语法编译配置
|-- .editorconfig                    // 定义代码格式
|-- .gitignore                       // git上传需要忽略的文件格式
|-- README.md                        // 项目说明
|-- favicon.ico                      // 页面标签显示的logo
|-- index.html                       // 入口页面
|-- package.json                     // 项目基本信息

build文件夹


|-- build                            // 项目构建webpack相关代码
     |--build.js                          //生产环境构建
     |--check-version.js                  //版本检查
     |--dev-client.js                     //开发服务器热重载
     |--dev-server.js                     //构建本地服务器
     |--utils                             //构建相关工具
     |--vue-loader.conf.js                //CSS加载器配置
     |--webpack.base.conf.js              //webpack基础配置
     |--webpack.dev.conf.js                //webpack开发环境配置
     |--webpack.prod.conf.js               //webpack生产环境配置
     |--webpack.test.conf.js               //webpack测试环境配置

build主要是用于webpack的一些相关配置,比如内部含有的启动文件dev-server.js.当我们运行npm run dev命令时node就会根据
package.json中的"dev": "node build/dev-server.js",来寻找此文件,这些都是默认设置。无需要修改

  "scripts": {
    "dev": "node build/dev-server.js",
    "start": "node build/dev-server.js",
    "build": "node build/build.js",
    "unit": "cross-env BABEL_ENV=test karma start test/unit/karma.conf.js --single-run",
    "e2e": "node test/e2e/runner.js",
    "test": "npm run unit && npm run e2e"
  },

config文件夹

config主要就是项目的相关配置,比如自定义修改监听端口,打包输出的路径及其输出文件的命名


|-- config                           // 项目构建webpack相关代码
     |--dev.env.js                      //项目开发环境配置
     |--index.js                        //项目主要的配置(监听端口,打包路径啥的都在这里写)
     |--prod.env.js                     //项目生产环境配置
     |--test.env.js                     //项目测试环境配置

上述三个文件做简单介绍是因为最后我们在打包优化主要是对于webpack的配置文件进行修改,所以先做简单介绍。

编码过程问题总结

路由标签自定义

用到vue2框架的时候不可避免会用到路由插件,一般配合vue2的官方路由插件是vue-router2

其中有个路由跳转标签为router-link

例子如下

<router-link to="/foo">foo</router-link>
<!-- 渲染结果 -->
<a href="/foo">foo</a>

但是由于样式的原因。有时候我们不希望他被渲染成<a href=""></a>

那我们可以利用router-link中的tag属性改变渲染过后的标签

例子如下

<router-link to="/foo" tag="li">foo</router-link>
<!-- 渲染结果 -->
<li>foo</li>

自定义路径别名(@,~)

在vue2过程导入组件或者css时可能会有这种语法

import Index from '@/components/Index'

这种@是什么东西?
在配置文件中这是webpack的配置项之一:路径别名

我们可以在基础配置文件中自定义自己的路径别名,比如设置~src/components:

// build/webpack.base.js

{
  resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
      'vue$': 'vue/dist/vue.esm.js',
      '@': resolve('src'),
      '~': resolve('src/components')
    }
  }
}

然后导入组件就可以直接这样写

//import YourComponent from 'src/components/YourComponent

import YourComponent from '~/YourComponent'

这样就解决了路径过长与相对路径的烦恼,方便多了吧

CSS作用域与模块

在组件化开发过程中本着分离的原则,CSS也应该进行独立分离,这样更方便以后维护。

我们可以通过添加scoped属性来使style中的样式只作用于当前组件

<style lang="less" scoped>
  @import 'other.less';
  .main{
    color:#fff
  }
</style>

注意:

在有scoped属性的style标签内导入其他样式,同样会被限制于该作用域,变为组件内的样式。这样再每次打包之后会大大增加CSS体积,所以复用程度较高的样式不建议这样使用
,第一次我就出了这个问题

另外,在组件内样式中应该避免使用元素选择器,原因在于元素选择器与属性选择器进行查询时性能会大大降低

好像这条不止于在vue中,而是css本来就存在的

v-for的使用

v-for指令真是无比便捷,他让我们大大减少了HTML代码的编码量,并且让模板更加与数据契合。
不仅可以遍历数组,对象,甚至可以遍历字符串与数字

我们经常会遇到一些比如,上下移动行啊什么的需求。这些需求基本都绕不过索引
在使用v-for时候我们可以直接
<li v-for="(item,index) of items" :index="index" :key="index"></li>
这样直接可以利用li标签的index属性就可以拿到当前这行的index。tr同理
但是在便利数字时候需要特别注意,数字是从1开始的

项目路径配置

vue-cli提供的 npm run build打包出的dist文件是默认把index.html当做根目录引用的,然而我们有时候是需要部署到服务中的子目录下

那么我们可以修改config/index.js中来改变相对路径:

build.assetsSubDirectory: 'static'
build.assetsPublicPath: '/'

dev.assetsSubDirectory: 'static'
dev.assetsPublicPath: '/'

assetsSubDirectory指的是静态资源文件夹,也就是打包后的js、css、img等文件所放置的文件夹。这个一般都不需要修改
assetsPublicPath而这个属性就是指index中引用静态资源的路径,默认为/。如果我们需要做特殊配置修改这里的路径就好。路径修改为最后你的index.html到这个静态资源的相对路径

开发环境配置

何为开发环境:在开发时,不可避免会产生大量debug又或是测试的代码,这些代码不应出现在生产环境中(也即不应提供给用户)。

开启webpack的cache

webpack.base.conf.js中,在module.exports内加入cache: true这个属性

配置加载器loader中的include与exclude

加载器loader中的include属性代表需要编译的文件,而反之exclude就是不需要编译的文件。

大多数情况下我们几乎都不需要对node_modules下的js文件进行编译,我们只需要对我们项目目录下自己编写的js进行编辑就好,所以我们通过配置这两个选项,大大提升我们的构建速度

webpack.base.conf.js

// ... 其他配置
module: {
  rules: [
    {
      test: /\.js$/,
      loader: ['babel-loader?cacheDirectory=true'],
      include: [resolve('src')], // src是项目开发的目录
      exclude: [path.resolve('../../node_modules')] // 不需要编译node_modules下的js 
    },
    // ... 其他loader
  ]
}

开启babel-loader插件的cache

开启babel-loader的编译缓存,以后编译就只会编译修改过的地方,重用的地方就不会重新编译,大大节约构建速度。

此代码在webpack.base.conf.js

module:{
      rules: [
    {
      test: /\.js$/,
      loader: ['babel-loader?cacheDirectory=true']  //修改这里即可
    },
  ]
}

使用HappyPack加快编译速度

虽然我们有webpack的热更新,但每次初始化启动项目时发现总是需要等待很长的时间才能完成编译。

那么我们就可以利用HappyPack插件开启多线程,大大加快代码构建速度。

主要核心技术有两点:

  1. 利用Loader的并发可行性完成多线程
  2. 在每次编译时候都会针对对应文件存入一个时间戳并且将编译结果缓存 ,下次编译时,就会先读取这个时间戳。利用这个做key去对比,如果没有变那么就直接读取缓存。

例子代码如下:


//先引入happypack与相关模块
let HappyPack = require('happypack');
let os = require('os');
let happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length });

module:{
 rules: [{
      test: /\.vue$/,
      loader: 'vue-loader',
      // options: vueLoaderConfig
      options: {
        loaders: {
          js: 'happypack/loader?id=js' // 将loader换成happypack
        }
      }
    },
    {
      test: /\.js$/,
      // loader: 'babel-loader',
      // loader: ['babel-loader?cacheDirectory=true'],
      loader: ['happypack/loader?id=js'], // 将loader换成happypack
      include: [resolve('src'), resolve('test')],
      exclude: [path.resolve('../../node_modules')] // 不需要编译node_modules下的js 
    },
    ...
}

plugins:[
    new HappyPack({
      id: 'vue',
      threadPool: happyThreadPool,
      cache: true,
      verbose: true,
      loaders: ['vue-loader'],
    }),

    new HappyPack({
      id: 'js',
      threadPool: happyThreadPool,
      cache: true,
      verbose: true,
      loaders: ['babel-loader'],
    }),
]

生产环境配置

何为生产环境配置:页面部署到服务器时,为了追求性能加大用户体验,所以我们会对代码进行各种各样的优化,比如说混淆、压缩,这些手段往往会彻底破坏代码本身的可读性,不利于我们进行debug等工作。

利用CommonsChuncksPlugin解决重复引用

我们在开发过程中为了方便代码维护,可能会抽出一些公关的模块,这里不止于vue的共用组件,如果用了css预编译器,那更是会有@mixin这种宏(scss是这样,其他可能不是这个名词但是也会有)。

那么在打包过程中将会把引入的模块重复打包,这样大大增加了最后的文件体积,这样是肯定不可取的。

而webpack有个插件叫CommonsChuncksPlugin

就是专门把重复打包的模块给抽取出来单独打包的插件。这个能够显著降低最后打包的体积,也能提升一些打包速度。

使用也很方便,就是在webpack.base.conf.js中的plugins添加相关的配置代码,如下

plugins: [
  new webpack.optimize.CommonsChunkPlugin({
    async: 'shared-module',
    minChunks: (module, count) => (
      count >= 2    // 当一个模块被重复引用2次或以上的时候单独打包起来。 
    )
  }),
  //...
]
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容