使用Webpack提升Vue.js应用程序的4种方法(翻译)


Posted in Javascript onOctober 09, 2019

本文翻译自,翻译技巧不太好,不喜勿碰 :
4 Ways To Boost Your Vue.js App With Webpack

众所周知,webpack 是 开发 vue.js 单页面应用程序的必备工具,通过管理复杂的构建步骤,它可以使您的开发工作流程更加简单,并且可以优化应用程序的大小和性能。

在本文中,我将解释Webpack增强Vue应用程序的四种方法,包括:

  • Single file components 单文件组件
  • Optimising the Vue build
  • Browser cache management
  • Code splitting

关于 vue-cli

如果您使用模板从vue-cli构建应用程序,那么将提供预制的Webpack配置。它们已经过优化,没有任何改进建议!
但是,由于它们开箱即用的效果非常好,您可能对它们的实际功能并不太了解,对吗?
考虑一下本文,对vue-cli模板中使用的Webpack配置进行概述,因为它们包含了我在这里讨论的相同优化。

1. Single file components

Vue的特有功能之一是将HTML用于组件模板。但是,这些带有一个固有的问题:要么您的HTML标记需要使用笨拙的JavaScript字符串,要么您的模板和组件定义必须位于单独的文件中,从而使其难以使用。

Vue有一个优雅的解决方案,称为“单个文件组件(SFC)”,该文件将模板,组件定义和CSS都包含在一个简单的.vue文件中:

<template>
 <div id="my-component">...</div>
</template>
<script>
 export default {...}
</script>
<style>
 #my-component {...}
</style>

vue-loader Webpack插件使SFC成为可能。该加载器拆分SFC语言块并将每个管道通过管道传输到适当的加载器,例如脚本块转到babel-loader,而模板块转到Vue自己的vue-template-loader,后者将模板转换为JavaScript渲染函数。
vue-loader的最终输出是一个JavaScript模块,准备将其包含在Webpack捆绑包中。

vue-loader的典型配置如下:

module: {
 rules: [
  {
   test: /\.vue$/,
   loader: 'vue-loader',
   options: {
    loaders: {
     // Override the default loaders
    }
   }
  },
 ]
}

2. Optimising the Vue build

如果仅在Vue应用程序*中使用渲染功能,而没有HTML模板,则不需要Vue的模板编译器。您可以通过从Webpack构建中省略编译器来减小捆绑包的大小。

请记住,单个文件组件模板已在开发中预编译以呈现功能!

Vue.js库只有运行时版本,其中包含Vue.js的所有功能,但模板编译器称为vue.runtime.js。它比完整版本小20KB,因此如果可以的话值得使用。

默认情况下,仅使用运行时构建,因此,每次使用 import vue from 'vue' 时,都将使用它。在您的项目中,这就是您所得到的。但是,您可以使用alias 别名配置选项更改为其他版本:

resolve: {
 alias: {
  'vue$': 'vue/dist/vue.esm.js' // Use the full build
 }
},

Stripping out warnings and error messages in production

减小Vue.js构建大小的另一种方法是删除生产中的任何错误消息和警告。这些使用不必要的代码使输出包大小膨胀,并且还导致您最好避免运行时开销

如果您检查Vue源代码,则会看到警告块取决于环境变量process.env.NODE_ENV的值,例如:

if (process.env.NODE_ENV !== 'production') {
 warn(("Error in " + info + ": \"" + (err.toString()) + "\""), vm);
}

如果将process.env.NODE_ENV设置为生产,那么在构建过程中,minifier可以自动将此类警告块从代码中剥离。

您可以使用DefinePlugin来设置process.env.NODE_ENV的值,并使用UglifyJsPlugin来减少代码并去除未使用的块:

if (process.env.NODE_ENV === 'production') {
 module.exports.plugins = (module.exports.plugins || []).concat([
  new webpack.DefinePlugin({
   'process.env': {
    NODE_ENV: '"production"'
   }
  }),
  new webpack.optimize.UglifyJsPlugin()
 ])
}

3. Browser cache management

用户的浏览器将缓存您网站的文件,以便仅在该浏览器尚无本地副本或本地副本已过期时才下载。

如果您所有的代码都在一个文件中,那么进行微小的更改就意味着需要重新下载整个文件。

理想情况下,您希望用户下载得尽可能少,因此将应用程序很少更改的代码与频繁更改的代码分开是明智的。

Vendor file

Common Chunks插件可以将您的 vendor 代码(例如,不太可能经常更改的Vue.js库之类的依赖项)与您的应用程序代码(每次部署可能更改的代码)分离。

您可以配置插件以检查依赖项是否来自node_modules文件夹,如果是,则将其输出到单独的文件vendor.js中:

new webpack.optimize.CommonsChunkPlugin({
 name: 'vendor',
 minChunks: function (module) {
  return module.context && module.context.indexOf('node_modules') !== -1;
 }
})

如果这样做,您现在在构建输出中将有两个单独的文件,这些文件将由浏览器独立缓存:

<script src="vendor.js" charset="utf-8"></script>
<script src="app.js" charset="utf-8"></script>

Fingerprinting

当构建文件更改时,我们如何破坏浏览器的缓存?

默认情况下,仅当缓存的文件到期时,或者当用户手动清除缓存时,浏览器才会再次从服务器请求文件。

如果服务器指示文件已更改,则将重新下载该文件(否则服务器返回HTTP 304 Not Modified)。

为了节省不必要的服务器请求,我们可以在每次文件内容更改时更改其名称,以强制浏览器重新下载该文件。一个简单的系统可以通过在文件名后附加一个哈希来为文件名添加“指纹”:

使用Webpack提升Vue.js应用程序的4种方法(翻译)

Common Chunks插件会发出“ chunkhash”,如果文件内容已更改,则将对其进行更新。 Webpack可以在输出文件名时将此哈希附加到文件名中:

output: {
 filename: '[name].[chunkhash].js'
},

执行此操作时,您将看到输出的文件将具有类似app.3b80b7c17398c31e4705.js的名称。

Auto inject build files

当然,如果添加哈希,则必须更新索引文件中对该文件的引用,否则浏览器将不知道该哈希:

<script src="app.3b80b7c17398c31e4705.js"></script>

手动完成这项工作非常繁琐,因此请使用HTML Webpack插件为您完成。该插件可以在捆绑过程中自动将对构建文件的引用注入到HTML文件中。

首先删除对构建文件的引用:

<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8">
  <title>test-6</title>
 </head>
 <body>
  <div id="app"></div>
  <!-- built files should go here, but will be auto injected -->
 </body>
</html>

并将HTML Webpack插件添加到您的Webpack配置中:

new HtmlWebpackPlugin({
 filename: 'index.html'
 template: 'index.html',
 inject: true,
 chunksSortMode: 'dependency'
}),

现在,带有哈希的构建文件将自动添加到索引文件中。另外,您的index.html文件现在将包含在捆绑输出中,因此您可能需要告诉Web服务器其位置已更改

4. Code splitting

默认情况下,Webpack会将所有应用程序代码输出到一个大捆绑包中。但是,如果您的应用有多个页面,则拆分代码会更有效,因此每个单独的页面代码都位于单独的文件中,并且仅在需要时才加载
Webpack具有一项称为“代码拆分”的功能。在Vue.js中实现此功能还需要异步组件,并且通过Vue Router变得更加容易。

Async components

异步组件没有将定义对象作为第二个参数,而是具有一个Promise函数来解析该定义对象,例如:

Vue.component('async-component', function (resolve, reject) {
 setTimeout(() => {
  resolve({
   // Component definition including props, methods etc.
  });
 }, 1000)
})

Vue仅在组件实际需要渲染时才调用该函数。它还会缓存结果以供将来重新渲染。
如果我们设计应用程序,使每个“页面”都是一个组件,并且将定义存储在服务器上,那么我们就完成了代码拆分的一半。

require

要从服务器加载异步组件的代码,请使用Webpack require语法
这将指示Webpack在构建时将async-component捆绑在一个单独的bundle中,更好的是,Webpack将使用AJAX处理此bundle的加载,因此您的代码可以像这样简单:

Vue.component('async-component', function (resolve) {
 require(['./AsyncComponent.vue'], resolve)
});

Lazy loading

在Vue.js应用程序中,vue-router通常是您用于将SPA组织到多个页面中的模块。延迟加载是使用Vue和Webpack实现代码拆分的一种形式化方法。

const HomePage = resolve => require(['./HomePage.vue'], resolve);const rounter = new VueRouter({ routes: [  {   path: '/',   name: 'HomePage',   component: HomePage  } ]})

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

Javascript 相关文章推荐
JavaScript入门教程(1) 什么是JS
Jan 31 Javascript
jQuery EasyUI API 中文文档 - MenuButton菜单按钮使用介绍
Oct 06 Javascript
jQuery点击后一组图片左右滑动的实现代码
Aug 16 Javascript
JS HTML5 音乐天气播放器(Ajax获取天气信息)
May 26 Javascript
用js读、写、删除Cookie代码续篇
Dec 03 Javascript
jquery实现鼠标滑过后动态图片提示效果实例
Aug 10 Javascript
javascript实现的网站访问量统计代码
Dec 20 Javascript
使用jquery.form.js实现图片上传的方法
May 05 Javascript
如何让你的JS代码更好看易读
Dec 01 Javascript
解决在Bootstrap模糊框中使用WebUploader的问题
Mar 22 Javascript
微信小程序模板消息限制实现无限制主动推送的示例代码
Aug 27 Javascript
Vuex中的Mutations的具体使用方法
Jun 01 Javascript
微信小程序本地存储实现每日签到、连续签到功能
Oct 09 #Javascript
Vue.js实现大转盘抽奖总结及实现思路
Oct 09 #Javascript
js基础之事件捕获与冒泡原理
Oct 09 #Javascript
微信内置浏览器图片查看器的代码实例
Oct 08 #Javascript
vue封装swiper代码实例解析
Oct 08 #Javascript
jQuery实现提交表单时不提交隐藏div中input的方法
Oct 08 #jQuery
简单实现节流函数和防抖函数过程解析
Oct 08 #Javascript
You might like
支持php4、php5的mysql数据库操作类
2008/01/10 PHP
基于PHP 面向对象之成员方法详解
2013/05/04 PHP
PHP把空格、换行符、中文逗号等替换成英文逗号的正则表达式
2014/05/04 PHP
PHP结合jQuery.autocomplete插件实现输入自动完成提示的功能
2015/04/27 PHP
ThinkPHP中使用Ueditor富文本编辑器
2015/09/02 PHP
PHP实现的简单分页类及用法示例
2016/05/06 PHP
jQuery技巧总结
2011/01/01 Javascript
js简单实现删除记录时的提示效果
2013/12/05 Javascript
关于JS中的方法是否加括号的问题
2016/07/27 Javascript
ajax级联菜单实现方法实例分析
2016/11/28 Javascript
AngularJs 利用百度地图API 定位当前位置 获取地址信息
2017/01/18 Javascript
Bootstrap面板学习使用
2017/02/09 Javascript
AngularJS双向绑定和依赖反转实例详解
2017/04/15 Javascript
Vue.js鼠标悬浮更换图片功能
2017/05/17 Javascript
js轮播图无缝滚动效果
2017/06/17 Javascript
Vue实现数字输入框中分割手机号码的示例
2017/10/10 Javascript
AngularJS实现表单元素值绑定操作示例
2017/10/11 Javascript
vue 中基于html5 drag drap的拖放效果案例分析
2018/11/01 Javascript
利用Vue-draggable组件实现Vue项目中表格内容的拖拽排序
2019/06/07 Javascript
解决vue watch数据的方法被调用了两次的问题
2020/11/07 Javascript
[02:02]2018DOTA2亚洲邀请赛Mineski赛前采访
2018/04/04 DOTA
python根据出生年份简单计算生肖的方法
2015/03/27 Python
python获取外网ip地址的方法总结
2015/07/02 Python
Python实现截屏的函数
2015/07/25 Python
Python 12306抢火车票脚本
2018/02/07 Python
wxPython的安装与使用教程
2018/08/31 Python
python自动化之Ansible的安装教程
2019/06/13 Python
Python安装Bs4的多种方法
2020/11/28 Python
Python字符串的15个基本操作(小结)
2021/02/03 Python
乌克兰巴士票购买网站:inBus
2021/03/12 全球购物
方法名是否可以与构造器的名字相同
2012/06/04 面试题
合唱兴趣小组活动总结
2014/07/10 职场文书
亲子运动会的活动方案
2014/08/17 职场文书
幼儿园圣诞节活动总结
2015/05/06 职场文书
美甲店的创业计划书模板
2019/08/23 职场文书
日本十大血腥动漫,那些被禁播的动漫盘点
2022/03/21 日漫