Laravel框架中缩小Vue应用的体积

栏目: PHP · 发布时间: 6年前

内容简介:Laravel框架中缩小Vue应用的体积

这两天写一个很小的Laravel+Vue的前后端分离应用,前端的代码文件并不多,但webpack打包生成的app.js居然有3M,生成的production版也有1.4M,放到自己的服务器上,那速度完全无法忍受。于是探究起如何缩小应用体积。

定位导致应用体积大的原因

这里使用 webpack-bundle-analyzer ,该插件可以将内容束显示为很直观的树状图,让你明白构建包中真正引入的内容。借助这个插件可以了解应用有哪些模块组成,找到不合时宜的存在,然后进行优化。

  1. 安装: npm install --save-dev webpack-bundle-analyzer
  2. 修改webpack.mix.js,注意 Laravel 自带的 webpack-mix 的配置方式与平常的webpack配置略有不同
    const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
    
    mix.webpackConfig({
      plugins: [
        new BundleAnalyzerPlugin(),
      ],
    }).js('resources/assets/js/app.js', 'public/js')
      .sass('resources/assets/sass/app.scss', 'public/css');

修改完之后像平常一样使用 npm run devnpm run production 打包应用,打包完成后,会自动打开 http://127.0.0.1:8888 来展示结果。

Laravel框架中缩小Vue应用的体积

解决办法

从上面的这张图可以分析出导致应用体积变大的原因就是在于引用很多第三方库,这些库会被webpack一起打包到应用内,所以减小应用体积的最有效方法就是将这些库分离出去,别将它们与我们自己写的应用代码打包到一起。大部分有名的第三方库在公共CDN都有存放,如 bootcss , unpkg 等,速度飞快,可以直接引用。

webpack的选项有一个 externals ,可以指定哪些包不参与打包,即忽略掉相应 import XXX from package ,而代码中依旧可以通过CMD、AMD或window/global全局的方式访问。

mix.webpackConfig({
  plugins: [
    new BundleAnalyzerPlugin(),
  ],
  externals: {
    'element-ui': 'Element',
    'axios': 'axios',
    'vue': 'Vue',
    'vuex': 'Vuex',
    'vue-router': 'VueRouter',
    'vue-chartjs': 'VueChartJs',
    'lodash': '_',
  }
}).js('resources/assets/js/app.js', 'public/js')
 .sass('resources/assets/sass/app.scss', 'public/css')
 .styles(['node_modules/element-ui/lib/theme-chalk/index.css'], 'public/css/element-ui.css');

在blade文件中加入外链

<head>
    ...
    <script src="//cdn.bootcss.com/vue/2.5.13/vue.min.js"></script>
    <script src="//cdn.bootcss.com/vuex/3.0.1/vuex.min.js"></script>
    <script src="//cdn.bootcss.com/vue-router/3.0.1/vue-router.min.js"></script>
    <script src="//cdn.bootcss.com/element-ui/2.0.11/index.js"></script>
    <script src="//cdn.bootcss.com/axios/0.17.1/axios.min.js"></script>
    <script src="//cdn.bootcss.com/lodash.js/4.17.4/lodash.min.js"></script>
    <script src="//unpkg.com/vue-chartjs@2.8.7/dist/vue-chartjs.full.min.js"></script>
    <link href="https://cdn.bootcss.com/element-ui/2.0.11/theme-chalk/index.css" rel="stylesheet">
    ...
</head>

然后重新打包应用,最后生成的应用只有几十K了,这大小已经不成问题了

进一步优化

这里将第三方库完全改为外链,在生成环境内是没问题,但我们在开发时,并不希望每次都是从网络获取第三方库,网络加载始终不会有本地加载来的快,本地加载并不需要考虑大小问题。

我们可以通过使用环境变量来控制要不要使用外链。

在.env中添加一个变量 MIX_EXTERNAL=true (注意:如果要在App应用里使用这个变量,这里必须是以 MIX_ 开头,参考Mix 环境变量)

Laravel自带的webpack-mix默认不加载 .env 文件,但已经带有 dotenv 包,加载即可。

最后的 webpack.mix.js 文件如下

let mix = require('laravel-mix');
require('dotenv').config();

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

let externals = undefined;
if (process.env.MIX_EXTERNAL === 'true') {
  externals = {
    'element-ui': 'Element',
    'axios': 'axios',
    'vue': 'Vue',
    'vuex': 'Vuex',
    'vue-router': 'VueRouter',
    'vue-chartjs': 'VueChartJs',
    'lodash': '_',
  };
}

mix.webpackConfig({
  plugins: [
    // new BundleAnalyzerPlugin(),
  ],
  externals,
})
  .js('resources/assets/js/app.js', 'public/js')
  .sass('resources/assets/sass/app.scss', 'public/css')
  .styles(['node_modules/element-ui/lib/theme-chalk/index.css'], 'public/css/element-ui.css');

blade文件:

@if (env('MIX_EXTERNAL'))
    <script src="//cdn.bootcss.com/vue/2.5.13/vue.min.js"></script>
    <script src="//cdn.bootcss.com/vuex/3.0.1/vuex.min.js"></script>
    <script src="//cdn.bootcss.com/vue-router/3.0.1/vue-router.min.js"></script>
    <script src="//cdn.bootcss.com/element-ui/2.0.11/index.js"></script>
    <script src="//cdn.bootcss.com/axios/0.17.1/axios.min.js"></script>
    <script src="//cdn.bootcss.com/lodash.js/4.17.4/lodash.min.js"></script>
    <script src="//unpkg.com/vue-chartjs@2.8.7/dist/vue-chartjs.full.min.js"></script>
    <link href="https://cdn.bootcss.com/element-ui/2.0.11/theme-chalk/index.css" rel="stylesheet">
@else
    <link rel="stylesheet" href="css/element-ui.css">
@endif

应用内有些代码需要针对外链做区别处理,如ElementUI,如果使用 import 方式引入,需要加入 Vue.use(ElementUI) ,但如果使用外链时,这句会出错,所以可以加入判断

if (process.env.MIX_EXTERNAL !== 'true') { // **注意是字符串**
  Vue.use(Element);
}

在app内使用 process.env.MIX_XXXXX 环境变量时,这些变量实际在打包过程中已经被替换为变量值(就像C里面的宏定义一样),不会在运行求值,也不存在 process 对象,上面的if语句在打包后变成 if (false) Vue.use(Element)

至此优化完毕,只需在 .env 里修改一下变量,即可在两种打包方式间切换,可以愉快地继续开发了。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Designing Data-Intensive Applications

Designing Data-Intensive Applications

Martin Kleppmann / O'Reilly Media / 2017-4-2 / USD 44.99

Data is at the center of many challenges in system design today. Difficult issues need to be figured out, such as scalability, consistency, reliability, efficiency, and maintainability. In addition, w......一起来看看 《Designing Data-Intensive Applications》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

SHA 加密
SHA 加密

SHA 加密工具