使用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 相关文章推荐
JS中字符问题(二进制/十进制/十六进制及ASCII码之间的转换)
Nov 03 Javascript
jquery实现在页面加载完毕后获取图片高度或宽度
Jun 16 Javascript
JavaScript电子时钟倒计时第二款
Jan 10 Javascript
javascript事件绑定学习要点
Mar 09 Javascript
JS中的二叉树遍历详解
Mar 18 Javascript
jQuery的extend方法【三种】
Dec 14 Javascript
利用Vue.js实现checkbox的全选反选效果
Jan 18 Javascript
jQuery实现的隔行变色功能【案例】
Feb 18 jQuery
jQuery实现的卷帘门滑入滑出效果【案例】
Feb 18 jQuery
微信小程序登录时如何获取input框中的内容
Dec 04 Javascript
JS+CSS实现3D切割轮播图
Mar 21 Javascript
Vue3中的Refs和Ref详情
Nov 11 Vue.js
微信小程序本地存储实现每日签到、连续签到功能
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
PHP 页面跳转到另一个页面的多种方法方法总结
2009/07/07 PHP
PHP 验证码不显示只有一个小红叉的解决方法
2013/09/30 PHP
php限制文件下载速度的代码
2015/10/20 PHP
php制作的简单验证码识别代码
2016/01/26 PHP
PHP读取大文件的几种方法介绍
2016/10/27 PHP
PHP获取文件扩展名的常用方法小结【五种方式】
2018/04/27 PHP
非常好的js代码
2006/06/27 Javascript
javascript 导出数据到Excel(处理table中的元素)
2009/12/18 Javascript
复制小说文本时出现的随机乱码的去除方法
2010/09/07 Javascript
Node.js的MongoDB驱动Mongoose基本使用教程
2016/03/01 Javascript
JS 对java返回的json格式的数据处理方法
2016/12/05 Javascript
基于JavaScript实现熔岩灯效果导航菜单
2017/01/04 Javascript
thinkjs之页面跳转同步异步操作
2017/02/05 Javascript
网页中右键功能的实现方法之contextMenu的使用
2017/02/20 Javascript
underscore之function_动力节点Java学院整理
2017/07/11 Javascript
基于 D3.js 绘制动态进度条的实例详解
2018/02/26 Javascript
解决axios会发送两次请求,有个OPTIONS请求的问题
2018/10/25 Javascript
用vue 实现手机触屏滑动功能
2020/05/28 Javascript
Python读写ini文件的方法
2015/05/28 Python
python随机取list中的元素方法
2018/04/08 Python
python版opencv摄像头人脸实时检测方法
2018/08/03 Python
深入理解Python中的 __new__ 和 __init__及区别介绍
2018/09/17 Python
python调用java的jar包方法
2018/12/15 Python
python消费kafka数据批量插入到es的方法
2018/12/27 Python
django之使用celery-把耗时程序放到celery里面执行的方法
2019/07/12 Python
Python Handler处理器和自定义Opener原理详解
2020/03/05 Python
python字典按照value排序方法
2020/12/28 Python
html5使用window.postMessage进行跨域实现数据交互的一次实战
2021/02/24 HTML / CSS
Ticketmaster意大利:音乐会、节日、艺术和剧院的官方门票
2019/12/23 全球购物
超市业务员岗位职责
2013/12/05 职场文书
餐饮采购员岗位职责
2014/03/15 职场文书
三年级小学生评语
2014/04/22 职场文书
高一军训的心得体会
2014/09/01 职场文书
企业廉洁教育心得体会
2016/01/20 职场文书
为什么中国式养孩子很累?
2019/08/07 职场文书
HTML中link标签属性的具体用法
2023/05/07 HTML / CSS