• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

文档_Vue04_生产部署_单文件组件_单元测试_TypeScript支持_路由_状态管理_响应式原理_ ...

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

Vue.js_官方文档学习笔记_Part_04





生产环境部署

开启生产环境模式

开发环境下,Vue 会提供很多警告来帮你对付常见的错误与陷阱。

而在生产环境下,这些警告语句却没有用,反而会增加应用的体积。

此外,有些警告检查还有一些小的运行时开销,这在生产环境模式下是可以避免的。

不使用构建工具

如果用 Vue 完整独立版本,即直接用 <script> 元素引入 Vue 而不提前进行构建,

请记得在生产环境下使用压缩后的版本 (vue.min.js)。

两种版本都可以在安装指导中找到。

使用构建工具

当使用 webpack 或 Browserify 类似的构建工具时,

Vue 源码会根据 process.env.NODE_ENV决定是否启用生产环境模式,默认情况为开发环境模式。

在 webpack 与 Browserify 中都有方法来覆盖此变量,以启用 Vue 的生产环境模式,

同时在构建过程中警告语句也会被压缩工具去除。

这些所有 vue-cli 模板中都预先配置好了,但了解一下怎样配置会更好。


webpack

使用 webpack 的 DefinePlugin 来指定生产环境,以便在压缩时可以让 UglifyJS 自动删除警告代码块。

例如配置:

var webpack = require('webpack')

module.exports = {
  // ...
  plugins: [
    // ...
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: '"production"'
      }
    }),
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false
      }
    })
  ]
}

Browserify

  • 在运行打包命令时将 NODE_ENV 设置为 "production"。这等于告诉 vueify 避免引入热重载和开发相关的代码。
  • 对打包后的文件进行一次全局的 envify 转换。这使得压缩工具能清除调 Vue 源码中所有用环境变量条件包裹起来的警告语句。例如:
NODE_ENV=production browserify -g envify -e main.js | uglifyjs -c -m > build.js
  • 或者在 Gulp 中使用 envify

    // 使用 envify 的自定义模块来定制环境变量
    var envify = require('envify/custom')
    
    browserify(browserifyOptions)
      .transform(vueify)
      .transform(
        // 必填项,以处理 node_modules 里的文件
        { global: true },
        envify({ NODE_ENV: 'production' })
      )
      .bundle()
    
  • 或者配合 Grunt 和 grunt-browserify 使用 envify

    // 使用 envify 自定义模块指定环境变量
    var envify = require('envify/custom')
    
    browserify: {
      dist: {
        options: {
            // 该函数用来调整 grunt-browserify 的默认指令
            configure: b => b
            .transform('vueify')
            .transform(
                // 用来处理 `node_modules` 文件
              { global: true },
              envify({ NODE_ENV: 'production' })
            )
            .bundle()
        }
      }
    }
    

Rollup

使用 rollup-plugin-replace

const replace = require('rollup-plugin-replace')
rollup({
  // ...
  plugins: [
    replace({
      'process.env.NODE_ENV': JSON.stringify( 'production' )
    })
  ]
}).then(...)

模板预编译

当使用 DOM 内模板或 JavaScript 内的字符串模板时,模板会在运行时被编译为渲染函数。

通常情况下这个过程已经足够快了,但对性能敏感的应用还是最好避免这种用法。


预编译模板最简单的方式就是使用单文件组件——相关的构建设置会自动把预编译处理好,

所以构建好的代码已经包含了编译出来的渲染函数而不是原始的模板字符串。


如果你使用 webpack,并且喜欢分离 JavaScript 和模板文件,

你可以使用 vue-template-loader,它也可以在构建过程中把模板文件转换成为 JavaScript 渲染函数。

提取组件的 CSS

当使用单文件组件时,组件内的 CSS 会以 <style> 标签的方式通过 JavaScript 动态注入。

这有一些小小的运行时开销,如果你使用服务端渲染,这会导致一段“无样式内容闪烁 (fouc)”。

将所有组件的 CSS 提取到同一个文件可以避免这个问题,也会让 CSS 更好地进行压缩和缓存。

查阅这个构建工具各自的文档来了解更多:

  • webpack + vue-loader (vue-cli 的 webpack 模板已经预先配置好)
  • Browserify + vueify
  • Rollup + rollup-plugin-vue

跟踪运行时错误

如果在组件渲染时出现运行错误,错误将会被传递至全局 Vue.config.errorHandler 配置函数 (如果已设置)。

利用这个钩子函数来配合错误跟踪服务是个不错的主意。

比如 Sentry,它为 Vue 提供了官方集成




单文件组件

介绍

在很多 Vue 项目中,我们使用 Vue.component 来定义全局组件,

紧接着用 new Vue({ el: '#container '}) 在每个页面内指定一个容器元素。

这种方式在很多中小规模的项目中运作的很好,在这些项目里 JavaScript 只被用来加强特定的视图。

但当在更复杂的项目中,或者你的前端完全由 JavaScript 驱动的时候,下面这些缺点将变得非常明显:

  • 全局定义 (Global definitions) 强制要求每个 component 中的命名不得重复
  • 字符串模板 (String templates) 缺乏语法高亮,在 HTML 有多行的时候,需要用到丑陋的 \
  • 不支持 CSS (No CSS support) 意味着当 HTML 和 JavaScript 组件化时,CSS 明显被遗漏
  • 没有构建步骤 (No build step) 限制只能使用 HTML 和 ES5 JavaScript, 而不能使用预处理器,如 Pug (formerly Jade) 和 Babel

文件扩展名为 .vue 的 single-file components(单文件组件) 为以上所有问题提供了解决方法,

并且还可以使用 webpack 或 Browserify 等构建工具。

这是一个文件名为 Hello.vue 的简单实例:

现在我们获得:

  • 完整语法高亮
  • CommonJS 模块
  • 组件作用域的 CSS

正如我们说过的,我们可以使用预处理器来构建简洁和功能更丰富的组件,

比如 Pug,Babel (with ES2015 modules),和 Stylus。

这些特定的语言只是例子,

你可以只是简单地使用 Babel,TypeScript,SCSS,PostCSS - 或者其他任何能够帮助你提高生产力的预处理器。

如果搭配 vue-loader 使用 webpack,它也是把 CSS Modules 当作第一公民来对待的。

怎么看待关注点分离?

一个重要的事情值得注意,关注点分离不等于文件类型分离。

在现代 UI 开发中,我们已经发现:

相比于把代码库分离成三个大的层次并将其相互交织起来,把它们划分为松散耦合的组件再将其组合起来更合理一些。

在一个组件里,其模板、逻辑和样式是内部耦合的,并且把他们搭配在一起实际上使得组件更加内聚且更可维护。

即便你不喜欢单文件组件,你仍然可以把 JavaScript、CSS 分离成独立的文件然后做到热重载和预编译。

<!-- my-component.vue -->
<template>
  <div>This will be pre-compiled</div>
</template>
<script src="./my-component.js"></script>
<style src="./my-component.css"></style>

起步

例子沙箱

如果你希望深入了解并开始使用单文件组件,请来 CodeSandbox 看看这个简单的 todo 应用

针对刚接触 JavaScript 模块开发系统的用户

有了 .vue 组件,我们就进入了高级 JavaScript 应用领域。

如果你没有准备好的话,意味着还需要学会使用一些附加的工具:

  • Node Package Manager (NPM):阅读 Getting Started guide 直到 10: Uninstalling global packages章节。

  • Modern JavaScript with ES2015/16:阅读 Babel 的 Learn ES2015 guide。你不需要立刻记住每一个方法,但是你可以保留这个页面以便后期参考。

在你花一天时间了解这些资源之后,我们建议你参考 webpack 模板。

只要遵循指示,你就能很快地运行一个用到 .vue 组件,ES2015 和热重载 (hot-reloading) 的 Vue 项目!

想学习更多 webpack 的知识,请移步它们的官方文档以及 webpack learning academy


在 webpack 中,每个模块被打包到 bundle 之前都由一个相应的“loader”来转换,

Vue 也提供 vue-loader 插件来执行 .vue 单文件组件 的转换。

针对高级用户

无论你更钟情 webpack 或是 Browserify,我们为简单的和更复杂的项目都提供了一些文档模板。

我们建议浏览 github.com/vuejs-templates,找到你需要的部分,

然后参考 README 中的说明,使用 vue-cli 工具生成新的项目。


模板中使用 webpack,一个模块加载器加载多个模块然后构建成最终应用。

为了进一步了解 webpack,可以看 官方介绍视频。如果你有基础,可以看 在 Egghead.io 上的 webpack 进阶教程



单元测试

配置和工具

任何兼容基于模块的构建系统都可以正常使用,但如果你需要一个具体的建议,可以使用 Karma 进行自动化测试。

它有很多社区版的插件,包括对 Webpack 和 Browserify 的支持。


更多详细的安装步骤,请参考各项目的安装文档,

通过这些 Karma 配置的例子可以快速帮助你上手 (Webpack 配置,Browserify 配置)。

简单的断言

你不必为了可测性在组件中做任何特殊的操作,导出原始设置就可以了:

<template>
  <span>{{ message }}</span>
</template>

<script>
  export default {
    data () {
      return {
        message: 'hello!'
      }
    },
    created () {
      this.message = 'bye!'
    }
  }
</script>

然后随着 Vue 导入组件的选项,你可以使用许多常见的断言:

// 导入 Vue.js 和组件,进行测试
import Vue from 'vue'
import MyComponent from 'path/to/MyComponent.vue'

// 这里是一些 Jasmine 2.0 的测试,你也可以使用你喜欢的任何断言库或测试工具。

describe('MyComponent', () => {
  // 检查原始组件选项
  it('has a created hook', () => {
    expect(typeof MyComponent.created).toBe('function')
  })

  // 评估原始组件选项中的函数的结果
  it('sets the correct default data', () => {
    expect(typeof MyComponent.data).toBe('function')
    const defaultData = MyComponent.data()
    expect(defaultData.message).toBe('hello!')
  })

  // 检查 mount 中的组件实例
  it('correctly sets the message when created', () => {
    const vm = new Vue(MyComponent).$mount()
    expect(vm.message).toBe('bye!')
  })

  // 创建一个实例并检查渲染输出
  it('renders the correct message', () => {
    const Constructor = Vue.extend(MyComponent)
    const vm = new Constructor().$mount()
    expect(vm.$el.textContent).toBe('bye!')
  })
})

编写可被测试的组件

很多组件的渲染输出由它的 props 决定。

事实上,如果一个组件的渲染输出完全取决于它的 props,

那么它会让测试变得简单,就好像断言不同参数的纯函数的返回值。

看下面这个例子:

<template>
  <p>{{ msg }}</p>
</template>

<script>
  export default {
    props: ['msg']
  }
</script>

你可以在不同的 props 中,通过 propsData 选项断言它的渲染输出:

import Vue from 'vue'
import MyComponent from './MyComponent.vue'

// 挂载元素并返回已渲染的文本的工具函数
function getRenderedText (Component, propsData) {
  const Constructor = Vue.extend(Component)
  const vm = new Constructor({ propsData: propsData }).$mount()
  return vm.$el.textContent
}

describe('MyComponent', () => {
  it(
                      

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
vue3.0+vite+axios+vuex+vue-router+typescript发布时间:2022-07-18
下一篇:
Typescript类型限定发布时间:2022-07-18
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap