defineplugin webpack_使用webpack提升vue.js应用程序的四种方法

0c6aa885810a00d9f70ccb86ccc793fa.png
使用webpack提升vue.js应用程序的四种方法​mp.weixin.qq.com
53875d4fee13f268c94b058ea464718b.png

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

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

  • 单一文件组件
  • 优化Vue构建
  • 浏览器缓存管理
  • 代码分离

vue-cli怎么样?

如果您使用模板从vue-cli构建您的应用程序,将提供一个预先制作的Webpack配置。它们已经被很好地优化了,而且我不能建议任何改进!

但由于它们的开箱即用效果非常好,你可能对它们真正在做什么并不了解,对吧?考虑一下本文对vue-cli模板中使用的Webpack配置的概述,因为它们包含了我在这里讨论的相同的优化。

一、单一文件组件

Vue的特性之一是使用HTML作为组件模板。但是,这些都有一个内在的问题:要么HTML标记需要放在一个笨拙的JavaScript字符串中,要么模板和组件定义需要放在单独的文件中,这使得它们很难处理。

Vue有一个优雅的解决方案,称为单文件组件(SFCs),其中包括模板、组件定义和CSS都在一个整洁的.vue文件中:

MyComponent.vue

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

SFCs是由vue-loader Webpack插件实现的。这个加载器将SFCs语言块分割开来,并将每个块通过管道传输到一个适当的加载器,例如脚本块传输到babel-loader,而模板块传输到Vue自己的Vue -template-loader,后者将模板转换成JavaScript呈现函数。

vue-loader的最终输出是一个JavaScript模块,可以包含在您的Webpack包中。

典型配置vue-loader如下:

module: {
  rules: [
    {
      test: /.vue$/,
      loader: 'vue-loader',
      options: {
        loaders: {
          // 覆盖默认加载器
        }
      }
    },
  ]
}

二、优化Vue构建

运行时只构建

如果只在Vue应用程序*中使用呈现函数,而没有HTML模板,则不需要Vue的模板编译器。您可以通过从Webpack构建中省略编译器来减小包的大小。

*请记住,单个文件组件模板是在开发中预编译来呈现函数的!

有一个只运行时构建的Vue.js库,它包含了Vue.js的所有特性,除了模板编译器vue.runtime.js。它比完整的构建版本小大约20KB,所以如果可以的话值得使用。

默认情况下只使用运行时构建,所以每次使用从“vue”导入vue;在你的项目中,你会得到这样的结果。不过,您可以通过使用别名配置选项切换到另一个版本:

resolve: {
  alias: {
    'vue$': 'vue/dist/vue.esm.js' // 使用完整的构建
  }
},

删除生产中的警告和错误消息

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

如果检查Vue源代码,您将看到警告块是以环境变量process.env.node_env的值为条件的,例如:

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

如果process.env。将NODE_ENV设置为production,然后可以在构建过程中通过一个缩小器自动将这些警告块从代码中删除。

您可以使用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()
  ])
}

三、浏览器缓存管理

用户的浏览器将缓存站点的文件,这样只有在浏览器还没有本地副本,或者本地副本已经过期时,它们才会下载。

如果您的所有代码都在一个文件中,那么一个小小的更改就意味着需要重新下载整个文件。理想情况下,您希望用户尽可能少地下载,因此明智的做法是将应用程序很少更改的代码与频繁更改的代码分开。

供应商文件

公共块插件可以将您的供应商代码(例如依赖关系,如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>

指纹识别

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

默认情况下,只有当缓存的文件过期或用户手动清除缓存时,浏览器才会再次从服务器请求该文件。如果服务器指示文件已更改,则将重新下载该文件(否则服务器返回HTTP 304未修改)。

为了保存不必要的服务器请求,我们可以每次更改文件的内容时更改它的名称,以迫使浏览器重新下载它。一个简单的系统可以做到这一点,就是在文件名中添加一个“指纹”,方法是添加一个散列,例如:

517e025507bf5dd06ed641c9a440a97a.png

Common Chunks插件会发出一个“chunkhash”,如果文件的内容发生了变化,它就会进行更新。Webpack可以在文件名输出时附加这个散列:

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

当您这样做时,您将看到您输出的文件的名称将类似于app.3b80b7c17398c31e4705.js。

自动注入构建文件

当然,如果你添加了一个散列,你就必须在索引文件中更新对文件的引用,否则浏览器不会知道:

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

这将是一个非常单调乏味的手工任务,所以使用HTML Webpack插件来为您完成它。这个插件可以自动将对构建文件的引用注入到绑定过程中的HTML文件中。

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

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>test-6</title>
  </head>
  <body>
    <div id="app"></div>
    <!-- 构建的文件应该在这里,但将自动注入 -->
  </body>
</html>

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

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

现在,带有散列的构建文件将自动添加到索引文件中。此外,您的index.html文件现在将包含在包输出中,因此您可能需要告诉web服务器它的位置已经更改。

四、代码分离

默认情况下,Webpack将把所有应用程序代码输出到一个大的包中。但是,如果你的应用程序有多个页面,那么分割代码会更有效,因此每个单独的页面代码都在一个单独的文件中,并且只在需要时加载。

Webpack有一个叫做“代码分割”的功能,它就是这样做的。在Vue.js中实现这一点还需要异步组件,使用Vue路由器甚至更容易。

异步组件

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

Vue.component('async-component', function (resolve, reject) {
  setTimeout(() => {
    resolve({
      // 组件定义包括道具、方法等。
    });
  }, 1000)
})

Vue只在组件实际需要呈现时调用该函数。它还将缓存结果,以便将来重新呈现。

如果我们设计我们的应用程序,使每个“页面”都是一个组件,并将定义存储在服务器上,那么我们就完成了代码分割的一半。

需要

要从服务器加载异步组件的代码,请使用Webpack require语法。这将指导Webpack在构建异步组件时将其捆绑到一个单独的捆绑包中,更好的是,Webpack将使用AJAX处理这个捆绑包的加载,所以您的代码可以像这样简单:

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

延迟加载

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

const HomePage = resolve => require(['./HomePage.vue'], resolve);

const rounter = new VueRouter({
  routes: [
    {
      path: '/',
      name: 'HomePage',
      component: HomePage
    }
  ]
})
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值